diff options
author | Jon Santmyer <jon@jonsantmyer.com> | 2024-03-11 21:30:31 -0400 |
---|---|---|
committer | Jon Santmyer <jon@jonsantmyer.com> | 2024-03-11 21:30:31 -0400 |
commit | d1ff7bcc91886626dc9060ec5fb67ee102ab7c1d (patch) | |
tree | 8f0b5cd8aad31089131785dc6e37b659490f9955 /arch/x86_64/gdt.c | |
download | jove-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.c | 125 |
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(); +} |