aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/tables
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/tables')
-rw-r--r--src/kernel/tables/compile_flags.txt1
-rw-r--r--src/kernel/tables/gdt.c52
-rw-r--r--src/kernel/tables/idt.c27
-rw-r--r--src/kernel/tables/stub.s53
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