#include "arch/x86_64/tables.h" #include "arch/x86_64/processor.h" #include "string.h" static segment_descriptor_t s_gdt[] = { { 0 }, //Kernel NULL { //Kernel Code .limit_0_15 = 0xFFFF, .base_0_15 = 0x0, .type = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_WRITEABLE, .s = 1, .dpl = 0, .p = 1, .limit_16_19 = 0xF, .avl = 0, .l = 1, .d_b = 0, .g = 1, .base_24_31 = 0x0 }, { //Kernel Data .limit_0_15 = 0xFFFF, .base_0_15 = 0x0, .type = CD_SEGMENT_TYPE_WRITEABLE, .s = 1, .dpl = 0, .p = 1, .limit_16_19 = 0xF, .avl = 0, .l = 0, .d_b = 1, .g = 1, .base_24_31 = 0x0 }, { 0 }, //User NULL { //User Data .limit_0_15 = 0xFFFF, .base_0_15 = 0x0, .type = CD_SEGMENT_TYPE_WRITEABLE, .s = 1, .dpl = 3, .p = 1, .limit_16_19 = 0xF, .avl = 0, .l = 0, .d_b = 1, .g = 1, .base_24_31 = 0x0 }, { //User Code .limit_0_15 = 0xFFFF, .base_0_15 = 0x0, .type = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_WRITEABLE, .s = 1, .dpl = 3, .p = 1, .limit_16_19 = 0xF, .avl = 0, .l = 1, .d_b = 0, .g = 1, .base_24_31 = 0x0 }, { //TSS Low .limit_0_15 = 0, .base_0_15 = 0, .base_16_23 = 0, .type = S_SEGMENT_TYPE_TSS_AVAIL, .avl = 0, .s = 0, .dpl = 0, .p = 1, .limit_16_19 = 0, .l = 0, .d_b = 0, .g = 0, .base_24_31 = 0 }, { 0 } //TSS High }; void gdt_setup(processor_t *processor) { memcpy(processor->gdt, s_gdt, sizeof(s_gdt)); processor->gdtr.base = (uintptr_t)&s_gdt; processor->gdtr.length = sizeof(s_gdt) - 1; segment_descriptor_t *tss_lo = &processor->gdt[GDT_ENTRY_TSS_LOW]; segment_descriptor_t *tss_hi = &processor->gdt[GDT_ENTRY_TSS_HIGH]; uintptr_t tssb = (uintptr_t)&processor->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; size_t tssl = sizeof(tss_t); tss_lo->limit_0_15 = tssl & 0xFFFF; tss_lo->limit_16_19 = (tssl >> 16) & 0xF; processor->tss.iopb = tssl; extern void gdt_load(void*); gdt_load(&processor->gdtr); extern void tss_flush(uint16_t); tss_flush(GDT_ENTRY_TSS_LOW * sizeof(segment_descriptor_t)); }