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