Kernel: Store current processor pointer in IA32_GS_BASE

This allows easier access to processors fields
This commit is contained in:
2024-03-07 16:05:29 +02:00
parent efed67cbd0
commit 29fd682672
13 changed files with 119 additions and 98 deletions

View File

@@ -1,57 +1,70 @@
#include <BAN/Vector.h>
#include <kernel/Memory/kmalloc.h>
#include <kernel/Processor.h>
#include <kernel/Debug.h>
namespace Kernel
{
static constexpr uint32_t MSR_IA32_GS_BASE = 0xC0000101;
ProcessorID Processor::s_bsb_id { PROCESSOR_NONE };
static BAN::Vector<Processor> s_processors;
static BAN::Array<Processor, 0xFF> s_processors;
static ProcessorID read_processor_id()
{
uint8_t id;
asm volatile(
"movl $1, %%eax;"
"cpuid;"
"shrl $24, %%ebx;"
"movb %%bl, %0;"
: "=rm"(id)
:: "eax", "ebx", "ecx", "edx"
);
return id;
}
Processor& Processor::create(ProcessorID id)
{
// bsb is the first processor
if (s_bsb_id == PROCESSOR_NONE)
s_bsb_id = id;
s_bsb_id = id = read_processor_id();
while (s_processors.size() <= id)
MUST(s_processors.emplace_back());
auto& processor = s_processors[id];
if (processor.m_stack == nullptr)
{
processor.m_stack = kmalloc(m_stack_size, 4096, true);
ASSERT(processor.m_stack);
}
ASSERT(processor.m_id == PROCESSOR_NONE);
processor.m_id = id;
processor.m_stack = kmalloc(s_stack_size, 4096, true);
ASSERT(processor.m_stack);
processor.m_gdt = GDT::create();
ASSERT(processor.m_gdt);
processor.m_idt = IDT::create(id == s_bsb_id);
ASSERT(processor.m_idt);
return processor;
}
Processor::~Processor()
Processor& Processor::initialize()
{
if (m_stack)
kfree(m_stack);
m_stack = nullptr;
auto id = read_processor_id();
auto& processor = s_processors[id];
if (m_gdt)
delete m_gdt;
m_gdt = nullptr;
}
// set gs base to pointer to this processor
uint64_t ptr = reinterpret_cast<uint64_t>(&processor);
asm volatile("wrmsr" :: "d"(ptr >> 32), "a"(ptr), "c"(MSR_IA32_GS_BASE));
Processor& Processor::get(ProcessorID id)
{
return s_processors[id];
}
ASSERT(processor.m_gdt);
processor.gdt().load();
void Processor::initialize()
{
ASSERT(this == &Processor::current());
ASSERT(processor.m_idt);
processor.idt().load();
ASSERT(m_gdt == nullptr);
m_gdt = GDT::create();
ASSERT(m_gdt);
ASSERT(m_idt == nullptr);
m_idt = IDT::create();
ASSERT(m_idt);
return processor;
}
}