summaryrefslogtreecommitdiffstats
path: root/arch/x86_64/gdt.c
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2024-03-11 21:30:31 -0400
committerJon Santmyer <jon@jonsantmyer.com>2024-03-11 21:30:31 -0400
commitd1ff7bcc91886626dc9060ec5fb67ee102ab7c1d (patch)
tree8f0b5cd8aad31089131785dc6e37b659490f9955 /arch/x86_64/gdt.c
downloadjove-kernel-d1ff7bcc91886626dc9060ec5fb67ee102ab7c1d.tar.gz
jove-kernel-d1ff7bcc91886626dc9060ec5fb67ee102ab7c1d.tar.bz2
jove-kernel-d1ff7bcc91886626dc9060ec5fb67ee102ab7c1d.zip
usermode capable kernel with logging syscall
Diffstat (limited to 'arch/x86_64/gdt.c')
-rw-r--r--arch/x86_64/gdt.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/arch/x86_64/gdt.c b/arch/x86_64/gdt.c
new file mode 100644
index 0000000..d996dcb
--- /dev/null
+++ b/arch/x86_64/gdt.c
@@ -0,0 +1,125 @@
+#include "tables.h"
+#include "tss.h"
+
+enum
+{
+ GDT_SEGMENT_KERNEL_NULL = 0,
+ GDT_SEGMENT_KERNEL_CODE,
+ GDT_SEGMENT_KERNEL_DATA,
+
+ GDT_SEGMENT_USER_NULL,
+ GDT_SEGMENT_USER_DATA,
+ GDT_SEGMENT_USER_CODE,
+
+ GDT_SEGMENT_TSS_LOW,
+ GDT_SEGMENT_TSS_HIGH,
+
+ GDT_SEGMENT_COUNT
+};
+
+__attribute__((aligned(0x1000)))
+static struct SegmentDescriptor s_gdtd[GDT_SEGMENT_COUNT] =
+{
+ { 0 }, /* Kernel NULL */
+ { /* Kernel Code (64-bit RO EX DPL0) */
+ .limit_0_15 = 0xFFFF,
+ .base_0_15 = 0,
+ .base_16_23 = 0,
+ .type = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_CODE_CONFORMING,
+ .s = 1,
+ .dpl = 0,
+ .p = 1,
+ .limit_16_19 = 0xF,
+ .l = 1,
+ .d_b = 0,
+ .g = 0,
+ .base_24_31 = 0
+ },
+ { /* Kernel Data (64-bit RW DPL0) */
+ .limit_0_15 = 0xFFFF,
+ .base_0_15 = 0,
+ .base_16_23 = 0,
+ .type = CD_SEGMENT_TYPE_WRITEABLE,
+ .s = 1,
+ .dpl = 0,
+ .p = 1,
+ .limit_16_19 = 0xF,
+ .l = 1,
+ .d_b = 0,
+ .g = 0,
+ .base_24_31 = 0
+ },
+ { 0 }, /* User NULL */
+ { /* User Data (64-bit RO EX DPL3)*/
+ .limit_0_15 = 0xFFFF,
+ .base_0_15 = 0,
+ .base_16_23 = 0,
+ .type = CD_SEGMENT_TYPE_WRITEABLE,
+ .s = 1,
+ .dpl = 3,
+ .p = 1,
+ .limit_16_19 = 0xF,
+ .l = 1,
+ .d_b = 0,
+ .g = 0,
+ .base_24_31 = 0,
+ },
+ { /* User Code (64-bit RO EX DPL3)*/
+ .limit_0_15 = 0xFFFF,
+ .base_0_15 = 0,
+ .base_16_23 = 0,
+ .type = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_CODE_CONFORMING,
+ .s = 1,
+ .dpl = 3,
+ .p = 1,
+ .limit_16_19 = 0xF,
+ .l = 1,
+ .d_b = 0,
+ .g = 0,
+ .base_24_31 = 0,
+ },
+ { /* TSS Low */
+ .limit_0_15 = sizeof(struct TSS),
+ .base_0_15 = 0,
+ .base_16_23 = 0,
+ .type = S_SEGMENT_TYPE_TSS_AVAIL,
+ .avl = 1,
+ .s = 0,
+ .dpl = 0,
+ .p = 1,
+ .limit_16_19 = 0,
+ .l = 1,
+ .d_b = 0,
+ .g = 0,
+ .base_24_31 = 0,
+ },
+ { 0 }
+};
+static struct XDTR s_gdtr = {
+ .length = sizeof(s_gdtd) - 1,
+ .address = (uintptr_t)&s_gdtd
+};
+
+static struct TSS s_tss = {
+
+};
+
+extern void x86_64_lgdt(struct XDTR *gdtr);
+extern void x86_64_flush_tss(void);
+void
+x86_64_load_gdt(void)
+{
+ {
+ struct SegmentDescriptor *tss_lo = &s_gdtd[GDT_SEGMENT_TSS_LOW];
+ struct SegmentDescriptor *tss_hi = &s_gdtd[GDT_SEGMENT_TSS_HIGH];
+ uintptr_t tssb = (uintptr_t)&s_tss;
+ tss_lo->base_0_15 = tssb & 0xFFFF;
+ tss_lo->base_16_23 = (tssb >> 16) & 0xFF;
+ tss_lo->base_24_31 = (tssb >> 24) & 0xFF;
+ tss_hi->limit_0_15 = (tssb >> 32) & 0xFFFF;
+ tss_hi->base_0_15 = (tssb >> 48) & 0xFFFF;
+ }
+
+ x86_64_lgdt(&s_gdtr);
+ x86_64_flush_tss();
+}