diff options
Diffstat (limited to 'arch/x86_64/hal/gdt.c')
| -rw-r--r-- | arch/x86_64/hal/gdt.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/arch/x86_64/hal/gdt.c b/arch/x86_64/hal/gdt.c new file mode 100644 index 0000000..a64bdc1 --- /dev/null +++ b/arch/x86_64/hal/gdt.c @@ -0,0 +1,81 @@ +#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)); + + 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); + + 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); + + extern void load_tss(void); + load_tss(); +} |
