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