[arch][x86][exceptions] clean up the exception handlers
For both 32 and 64bit x86, have each of the exception stubs which push a few words and branch to the common isr routine be simply 16 byte aligned to make it easy to calculate the offset from the main isr table. This cleans up some complexity that was actually broken for interrupts >= 0x80. Also: -Switch alignment directives to .balign -Expand the x86-32 exception table to a full 256 -Remove an extraneous define -Make sure the IDT is 8 or 16 byte aligned -Use END_DATA and END_FUNCTION in the exception and gdt asm files
This commit is contained in:
@@ -10,39 +10,34 @@
|
||||
#include <lk/asm.h>
|
||||
#include <arch/x86/descriptor.h>
|
||||
|
||||
#define NUM_INT 0x31
|
||||
#define NUM_EXC 0x14
|
||||
#define NUM_INT 0x100
|
||||
#define ISR_STUB_LEN 16
|
||||
|
||||
.text
|
||||
|
||||
/* interrupt service routine stubs */
|
||||
_isr:
|
||||
|
||||
.balign ISR_STUB_LEN
|
||||
LOCAL_FUNCTION(_isr_vectors)
|
||||
.set i, 0
|
||||
.rept NUM_INT
|
||||
|
||||
100: /* unnamed label for start of isr stub */
|
||||
.balign ISR_STUB_LEN
|
||||
.if i == 8 || (i >= 10 && i <= 14) || i == 17
|
||||
nop /* error code pushed by exception */
|
||||
nop /* 2 nops are the same length as push byte */
|
||||
pushl $i /* interrupt number */
|
||||
/* error code pushed by exception */
|
||||
push $i /* interrupt number */
|
||||
jmp interrupt_common
|
||||
.else
|
||||
pushl $0 /* fill in error code in iframe */
|
||||
pushl $i /* interrupt number */
|
||||
push $0 /* fill in error code in iframe */
|
||||
push $i /* interrupt number */
|
||||
jmp interrupt_common
|
||||
.endif
|
||||
|
||||
.set i, i + 1
|
||||
.endr
|
||||
END_FUNCTION(_isr_vectors)
|
||||
|
||||
/* figure out the length of a single isr stub (usually 6 or 9 bytes) */
|
||||
.set isr_stub_len, . - 100b
|
||||
|
||||
/* annoying, but force AS to use the same (longer) encoding of jmp for all of the stubs */
|
||||
.fill 256
|
||||
|
||||
FUNCTION(interrupt_common)
|
||||
.balign 16
|
||||
LOCAL_FUNCTION(interrupt_common)
|
||||
cld
|
||||
pushl %gs /* save segment registers */
|
||||
pushl %fs
|
||||
@@ -69,10 +64,11 @@ FUNCTION(interrupt_common)
|
||||
popl %gs
|
||||
addl $8, %esp /* drop exception number and error code */
|
||||
iret
|
||||
END_FUNCTION(interrupt_common)
|
||||
|
||||
FUNCTION(setup_idt)
|
||||
/* setup isr stub descriptors in the idt */
|
||||
movl $_isr, %esi
|
||||
movl $_isr_vectors, %esi
|
||||
movl $_idt, %edi
|
||||
movl $NUM_INT, %ecx
|
||||
|
||||
@@ -82,7 +78,7 @@ FUNCTION(setup_idt)
|
||||
shrl $16, %ebx
|
||||
movw %bx, 6(%edi) /* high word in IDT(n).high */
|
||||
|
||||
addl $isr_stub_len, %esi/* index the next ISR stub */
|
||||
addl $ISR_STUB_LEN, %esi/* index the next ISR stub */
|
||||
addl $8, %edi /* index the next IDT entry */
|
||||
|
||||
loop .Lloop
|
||||
@@ -90,19 +86,19 @@ FUNCTION(setup_idt)
|
||||
lidt _idtr
|
||||
|
||||
ret
|
||||
END_FUNCTION(setup_idt)
|
||||
|
||||
.data
|
||||
|
||||
.align 8
|
||||
.global _idtr
|
||||
_idtr:
|
||||
.balign 8
|
||||
DATA(_idtr)
|
||||
.short _idt_end - _idt - 1 /* IDT limit */
|
||||
.int _idt
|
||||
END_DATA(_idtr)
|
||||
|
||||
/* interrupt descriptor table (IDT) */
|
||||
.global _idt
|
||||
_idt:
|
||||
|
||||
.balign 8
|
||||
DATA(_idt)
|
||||
.set i, 0
|
||||
.rept NUM_INT-1
|
||||
.short 0 /* low 16 bits of ISR offset (_isr#i & 0FFFFh) */
|
||||
@@ -114,15 +110,6 @@ _idt:
|
||||
.set i, i + 1
|
||||
.endr
|
||||
|
||||
/* syscall int (ring 3) */
|
||||
_idt30:
|
||||
.short 0 /* low 16 bits of ISR offset (_isr#i & 0FFFFh) */
|
||||
.short CODE_SELECTOR /* selector */
|
||||
.byte 0
|
||||
.byte 0xee /* present, ring 3, 32-bit interrupt gate */
|
||||
.short 0 /* high 16 bits of ISR offset (_isr#i / 65536) */
|
||||
|
||||
.global _idt_end
|
||||
_idt_end:
|
||||
|
||||
END_DATA(_idt)
|
||||
|
||||
DATA(_idt_end)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <arch/x86/descriptor.h>
|
||||
|
||||
#define NUM_INT 0x100
|
||||
#define NUM_EXC 0x14
|
||||
#define ISR_STUB_LEN 16
|
||||
|
||||
.text
|
||||
|
||||
@@ -22,36 +22,29 @@
|
||||
* 2 bytes when i < 0x80, use align to fill the gap
|
||||
* to make sure isr_stub_len correct for each interrupts
|
||||
*/
|
||||
.balign ISR_STUB_LEN
|
||||
LOCAL_FUNCTION(_isr_vectors)
|
||||
_isr:
|
||||
.set i, 0
|
||||
.rept NUM_INT
|
||||
|
||||
100: /* unnamed label for start of isr stub */
|
||||
|
||||
.balign ISR_STUB_LEN
|
||||
.if i == 8 || (i >= 10 && i <= 14) || i == 17
|
||||
.align 16
|
||||
nop /* error code pushed by exception */
|
||||
nop /* 2 nops are the same length as push byte */
|
||||
pushq $i /* interrupt number */
|
||||
jmp interrupt_common
|
||||
.align 16
|
||||
/* error code pushed by exception */
|
||||
push $i /* interrupt number */
|
||||
jmp interrupt_common
|
||||
.else
|
||||
.align 16
|
||||
pushq $0 /* fill in error code in iframe */
|
||||
pushq $i /* interrupt number */
|
||||
jmp interrupt_common
|
||||
.align 16
|
||||
push $0 /* fill in error code in iframe */
|
||||
push $i /* interrupt number */
|
||||
jmp interrupt_common
|
||||
.endif
|
||||
|
||||
.set i, i + 1
|
||||
.endr
|
||||
END_FUNCTION(_isr_vectors)
|
||||
|
||||
/* figure out the length of a single isr stub (usually 6 or 9 bytes) */
|
||||
.set isr_stub_len, . - 100b
|
||||
|
||||
/* annoying, but force AS to use the same (longer) encoding of jmp for all of the stubs */
|
||||
.fill 256
|
||||
|
||||
.balign 16
|
||||
LOCAL_FUNCTION(interrupt_common)
|
||||
interrupt_common:
|
||||
|
||||
/* clear the direction bit */
|
||||
@@ -99,10 +92,11 @@ interrupt_common:
|
||||
/* drop vector number and error code*/
|
||||
addq $16, %rsp
|
||||
iretq
|
||||
END_FUNCTION(interrupt_common)
|
||||
|
||||
FUNCTION(setup_idt)
|
||||
/* setup isr stub descriptors in the idt */
|
||||
mov $_isr, %rsi
|
||||
mov $_isr_vectors, %rsi
|
||||
mov $_idt, %rdi
|
||||
movl $NUM_INT, %ecx
|
||||
|
||||
@@ -114,7 +108,7 @@ FUNCTION(setup_idt)
|
||||
shr $16, %rbx
|
||||
movl %ebx, 8(%rdi) /* offset [32:63] */
|
||||
|
||||
add $isr_stub_len, %rsi /* index the next ISR stub */
|
||||
add $ISR_STUB_LEN, %rsi /* index the next ISR stub */
|
||||
add $16, %rdi /* index the next IDT entry */
|
||||
|
||||
loop .Lloop
|
||||
@@ -122,16 +116,17 @@ FUNCTION(setup_idt)
|
||||
lidt _idtr
|
||||
|
||||
ret
|
||||
END_FUNCTION(setup_idt)
|
||||
|
||||
.data
|
||||
|
||||
.align 8
|
||||
.balign 8
|
||||
DATA(_idtr)
|
||||
.short _idt_end - _idt - 1 /* IDT limit */
|
||||
.quad _idt
|
||||
.fill 8
|
||||
END_DATA(_idtr)
|
||||
|
||||
.align 8
|
||||
.balign 16
|
||||
/* interrupt descriptor table (IDT) */
|
||||
DATA(_idt)
|
||||
|
||||
@@ -147,10 +142,11 @@ DATA(_idt)
|
||||
.short 0 /* 32bits Reserved */
|
||||
.short 0 /* 32bits Reserved */
|
||||
|
||||
|
||||
.set i, i + 1
|
||||
.endr
|
||||
|
||||
.global _idt_end
|
||||
_idt_end:
|
||||
END_DATA(_idt)
|
||||
|
||||
DATA(_idt_end)
|
||||
|
||||
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
|
||||
.section .rodata
|
||||
|
||||
.align 8
|
||||
.balign 8
|
||||
DATA(_gdtr_phys)
|
||||
.short _gdt_end - _gdt - 1
|
||||
.int PHYS(_gdt)
|
||||
END_DATA(_gdtr_phys)
|
||||
|
||||
.align 8
|
||||
.balign 8
|
||||
DATA(_gdtr)
|
||||
.short _gdt_end - _gdt - 1
|
||||
#if ARCH_X86_32
|
||||
@@ -29,9 +30,10 @@ DATA(_gdtr)
|
||||
#elif ARCH_X86_64
|
||||
.quad _gdt
|
||||
#endif
|
||||
END_DATA(_gdtr)
|
||||
|
||||
.data
|
||||
.align 8
|
||||
.balign 8
|
||||
DATA(_gdt)
|
||||
.int 0
|
||||
.int 0
|
||||
@@ -125,5 +127,7 @@ _tss_gde:
|
||||
.set i, i+1
|
||||
.endr
|
||||
|
||||
END_DATA(_gdt)
|
||||
|
||||
DATA(_gdt_end)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user