#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)); memset(processor->iopb, 0, 0x2000); 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) + 0x2000; 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); processor->tss.iopb = sizeof(struct tss); extern void load_tss(void); load_tss(); }