1 /* $NetBSD: frameasm.h,v 1.15 2011/07/26 12:57:35 yamt Exp $ */
3 #ifndef _I386_FRAMEASM_H_
4 #define _I386_FRAMEASM_H_
7 #include "opt_multiprocessor.h"
16 #define TRAP_INSTR int $0x82
17 #define XEN_BLOCK_EVENTS(reg) movb $1,EVTCHN_UPCALL_MASK(reg)
18 #define XEN_UNBLOCK_EVENTS(reg) movb $0,EVTCHN_UPCALL_MASK(reg)
19 #define XEN_TEST_PENDING(reg) testb $0xFF,EVTCHN_UPCALL_PENDING(reg)
21 #define CLI(reg) movl CPUVAR(VCPU),reg ; \
23 #define STI(reg) movl CPUVAR(VCPU),reg ; \
24 XEN_UNBLOCK_EVENTS(reg)
25 #define STIC(reg) movl CPUVAR(VCPU),reg ; \
26 XEN_UNBLOCK_EVENTS(reg) ; \
27 testb $0xff,EVTCHN_UPCALL_PENDING(reg)
38 movl %fs:CPU_TLOG_OFFSET, %eax; \
39 movl %fs:CPU_TLOG_BASE, %ebx; \
40 addl $SIZEOF_TREC,%eax; \
41 andl $SIZEOF_TLOG-1,%eax; \
43 movl %eax,%fs:CPU_TLOG_OFFSET; \
44 movl %esp,TREC_SP(%ebx); \
45 movl $9b,TREC_HPC(%ebx); \
46 movl TF_EIP(%esp),%eax; \
47 movl %eax,TREC_IPC(%ebx); \
49 movl %eax,TREC_TSC(%ebx); \
50 movl $MSR_LASTBRANCHFROMIP,%ecx; \
52 movl %eax,TREC_LBF(%ebx); \
55 movl %eax,TREC_LBT(%ebx); \
58 movl %eax,TREC_IBF(%ebx); \
61 movl %eax,TREC_IBT(%ebx)
65 * These are used on interrupt or trap entry or exit.
68 subl $TF_PUSHSIZE,%esp ; \
69 movw %gs,TF_GS(%esp) ; \
70 movw %fs,TF_FS(%esp) ; \
71 movl %eax,TF_EAX(%esp) ; \
72 movw %es,TF_ES(%esp) ; \
73 movw %ds,TF_DS(%esp) ; \
74 movl $GSEL(GDATA_SEL, SEL_KPL),%eax ; \
75 movl %edi,TF_EDI(%esp) ; \
76 movl %esi,TF_ESI(%esp) ; \
78 movl %ebp,TF_EBP(%esp) ; \
80 movl %ebx,TF_EBX(%esp) ; \
82 movl %edx,TF_EDX(%esp) ; \
83 movl $GSEL(GCPU_SEL, SEL_KPL),%eax ; \
84 movl %ecx,TF_ECX(%esp) ; \
90 * INTRFASTEXIT should be in sync with trap(), resume_iret and friends.
92 #define INTRFASTEXIT \
93 movw TF_GS(%esp),%gs ; \
94 movw TF_FS(%esp),%fs ; \
95 movw TF_ES(%esp),%es ; \
96 movw TF_DS(%esp),%ds ; \
97 movl TF_EDI(%esp),%edi ; \
98 movl TF_ESI(%esp),%esi ; \
99 movl TF_EBP(%esp),%ebp ; \
100 movl TF_EBX(%esp),%ebx ; \
101 movl TF_EDX(%esp),%edx ; \
102 movl TF_ECX(%esp),%ecx ; \
103 movl TF_EAX(%esp),%eax ; \
104 addl $(TF_PUSHSIZE+8),%esp ; \
107 #define DO_DEFERRED_SWITCH \
108 cmpl $0, CPUVAR(WANT_PMAPLOAD) ; \
110 call _C_LABEL(pmap_load) ; \
113 #define DO_DEFERRED_SWITCH_RETRY \
115 cmpl $0, CPUVAR(WANT_PMAPLOAD) ; \
117 call _C_LABEL(pmap_load) ; \
121 #define CHECK_DEFERRED_SWITCH \
122 cmpl $0, CPUVAR(WANT_PMAPLOAD)
124 #define CHECK_ASTPENDING(reg) movl CPUVAR(CURLWP),reg ; \
125 cmpl $0, L_MD_ASTPENDING(reg)
126 #define CLEAR_ASTPENDING(reg) movl $0, L_MD_ASTPENDING(reg)
130 * increase ci_idepth and switch to the interrupt stack if necessary.
131 * note that the initial value of ci_idepth is -1.
133 * => should be called with interrupt disabled.
134 * => save the old value of %esp in %eax.
137 #define IDEPTH_INCR \
138 incl CPUVAR(IDEPTH); \
141 movl CPUVAR(INTRSTACK), %esp; \
142 999: pushl %eax; /* eax == pointer to intrframe */ \
146 * decrement ci_idepth and switch back to
147 * the original stack saved by IDEPTH_INCR.
149 * => should be called with interrupt disabled.
152 #define IDEPTH_DECR \
156 #endif /* _I386_FRAMEASM_H_ */