diff options
author | dzwdz | 2022-07-16 13:33:00 +0200 |
---|---|---|
committer | dzwdz | 2022-07-16 13:33:00 +0200 |
commit | 912d2e3c7eb1baa71dda2c0a28aa5809eaa96f27 (patch) | |
tree | 4e27f3538466d5fd63a311d50916039a7a15a485 /src/kernel/arch/amd64/interrupts/idt.c | |
parent | 1eeb66af44ab335888410d716d604e569f20866e (diff) |
amd64: barely boot into kernel code
Diffstat (limited to 'src/kernel/arch/amd64/interrupts/idt.c')
-rw-r--r-- | src/kernel/arch/amd64/interrupts/idt.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/src/kernel/arch/amd64/interrupts/idt.c b/src/kernel/arch/amd64/interrupts/idt.c new file mode 100644 index 0000000..9c71000 --- /dev/null +++ b/src/kernel/arch/amd64/interrupts/idt.c @@ -0,0 +1,71 @@ +#include <kernel/arch/amd64/32/gdt.h> +#include <kernel/arch/amd64/interrupts/idt.h> +#include <kernel/arch/amd64/interrupts/isr.h> +#include <kernel/panic.h> +#include <stdbool.h> +#include <stdint.h> + +struct idt_entry { + uint16_t offset_low; + uint16_t seg; + uint8_t ist; + uint8_t type : 4; // 0xE - interrupt, 0xF - trap + uint8_t zero1 : 1; + uint8_t ring : 2; + uint8_t present : 1; + uint16_t offset_mid; + uint32_t offset_high; + uint32_t zero2; +} __attribute__((packed)); + +// is exactly the same as lgdt_arg, i should combine them into a single struct +// later +struct lidt_arg { + uint16_t limit; + uintptr_t base; +} __attribute__((packed)); + +__attribute__((section(".shared"))) +static struct idt_entry IDT[256]; +static struct lidt_arg lidt_arg; + +static void idt_prepare(void); +static void idt_load(void); +static void idt_test(void); + + +static void idt_prepare(void) { + for (int i = 0; i < 256; i++) { + uintptr_t offset = (uintptr_t) &_isr_stubs + i * 8; + + IDT[i] = (struct idt_entry) { + .offset_low = offset, + .offset_mid = offset >> 16, + .offset_high = offset >> 32, + .seg = SEG_r0code << 3, + .present = 1, + .type = 0xE, + .ist = 1, + }; + } +} + +static void idt_load(void) { + lidt_arg.limit = sizeof(IDT) - 1; + lidt_arg.base = (uintptr_t) &IDT; + asm("lidt (%0)" : : "r" (&lidt_arg) : "memory"); +} + +static void idt_test(void) { + kprintf("idt test?\n"); + asm("xchgw %%bx, %%bx" ::: "memory"); + asm("int $0x34" : : : "memory"); + assert(isr_test_interrupt_called); + kprintf("done.\n"); +} + +void idt_init(void) { + idt_prepare(); + idt_load(); + idt_test(); +} |