xref: /minix3/minix/kernel/arch/i386/sconst.h (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc #ifndef __SCONST_H__
2*433d6423SLionel Sambuc #define __SCONST_H__
3*433d6423SLionel Sambuc 
4*433d6423SLionel Sambuc #include "kernel/const.h"
5*433d6423SLionel Sambuc #include "kernel/procoffsets.h"
6*433d6423SLionel Sambuc 
7*433d6423SLionel Sambuc /*
8*433d6423SLionel Sambuc  * offset to current process pointer right after trap, we assume we always have
9*433d6423SLionel Sambuc  * error code on the stack
10*433d6423SLionel Sambuc  */
11*433d6423SLionel Sambuc #define CURR_PROC_PTR		20
12*433d6423SLionel Sambuc 
13*433d6423SLionel Sambuc /*
14*433d6423SLionel Sambuc  * tests whether the interrupt was triggered in kernel. If so, jump to the
15*433d6423SLionel Sambuc  * label. Displacement tell the macro ha far is the CS value saved by the trap
16*433d6423SLionel Sambuc  * from the current %esp. The kernel code segment selector has the lower 3 bits
17*433d6423SLionel Sambuc  * zeroed
18*433d6423SLionel Sambuc  */
19*433d6423SLionel Sambuc #define TEST_INT_IN_KERNEL(displ, label)	\
20*433d6423SLionel Sambuc 	cmpl	$KERN_CS_SELECTOR, displ(%esp)	;\
21*433d6423SLionel Sambuc 	je	label				;
22*433d6423SLionel Sambuc 
23*433d6423SLionel Sambuc /*
24*433d6423SLionel Sambuc  * saves the basic interrupt context (no error code) to the process structure
25*433d6423SLionel Sambuc  *
26*433d6423SLionel Sambuc  * displ is the displacement of %esp from the original stack after trap
27*433d6423SLionel Sambuc  * pptr is the process structure pointer
28*433d6423SLionel Sambuc  * tmp is an available temporary register
29*433d6423SLionel Sambuc  */
30*433d6423SLionel Sambuc #define SAVE_TRAP_CTX(displ, pptr, tmp)			\
31*433d6423SLionel Sambuc 	movl	(0 + displ)(%esp), tmp			;\
32*433d6423SLionel Sambuc 	movl	tmp, PCREG(pptr)			;\
33*433d6423SLionel Sambuc 	movl	(4 + displ)(%esp), tmp			;\
34*433d6423SLionel Sambuc 	movl	tmp, CSREG(pptr)			;\
35*433d6423SLionel Sambuc 	movl	(8 + displ)(%esp), tmp			;\
36*433d6423SLionel Sambuc 	movl	tmp, PSWREG(pptr)			;\
37*433d6423SLionel Sambuc 	movl	(12 + displ)(%esp), tmp			;\
38*433d6423SLionel Sambuc 	movl	tmp, SPREG(pptr)
39*433d6423SLionel Sambuc 
40*433d6423SLionel Sambuc /*
41*433d6423SLionel Sambuc  * restore kernel segments. %cs is already set and %fs, %gs are not used */
42*433d6423SLionel Sambuc #define RESTORE_KERNEL_SEGS	\
43*433d6423SLionel Sambuc 	mov	$KERN_DS_SELECTOR, %si	;\
44*433d6423SLionel Sambuc 	mov	%si, %ds	;\
45*433d6423SLionel Sambuc 	mov	%si, %es	;\
46*433d6423SLionel Sambuc 	movw	$0, %si		;\
47*433d6423SLionel Sambuc 	mov	%si, %gs	;\
48*433d6423SLionel Sambuc 	mov	%si, %fs	;
49*433d6423SLionel Sambuc 
50*433d6423SLionel Sambuc #define SAVE_GP_REGS(pptr)	\
51*433d6423SLionel Sambuc 	mov	%eax, AXREG(pptr)		;\
52*433d6423SLionel Sambuc 	mov	%ecx, CXREG(pptr)		;\
53*433d6423SLionel Sambuc 	mov	%edx, DXREG(pptr)		;\
54*433d6423SLionel Sambuc 	mov	%ebx, BXREG(pptr)		;\
55*433d6423SLionel Sambuc 	mov	%esi, SIREG(pptr)		;\
56*433d6423SLionel Sambuc 	mov	%edi, DIREG(pptr)		;
57*433d6423SLionel Sambuc 
58*433d6423SLionel Sambuc #define RESTORE_GP_REGS(pptr)	\
59*433d6423SLionel Sambuc 	movl	AXREG(pptr), %eax		;\
60*433d6423SLionel Sambuc 	movl	CXREG(pptr), %ecx		;\
61*433d6423SLionel Sambuc 	movl	DXREG(pptr), %edx		;\
62*433d6423SLionel Sambuc 	movl	BXREG(pptr), %ebx		;\
63*433d6423SLionel Sambuc 	movl	SIREG(pptr), %esi		;\
64*433d6423SLionel Sambuc 	movl	DIREG(pptr), %edi		;
65*433d6423SLionel Sambuc 
66*433d6423SLionel Sambuc /*
67*433d6423SLionel Sambuc  * save the context of the interrupted process to the structure in the process
68*433d6423SLionel Sambuc  * table. It pushses the %ebp to stack to get a scratch register. After %esi is
69*433d6423SLionel Sambuc  * saved, we can use it to get the saved %ebp from stack and save it to the
70*433d6423SLionel Sambuc  * final location
71*433d6423SLionel Sambuc  *
72*433d6423SLionel Sambuc  * displ is the stack displacement. In case of an exception, there are two extra
73*433d6423SLionel Sambuc  * value on the stack - error code and the exception number
74*433d6423SLionel Sambuc  */
75*433d6423SLionel Sambuc #define SAVE_PROCESS_CTX(displ, trapcode) \
76*433d6423SLionel Sambuc 								\
77*433d6423SLionel Sambuc 	cld /* set the direction flag to a known state */	;\
78*433d6423SLionel Sambuc 								\
79*433d6423SLionel Sambuc 	push	%ebp					;\
80*433d6423SLionel Sambuc 							;\
81*433d6423SLionel Sambuc 	movl	(CURR_PROC_PTR + 4 + displ)(%esp), %ebp	;\
82*433d6423SLionel Sambuc 							\
83*433d6423SLionel Sambuc 	SAVE_GP_REGS(%ebp)				;\
84*433d6423SLionel Sambuc         movl	$trapcode, P_KERN_TRAP_STYLE(%ebp)	;\
85*433d6423SLionel Sambuc 	pop	%esi			/* get the orig %ebp and save it */ ;\
86*433d6423SLionel Sambuc 	mov	%esi, BPREG(%ebp)			;\
87*433d6423SLionel Sambuc 							\
88*433d6423SLionel Sambuc 	RESTORE_KERNEL_SEGS				;\
89*433d6423SLionel Sambuc 	SAVE_TRAP_CTX(displ, %ebp, %esi)		;
90*433d6423SLionel Sambuc 
91*433d6423SLionel Sambuc /*
92*433d6423SLionel Sambuc  * clear the IF flag in eflags which are stored somewhere in memory, e.g. on
93*433d6423SLionel Sambuc  * stack. iret or popf will load the new value later
94*433d6423SLionel Sambuc  */
95*433d6423SLionel Sambuc #define CLEAR_IF(where)	\
96*433d6423SLionel Sambuc 	mov	where, %eax						;\
97*433d6423SLionel Sambuc 	andl	$0xfffffdff, %eax					;\
98*433d6423SLionel Sambuc 	mov	%eax, where						;
99*433d6423SLionel Sambuc 
100*433d6423SLionel Sambuc #endif /* __SCONST_H__ */
101