/** * @file kernel/arch/x86_64/gdt.c * @author K. Lange * @brief x86-64 GDT */ #include #include #include /** * @brief 64-bit TSS */ typedef struct tss_entry { uint32_t reserved_0; uint64_t rsp[3]; uint64_t reserved_1; uint64_t ist[7]; uint64_t reserved_2; uint16_t reserved_3; uint16_t iomap_base; } __attribute__ ((packed)) tss_entry_t; typedef struct { uint16_t limit_low; uint16_t base_low; uint8_t base_middle; uint8_t access; uint8_t granularity; uint8_t base_high; } __attribute__((packed)) gdt_entry_t; typedef struct { uint32_t base_highest; uint32_t reserved0; } __attribute__((packed)) gdt_entry_high_t; typedef struct { uint16_t limit; uintptr_t base; } __attribute__((packed)) gdt_pointer_t; typedef struct { gdt_entry_t entries[6]; gdt_entry_high_t tss_extra; gdt_pointer_t pointer; tss_entry_t tss; } __attribute__((packed)) __attribute__((aligned(0x10))) FullGDT; FullGDT gdt[32] __attribute__((used)) = {{ { {0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00}, {0xFFFF, 0x0000, 0x00, 0x9A, (1 << 5) | (1 << 7) | 0x0F, 0x00}, {0xFFFF, 0x0000, 0x00, 0x92, (1 << 5) | (1 << 7) | 0x0F, 0x00}, {0xFFFF, 0x0000, 0x00, 0xFA, (1 << 5) | (1 << 7) | 0x0F, 0x00}, {0xFFFF, 0x0000, 0x00, 0xF2, (1 << 5) | (1 << 7) | 0x0F, 0x00}, {0x0067, 0x0000, 0x00, 0xE9, 0x00, 0x00}, }, {0x00000000, 0x00000000}, {0x0000, 0x0000000000000000}, {0,{0,0,0},0,{0,0,0,0,0,0,0},0,0,0}, }}; void gdt_install(void) { for (int i = 1; i < 32; ++i) { memcpy(&gdt[i], &gdt[0], sizeof(*gdt)); } for (int i = 0; i < 32; ++i) { gdt[i].pointer.limit = sizeof(gdt[i].entries)+sizeof(gdt[i].tss_extra)-1; gdt[i].pointer.base = (uintptr_t)&gdt[i].entries; uintptr_t addr = (uintptr_t)&gdt[i].tss; gdt[i].entries[5].limit_low = sizeof(gdt[i].tss); gdt[i].entries[5].base_low = (addr & 0xFFFF); gdt[i].entries[5].base_middle = (addr >> 16) & 0xFF; gdt[i].entries[5].base_high = (addr >> 24) & 0xFF; gdt[i].tss_extra.base_highest = (addr >> 32) & 0xFFFFFFFF; } extern void * stack_top; gdt[0].tss.rsp[0] = (uintptr_t)&stack_top; asm volatile ( "mov %0, %%rdi\n" "lgdt (%%rdi)\n" "mov $0x10, %%ax\n" "mov %%ax, %%ds\n" "mov %%ax, %%es\n" "mov %%ax, %%ss\n" "mov $0x2b, %%ax\n" "ltr %%ax\n" : : "r"(&gdt[0].pointer) ); } void gdt_copy_to_trampoline(int ap, char * trampoline) { memcpy(trampoline, &gdt[ap].pointer, sizeof(gdt[ap].pointer)); } void arch_set_kernel_stack(uintptr_t stack) { gdt[this_core->cpu_id].tss.rsp[0] = stack; } void arch_set_tls_base(uintptr_t tlsbase) { asm volatile ("wrmsr" : : "c"(0xc0000100), "d"((uint32_t)(tlsbase >> 32)), "a"((uint32_t)(tlsbase & 0xFFFFFFFF))); }