diff --git a/src/kernel/boot.s b/src/kernel/boot.s index 081185c..fec42f1 100644 --- a/src/kernel/boot.s +++ b/src/kernel/boot.s @@ -28,7 +28,8 @@ _start: extern kernel_main call kernel_main - ; Kernel init is over, wait for interrupts + ; Kernel init is over, wait for the scheduler to + ; take over .hang: hlt jmp .hang diff --git a/src/kernel/gdt.cpp b/src/kernel/gdt.cpp index 52def38..38e2eb2 100644 --- a/src/kernel/gdt.cpp +++ b/src/kernel/gdt.cpp @@ -137,10 +137,17 @@ idt_set_entry(uint8_t i, uint64_t addr, uint16_t selector, uint8_t flags) void tss_set_stack(int ring, addr_t rsp) { - kassert(ring < 3, "Bad ring passed to set_tss_stack."); + kassert(ring < 3, "Bad ring passed to tss_set_stack."); g_tss.rsp[ring] = rsp; } +addr_t +tss_get_stack(int ring) +{ + kassert(ring < 3, "Bad ring passed to tss_get_stack."); + return g_tss.rsp[ring]; +} + void gdt_init() { @@ -150,12 +157,18 @@ gdt_init() g_gdtr.limit = sizeof(g_gdt_table) - 1; g_gdtr.base = reinterpret_cast(&g_gdt_table); + // Kernel CS/SS - always 64bit gdt_set_entry(1, 0, 0xfffff, true, gdt_type::read_write | gdt_type::execute); gdt_set_entry(2, 0, 0xfffff, true, gdt_type::read_write); - gdt_set_entry(3, 0, 0xfffff, true, gdt_type::ring3 | gdt_type::read_write | gdt_type::execute); + + // User CS32/SS/CS64 - layout expected by SYSRET + gdt_set_entry(3, 0, 0xfffff, false, gdt_type::ring3 | gdt_type::read_write | gdt_type::execute); gdt_set_entry(4, 0, 0xfffff, true, gdt_type::ring3 | gdt_type::read_write); + gdt_set_entry(5, 0, 0xfffff, true, gdt_type::ring3 | gdt_type::read_write | gdt_type::execute); kutil::memset(&g_tss, 0, sizeof(tss_entry)); + g_tss.iomap_offset = sizeof(tss_entry); + addr_t tss_base = reinterpret_cast(&g_tss); // Note that this takes TWO GDT entries diff --git a/src/kernel/gdt.h b/src/kernel/gdt.h index 20c22a5..6022517 100644 --- a/src/kernel/gdt.h +++ b/src/kernel/gdt.h @@ -20,6 +20,11 @@ void idt_set_entry(uint8_t i, uint64_t addr, uint16_t selector, uint8_t flags); /// \arg rsp Stack pointer to set void tss_set_stack(int ring, addr_t rsp); +/// Get the stack pointer for a given ring in the TSS +/// \arg ring Ring to get (0-2) +/// \returns Stack pointers for that ring +addr_t tss_get_stack(int ring); + /// Dump information about the current GDT to the screen void gdt_dump();