Changed the trap prolog, each exception can have its own trap handler.

svn path=/trunk/; revision=15132
This commit is contained in:
Hartmut Birr 2005-05-08 16:07:43 +00:00
parent 647ee2a30d
commit 578153056c

View file

@ -66,8 +66,10 @@ _KiTrapRet:
/* Restore the old previous mode */ /* Restore the old previous mode */
popl %ebx popl %ebx
cmpl $0, %esi
je .L7
movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi) movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
.L7:
/* Restore the old exception handler list */ /* Restore the old exception handler list */
popl %ebx popl %ebx
movl %ebx, %fs:KPCR_EXCEPTION_LIST movl %ebx, %fs:KPCR_EXCEPTION_LIST
@ -83,48 +85,16 @@ _KiTrapRet:
.globl _KiTrapProlog .globl _KiTrapProlog
_KiTrapProlog: _KiTrapProlog:
movl $_KiTrapHandler, %ebx
.global _KiTrapProlog2
_KiTrapProlog2:
pushl %edi pushl %edi
pushl %fs pushl %fs
/* /* Make room for the previous mode and the exception list */
* Check that the PCR exists, very early in the boot process it may subl $8, %esp
* not
*/
cmpl $0, %ss:_KiPcrInitDone
je .L5
/* Load the PCR selector into fs */
movl $PCR_SELECTOR, %ebx
movl %ebx, %fs
/* Save the old exception list */
movl %fs:KPCR_EXCEPTION_LIST, %ebx
pushl %ebx
/* Get a pointer to the current thread */
movl %fs:KPCR_CURRENT_THREAD, %edi
/* The current thread may be NULL early in the boot process */
cmpl $0, %edi
je .L4
/* Save the old previous mode */
movl $0, %ebx
movb %ss:KTHREAD_PREVIOUS_MODE(%edi), %bl
pushl %ebx
/* Set the new previous mode based on the saved CS selector */
movl 0x24(%esp), %ebx
andl $0x0000FFFF, %ebx
cmpl $KERNEL_CS, %ebx
jne .L1
movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%edi)
jmp .L3
.L1:
movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%edi)
.L3:
/* Save other registers */ /* Save other registers */
pushl %eax pushl %eax
pushl %ecx pushl %ecx
@ -147,70 +117,88 @@ _KiTrapProlog:
pushl %eax /* Dr1 */ pushl %eax /* Dr1 */
movl %dr0, %eax movl %dr0, %eax
pushl %eax /* Dr0 */ pushl %eax /* Dr0 */
leal 0x64(%esp), %eax leal 0x64(%esp), %eax
pushl %eax /* XXX: TempESP */ pushl %eax /* XXX: TempESP */
pushl %ss /* XXX: TempSS */ pushl %ss /* XXX: TempSS */
pushl $0 /* XXX: DebugPointer */ pushl $0 /* XXX: DebugPointer */
pushl $0 /* XXX: DebugArgMark */ pushl $0 /* XXX: DebugArgMark */
movl 0x60(%esp), %ebx movl 0x60(%esp), %eax
pushl %ebx /* XXX: DebugEIP */ pushl %eax /* XXX: DebugEIP */
pushl %ebp /* XXX: DebugEBP */ pushl %ebp /* XXX: DebugEBP */
/* Load the segment registers */
movl $KERNEL_DS, %ebx
movl %ebx, %ds
movl %ebx, %es
movl %ebx, %gs
/* Set ES to kernel segment */ /* Load the segment registers */
movw $KERNEL_DS,%bx movl $KERNEL_DS, %eax
movw %bx,%es movl %eax, %ds
movl %eax, %es
movl %esp, %ebx movl %eax, %gs
/* save the trap frame */
movl %esp, %ebp movl %esp, %ebp
/* Load the PCR selector into fs */
movl $PCR_SELECTOR, %eax
movl %eax, %fs
/* Save the old exception list */
movl %fs:KPCR_EXCEPTION_LIST, %eax
movl %eax, KTRAP_FRAME_EXCEPTION_LIST(%ebp)
/* Get a pointer to the current thread */
movl %fs:KPCR_CURRENT_THREAD, %edi
/* The current thread may be NULL early in the boot process */
cmpl $0, %edi
je .L4
/* Save the old previous mode */
movl $0, %eax
movb KTHREAD_PREVIOUS_MODE(%edi), %al
movl %eax, KTRAP_FRAME_PREVIOUS_MODE(%ebp)
/* Set the new previous mode based on the saved CS selector */
movl KTRAP_FRAME_CS(%ebp), %eax
andl $0x0000FFFF, %eax
cmpl $KERNEL_CS, %eax
jne .L1
movb $KernelMode, KTHREAD_PREVIOUS_MODE(%edi)
jmp .L3
.L1:
movb $UserMode, KTHREAD_PREVIOUS_MODE(%edi)
.L3:
/* Save the old trap frame. */ /* Save the old trap frame. */
cmpl $0, %edi movl KTHREAD_TRAP_FRAME(%edi), %edx
je .L7
movl %ss:KTHREAD_TRAP_FRAME(%edi), %edx
pushl %edx pushl %edx
jmp .L8
.L7:
pushl $0
.L8:
/* Save a pointer to the trap frame in the current KTHREAD */ /* Save a pointer to the trap frame in the current KTHREAD */
cmpl $0, %edi movl %ebp, KTHREAD_TRAP_FRAME(%edi)
je .L6
movl %ebx, %ss:KTHREAD_TRAP_FRAME(%edi)
.L6: .L6:
/* Call the C exception handler */ /* Call the C exception handler */
pushl %esi pushl %esi
pushl %ebx pushl %ebp
call _KiTrapHandler call *%ebx
addl $4, %esp addl $8, %esp
addl $4, %esp
/* Get a pointer to the current thread */ /* Get a pointer to the current thread */
movl %fs:KPCR_CURRENT_THREAD, %esi movl %fs:KPCR_CURRENT_THREAD, %esi
/* Restore the old trap frame pointer */ /* Restore the old trap frame pointer */
popl %ebx popl %ebx
cmpl $0, %esi
je _KiTrapEpilog
movl %ebx, KTHREAD_TRAP_FRAME(%esi) movl %ebx, KTHREAD_TRAP_FRAME(%esi)
/* Return to the caller */ /* Return to the caller */
jmp _KiTrapEpilog jmp _KiTrapEpilog
/* Handle the no-pcr case out of line */
.L5:
pushl $0
/* Handle the no-thread case out of line */ /* Handle the no-thread case out of line */
.L4: .L4:
pushl $0 movl $0, %eax /* previous mode */
jmp .L3 movl %eax, KTRAP_FRAME_PREVIOUS_MODE(%ebp)
pushl %eax /* old trap frame */
jmp .L6
.globl _KiTrap0 .globl _KiTrap0
_KiTrap0: _KiTrap0:
/* No error code */ /* No error code */
@ -337,7 +325,8 @@ _KiTrap14:
pushl %ebx pushl %ebx
pushl %esi pushl %esi
movl $14, %esi movl $14, %esi
jmp _KiTrapProlog movl $_KiTrapHandler, %ebx
jmp _KiTrapProlog2
.globl _KiTrap15 .globl _KiTrap15
_KiTrap15: _KiTrap15: