#include "arch/x86_64/tables.h" #include "arch/x86_64/processor.h" #include "string.h" #include "print.h" static segment_descriptor_t s_gdt[] = { [GDT_ENTRY_KERNEL_NULL] = { 0 }, //Kernel NULL [GDT_ENTRY_KERNEL_CODE] = { //Kernel Code .limit_0_15 = 0xFFFF, .base_0_15 = 0x0, .type_flags = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_WRITEABLE | GDT_SEGMENT_FLAG_S | GDT_SEGMENT_FLAG_DPL(0) | GDT_SEGMENT_FLAG_P, .limit_16_19_avlx = 0xF | GDT_SEGMENT_AVLX_L | GDT_SEGMENT_AVLX_G, .base_24_31 = 0x0 }, [GDT_ENTRY_KERNEL_DATA] = { //Kernel Data .limit_0_15 = 0xFFFF, .base_0_15 = 0x0, .type_flags = CD_SEGMENT_TYPE_WRITEABLE | GDT_SEGMENT_FLAG_S | GDT_SEGMENT_FLAG_DPL(0) | GDT_SEGMENT_FLAG_P, .limit_16_19_avlx = 0xF | GDT_SEGMENT_AVLX_L | GDT_SEGMENT_AVLX_G, .base_24_31 = 0x0 }, [GDT_ENTRY_USER_NULL] = { 0 }, //User NULL [GDT_ENTRY_USER_DATA] = { //User Data .limit_0_15 = 0xFFFF, .base_0_15 = 0x0, .type_flags = CD_SEGMENT_TYPE_WRITEABLE | GDT_SEGMENT_FLAG_S | GDT_SEGMENT_FLAG_DPL(3) | GDT_SEGMENT_FLAG_P, .limit_16_19_avlx = 0xF | GDT_SEGMENT_AVLX_L | GDT_SEGMENT_AVLX_G, .base_24_31 = 0x0 }, [GDT_ENTRY_USER_CODE] = { //User Code .limit_0_15 = 0xFFFF, .base_0_15 = 0x0, .type_flags = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_WRITEABLE | GDT_SEGMENT_FLAG_S | GDT_SEGMENT_FLAG_DPL(3) | GDT_SEGMENT_FLAG_P, .limit_16_19_avlx = 0xF | GDT_SEGMENT_AVLX_L | GDT_SEGMENT_AVLX_G, .base_24_31 = 0x0 }, [GDT_ENTRY_TSS_LOW] = { //TSS Low .limit_0_15 = 0, .base_0_15 = 0, .base_16_23 = 0, .type_flags = GDT_SEGMENT_TYPE_TSS_AVAIL | GDT_SEGMENT_FLAG_DPL(0) | GDT_SEGMENT_FLAG_P, .limit_16_19_avlx = 0, .base_24_31 = 0 }, [GDT_ENTRY_TSS_HIGH] = { 0 } //TSS High }; void gdt_setup(processor_t *processor) { size_t gdtw = GDT_ENTRY_COUNT * sizeof(segment_descriptor_t); klogf("%X\n", gdtw); memcpy(processor->gdt, &s_gdt, gdtw); processor->gdtr.base = (uintptr_t)&s_gdt; processor->gdtr.length = gdtw - 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; size_t tssl = sizeof(tss_t); tss_lo->limit_0_15 = tssl & 0xFF; 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; tss_lo->limit_16_19_avlx = (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_OFFSET_TSS); }