3.1.7 branch.
[minix.git] / kernel / arch / i386 / sconst.h
blob0b8cc910a354ea80203d93ee70158282ea1b4e89
1 #ifndef __SCONST_H__
2 #define __SCONST_H__
4 #include "kernel/const.h"
6 /* Miscellaneous constants used in assembler code. */
7 W = _WORD_SIZE /* Machine word size. */
9 /* Offsets in struct proc. They MUST match proc.h. */
10 P_STACKBASE = 0
11 GSREG = P_STACKBASE
12 FSREG = GSREG+2 /* 386 introduces FS and GS segments*/
13 ESREG = FSREG+2
14 DSREG = ESREG+2
15 DIREG = DSREG+2
16 SIREG = DIREG+W
17 BPREG = SIREG+W
18 STREG = BPREG+W /* hole for another SP*/
19 BXREG = STREG+W
20 DXREG = BXREG+W
21 CXREG = DXREG+W
22 AXREG = CXREG+W
23 RETADR = AXREG+W /* return address for save() call*/
24 PCREG = RETADR+W
25 CSREG = PCREG+W
26 PSWREG = CSREG+W
27 SPREG = PSWREG+W
28 SSREG = SPREG+W
29 P_STACKTOP = SSREG+W
30 FP_SAVE_AREA_P = P_STACKTOP
31 P_LDT_SEL = FP_SAVE_AREA_P + 532
32 P_CR3 = P_LDT_SEL+W
33 P_CR3_V = P_CR3+4
34 P_LDT = P_CR3_V+W
35 P_MISC_FLAGS = P_LDT + 50
36 Msize = 9 /* size of a message in 32-bit words*/
40 * offset to current process pointer right after trap, we assume we always have
41 * error code on the stack
43 #define CURR_PROC_PTR 20
46 * tests whether the interrupt was triggered in kernel. If so, jump to the
47 * label. Displacement tell the macro ha far is the CS value saved by the trap
48 * from the current %esp. The kernel code segment selector has the lower 3 bits
49 * zeroed
51 #define TEST_INT_IN_KERNEL(displ, label) \
52 cmpl $CS_SELECTOR, displ(%esp) ;\
53 je label ;
56 * saves the basic interrupt context (no error code) to the process structure
58 * displ is the displacement of %esp from the original stack after trap
59 * pptr is the process structure pointer
60 * tmp is an available temporary register
62 #define SAVE_TRAP_CTX(displ, pptr, tmp) \
63 movl (0 + displ)(%esp), tmp ;\
64 movl tmp, PCREG(pptr) ;\
65 movl (4 + displ)(%esp), tmp ;\
66 movl tmp, CSREG(pptr) ;\
67 movl (8 + displ)(%esp), tmp ;\
68 movl tmp, PSWREG(pptr) ;\
69 movl (12 + displ)(%esp), tmp ;\
70 movl tmp, SPREG(pptr) ;\
71 movl tmp, STREG(pptr) ;\
72 movl (16 + displ)(%esp), tmp ;\
73 movl tmp, SSREG(pptr) ;
75 #define SAVE_SEGS(pptr) \
76 mov %ds, %ss:DSREG(pptr) ;\
77 mov %es, %ss:ESREG(pptr) ;\
78 mov %fs, %ss:FSREG(pptr) ;\
79 mov %gs, %ss:GSREG(pptr) ;
81 #define RESTORE_SEGS(pptr) \
82 movw %ss:DSREG(pptr), %ds ;\
83 movw %ss:ESREG(pptr), %es ;\
84 movw %ss:FSREG(pptr), %fs ;\
85 movw %ss:GSREG(pptr), %gs ;
88 * restore kernel segments, %ss is kernnel data segment, %cs is aready set and
89 * %fs, %gs are not used
91 #define RESTORE_KERNEL_SEGS \
92 mov %ss, %si ;\
93 mov %si, %ds ;\
94 mov %si, %es ;\
95 movw $0, %si ;\
96 mov %si, %gs ;\
97 mov %si, %fs ;
99 #define SAVE_GP_REGS(pptr) \
100 mov %eax, %ss:AXREG(pptr) ;\
101 mov %ecx, %ss:CXREG(pptr) ;\
102 mov %edx, %ss:DXREG(pptr) ;\
103 mov %ebx, %ss:BXREG(pptr) ;\
104 mov %esi, %ss:SIREG(pptr) ;\
105 mov %edi, %ss:DIREG(pptr) ;
107 #define RESTORE_GP_REGS(pptr) \
108 movl %ss:AXREG(pptr), %eax ;\
109 movl %ss:CXREG(pptr), %ecx ;\
110 movl %ss:DXREG(pptr), %edx ;\
111 movl %ss:BXREG(pptr), %ebx ;\
112 movl %ss:SIREG(pptr), %esi ;\
113 movl %ss:DIREG(pptr), %edi ;
116 * save the context of the interrupted process to the structure in the process
117 * table. It pushses the %ebp to stack to get a scratch register. After %esi is
118 * saved, we can use it to get the saved %ebp from stack and save it to the
119 * final location
121 * displ is the stack displacement. In case of an exception, there are two extra
122 * value on the stack - error code and the exception number
124 #define SAVE_PROCESS_CTX_NON_LAZY(displ) \
126 cld /* set the direction flag to a known state */ ;\
128 push %ebp ;\
130 movl (CURR_PROC_PTR + 4 + displ)(%esp), %ebp ;\
132 /* save the segment registers */ \
133 SAVE_SEGS(%ebp) ;\
135 SAVE_GP_REGS(%ebp) ;\
136 pop %esi /* get the orig %ebp and save it */ ;\
137 mov %esi, %ss:BPREG(%ebp) ;\
139 RESTORE_KERNEL_SEGS ;\
140 SAVE_TRAP_CTX(displ, %ebp, %esi) ;
142 #define SAVE_PROCESS_CTX(displ) \
143 SAVE_PROCESS_CTX_NON_LAZY(displ) ;\
144 push %eax ;\
145 push %ebx ;\
146 push %ecx ;\
147 push %edx ;\
148 push %ebp ;\
149 call _save_fpu ;\
150 pop %ebp ;\
151 pop %edx ;\
152 pop %ecx ;\
153 pop %ebx ;\
154 pop %eax ;
157 * clear the IF flag in eflags which are stored somewhere in memory, e.g. on
158 * stack. iret or popf will load the new value later
160 #define CLEAR_IF(where) \
161 mov where, %eax ;\
162 andl $0xfffffdff, %eax ;\
163 mov %eax, where ;
165 #endif /* __SCONST_H__ */