diff options
Diffstat (limited to 'src/kernel/tables')
| -rw-r--r-- | src/kernel/tables/compile_flags.txt | 1 | ||||
| -rw-r--r-- | src/kernel/tables/gdt.c | 52 | ||||
| -rw-r--r-- | src/kernel/tables/idt.c | 27 | ||||
| -rw-r--r-- | src/kernel/tables/stub.s | 53 |
4 files changed, 133 insertions, 0 deletions
diff --git a/src/kernel/tables/compile_flags.txt b/src/kernel/tables/compile_flags.txt new file mode 100644 index 0000000..2af49c7 --- /dev/null +++ b/src/kernel/tables/compile_flags.txt @@ -0,0 +1 @@ +-I../../include/ diff --git a/src/kernel/tables/gdt.c b/src/kernel/tables/gdt.c new file mode 100644 index 0000000..9c65152 --- /dev/null +++ b/src/kernel/tables/gdt.c @@ -0,0 +1,52 @@ +#include "gdt.h" +#include <stdint.h> + +GDT_t table = 0x0; +extern GDTR_t gdtr; +void get_gdtr() { + uint32_t base = (uint32_t)table; + + table[0] = make_descriptor(base, 0, 0); + table[1] = make_descriptor(base, 0x3FFFF, make_code(0, 0, 1)); + table[2] = make_descriptor(base, 0x3FFFF, make_data(0, 0, 1)); + + gdtr.size = sizeof(Segment_Descriptor_t) * 3 - 1; + gdtr.offset = base; +} + +uint16_t make_code(uint8_t priv, uint8_t dc, uint8_t rw) { + uint16_t access = 0; + access |= (1 << 7); + access |= (priv << 5); + access |= (0b11 << 3); + access |= (dc << 2); + access |= (rw << 1); // 10 + access <<= 8; + access |= FLAG; + return access; +} + +uint16_t make_data(uint8_t priv, uint8_t dc, uint8_t rw) { + uint16_t access = 0; + access |= (1 << 7); + access |= (priv << 5); + access |= (0b10 << 3); + access |= (dc << 2); + access |= (rw << 1); // 10 + access <<= 8; + access |= FLAG; + return access; +} + +Segment_Descriptor_t make_descriptor(uint32_t base, uint32_t limit, + uint16_t access_flag) { + uint16_t lim_low = limit; + uint16_t base_low = base; + uint8_t base_mid = (base >> 16); + uint8_t access_byte = access_flag >> 8; + uint8_t lim_flag = ((access_flag << 4) | (limit >> 16)); + uint8_t base_high = (base >> 24); + return (Segment_Descriptor_t){ + lim_low, base_low, base_mid, access_byte, lim_flag, base_high, + }; +} diff --git a/src/kernel/tables/idt.c b/src/kernel/tables/idt.c new file mode 100644 index 0000000..01a6776 --- /dev/null +++ b/src/kernel/tables/idt.c @@ -0,0 +1,27 @@ +#include "idt.h" +#include "gdt.h" +#include "isr.h" +#include <stdint.h> + +__attribute__((aligned(0x10))) static Gate_Descriptor_t idt[256]; +extern GDTR_t idtr; +extern void *isr_stub_table; + +void get_idtr() { + idtr.offset = (uintptr_t)&idt[0]; + idtr.size = sizeof(Gate_Descriptor_t) * 256 - 1; + for (uint8_t vec = 0; vec < 32; vec++) { + make_gate(((void **)(isr_stub_table))[vec], 0x8E, vec); + } + make_gate(wrap_keyboard_handler, 0x8E, 0x21); +} + +void make_gate(void *isr, uint8_t attrs, uint8_t vec) { + Gate_Descriptor_t *descriptor = &idt[vec]; + + descriptor->offset_low = (uint32_t)isr & 0xFFFF; + descriptor->attrs = (0b1000 << 4) | attrs; + descriptor->offset_high = (uint32_t)isr >> 16; + descriptor->segment_selector = 0x08; + descriptor->reserved = 0; +} diff --git a/src/kernel/tables/stub.s b/src/kernel/tables/stub.s new file mode 100644 index 0000000..11e457a --- /dev/null +++ b/src/kernel/tables/stub.s @@ -0,0 +1,53 @@ + +%macro isr_err_stub 1 +isr_stub_%+%1: + call exception_handler + iret +%endmacro +%macro isr_no_err_stub 1 +isr_stub_%+%1: + call exception_handler + iret +%endmacro + +extern exception_handler +isr_no_err_stub 0 +isr_no_err_stub 1 +isr_no_err_stub 2 +isr_no_err_stub 3 +isr_no_err_stub 4 +isr_no_err_stub 5 +isr_no_err_stub 6 +isr_no_err_stub 7 +isr_err_stub 8 +isr_no_err_stub 9 +isr_err_stub 10 +isr_err_stub 11 +isr_err_stub 12 +isr_err_stub 13 +isr_err_stub 14 +isr_no_err_stub 15 +isr_no_err_stub 16 +isr_err_stub 17 +isr_no_err_stub 18 +isr_no_err_stub 19 +isr_no_err_stub 20 +isr_no_err_stub 21 +isr_no_err_stub 22 +isr_no_err_stub 23 +isr_no_err_stub 24 +isr_no_err_stub 25 +isr_no_err_stub 26 +isr_no_err_stub 27 +isr_no_err_stub 28 +isr_no_err_stub 29 +isr_err_stub 30 +isr_no_err_stub 31 + +global isr_stub_table +isr_stub_table: +%assign i 0 +%rep 32 + dd isr_stub_%+i +%assign i i+1 +%endrep |
