frameasm.h revision 1.11 1 1.10 yamt /* $NetBSD: frameasm.h,v 1.11 2008/01/11 20:00:15 bouyer Exp $ */
2 1.1 fvdl
3 1.1 fvdl #ifndef _I386_FRAMEASM_H_
4 1.1 fvdl #define _I386_FRAMEASM_H_
5 1.1 fvdl
6 1.1 fvdl #ifdef _KERNEL_OPT
7 1.1 fvdl #include "opt_multiprocessor.h"
8 1.11 bouyer #include "opt_xen.h"
9 1.11 bouyer #endif
10 1.11 bouyer
11 1.11 bouyer #if !defined(XEN)
12 1.11 bouyer #define CLI(reg) cli
13 1.11 bouyer #define STI(reg) sti
14 1.11 bouyer #else
15 1.11 bouyer /* XXX assym.h */
16 1.11 bouyer #define TRAP_INSTR int $0x82
17 1.11 bouyer #define XEN_BLOCK_EVENTS(reg) movb $1,EVTCHN_UPCALL_MASK(reg)
18 1.11 bouyer #define XEN_UNBLOCK_EVENTS(reg) movb $0,EVTCHN_UPCALL_MASK(reg)
19 1.11 bouyer #define XEN_TEST_PENDING(reg) testb $0xFF,EVTCHN_UPCALL_PENDING(reg)
20 1.11 bouyer
21 1.11 bouyer #define CLI(reg) movl _C_LABEL(HYPERVISOR_shared_info),reg ; \
22 1.11 bouyer XEN_BLOCK_EVENTS(reg)
23 1.11 bouyer #define STI(reg) movl _C_LABEL(HYPERVISOR_shared_info),reg ; \
24 1.11 bouyer XEN_UNBLOCK_EVENTS(reg)
25 1.11 bouyer #define STIC(reg) movl _C_LABEL(HYPERVISOR_shared_info),reg ; \
26 1.11 bouyer XEN_UNBLOCK_EVENTS(reg) ; \
27 1.11 bouyer testb $0xff,EVTCHN_UPCALL_PENDING(reg)
28 1.1 fvdl #endif
29 1.1 fvdl
30 1.1 fvdl #ifndef TRAPLOG
31 1.1 fvdl #define TLOG /**/
32 1.1 fvdl #else
33 1.1 fvdl /*
34 1.1 fvdl * Fill in trap record
35 1.1 fvdl */
36 1.1 fvdl #define TLOG \
37 1.1 fvdl 9: \
38 1.1 fvdl movl %fs:CPU_TLOG_OFFSET, %eax; \
39 1.1 fvdl movl %fs:CPU_TLOG_BASE, %ebx; \
40 1.1 fvdl addl $SIZEOF_TREC,%eax; \
41 1.1 fvdl andl $SIZEOF_TLOG-1,%eax; \
42 1.1 fvdl addl %eax,%ebx; \
43 1.1 fvdl movl %eax,%fs:CPU_TLOG_OFFSET; \
44 1.1 fvdl movl %esp,TREC_SP(%ebx); \
45 1.1 fvdl movl $9b,TREC_HPC(%ebx); \
46 1.1 fvdl movl TF_EIP(%esp),%eax; \
47 1.1 fvdl movl %eax,TREC_IPC(%ebx); \
48 1.1 fvdl rdtsc ; \
49 1.1 fvdl movl %eax,TREC_TSC(%ebx); \
50 1.1 fvdl movl $MSR_LASTBRANCHFROMIP,%ecx; \
51 1.1 fvdl rdmsr ; \
52 1.1 fvdl movl %eax,TREC_LBF(%ebx); \
53 1.1 fvdl incl %ecx ; \
54 1.1 fvdl rdmsr ; \
55 1.1 fvdl movl %eax,TREC_LBT(%ebx); \
56 1.1 fvdl incl %ecx ; \
57 1.1 fvdl rdmsr ; \
58 1.1 fvdl movl %eax,TREC_IBF(%ebx); \
59 1.1 fvdl incl %ecx ; \
60 1.1 fvdl rdmsr ; \
61 1.1 fvdl movl %eax,TREC_IBT(%ebx)
62 1.1 fvdl #endif
63 1.1 fvdl
64 1.1 fvdl /*
65 1.1 fvdl * These are used on interrupt or trap entry or exit.
66 1.1 fvdl */
67 1.1 fvdl #define INTRENTRY \
68 1.1 fvdl subl $TF_PUSHSIZE,%esp ; \
69 1.1 fvdl movl %gs,TF_GS(%esp) ; \
70 1.1 fvdl movl %fs,TF_FS(%esp) ; \
71 1.3 junyoung movl %eax,TF_EAX(%esp) ; \
72 1.1 fvdl movl %es,TF_ES(%esp) ; \
73 1.1 fvdl movl %ds,TF_DS(%esp) ; \
74 1.3 junyoung movl $GSEL(GDATA_SEL, SEL_KPL),%eax ; \
75 1.1 fvdl movl %edi,TF_EDI(%esp) ; \
76 1.1 fvdl movl %esi,TF_ESI(%esp) ; \
77 1.1 fvdl movl %eax,%ds ; \
78 1.1 fvdl movl %ebp,TF_EBP(%esp) ; \
79 1.1 fvdl movl %eax,%es ; \
80 1.1 fvdl movl %ebx,TF_EBX(%esp) ; \
81 1.1 fvdl movl %eax,%gs ; \
82 1.3 junyoung movl %edx,TF_EDX(%esp) ; \
83 1.1 fvdl movl $GSEL(GCPU_SEL, SEL_KPL),%eax ; \
84 1.3 junyoung movl %ecx,TF_ECX(%esp) ; \
85 1.1 fvdl movl %eax,%fs ; \
86 1.9 ad cld ; \
87 1.1 fvdl TLOG
88 1.1 fvdl
89 1.5 yamt /*
90 1.5 yamt * INTRFASTEXIT should be in sync with trap(), resume_iret and friends.
91 1.5 yamt */
92 1.1 fvdl #define INTRFASTEXIT \
93 1.1 fvdl movl TF_GS(%esp),%gs ; \
94 1.1 fvdl movl TF_FS(%esp),%fs ; \
95 1.1 fvdl movl TF_ES(%esp),%es ; \
96 1.1 fvdl movl TF_DS(%esp),%ds ; \
97 1.1 fvdl movl TF_EDI(%esp),%edi ; \
98 1.1 fvdl movl TF_ESI(%esp),%esi ; \
99 1.1 fvdl movl TF_EBP(%esp),%ebp ; \
100 1.1 fvdl movl TF_EBX(%esp),%ebx ; \
101 1.1 fvdl movl TF_EDX(%esp),%edx ; \
102 1.1 fvdl movl TF_ECX(%esp),%ecx ; \
103 1.1 fvdl movl TF_EAX(%esp),%eax ; \
104 1.1 fvdl addl $(TF_PUSHSIZE+8),%esp ; \
105 1.1 fvdl iret
106 1.1 fvdl
107 1.8 yamt #define DO_DEFERRED_SWITCH \
108 1.4 yamt cmpl $0, CPUVAR(WANT_PMAPLOAD) ; \
109 1.4 yamt jz 1f ; \
110 1.4 yamt call _C_LABEL(pmap_load) ; \
111 1.4 yamt 1:
112 1.4 yamt
113 1.10 yamt #define DO_DEFERRED_SWITCH_RETRY \
114 1.10 yamt 1: ; \
115 1.10 yamt cmpl $0, CPUVAR(WANT_PMAPLOAD) ; \
116 1.10 yamt jz 1f ; \
117 1.10 yamt call _C_LABEL(pmap_load) ; \
118 1.10 yamt jmp 1b ; \
119 1.10 yamt 1:
120 1.10 yamt
121 1.8 yamt #define CHECK_DEFERRED_SWITCH \
122 1.4 yamt cmpl $0, CPUVAR(WANT_PMAPLOAD)
123 1.4 yamt
124 1.2 thorpej #define CHECK_ASTPENDING(reg) movl CPUVAR(CURLWP),reg ; \
125 1.2 thorpej cmpl $0, reg ; \
126 1.2 thorpej je 1f ; \
127 1.7 ad cmpl $0, L_MD_ASTPENDING(reg); \
128 1.2 thorpej 1:
129 1.7 ad #define CLEAR_ASTPENDING(reg) movl $0, L_MD_ASTPENDING(reg)
130 1.1 fvdl
131 1.6 yamt /*
132 1.6 yamt * IDEPTH_INCR:
133 1.6 yamt * increase ci_idepth and switch to the interrupt stack if necessary.
134 1.6 yamt * note that the initial value of ci_idepth is -1.
135 1.6 yamt *
136 1.6 yamt * => should be called with interrupt disabled.
137 1.6 yamt * => save the old value of %esp in %eax.
138 1.6 yamt */
139 1.6 yamt
140 1.6 yamt #define IDEPTH_INCR \
141 1.6 yamt incl CPUVAR(IDEPTH); \
142 1.6 yamt movl %esp, %eax; \
143 1.6 yamt jne 999f; \
144 1.6 yamt movl CPUVAR(INTRSTACK), %esp; \
145 1.6 yamt 999: pushl %eax; \
146 1.6 yamt
147 1.6 yamt /*
148 1.6 yamt * IDEPTH_DECR:
149 1.6 yamt * decrement ci_idepth and switch back to
150 1.6 yamt * the original stack saved by IDEPTH_INCR.
151 1.6 yamt *
152 1.6 yamt * => should be called with interrupt disabled.
153 1.6 yamt */
154 1.6 yamt
155 1.6 yamt #define IDEPTH_DECR \
156 1.6 yamt popl %esp; \
157 1.6 yamt decl CPUVAR(IDEPTH)
158 1.6 yamt
159 1.1 fvdl #endif /* _I386_FRAMEASM_H_ */
160