frameasm.h revision 1.8 1 /* $NetBSD: frameasm.h,v 1.8 2007/10/18 15:28:37 yamt Exp $ */
2
3 #ifndef _I386_FRAMEASM_H_
4 #define _I386_FRAMEASM_H_
5
6 #ifdef _KERNEL_OPT
7 #include "opt_multiprocessor.h"
8 #endif
9
10 #ifndef TRAPLOG
11 #define TLOG /**/
12 #else
13 /*
14 * Fill in trap record
15 */
16 #define TLOG \
17 9: \
18 movl %fs:CPU_TLOG_OFFSET, %eax; \
19 movl %fs:CPU_TLOG_BASE, %ebx; \
20 addl $SIZEOF_TREC,%eax; \
21 andl $SIZEOF_TLOG-1,%eax; \
22 addl %eax,%ebx; \
23 movl %eax,%fs:CPU_TLOG_OFFSET; \
24 movl %esp,TREC_SP(%ebx); \
25 movl $9b,TREC_HPC(%ebx); \
26 movl TF_EIP(%esp),%eax; \
27 movl %eax,TREC_IPC(%ebx); \
28 rdtsc ; \
29 movl %eax,TREC_TSC(%ebx); \
30 movl $MSR_LASTBRANCHFROMIP,%ecx; \
31 rdmsr ; \
32 movl %eax,TREC_LBF(%ebx); \
33 incl %ecx ; \
34 rdmsr ; \
35 movl %eax,TREC_LBT(%ebx); \
36 incl %ecx ; \
37 rdmsr ; \
38 movl %eax,TREC_IBF(%ebx); \
39 incl %ecx ; \
40 rdmsr ; \
41 movl %eax,TREC_IBT(%ebx)
42 #endif
43
44 /*
45 * These are used on interrupt or trap entry or exit.
46 */
47 #define INTRENTRY \
48 subl $TF_PUSHSIZE,%esp ; \
49 movl %gs,TF_GS(%esp) ; \
50 movl %fs,TF_FS(%esp) ; \
51 movl %eax,TF_EAX(%esp) ; \
52 movl %es,TF_ES(%esp) ; \
53 movl %ds,TF_DS(%esp) ; \
54 movl $GSEL(GDATA_SEL, SEL_KPL),%eax ; \
55 movl %edi,TF_EDI(%esp) ; \
56 movl %esi,TF_ESI(%esp) ; \
57 movl %eax,%ds ; \
58 movl %ebp,TF_EBP(%esp) ; \
59 movl %eax,%es ; \
60 movl %ebx,TF_EBX(%esp) ; \
61 movl %eax,%gs ; \
62 movl %edx,TF_EDX(%esp) ; \
63 movl $GSEL(GCPU_SEL, SEL_KPL),%eax ; \
64 movl %ecx,TF_ECX(%esp) ; \
65 movl %eax,%fs ; \
66 TLOG
67
68 /*
69 * INTRFASTEXIT should be in sync with trap(), resume_iret and friends.
70 */
71 #define INTRFASTEXIT \
72 movl TF_GS(%esp),%gs ; \
73 movl TF_FS(%esp),%fs ; \
74 movl TF_ES(%esp),%es ; \
75 movl TF_DS(%esp),%ds ; \
76 movl TF_EDI(%esp),%edi ; \
77 movl TF_ESI(%esp),%esi ; \
78 movl TF_EBP(%esp),%ebp ; \
79 movl TF_EBX(%esp),%ebx ; \
80 movl TF_EDX(%esp),%edx ; \
81 movl TF_ECX(%esp),%ecx ; \
82 movl TF_EAX(%esp),%eax ; \
83 addl $(TF_PUSHSIZE+8),%esp ; \
84 iret
85
86 #define DO_DEFERRED_SWITCH \
87 cmpl $0, CPUVAR(WANT_PMAPLOAD) ; \
88 jz 1f ; \
89 call _C_LABEL(pmap_load) ; \
90 1:
91
92 #define CHECK_DEFERRED_SWITCH \
93 cmpl $0, CPUVAR(WANT_PMAPLOAD)
94
95 #define CHECK_ASTPENDING(reg) movl CPUVAR(CURLWP),reg ; \
96 cmpl $0, reg ; \
97 je 1f ; \
98 cmpl $0, L_MD_ASTPENDING(reg); \
99 1:
100 #define CLEAR_ASTPENDING(reg) movl $0, L_MD_ASTPENDING(reg)
101
102 /*
103 * IDEPTH_INCR:
104 * increase ci_idepth and switch to the interrupt stack if necessary.
105 * note that the initial value of ci_idepth is -1.
106 *
107 * => should be called with interrupt disabled.
108 * => save the old value of %esp in %eax.
109 */
110
111 #define IDEPTH_INCR \
112 incl CPUVAR(IDEPTH); \
113 movl %esp, %eax; \
114 jne 999f; \
115 movl CPUVAR(INTRSTACK), %esp; \
116 999: pushl %eax; \
117
118 /*
119 * IDEPTH_DECR:
120 * decrement ci_idepth and switch back to
121 * the original stack saved by IDEPTH_INCR.
122 *
123 * => should be called with interrupt disabled.
124 */
125
126 #define IDEPTH_DECR \
127 popl %esp; \
128 decl CPUVAR(IDEPTH)
129
130 #endif /* _I386_FRAMEASM_H_ */
131