diff options
| -rw-r--r-- | boot/startup-x86_64.s | 86 | ||||
| -rw-r--r-- | defs/x86_64-linker.ld | 2 | ||||
| -rw-r--r-- | src/arch/x86_64/asm/vectors.s | 88 |
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 |
