mirror of
https://github.com/memtest86plus/memtest86plus.git
synced 2024-11-23 08:26:23 -06:00
Fix interrupt handling when long mode is enabled in a 32-bit binary (part 2).
Handle passing the processor state to the application interrupt handler. Update the 64-bit code to match the new trap state structure definition.
This commit is contained in:
parent
111e619b10
commit
39d5715224
@ -68,22 +68,29 @@ typedef uint32_t reg_t;
|
||||
#endif
|
||||
|
||||
struct trap_regs {
|
||||
reg_t ss;
|
||||
reg_t es;
|
||||
reg_t ds;
|
||||
reg_t sp;
|
||||
reg_t bp;
|
||||
reg_t si;
|
||||
reg_t di;
|
||||
reg_t dx;
|
||||
reg_t cx;
|
||||
reg_t bx;
|
||||
reg_t es;
|
||||
reg_t ss;
|
||||
reg_t ax;
|
||||
reg_t bx;
|
||||
reg_t cx;
|
||||
reg_t dx;
|
||||
reg_t di;
|
||||
reg_t si;
|
||||
#ifndef __x86_64__
|
||||
reg_t reserved1;
|
||||
reg_t reserved2;
|
||||
reg_t sp;
|
||||
#endif
|
||||
reg_t bp;
|
||||
reg_t vect;
|
||||
reg_t code;
|
||||
reg_t ip;
|
||||
reg_t cs;
|
||||
reg_t flags;
|
||||
#ifdef __x86_64__
|
||||
reg_t sp;
|
||||
#endif
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
120
boot/startup32.S
120
boot/startup32.S
@ -404,11 +404,42 @@ vec64_19:
|
||||
pushq $19 # vector
|
||||
jmp int_handler64
|
||||
|
||||
# The common interrupt handler code for long mode. Pass the register state
|
||||
# to the application interrupt handler.
|
||||
# The interrupt handler code for long mode. Pass the register state to the
|
||||
# common interrupt handler. On entry this expects the stack to contain:
|
||||
#
|
||||
# rsp+30 ss
|
||||
# rsp+28 rsp
|
||||
# rsp+20 rflags
|
||||
# rsp+18 cs
|
||||
# rsp+10 rip
|
||||
# rsp+08 error code
|
||||
# rsp+00 vector number
|
||||
#
|
||||
# We create a new stack frame in the format expected by int_handler. We can
|
||||
# reuse the space currently occupied by the vector number and the error code,
|
||||
# as they are not needed on return.
|
||||
|
||||
int_handler64:
|
||||
addq $16, %rsp
|
||||
subq $16, %rsp
|
||||
movl %ebp, 0x04(%rsp) # save the state of ebp
|
||||
leal 0x48(%rsp), %ebp # save the state of esp before the interrupt
|
||||
movl %ebp, 0x00(%rsp)
|
||||
movl 0x10(%rsp), %ebp # save the vector number
|
||||
movl %ebp, 0x08(%rsp)
|
||||
movl 0x18(%rsp), %ebp # save the error code
|
||||
movl %ebp, 0x0c(%rsp)
|
||||
movl 0x20(%rsp), %ebp # save the state of eip
|
||||
movl %ebp, 0x10(%rsp)
|
||||
movl 0x28(%rsp), %ebp # save the state of cs
|
||||
movl %ebp, 0x14(%rsp)
|
||||
movl 0x30(%rsp), %ebp # save the state of eflags
|
||||
movl %ebp, 0x18(%rsp)
|
||||
leal int_handler(%rip), %ebp
|
||||
movw $KERNEL_CS, -2(%rsp)
|
||||
movl %ebp, -6(%rsp)
|
||||
lcall *-6(%rsp)
|
||||
movl 0x04(%rsp), %ebp # restore the saved state of ebp
|
||||
addq $32, %rsp # discard the stack frame we created
|
||||
iretq
|
||||
|
||||
# Individual interrupt vector handlers for protected mode. These need to be
|
||||
@ -517,38 +548,67 @@ vec32_19:
|
||||
pushl $19 # vector
|
||||
jmp int_handler32
|
||||
|
||||
# The common interrupt handler code for protected mode. Pass the register
|
||||
# state to the application interrupt handler.
|
||||
# The interrupt handler code for protected mode. Pass the register state to
|
||||
# the common interrupt handler. On entry this expects the stack to contain:
|
||||
#
|
||||
# esp+10 eflags
|
||||
# esp+0c cs
|
||||
# esp+08 eip
|
||||
# esp+04 error code
|
||||
# esp+00 vector number
|
||||
#
|
||||
# It adds the additional state expected by int_handler to the bottom of the
|
||||
# stack frame.
|
||||
|
||||
int_handler32:
|
||||
pushl %eax
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebp # save the state of ebp
|
||||
leal 24(%esp), %ebp # save the state of esp before the interrupt
|
||||
pushl %ebp
|
||||
|
||||
# original stack pointer
|
||||
leal 48(%esp), %eax
|
||||
pushl %eax
|
||||
pushl %ds
|
||||
pushl %es
|
||||
pushl %ss
|
||||
pushl %esp # pointer to trap regs struct on the stack
|
||||
call interrupt
|
||||
addl $20, %esp
|
||||
|
||||
popl %ebp
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %eax
|
||||
addl $8, %esp
|
||||
leal int_handler@GOTOFF(%ebx), %ebp
|
||||
movw $KERNEL_CS, -2(%esp)
|
||||
movl %ebp, -6(%esp)
|
||||
lcall *-6(%esp)
|
||||
popl %ebp # discard the saved state of esp
|
||||
popl %ebp # restore the saved state of ebp
|
||||
addl $8, %esp # discard the vector number and error code
|
||||
iret
|
||||
|
||||
# The common interrupt handler code. Pass the register state to the application
|
||||
# interrupt handler. On entry this expects the stack to contain:
|
||||
#
|
||||
# esp+18 eflags
|
||||
# esp+14 cs
|
||||
# esp+10 eip
|
||||
# esp+0c error code
|
||||
# esp+08 vector number
|
||||
# esp+04 ebp
|
||||
# esp+00 esp
|
||||
#
|
||||
# It adds the additional state expected by the application to the bottom of the
|
||||
# stack frame.
|
||||
|
||||
int_handler:
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
pushl %edx
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
pushl %eax
|
||||
pushl %ss
|
||||
pushl %es
|
||||
pushl %ds
|
||||
pushl %esp # pointer to trap regs struct on the stack
|
||||
cld
|
||||
call interrupt
|
||||
addl $16, %esp
|
||||
popl %eax
|
||||
popl %ebx
|
||||
popl %ecx
|
||||
popl %edx
|
||||
popl %edi
|
||||
popl %esi
|
||||
lret
|
||||
|
||||
# The interrupt descriptor table, used for both long mode and protected mode.
|
||||
|
||||
.align 4
|
||||
|
@ -390,40 +390,47 @@ vec19:
|
||||
pushq $19 # vector
|
||||
jmp int_handler
|
||||
|
||||
# The common interrupt handler code. Pass the register state to the
|
||||
# application interrupt handler.
|
||||
# The common interrupt handler code. Pass the register state to the application
|
||||
# interrupt handler. On entry this expects the stack to contain:
|
||||
#
|
||||
# rsp+30 ss
|
||||
# rsp+28 rsp
|
||||
# rsp+20 rflags
|
||||
# rsp+18 cs
|
||||
# rsp+10 rip
|
||||
# rsp+08 error code
|
||||
# rsp+00 vector number
|
||||
#
|
||||
# It adds the additional state expected by the application to the bottom of the
|
||||
# stack frame.
|
||||
|
||||
int_handler:
|
||||
pushq %rax
|
||||
pushq %rbx
|
||||
pushq %rcx
|
||||
pushq %rdx
|
||||
pushq %rdi
|
||||
pushq %rsi
|
||||
pushq %rbp
|
||||
|
||||
# original stack pointer
|
||||
leaq 104(%rsp), %rax
|
||||
pushq %rsi
|
||||
pushq %rdi
|
||||
pushq %rdx
|
||||
pushq %rcx
|
||||
pushq %rbx
|
||||
pushq %rax
|
||||
xorq %rax, %rax
|
||||
movw %ds, %ax
|
||||
movw %ss, %ax
|
||||
pushq %rax
|
||||
movw %es, %ax
|
||||
pushq %rax
|
||||
movw %ss, %ax
|
||||
movw %ds, %ax
|
||||
pushq %rax
|
||||
movq %rsp, %rdi # pointer to trap regs struct on the stack
|
||||
movq %rsp, %rdi # pointer to trap regs struct on the stack
|
||||
cld
|
||||
call interrupt
|
||||
addq $32, %rsp
|
||||
|
||||
popq %rbp
|
||||
popq %rsi
|
||||
popq %rdi
|
||||
popq %rdx
|
||||
popq %rcx
|
||||
popq %rbx
|
||||
addq $24, %rsp
|
||||
popq %rax
|
||||
addq $16, %rsp
|
||||
popq %rbx
|
||||
popq %rcx
|
||||
popq %rdx
|
||||
popq %rdi
|
||||
popq %rsi
|
||||
popq %rbp
|
||||
addq $16, %rsp # discard the vector number and error code
|
||||
iretq
|
||||
|
||||
# The interrupt descriptor table.
|
||||
|
Loading…
Reference in New Issue
Block a user