aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Geiselbrecht <geist@foobox.com>2024-03-10 21:29:47 -0700
committerTravis Geiselbrecht <geist@foobox.com>2024-03-10 21:50:01 -0700
commitab0e1fd3a164ac3dedcd61810dd33863b42cd9da (patch)
tree98ed518c18ce0760e8ffd7e308005e687250a7a0
parent6d7d31d9b43f2d3526ea736bcefe539abe4ccc87 (diff)
downloadlk-ab0e1fd3a164ac3dedcd61810dd33863b42cd9da.tar.gz
[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
-rw-r--r--arch/x86/32/exceptions.S59
-rw-r--r--arch/x86/64/exceptions.S52
-rw-r--r--arch/x86/gdt.S10
3 files changed, 54 insertions, 67 deletions
diff --git a/arch/x86/32/exceptions.S b/arch/x86/32/exceptions.S
index 98ac81f1..e1bca374 100644
--- a/arch/x86/32/exceptions.S
+++ b/arch/x86/32/exceptions.S
@@ -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)
diff --git a/arch/x86/64/exceptions.S b/arch/x86/64/exceptions.S
index 86a54827..cecb5eb5 100644
--- a/arch/x86/64/exceptions.S
+++ b/arch/x86/64/exceptions.S
@@ -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)
+
diff --git a/arch/x86/gdt.S b/arch/x86/gdt.S
index 398a2671..abb9c794 100644
--- a/arch/x86/gdt.S
+++ b/arch/x86/gdt.S
@@ -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)