forked from Bananymous/banan-os
Kernel: Cleanup GDT code
This commit is contained in:
parent
6b180da4e8
commit
45a6783c3d
|
@ -1,4 +1,4 @@
|
||||||
#include <BAN/Assert.h>
|
#include <BAN/Array.h>
|
||||||
#include <kernel/GDT.h>
|
#include <kernel/GDT.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -56,44 +56,44 @@ namespace Kernel::GDT
|
||||||
|
|
||||||
static constexpr uint16_t s_tss_offset = 0x28;
|
static constexpr uint16_t s_tss_offset = 0x28;
|
||||||
|
|
||||||
static TaskStateSegment* s_tss = nullptr;
|
static TaskStateSegment s_tss;
|
||||||
static SegmentDescriptor* s_gdt = nullptr;
|
static BAN::Array<SegmentDescriptor, 7> s_gdt; // null, kernel code, kernel data, user code, user data, tss low, tss high
|
||||||
static GDTR s_gdtr;
|
static GDTR s_gdtr;
|
||||||
|
|
||||||
static void write_entry(uint8_t offset, uint32_t base, uint32_t limit, uint8_t access, uint8_t flags)
|
static void write_entry(uint8_t offset, uint32_t base, uint32_t limit, uint8_t access, uint8_t flags)
|
||||||
{
|
{
|
||||||
SegmentDescriptor& desc = *(SegmentDescriptor*)((uintptr_t)s_gdt + offset);
|
ASSERT(offset % sizeof(SegmentDescriptor) == 0);
|
||||||
desc.base1 = base;
|
|
||||||
desc.base2 = base >> 16;
|
|
||||||
desc.base3 = base >> 24;
|
|
||||||
|
|
||||||
desc.limit1 = limit;
|
SegmentDescriptor& desc = s_gdt[offset / sizeof(SegmentDescriptor)];
|
||||||
desc.limit2 = limit >> 16;
|
desc.base1 = (base >> 0) & 0xFFFF;
|
||||||
|
desc.base2 = (base >> 16) & 0xFF;
|
||||||
|
desc.base3 = (base >> 24) & 0xFF;
|
||||||
|
|
||||||
desc.access = access;
|
desc.limit1 = (limit >> 0) & 0xFFFF;
|
||||||
|
desc.limit2 = (limit >> 16) & 0x0F;
|
||||||
|
|
||||||
desc.flags = flags;
|
desc.access = access & 0xFF;
|
||||||
|
|
||||||
|
desc.flags = flags & 0x0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_tss()
|
static void write_tss()
|
||||||
{
|
{
|
||||||
s_tss = new TaskStateSegment();
|
memset(&s_tss, 0x00, sizeof(TaskStateSegment));
|
||||||
ASSERT(s_tss);
|
s_tss.iopb = sizeof(TaskStateSegment);
|
||||||
|
|
||||||
memset(s_tss, 0x00, sizeof(TaskStateSegment));
|
uint64_t base = (uint64_t)&s_tss;
|
||||||
s_tss->rsp0 = 0;
|
|
||||||
|
|
||||||
uintptr_t base = (uintptr_t)s_tss;
|
|
||||||
|
|
||||||
write_entry(s_tss_offset, (uint32_t)base, sizeof(TaskStateSegment), 0x89, 0x0);
|
write_entry(s_tss_offset, (uint32_t)base, sizeof(TaskStateSegment), 0x89, 0x0);
|
||||||
SegmentDescriptor& desc = *(SegmentDescriptor*)((uintptr_t)s_gdt + s_tss_offset + 0x08);
|
|
||||||
|
SegmentDescriptor& desc = s_gdt[s_tss_offset / sizeof(SegmentDescriptor) + 1];
|
||||||
desc.low = base >> 32;
|
desc.low = base >> 32;
|
||||||
desc.high = 0;
|
desc.high = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_tss_stack(uintptr_t rsp)
|
void set_tss_stack(uintptr_t rsp)
|
||||||
{
|
{
|
||||||
s_tss->rsp0 = rsp;
|
s_tss.rsp0 = rsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush_gdt()
|
static void flush_gdt()
|
||||||
|
@ -108,12 +108,8 @@ namespace Kernel::GDT
|
||||||
|
|
||||||
void initialize()
|
void initialize()
|
||||||
{
|
{
|
||||||
constexpr uint32_t descriptor_count = 6 + 1; // tss takes 2
|
s_gdtr.address = (uint64_t)&s_gdt;
|
||||||
s_gdt = new SegmentDescriptor[descriptor_count];
|
s_gdtr.size = s_gdt.size() * sizeof(SegmentDescriptor) - 1;
|
||||||
ASSERT(s_gdt);
|
|
||||||
|
|
||||||
s_gdtr.address = (uint64_t)s_gdt;
|
|
||||||
s_gdtr.size = descriptor_count * sizeof(SegmentDescriptor) - 1;
|
|
||||||
|
|
||||||
write_entry(0x00, 0x00000000, 0x00000, 0x00, 0x0); // null
|
write_entry(0x00, 0x00000000, 0x00000, 0x00, 0x0); // null
|
||||||
write_entry(0x08, 0x00000000, 0xFFFFF, 0x9A, 0xA); // kernel code
|
write_entry(0x08, 0x00000000, 0xFFFFF, 0x9A, 0xA); // kernel code
|
||||||
|
|
Loading…
Reference in New Issue