diff --git a/Architecture/amd64/cpu/GlobalDescriptorTable.cpp b/Architecture/amd64/cpu/GlobalDescriptorTable.cpp index a4cdaf6..e19e6ea 100644 --- a/Architecture/amd64/cpu/GlobalDescriptorTable.cpp +++ b/Architecture/amd64/cpu/GlobalDescriptorTable.cpp @@ -7,7 +7,7 @@ namespace GlobalDescriptorTable { - static GlobalDescriptorTableEntries GDTEntries = { + static GlobalDescriptorTableEntries GDTEntriesTemplate = { // null {.Length = 0x0, .BaseLow = 0x0, @@ -82,7 +82,8 @@ namespace GlobalDescriptorTable .Upper32 = 0x0, .Reserved = 0x0}}; - GlobalDescriptorTableDescriptor gdt = {.Length = sizeof(GlobalDescriptorTableEntries) - 1, .Entries = &GDTEntries}; + static GlobalDescriptorTableEntries GDTEntries[MAX_CPU]; + GlobalDescriptorTableDescriptor gdt[MAX_CPU]; TaskStateSegment tss[MAX_CPU] = { 0, @@ -93,13 +94,18 @@ namespace GlobalDescriptorTable 0, }; + void *CPUStackPointer[MAX_CPU]; + __attribute__((no_stack_protector)) void Init(int Core) { - debug("Kernel: Code Access: %ld; Data Access: %ld", GDTEntries.Code.Access.Raw, GDTEntries.Data.Access.Raw); - debug("Kernel: Code Flags: %ld; Data Flags: %ld", GDTEntries.Code.Flags.Raw, GDTEntries.Data.Flags.Raw); - debug("User: Code Access: %ld; Data Access: %ld", GDTEntries.UserCode.Access.Raw, GDTEntries.UserData.Access.Raw); - debug("User: Code Flags: %ld; Data Flags: %ld", GDTEntries.UserCode.Flags.Raw, GDTEntries.UserData.Flags.Raw); - CPU::x64::lgdt(&gdt); + memcpy(&GDTEntries[Core], &GDTEntriesTemplate, sizeof(GlobalDescriptorTableEntries)); + gdt[Core] = {.Length = sizeof(GlobalDescriptorTableEntries) - 1, .Entries = &GDTEntries[Core]}; + + debug("Kernel: Code Access: %ld; Data Access: %ld", GDTEntries[Core].Code.Access.Raw, GDTEntries[Core].Data.Access.Raw); + debug("Kernel: Code Flags: %ld; Data Flags: %ld", GDTEntries[Core].Code.Flags.Raw, GDTEntries[Core].Data.Flags.Raw); + debug("User: Code Access: %ld; Data Access: %ld", GDTEntries[Core].UserCode.Access.Raw, GDTEntries[Core].UserData.Access.Raw); + debug("User: Code Flags: %ld; Data Flags: %ld", GDTEntries[Core].UserCode.Flags.Raw, GDTEntries[Core].UserData.Flags.Raw); + CPU::x64::lgdt(&gdt[Core]); asmv("movq %%rsp, %%rax\n" "pushq $16\n" @@ -114,19 +120,21 @@ namespace GlobalDescriptorTable "movw %%ax, %%es\n" :: : "memory", "rax"); + CPUStackPointer[Core] = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)); + uint64_t Base = (uint64_t)&tss[Core]; - gdt.Entries->TaskStateSegment.Length = Base + sizeof(tss[0]); - gdt.Entries->TaskStateSegment.Low = (uint16_t)(Base & 0xFFFF); - gdt.Entries->TaskStateSegment.Middle = (uint8_t)((Base >> 16) & 0xFF); - gdt.Entries->TaskStateSegment.High = (uint8_t)((Base >> 24) & 0xFF); - gdt.Entries->TaskStateSegment.Upper32 = (uint32_t)((Base >> 32) & 0xFFFFFFFF); - gdt.Entries->TaskStateSegment.Flags1 = 0b10001001; - gdt.Entries->TaskStateSegment.Flags2 = 0b00000000; + gdt[Core].Entries->TaskStateSegment.Length = Base + sizeof(tss[0]); + gdt[Core].Entries->TaskStateSegment.Low = (uint16_t)(Base & 0xFFFF); + gdt[Core].Entries->TaskStateSegment.Middle = (uint8_t)((Base >> 16) & 0xFF); + gdt[Core].Entries->TaskStateSegment.High = (uint8_t)((Base >> 24) & 0xFF); + gdt[Core].Entries->TaskStateSegment.Upper32 = (uint32_t)((Base >> 32) & 0xFFFFFFFF); + gdt[Core].Entries->TaskStateSegment.Flags1 = 0b10001001; + gdt[Core].Entries->TaskStateSegment.Flags2 = 0b00000000; tss[Core].IOMapBaseAddressOffset = sizeof(TaskStateSegment); - tss[Core].StackPointer[0] = (uint64_t)KernelAllocator.RequestPage(); - tss[Core].InterruptStackTable[0] = (uint64_t)KernelAllocator.RequestPage(); - tss[Core].InterruptStackTable[1] = (uint64_t)KernelAllocator.RequestPage(); - tss[Core].InterruptStackTable[2] = (uint64_t)KernelAllocator.RequestPage(); + tss[Core].StackPointer[0] = (uint64_t)CPUStackPointer[Core] + STACK_SIZE; + tss[Core].InterruptStackTable[0] = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE; + tss[Core].InterruptStackTable[1] = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE; + tss[Core].InterruptStackTable[2] = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE; CPU::x64::ltr(GDT_TSS); asmv("mov %%rsp, %0" @@ -139,4 +147,9 @@ namespace GlobalDescriptorTable trace("GDT_TSS: %#lx", GDT_TSS); trace("Global Descriptor Table initialized"); } + + void SetKernelStack(void *Stack) + { + tss[GetCurrentCPU()->ID].StackPointer[0] = (uint64_t)Stack; + } } diff --git a/Architecture/amd64/cpu/InterruptDescriptorTable.cpp b/Architecture/amd64/cpu/InterruptDescriptorTable.cpp index 790e34f..df4c0fd 100644 --- a/Architecture/amd64/cpu/InterruptDescriptorTable.cpp +++ b/Architecture/amd64/cpu/InterruptDescriptorTable.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "gdt.hpp" @@ -428,6 +429,36 @@ namespace InterruptDescriptorTable void Init(int Core) { + static int once = 0; + if (!once++) + { + // PIC + outb(0x20, 0x10 | 0x1); + outb(0x80, 0); + outb(0xA0, 0x10 | 0x10); + outb(0x80, 0); + + outb(0x21, 0x20); + outb(0x80, 0); + outb(0xA1, 0x28); + outb(0x80, 0); + + outb(0x21, 0x04); + outb(0x80, 0); + outb(0xA1, 0x02); + outb(0x80, 0); + + outb(0x21, 1); + outb(0x80, 0); + outb(0xA1, 1); + outb(0x80, 0); + + // Masking and disabling PIC + outb(0x21, 0xff); + outb(0x80, 0); + outb(0xA1, 0xff); + } + /* ISR */ SetEntry(0x0, InterruptHandler_0x0, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); diff --git a/Architecture/amd64/cpu/gdt.hpp b/Architecture/amd64/cpu/gdt.hpp index d6b9f41..9cbe02d 100644 --- a/Architecture/amd64/cpu/gdt.hpp +++ b/Architecture/amd64/cpu/gdt.hpp @@ -86,7 +86,7 @@ namespace GlobalDescriptorTable typedef struct _TaskStateSegment { - uint32_t Reserved0; + uint32_t Reserved0 __attribute__((aligned(16))); uint64_t StackPointer[3]; uint64_t Reserved1; uint64_t InterruptStackTable[7]; @@ -128,7 +128,9 @@ namespace GlobalDescriptorTable GlobalDescriptorTableEntries *Entries; } __attribute__((packed)) GlobalDescriptorTableDescriptor; + extern void *CPUStackPointer[]; void Init(int Core); + void SetKernelStack(void *Stack); } #define GDT_KERNEL_CODE offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, Code) diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index 93c3676..47eb08d 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -384,6 +384,7 @@ namespace Tasking CurrentCPU->CurrentThread->Status = TaskStatus::Running; *Frame = CurrentCPU->CurrentThread->Registers; + GlobalDescriptorTable::SetKernelStack((void *)((uint64_t)CurrentCPU->CurrentThread->Stack + STACK_SIZE)); CPU::x64::writecr3({.raw = (uint64_t)CurrentCPU->CurrentProcess->PageTable}); CPU::x64::fxrstor(CurrentCPU->CurrentThread->FXRegion);