Updated GDT & IDT

This commit is contained in:
Alex
2022-11-06 04:55:12 +02:00
parent 776f6d71b0
commit 416e290c51
4 changed files with 66 additions and 19 deletions

View File

@ -7,7 +7,7 @@
namespace GlobalDescriptorTable namespace GlobalDescriptorTable
{ {
static GlobalDescriptorTableEntries GDTEntries = { static GlobalDescriptorTableEntries GDTEntriesTemplate = {
// null // null
{.Length = 0x0, {.Length = 0x0,
.BaseLow = 0x0, .BaseLow = 0x0,
@ -82,7 +82,8 @@ namespace GlobalDescriptorTable
.Upper32 = 0x0, .Upper32 = 0x0,
.Reserved = 0x0}}; .Reserved = 0x0}};
GlobalDescriptorTableDescriptor gdt = {.Length = sizeof(GlobalDescriptorTableEntries) - 1, .Entries = &GDTEntries}; static GlobalDescriptorTableEntries GDTEntries[MAX_CPU];
GlobalDescriptorTableDescriptor gdt[MAX_CPU];
TaskStateSegment tss[MAX_CPU] = { TaskStateSegment tss[MAX_CPU] = {
0, 0,
@ -93,13 +94,18 @@ namespace GlobalDescriptorTable
0, 0,
}; };
void *CPUStackPointer[MAX_CPU];
__attribute__((no_stack_protector)) void Init(int Core) __attribute__((no_stack_protector)) void Init(int Core)
{ {
debug("Kernel: Code Access: %ld; Data Access: %ld", GDTEntries.Code.Access.Raw, GDTEntries.Data.Access.Raw); memcpy(&GDTEntries[Core], &GDTEntriesTemplate, sizeof(GlobalDescriptorTableEntries));
debug("Kernel: Code Flags: %ld; Data Flags: %ld", GDTEntries.Code.Flags.Raw, GDTEntries.Data.Flags.Raw); gdt[Core] = {.Length = sizeof(GlobalDescriptorTableEntries) - 1, .Entries = &GDTEntries[Core]};
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); debug("Kernel: Code Access: %ld; Data Access: %ld", GDTEntries[Core].Code.Access.Raw, GDTEntries[Core].Data.Access.Raw);
CPU::x64::lgdt(&gdt); 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" asmv("movq %%rsp, %%rax\n"
"pushq $16\n" "pushq $16\n"
@ -114,19 +120,21 @@ namespace GlobalDescriptorTable
"movw %%ax, %%es\n" :: "movw %%ax, %%es\n" ::
: "memory", "rax"); : "memory", "rax");
CPUStackPointer[Core] = KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE));
uint64_t Base = (uint64_t)&tss[Core]; uint64_t Base = (uint64_t)&tss[Core];
gdt.Entries->TaskStateSegment.Length = Base + sizeof(tss[0]); gdt[Core].Entries->TaskStateSegment.Length = Base + sizeof(tss[0]);
gdt.Entries->TaskStateSegment.Low = (uint16_t)(Base & 0xFFFF); gdt[Core].Entries->TaskStateSegment.Low = (uint16_t)(Base & 0xFFFF);
gdt.Entries->TaskStateSegment.Middle = (uint8_t)((Base >> 16) & 0xFF); gdt[Core].Entries->TaskStateSegment.Middle = (uint8_t)((Base >> 16) & 0xFF);
gdt.Entries->TaskStateSegment.High = (uint8_t)((Base >> 24) & 0xFF); gdt[Core].Entries->TaskStateSegment.High = (uint8_t)((Base >> 24) & 0xFF);
gdt.Entries->TaskStateSegment.Upper32 = (uint32_t)((Base >> 32) & 0xFFFFFFFF); gdt[Core].Entries->TaskStateSegment.Upper32 = (uint32_t)((Base >> 32) & 0xFFFFFFFF);
gdt.Entries->TaskStateSegment.Flags1 = 0b10001001; gdt[Core].Entries->TaskStateSegment.Flags1 = 0b10001001;
gdt.Entries->TaskStateSegment.Flags2 = 0b00000000; gdt[Core].Entries->TaskStateSegment.Flags2 = 0b00000000;
tss[Core].IOMapBaseAddressOffset = sizeof(TaskStateSegment); tss[Core].IOMapBaseAddressOffset = sizeof(TaskStateSegment);
tss[Core].StackPointer[0] = (uint64_t)KernelAllocator.RequestPage(); tss[Core].StackPointer[0] = (uint64_t)CPUStackPointer[Core] + STACK_SIZE;
tss[Core].InterruptStackTable[0] = (uint64_t)KernelAllocator.RequestPage(); tss[Core].InterruptStackTable[0] = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE;
tss[Core].InterruptStackTable[1] = (uint64_t)KernelAllocator.RequestPage(); tss[Core].InterruptStackTable[1] = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE;
tss[Core].InterruptStackTable[2] = (uint64_t)KernelAllocator.RequestPage(); tss[Core].InterruptStackTable[2] = (uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE;
CPU::x64::ltr(GDT_TSS); CPU::x64::ltr(GDT_TSS);
asmv("mov %%rsp, %0" asmv("mov %%rsp, %0"
@ -139,4 +147,9 @@ namespace GlobalDescriptorTable
trace("GDT_TSS: %#lx", GDT_TSS); trace("GDT_TSS: %#lx", GDT_TSS);
trace("Global Descriptor Table initialized"); trace("Global Descriptor Table initialized");
} }
void SetKernelStack(void *Stack)
{
tss[GetCurrentCPU()->ID].StackPointer[0] = (uint64_t)Stack;
}
} }

