mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-07-05 12:29:16 +00:00
Updated GDT & IDT
This commit is contained in:
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user