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. */
12 FSREG
= GSREG
+2 /* 386 introduces FS and GS segments*/
18 STREG
= BPREG
+W
/* hole for another SP*/
23 RETADR
= AXREG
+W
/* return address for save() call*/
30 FP_SAVE_AREA_P
= P_STACKTOP
31 P_LDT_SEL
= FP_SAVE_AREA_P
+ 532
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
51 #define TEST_INT_IN_KERNEL(displ, label) \
52 cmpl $CS_SELECTOR, displ(%esp) ;\
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 \
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
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 */ ;\
130 movl (CURR_PROC_PTR + 4 + displ)(%esp), %ebp ;\
132 /* save the segment registers */ \
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) ;\
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) \
162 andl $0xfffffdff, %eax ;\
165 #endif /* __SCONST_H__ */