1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/* $NetBSD: frameasm.h,v 1.20 2012/07/15 15:17:56 dsl Exp $ */
#ifndef _AMD64_MACHINE_FRAMEASM_H
#define _AMD64_MACHINE_FRAMEASM_H
#ifdef _KERNEL_OPT
#include "opt_xen.h"
#endif
/*
* Macros to define pushing/popping frames for interrupts, traps
* and system calls. Currently all the same; will diverge later.
*/
#ifdef XEN
#define HYPERVISOR_iret hypercall_page + (__HYPERVISOR_iret * 32)
/* Xen do not need swapgs, done by hypervisor */
#define swapgs
#define iretq pushq $0 ; jmp HYPERVISOR_iret
#define XEN_ONLY2(x,y) x,y
#define NOT_XEN(x)
#define CLI(temp_reg) \
movq CPUVAR(VCPU),%r ## temp_reg ; \
movb $1,EVTCHN_UPCALL_MASK(%r ## temp_reg);
#define STI(temp_reg) \
movq CPUVAR(VCPU),%r ## temp_reg ; \
movb $0,EVTCHN_UPCALL_MASK(%r ## temp_reg);
#else /* XEN */
#define XEN_ONLY2(x,y)
#define NOT_XEN(x) x
#define CLI(temp_reg) cli
#define STI(temp_reg) sti
#endif /* XEN */
#define SWAPGS NOT_XEN(swapgs)
/*
* These are used on interrupt or trap entry or exit.
*/
#define INTR_SAVE_GPRS \
movq %rdi,TF_RDI(%rsp) ; \
movq %rsi,TF_RSI(%rsp) ; \
movq %rdx,TF_RDX(%rsp) ; \
movq %rcx,TF_RCX(%rsp) ; \
movq %r8,TF_R8(%rsp) ; \
movq %r9,TF_R9(%rsp) ; \
movq %r10,TF_R10(%rsp) ; \
movq %r11,TF_R11(%rsp) ; \
movq %r12,TF_R12(%rsp) ; \
movq %r13,TF_R13(%rsp) ; \
movq %r14,TF_R14(%rsp) ; \
movq %r15,TF_R15(%rsp) ; \
movq %rbp,TF_RBP(%rsp) ; \
movq %rbx,TF_RBX(%rsp) ; \
movq %rax,TF_RAX(%rsp) ; \
cld
#define INTR_RESTORE_GPRS \
movq TF_RDI(%rsp),%rdi ; \
movq TF_RSI(%rsp),%rsi ; \
movq TF_RDX(%rsp),%rdx ; \
movq TF_RCX(%rsp),%rcx ; \
movq TF_R8(%rsp),%r8 ; \
movq TF_R9(%rsp),%r9 ; \
movq TF_R10(%rsp),%r10 ; \
movq TF_R11(%rsp),%r11 ; \
movq TF_R12(%rsp),%r12 ; \
movq TF_R13(%rsp),%r13 ; \
movq TF_R14(%rsp),%r14 ; \
movq TF_R15(%rsp),%r15 ; \
movq TF_RBP(%rsp),%rbp ; \
movq TF_RBX(%rsp),%rbx ; \
movq TF_RAX(%rsp),%rax
#define INTRENTRY_L(kernel_trap, usertrap) \
subq $TF_REGSIZE,%rsp ; \
INTR_SAVE_GPRS ; \
testb $SEL_UPL,TF_CS(%rsp) ; \
je kernel_trap ; \
usertrap ; \
SWAPGS ; \
movw %gs,TF_GS(%rsp) ; \
movw %fs,TF_FS(%rsp) ; \
movw %es,TF_ES(%rsp) ; \
movw %ds,TF_DS(%rsp)
#define INTRENTRY \
INTRENTRY_L(98f,) ; \
98:
#define INTRFASTEXIT \
INTR_RESTORE_GPRS ; \
testq $SEL_UPL,TF_CS(%rsp) /* Interrupted %cs */ ; \
je 99f ; \
/* Disable interrupts until the 'iret', user registers loaded. */ \
NOT_XEN(cli;) \
movw TF_ES(%rsp),%es ; \
movw TF_DS(%rsp),%ds ; \
SWAPGS ; \
99: addq $TF_REGSIZE+16,%rsp /* + T_xxx and error code */ ; \
iretq
#define INTR_RECURSE_HWFRAME \
movq %rsp,%r10 ; \
movl %ss,%r11d ; \
pushq %r11 ; \
pushq %r10 ; \
pushfq ; \
movl %cs,%r11d ; \
pushq %r11 ; \
/* XEN: We must fixup CS, as even kernel mode runs at CPL 3 */ \
XEN_ONLY2(andb $0xfc,(%rsp);) \
pushq %r13 ;
#define DO_DEFERRED_SWITCH \
cmpl $0, CPUVAR(WANT_PMAPLOAD) ; \
jz 1f ; \
call _C_LABEL(do_pmap_load) ; \
1:
#define CHECK_DEFERRED_SWITCH \
cmpl $0, CPUVAR(WANT_PMAPLOAD)
#define CHECK_ASTPENDING(reg) cmpl $0, L_MD_ASTPENDING(reg)
#define CLEAR_ASTPENDING(reg) movl $0, L_MD_ASTPENDING(reg)
#endif /* _AMD64_MACHINE_FRAMEASM_H */
|