Load a bare-bones TSS for CPU0
This commit is contained in:
parent
355ca6ea9f
commit
59ab8c016d
@ -14,3 +14,8 @@ load_gdt:
|
|||||||
retfq
|
retfq
|
||||||
.reload_CS:
|
.reload_CS:
|
||||||
ret
|
ret
|
||||||
|
global load_tr
|
||||||
|
load_tr:
|
||||||
|
mov rax, rdi
|
||||||
|
ltr ax
|
||||||
|
ret
|
@ -1,7 +1,10 @@
|
|||||||
#define MODULE "gdt"
|
#define MODULE "gdt"
|
||||||
|
|
||||||
#include "gdt/GDT.h"
|
#include "gdt/GDT.h"
|
||||||
|
#include "assert.h"
|
||||||
#include "log/Log.h"
|
#include "log/Log.h"
|
||||||
|
#include "memory/KernelMemoryManager.h"
|
||||||
|
#include "std/string.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct GDTR
|
struct GDTR
|
||||||
@ -20,28 +23,74 @@ struct GDTEntry
|
|||||||
uint8_t base2;
|
uint8_t base2;
|
||||||
} __attribute__((packed));
|
} __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
|
struct InternalGDT
|
||||||
{
|
{
|
||||||
GDTEntry null;
|
GDTEntry null;
|
||||||
GDTEntry kernel_code;
|
GDTEntry kernel_code;
|
||||||
GDTEntry kernel_data;
|
GDTEntry kernel_data;
|
||||||
GDTEntry user_null;
|
|
||||||
GDTEntry user_code;
|
GDTEntry user_code;
|
||||||
GDTEntry user_data;
|
GDTEntry user_data;
|
||||||
|
GDTEntry tss;
|
||||||
|
HighGDTEntry tss2;
|
||||||
} __attribute__((packed)) __attribute((aligned(0x1000)));
|
} __attribute__((packed)) __attribute((aligned(0x1000)));
|
||||||
|
|
||||||
__attribute__((aligned(0x1000))) static InternalGDT internal_gdt = {
|
__attribute__((aligned(0x1000))) static InternalGDT internal_gdt = {{0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00},
|
||||||
{0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00}, {0xffff, 0x0000, 0x00, 0x9a, 0xaf, 0x00},
|
{0xffff, 0x0000, 0x00, 0x9a, 0xaf, 0x00},
|
||||||
{0xffff, 0x0000, 0x00, 0x92, 0xcf, 0x00}, {0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00},
|
{0xffff, 0x0000, 0x00, 0x92, 0xcf, 0x00},
|
||||||
{0xffff, 0x0000, 0x00, 0xfa, 0xaf, 0x00}, {0xffff, 0x0000, 0x00, 0xf2, 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_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()
|
void GDT::load()
|
||||||
{
|
{
|
||||||
static GDTR gdtr;
|
static GDTR gdtr;
|
||||||
gdtr.offset = (uint64_t)&internal_gdt;
|
gdtr.offset = (uint64_t)&internal_gdt;
|
||||||
gdtr.size = sizeof(InternalGDT);
|
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);
|
kdbgln("Loading GDT at offset %lx, size %d", gdtr.offset, gdtr.size);
|
||||||
load_gdt(&gdtr);
|
load_gdt(&gdtr);
|
||||||
|
kdbgln("Loading TR (GDT entry 0x28)");
|
||||||
|
load_tr(0x28);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user