summaryrefslogtreecommitdiffstats
path: root/arch/x86_64/hal/gdt.c
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-09-04 11:31:40 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-09-04 11:31:40 -0400
commit8251da342161767fe203627223ccd4a7026701c6 (patch)
treeaf2db0f11b0ea8ad35f88663a855bab39a80f679 /arch/x86_64/hal/gdt.c
downloadjove-kernel-8251da342161767fe203627223ccd4a7026701c6.tar.gz
jove-kernel-8251da342161767fe203627223ccd4a7026701c6.tar.bz2
jove-kernel-8251da342161767fe203627223ccd4a7026701c6.zip
initial commit. working on tasking
Diffstat (limited to 'arch/x86_64/hal/gdt.c')
-rw-r--r--arch/x86_64/hal/gdt.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/arch/x86_64/hal/gdt.c b/arch/x86_64/hal/gdt.c
new file mode 100644
index 0000000..a64bdc1
--- /dev/null
+++ b/arch/x86_64/hal/gdt.c
@@ -0,0 +1,81 @@
+#include "gdt.h"
+#include "smp.h"
+#include "lib/string.h"
+
+static struct gdt_entry _gdt[GDT_TSS_HI+1] =
+{
+ [GDT_KERNEL_NULL] = { 0 },
+ [GDT_KERNEL_CODE] = (struct gdt_entry) {
+ .limit_0_15 = 0xFFFF,
+ .base_0_15 = 0x0,
+ .base_16_23 = 0x0,
+ .type_flg = 0b10011010,
+ .limit_flg = 0b10101111,
+ .base_24_31 = 0x0
+ },
+ [GDT_KERNEL_DATA] = (struct gdt_entry) {
+ .limit_0_15 = 0xFFFF,
+ .base_0_15 = 0x0,
+ .base_16_23 = 0x0,
+ .type_flg = 0b10010010,
+ .limit_flg = 0b10101111,
+ .base_24_31 = 0x0
+ },
+ [GDT_USER_NULL] = { 0 },
+ [GDT_USER_DATA] = (struct gdt_entry) {
+ .limit_0_15 = 0xFFFF,
+ .base_0_15 = 0x0,
+ .base_16_23 = 0x0,
+ .type_flg = 0b11110010,
+ .limit_flg = 0b10101111,
+ .base_24_31 = 0x0
+ },
+ [GDT_USER_CODE] = (struct gdt_entry) {
+ .limit_0_15 = 0xFFFF,
+ .base_0_15 = 0x0,
+ .base_16_23 = 0x0,
+ .type_flg = 0b11111010,
+ .limit_flg = 0b10101111,
+ .base_24_31 = 0x0
+ },
+ [GDT_TSS_LO] = (struct gdt_entry) {
+ .limit_0_15 = 0x0,
+ .base_0_15 = 0x0,
+ .base_16_23 = 0x0,
+ .type_flg = 0x89,
+ .limit_flg = 0x0,
+ .base_24_31 = 0x0
+ },
+ [GDT_TSS_HI] = { 0 }
+};
+
+void
+gdt_setup(processor_t *processor)
+{
+ memcpy(processor->gdt, _gdt, sizeof(struct gdt_entry) * (GDT_TSS_HI+1));
+
+ struct gdt_descriptor gdtr;
+ gdtr.base = (uintptr_t)&processor->gdt;
+ gdtr.limit = sizeof(struct gdt_entry) * (GDT_TSS_HI+1) - 1;
+
+ extern void load_gdt(struct gdt_descriptor *gdtr);
+ load_gdt(&gdtr);
+
+ uintptr_t tss_base = (uintptr_t)&processor->tss;
+ size_t tss_limit = sizeof(struct tss);
+
+ struct gdt_entry *tss_lo = &processor->gdt[GDT_TSS_LO];
+ struct gdt_entry *tss_hi = &processor->gdt[GDT_TSS_HI];
+
+ tss_lo->base_0_15 = (uint16_t)(tss_base & 0xFFFF);
+ tss_lo->base_16_23 = (uint8_t)((tss_base >> 16) & 0xFF);
+ tss_lo->base_24_31 = (uint8_t)((tss_base >> 24) & 0xFF);
+ tss_hi->limit_0_15 = (uint16_t)((tss_base >> 32) & 0xFFFF);
+ tss_hi->base_0_15 = (uint16_t)((tss_base >> 48) & 0xFFFF);
+
+ tss_lo->limit_0_15 = (uint16_t)(tss_limit & 0xFFFF);
+ tss_lo->limit_flg |= (uint8_t)((tss_limit >> 16) & 0xF);
+
+ extern void load_tss(void);
+ load_tss();
+}