From 59ab8c016d0cf5f4ef3ae3a9ef92e437bd384f62 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 17 Sep 2022 17:40:35 +0200 Subject: [PATCH] Load a bare-bones TSS for CPU0 --- kernel/src/gdt/GDT.asm | 5 ++++ kernel/src/gdt/GDT.cpp | 59 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/kernel/src/gdt/GDT.asm b/kernel/src/gdt/GDT.asm index d09b90d7..171debdb 100644 --- a/kernel/src/gdt/GDT.asm +++ b/kernel/src/gdt/GDT.asm @@ -13,4 +13,9 @@ load_gdt: push rax retfq .reload_CS: + ret +global load_tr +load_tr: + mov rax, rdi + ltr ax ret \ No newline at end of file diff --git a/kernel/src/gdt/GDT.cpp b/kernel/src/gdt/GDT.cpp index e2e6bc7c..2b2116f0 100644 --- a/kernel/src/gdt/GDT.cpp +++ b/kernel/src/gdt/GDT.cpp @@ -1,7 +1,10 @@ #define MODULE "gdt" #include "gdt/GDT.h" +#include "assert.h" #include "log/Log.h" +#include "memory/KernelMemoryManager.h" +#include "std/string.h" #include struct GDTR @@ -20,28 +23,74 @@ struct GDTEntry uint8_t base2; } __attribute__((packed)); +struct HighGDTEntry +{ + uint32_t base_high; + uint32_t reserved; +} __attribute__((packed)); + +struct TSS +{ + uint32_t reserved0; + uint64_t rsp[3]; + uint64_t reserved1; + uint64_t ist[7]; + uint64_t reserved2; + uint16_t reserved3; + uint16_t iomap_base; +} __attribute__((packed)); + struct InternalGDT { GDTEntry null; GDTEntry kernel_code; GDTEntry kernel_data; - GDTEntry user_null; GDTEntry user_code; GDTEntry user_data; + GDTEntry tss; + HighGDTEntry tss2; } __attribute__((packed)) __attribute((aligned(0x1000))); -__attribute__((aligned(0x1000))) static InternalGDT internal_gdt = { - {0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00}, {0xffff, 0x0000, 0x00, 0x9a, 0xaf, 0x00}, - {0xffff, 0x0000, 0x00, 0x92, 0xcf, 0x00}, {0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00}, - {0xffff, 0x0000, 0x00, 0xfa, 0xaf, 0x00}, {0xffff, 0x0000, 0x00, 0xf2, 0xcf, 0x00}}; +__attribute__((aligned(0x1000))) static InternalGDT internal_gdt = {{0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00}, + {0xffff, 0x0000, 0x00, 0x9a, 0xaf, 0x00}, + {0xffff, 0x0000, 0x00, 0x92, 0xcf, 0x00}, + {0xffff, 0x0000, 0x00, 0xfa, 0xaf, 0x00}, + {0xffff, 0x0000, 0x00, 0xf2, 0xcf, 0x00}, + {0x0000, 0x0000, 0x00, 0xe9, 0xcf, 0x00}, + {0x00000000, 0x00000000}}; + +static TSS main_tss; extern "C" void load_gdt(GDTR* gdtr); +extern "C" void load_tr(int segment); + +static void set_base(GDTEntry* entry, uint32_t base) +{ + entry->base0 = (base & 0xFFFF); + entry->base1 = (base >> 16) & 0xFF; + entry->base2 = (base >> 24) & 0xFF; +} + +static void set_limit(GDTEntry* entry, uint32_t limit) +{ + ASSERT(limit <= 0xFFFFF); + entry->limit0 = limit; + entry->limit1_flags = (entry->limit1_flags & 0xF0) | (limit & 0xF); +} void GDT::load() { static GDTR gdtr; gdtr.offset = (uint64_t)&internal_gdt; gdtr.size = sizeof(InternalGDT); + memset(&main_tss, 0, sizeof(TSS)); + main_tss.rsp[0] = + (uint64_t)KernelMemoryManager::get_pages(4) + (4096 * 4) - 8; // allocate 16KB for the syscall stack + set_base(&internal_gdt.tss, (uint64_t)&main_tss & 0xffffffff); + internal_gdt.tss2.base_high = (uint64_t)&main_tss >> 32; + set_limit(&internal_gdt.tss, sizeof(TSS) - 1); kdbgln("Loading GDT at offset %lx, size %d", gdtr.offset, gdtr.size); load_gdt(&gdtr); + kdbgln("Loading TR (GDT entry 0x28)"); + load_tr(0x28); } \ No newline at end of file