View File

@ -2,6 +2,7 @@
#include <cpu.hpp> #include <cpu.hpp>
#include <debug.h> #include <debug.h>
#include <io.h>
#include "gdt.hpp" #include "gdt.hpp"
@ -428,6 +429,36 @@ namespace InterruptDescriptorTable
void Init(int Core) 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 */ /* ISR */
SetEntry(0x0, InterruptHandler_0x0, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE); SetEntry(0x0, InterruptHandler_0x0, FlagGate_32BIT_TRAP, 1, FlagGate_RING0, GDT_KERNEL_CODE);

View File

@ -86,7 +86,7 @@ namespace GlobalDescriptorTable
typedef struct _TaskStateSegment typedef struct _TaskStateSegment
{ {
uint32_t Reserved0; uint32_t Reserved0 __attribute__((aligned(16)));
uint64_t StackPointer[3]; uint64_t StackPointer[3];
uint64_t Reserved1; uint64_t Reserved1;
uint64_t InterruptStackTable[7]; uint64_t InterruptStackTable[7];
@ -128,7 +128,9 @@ namespace GlobalDescriptorTable
GlobalDescriptorTableEntries *Entries; GlobalDescriptorTableEntries *Entries;
} __attribute__((packed)) GlobalDescriptorTableDescriptor; } __attribute__((packed)) GlobalDescriptorTableDescriptor;
extern void *CPUStackPointer[];
void Init(int Core); void Init(int Core);
void SetKernelStack(void *Stack);
} }
#define GDT_KERNEL_CODE offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, Code) #define GDT_KERNEL_CODE offsetof(GlobalDescriptorTable::GlobalDescriptorTableEntries, Code)

View File

@ -384,6 +384,7 @@ namespace Tasking
CurrentCPU->CurrentThread->Status = TaskStatus::Running; CurrentCPU->CurrentThread->Status = TaskStatus::Running;
*Frame = CurrentCPU->CurrentThread->Registers; *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::writecr3({.raw = (uint64_t)CurrentCPU->CurrentProcess->PageTable});
CPU::x64::fxrstor(CurrentCPU->CurrentThread->FXRegion); CPU::x64::fxrstor(CurrentCPU->CurrentThread->FXRegion);