aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTianhao Wang <shrik3@mailbox.org>2024-04-17 21:49:43 +0200
committerTianhao Wang <shrik3@mailbox.org>2024-06-11 15:16:33 +0200
commitb5a8b9ba0f1461031c39b5a5abf1c544a9dc7ab8 (patch)
tree74aa419d91622a03fd9575b50f2ec818273a88c1
parent6609d771d429df9ef810d39f2180c9b651fc15d0 (diff)
split idt and vectors from startup code
-rw-r--r--boot/startup-x86_64.s86
-rw-r--r--defs/x86_64-linker.ld2
-rw-r--r--src/arch/x86_64/asm/vectors.s88
3 files changed, 95 insertions, 81 deletions
diff --git a/boot/startup-x86_64.s b/boot/startup-x86_64.s
index bb270a1..610d7ca 100644
--- a/boot/startup-x86_64.s
+++ b/boot/startup-x86_64.s
@@ -21,13 +21,14 @@ MULTIBOOT_EAX_MAGIC equ 0x2badb002
; exported symbols
[GLOBAL startup]
-[GLOBAL idt]
[GLOBAL pml4]
[GLOBAL pdp]
-; functions from the rust
+; functions from the other parts
+[EXTERN vectors_start]
+[EXTERN idt]
+[EXTERN idt_descr]
[EXTERN _entry]
-[EXTERN interrupt_gate]
; addresses provided by the linker
[EXTERN ___BSS_START__]
@@ -185,67 +186,13 @@ init_sse:
; Interrupt handling
;
-; template for header for each interrupt-handling routine
-; TODO: vectors should have their dedicated place
-%macro wrapper 1
-wrapper_%1:
- push rbp
- mov rbp, rsp
- push rax
- mov al, %1
- jmp wrapper_body
-%endmacro
-
-; automatic generation of 256 interrupt-handling routines, based on above macro
-%assign i 0
-%rep 256
-wrapper i
-%assign i i+1
-%endrep
-
-; common handler body
-wrapper_body:
- ; GCC expects the direction flag to be 0
- cld
- ; save volatile registers
- push rcx
- push rdx
- push rdi
- push rsi
- push r8
- push r9
- push r10
- push r11
-
- ; the generated wrapper only gives us 8 bits, mask the rest
- and rax, 0xff
- ; call the interrupt handling code with interrupt number as parameter
- mov rdi, rax
- call interrupt_gate
-
- ; restore volatile registers
- pop r11
- pop r10
- pop r9
- pop r8
- pop rsi
- pop rdi
- pop rdx
- pop rcx
-
- ; ... also those from the wrapper
- pop rax
- pop rbp
-
- ; done
- iretq
;
; Relocating of IDT entries and setting IDTR
;
setup_idt:
- mov rax, wrapper_0
+ mov rax, vectors_start
; bits 0..15 -> ax, 16..31 -> bx, 32..64 -> edx
mov rbx, rax
@@ -298,29 +245,6 @@ gdt_80:
dw 4*8 - 1 ; GDT limit=24, 4 GDT entries - 1
dq gdt ; GDT address
-;
-; Interrupt descriptor table with 256 entries
-;
-; TODO: use a interrupt stack instead of the current stack.
-idt:
-%macro idt_entry 1
- dw (wrapper_%1 - wrapper_0) & 0xffff ; offset 0 .. 15
- dw 0x0000 | 0x8 * 2 ; selector points to 64-bit code segment selector (GDT)
- dw 0x8e00 ; 8 -> interrupt is present, e -> 80386 32-bit interrupt gate
- dw ((wrapper_%1 - wrapper_0) & 0xffff0000) >> 16 ; offset 16 .. 31
- dd ((wrapper_%1 - wrapper_0) & 0xffffffff00000000) >> 32 ; offset 32..63
- dd 0x00000000 ; reserved
-%endmacro
-
-%assign i 0
-%rep 256
-idt_entry i
-%assign i i+1
-%endrep
-
-idt_descr:
- dw 256*8 - 1 ; 256 entries
- dq idt
[SECTION .bss]
diff --git a/defs/x86_64-linker.ld b/defs/x86_64-linker.ld
index 82f5eaa..aee69aa 100644
--- a/defs/x86_64-linker.ld
+++ b/defs/x86_64-linker.ld
@@ -12,6 +12,8 @@ SECTIONS
.data :
{
+ *(".data.idt")
+ *(".data.vectors")
*(".data")
*(".data$")
}
diff --git a/src/arch/x86_64/asm/vectors.s b/src/arch/x86_64/asm/vectors.s
new file mode 100644
index 0000000..c3fa12f
--- /dev/null
+++ b/src/arch/x86_64/asm/vectors.s
@@ -0,0 +1,88 @@
+; vectors.s - idt for x86_64
+
+[GLOBAL idt]
+[GLOBAL idt_descr]
+[GLOBAL vectors_start]
+[EXTERN interrupt_gate]
+
+[SECTION .data.idt]
+;
+; Interrupt descriptor table with 256 entries
+; TODO: use a interrupt stack instead of the current stack.
+;
+idt:
+%macro idt_entry 1
+ dw (wrapper_%1 - wrapper_0) & 0xffff ; offset 0 .. 15
+ dw 0x0000 | 0x8 * 2 ; selector points to 64-bit code segment selector (GDT)
+ dw 0x8e00 ; 8 -> interrupt is present, e -> 80386 32-bit interrupt gate
+ dw ((wrapper_%1 - wrapper_0) & 0xffff0000) >> 16 ; offset 16 .. 31
+ dd ((wrapper_%1 - wrapper_0) & 0xffffffff00000000) >> 32 ; offset 32..63
+ dd 0x00000000 ; reserved
+%endmacro
+
+%assign i 0
+%rep 256
+idt_entry i
+%assign i i+1
+%endrep
+
+idt_descr:
+ dw 256*8 - 1 ; 256 entries
+ dq idt
+
+; template for header for each interrupt-handling routine
+%macro wrapper 1
+wrapper_%1:
+ push rbp
+ mov rbp, rsp
+ push rax
+ mov al, %1
+ jmp wrapper_body
+%endmacro
+
+; automatic generation of 256 interrupt-handling routines, based on above macro
+
+[SECTION .data.vectors]
+vectors_start:
+%assign i 0
+%rep 256
+wrapper i
+%assign i i+1
+%endrep
+
+; common handler body
+wrapper_body:
+ ; GCC expects the direction flag to be 0
+ cld
+ ; save volatile registers
+ push rcx
+ push rdx
+ push rdi
+ push rsi
+ push r8
+ push r9
+ push r10
+ push r11
+
+ ; the generated wrapper only gives us 8 bits, mask the rest
+ and rax, 0xff
+ ; call the interrupt handling code with interrupt number as parameter
+ mov rdi, rax
+ call interrupt_gate
+
+ ; restore volatile registers
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+ pop rsi
+ pop rdi
+ pop rdx
+ pop rcx
+
+ ; ... also those from the wrapper
+ pop rax
+ pop rbp
+
+ ; done
+ iretq