Kernel: Move GDT to Processor

This commit is contained in:
2024-03-06 00:02:18 +02:00
parent 8670364f44
commit 58aca68726
6 changed files with 142 additions and 99 deletions

View File

@@ -1,16 +1,100 @@
#pragma once
#include <BAN/Array.h>
#include <BAN/NoCopyMove.h>
#include <stdint.h>
namespace Kernel::GDT
namespace Kernel
{
static constexpr inline bool is_user_segment(uint8_t segment)
struct TaskStateSegment
{
return (segment & 3) == 3;
}
uint32_t reserved1;
uint64_t rsp0;
uint64_t rsp1;
uint64_t rsp2;
uint64_t reserved2;
uint64_t ist1;
uint64_t ist2;
uint64_t ist3;
uint64_t ist4;
uint64_t ist5;
uint64_t ist6;
uint64_t ist7;
uint64_t reserved3;
uint16_t reserved4;
uint16_t iopb;
} __attribute__((packed));
void initialize();
void set_tss_stack(uintptr_t);
union SegmentDescriptor
{
struct
{
uint16_t limit1;
uint16_t base1;
uint8_t base2;
uint8_t access;
uint8_t limit2 : 4;
uint8_t flags : 4;
uint8_t base3;
} __attribute__((packed));
struct
{
uint32_t low;
uint32_t high;
} __attribute__((packed));
} __attribute__((packed));
struct GDTR
{
uint16_t size;
uint64_t address;
} __attribute__((packed));
class GDT
{
BAN_NON_COPYABLE(GDT);
BAN_NON_MOVABLE(GDT);
public:
static GDT* create();
static constexpr inline bool is_user_segment(uint8_t segment)
{
return (segment & 3) == 3;
}
void set_tss_stack(uintptr_t rsp)
{
m_tss.rsp0 = rsp;
}
private:
GDT() = default;
void write_entry(uint8_t offset, uint32_t base, uint32_t limit, uint8_t access, uint8_t flags);
void write_tss();
void flush_gdt()
{
asm volatile("lgdt %0" :: "m"(m_gdtr) : "memory");
}
void flush_tss()
{
asm volatile("ltr %0" :: "rm"((uint16_t)0x28) : "memory");
}
private:
BAN::Array<SegmentDescriptor, 7> m_gdt; // null, kernel code, kernel data, user code, user data, tss low, tss high
TaskStateSegment m_tss;
const GDTR m_gdtr {
.size = m_gdt.size() * sizeof(SegmentDescriptor) - 1,
.address = reinterpret_cast<uint64_t>(m_gdt.data())
};
};
}

View File

@@ -1,7 +1,9 @@
#pragma once
#include <BAN/ForwardList.h>
#include <kernel/Arch.h>
#include <kernel/GDT.h>
namespace Kernel
{
@@ -54,12 +56,19 @@ namespace Kernel
uintptr_t stack_bottom() const { return reinterpret_cast<uintptr_t>(m_stack); }
uintptr_t stack_top() const { return stack_bottom() + m_stack_size; }
void initialize();
GDT& gdt() { ASSERT(m_gdt); return *m_gdt; }
private:
Processor() = default;
Processor(Processor&& other)
{
m_stack = other.m_stack;
other.m_stack = nullptr;
m_gdt = other.m_gdt;
other.m_gdt = nullptr;
}
~Processor();
@@ -67,6 +76,8 @@ namespace Kernel
void* m_stack { nullptr };
static constexpr size_t m_stack_size { 4096 };
GDT* m_gdt { nullptr };
friend class BAN::Vector<Processor>;
};
#else