#ifndef __SCONST_H__ #define __SCONST_H__ /* * LSC Weirdness going on with the const.h header: FIXME #include "kernel/const.h" #include "kernel/procoffsets.h" */ #include "const.h" #include "procoffsets.h" /* * offset to current process pointer right after trap, we assume we always have * error code on the stack */ #define CURR_PROC_PTR 20 /* * tests whether the interrupt was triggered in kernel. If so, jump to the * label. Displacement tell the macro ha far is the CS value saved by the trap * from the current %esp. The kernel code segment selector has the lower 3 bits * zeroed */ #define TEST_INT_IN_KERNEL(displ, label) \ cmpl $KERN_CS_SELECTOR, displ(%esp) ;\ je label ; /* * saves the basic interrupt context (no error code) to the process structure * * displ is the displacement of %esp from the original stack after trap * pptr is the process structure pointer * tmp is an available temporary register */ #define SAVE_TRAP_CTX(displ, pptr, tmp) \ movl (0 + displ)(%esp), tmp ;\ movl tmp, PCREG(pptr) ;\ movl (4 + displ)(%esp), tmp ;\ movl tmp, CSREG(pptr) ;\ movl (8 + displ)(%esp), tmp ;\ movl tmp, PSWREG(pptr) ;\ movl (12 + displ)(%esp), tmp ;\ movl tmp, SPREG(pptr) ;\ movl tmp, STREG(pptr) /* * restore kernel segments. %cs is aready set and %fs, %gs are not used */ #define RESTORE_KERNEL_SEGS \ mov $KERN_DS_SELECTOR, %si ;\ mov %si, %ds ;\ mov %si, %es ;\ movw $0, %si ;\ mov %si, %gs ;\ mov %si, %fs ; #define SAVE_GP_REGS(pptr) \ mov %eax, AXREG(pptr) ;\ mov %ecx, CXREG(pptr) ;\ mov %edx, DXREG(pptr) ;\ mov %ebx, BXREG(pptr) ;\ mov %esi, SIREG(pptr) ;\ mov %edi, DIREG(pptr) ; #define RESTORE_GP_REGS(pptr) \ movl AXREG(pptr), %eax ;\ movl CXREG(pptr), %ecx ;\ movl DXREG(pptr), %edx ;\ movl BXREG(pptr), %ebx ;\ movl SIREG(pptr), %esi ;\ movl DIREG(pptr), %edi ; /* * save the context of the interrupted process to the structure in the process * table. It pushses the %ebp to stack to get a scratch register. After %esi is * saved, we can use it to get the saved %ebp from stack and save it to the * final location * * displ is the stack displacement. In case of an exception, there are two extra * value on the stack - error code and the exception number */ #define SAVE_PROCESS_CTX(displ, trapcode) \ \ cld /* set the direction flag to a known state */ ;\ \ push %ebp ;\ ;\ movl (CURR_PROC_PTR + 4 + displ)(%esp), %ebp ;\ \ SAVE_GP_REGS(%ebp) ;\ movl $trapcode, P_KERN_TRAP_STYLE(%ebp) ;\ pop %esi /* get the orig %ebp and save it */ ;\ mov %esi, BPREG(%ebp) ;\ \ RESTORE_KERNEL_SEGS ;\ SAVE_TRAP_CTX(displ, %ebp, %esi) ; /* * clear the IF flag in eflags which are stored somewhere in memory, e.g. on * stack. iret or popf will load the new value later */ #define CLEAR_IF(where) \ mov where, %eax ;\ andl $0xfffffdff, %eax ;\ mov %eax, where ; #endif /* __SCONST_H__ */