From 20b97ea7c0dbbdc13800e12ff5c86c00c4a342ec Mon Sep 17 00:00:00 2001 From: aqua Date: Fri, 8 Mar 2024 17:24:49 +0200 Subject: Bazel build --- arch/i386/lidt.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 arch/i386/lidt.c (limited to 'arch/i386/lidt.c') diff --git a/arch/i386/lidt.c b/arch/i386/lidt.c new file mode 100644 index 0000000..86567f8 --- /dev/null +++ b/arch/i386/lidt.c @@ -0,0 +1,55 @@ +#include "idt.h" +#include + +struct __attribute__((packed)) Pointer { + uint16_t limit; + uint32_t base; +}; + +enum Type { + Null = 0, + Intr = 0x8e /* 1000 1110 32-bit interrupt */ +}; + +struct __attribute__((packed)) Gate_t { + uint16_t offset_15_0; /* segment offset low */ + uint16_t selector; /* code segment selector */ + uint8_t __unused; /* unused in protected mode */ + uint8_t type; /* interrupt type */ + uint16_t offset_31_16; /* segment offset high */ +}; +/* _Static_assert(sizeof(struct Gate_t) == 8, "interrupt gate size"); */ + +void +Gate(struct Gate_t *entry, void (*f)(struct interrupt_frame *), uint16_t selector) +{ + uint32_t f_addr = (uint32_t)f; + entry->offset_15_0 = f_addr & 0xffff; + entry->offset_31_16 = (uint16_t)(f_addr >> 16) & 0xffff; + entry->selector = selector; + entry->__unused = 0; + entry->type = Intr; +} + +static struct Gate_t interrupt_table[256] __attribute((aligned(4096))); + +void +idt_install() +{ + int i; + const struct Pointer ptr = {sizeof(interrupt_table) - 1, (unsigned)&interrupt_table}; + + /* exceptions 0x00~0x13 */ + for (i = 0; i <= 0x13; ++i) Gate(&interrupt_table[i], &abort_handler, 0x10); + + /* irq 0x20~0x2f */ + for (i = 0x22; i <= 0x2f; ++i) Gate(&interrupt_table[i], &abort_handler, 0x10); + Gate(&interrupt_table[0x20], &irq0x00, 0x10); + Gate(&interrupt_table[0x21], &irq0x01, 0x10); + Gate(&interrupt_table[0x2c], &irq0x0c, 0x10); + + /* syscall 0x80 */ + Gate(&interrupt_table[0x80], &syscall_handler, 0x10); + + __asm__("lidt (%0)" : : "a"(&ptr)); +} -- cgit v1.2.1