[Zion] Access the KernelStackManager through the VMM.

This commit is contained in:
Drew Galbraith 2023-11-15 15:38:25 -08:00
parent c5b9d20c7e
commit 07e6e3028d
11 changed files with 46 additions and 38 deletions

View File

@ -93,8 +93,6 @@ void InitGdt() {
: "rax"); : "rax");
} }
void SetIst1(uint64_t* ist1) { void SetIst1(uint64_t ist1) { gTaskStateSegment.ist1 = ist1; }
gTaskStateSegment.ist1 = reinterpret_cast<uint64_t>(ist1);
}
void SetRsp0(uint64_t rsp0) { gTaskStateSegment.rsp0 = rsp0; } void SetRsp0(uint64_t rsp0) { gTaskStateSegment.rsp0 = rsp0; }

View File

@ -4,6 +4,6 @@
void InitGdt(); void InitGdt();
void SetIst1(uint64_t* ist1); void SetIst1(uint64_t ist1);
void SetRsp0(uint64_t rsp0); void SetRsp0(uint64_t rsp0);

View File

@ -2,30 +2,28 @@
#include "common/gdt.h" #include "common/gdt.h"
#include "debug/debug.h" #include "debug/debug.h"
#include "interrupt/interrupt.h"
#include "memory/paging_util.h" #include "memory/paging_util.h"
#define KERNEL_STACK_START 0xFFFFFFFF'90000000 #define KERNEL_STACK_START 0xFFFFFFFF'90000000
#define KERNEL_STACK_LIMIT 0xFFFFFFFF'9FFFFFFF #define KERNEL_STACK_LIMIT 0xFFFFFFFF'9FFFFFFF
#define KERNEL_STACK_OFFSET 0x4000 #define KERNEL_STACK_OFFSET 0x4000
KernelStackManager* gKernelStackManager;
void KernelStackManager::Init() {
gKernelStackManager = new KernelStackManager();
SetIst1(gKernelStackManager->AllocateKernelStack());
}
KernelStackManager::KernelStackManager() KernelStackManager::KernelStackManager()
: next_stack_addr_(KERNEL_STACK_START) {} : next_stack_addr_(KERNEL_STACK_START) {}
uint64_t* KernelStackManager::AllocateKernelStack() { void KernelStackManager::SetupInterruptStack() {
SetIst1(AllocateKernelStack());
UpdateFaultHandlersToIst1();
}
uint64_t KernelStackManager::AllocateKernelStack() {
next_stack_addr_ += KERNEL_STACK_OFFSET; next_stack_addr_ += KERNEL_STACK_OFFSET;
if (next_stack_addr_ >= KERNEL_STACK_LIMIT) { if (next_stack_addr_ >= KERNEL_STACK_LIMIT) {
panic("No more kernelstack space"); panic("No more kernelstack space");
} }
EnsureResident(next_stack_addr_ - 0x3000, 0x3000); EnsureResident(next_stack_addr_ - 0x3000, 0x3000);
return reinterpret_cast<uint64_t*>(next_stack_addr_) - 1; return next_stack_addr_ - 8;
} }
void KernelStackManager::FreeKernelStack(uint64_t stack_base) { void KernelStackManager::FreeKernelStack(uint64_t stack_base) {

View File

@ -14,14 +14,15 @@
// class. // class.
class KernelStackManager { class KernelStackManager {
public: public:
static void Init(); KernelStackManager();
uint64_t* AllocateKernelStack(); void SetupInterruptStack();
uint64_t AllocateKernelStack();
void FreeKernelStack(uint64_t stack_base); void FreeKernelStack(uint64_t stack_base);
private: private:
KernelStackManager();
uint64_t next_stack_addr_; uint64_t next_stack_addr_;
uint64_t freed_stack_cnt_ = 0; uint64_t freed_stack_cnt_ = 0;
}; };

View File

@ -13,12 +13,18 @@ KernelVmm::KernelVmm() {
panic("KernelVmm double init."); panic("KernelVmm double init.");
} }
gKernelVmm = this; gKernelVmm = this;
stack_manager_ = glcr::MakeUnique<KernelStackManager>();
stack_manager_->SetupInterruptStack();
} }
uint64_t KernelVmm::AcquireSlabHeapRegion(uint64_t slab_size_bytes) { uint64_t KernelVmm::AcquireSlabHeapRegion(uint64_t slab_size_bytes) {
return gKernelVmm->AcquireSlabHeapRegionInternal(slab_size_bytes); return gKernelVmm->AcquireSlabHeapRegionInternal(slab_size_bytes);
} }
uint64_t KernelVmm::AcquireKernelStack() {
return gKernelVmm->stack_manager_->AllocateKernelStack();
}
uint64_t KernelVmm::AcquireSlabHeapRegionInternal(uint64_t slab_size_bytes) { uint64_t KernelVmm::AcquireSlabHeapRegionInternal(uint64_t slab_size_bytes) {
uint64_t next_slab = next_slab_heap_page_; uint64_t next_slab = next_slab_heap_page_;
if (next_slab >= kKernelBuddyHeapEnd) { if (next_slab >= kKernelBuddyHeapEnd) {

View File

@ -3,15 +3,25 @@
#include <stdint.h> #include <stdint.h>
#include "memory/constants.h" #include "memory/constants.h"
#include "memory/kernel_heap.h"
#include "memory/kernel_stack_manager.h"
class KernelVmm { class KernelVmm {
public: public:
KernelVmm(); KernelVmm();
// TODO: Create a "MemoryRegion" style class to hold the return
// types from this object.
static uint64_t AcquireSlabHeapRegion(uint64_t slab_size_bytes); static uint64_t AcquireSlabHeapRegion(uint64_t slab_size_bytes);
static uint64_t AcquireKernelStack();
static void FreeKernelStack(uint64_t);
private: private:
uint64_t next_slab_heap_page_ = kKernelSlabHeapStart; uint64_t next_slab_heap_page_ = kKernelSlabHeapStart;
KernelHeap heap_;
glcr::UniquePtr<KernelStackManager> stack_manager_;
uint64_t AcquireSlabHeapRegionInternal(uint64_t slab_size_bytes); uint64_t AcquireSlabHeapRegionInternal(uint64_t slab_size_bytes);
}; };

View File

@ -153,10 +153,10 @@ void InitBootstrapPageAllocation() {
// if we limit the number of pages this should be fine. // if we limit the number of pages this should be fine.
// Currently set to the minimum of 3 for one kernel heap allocation: // Currently set to the minimum of 3 for one kernel heap allocation:
// PageDirectory + PageTable + Page // PageDirectory + PageTable + Page
if (entry.type == 0 && entry.length >= 0x5000) { if (entry.type == 0 && entry.length >= 0x9000) {
gBootstrap.init_page = entry.base; gBootstrap.init_page = entry.base;
gBootstrap.next_page = entry.base; gBootstrap.next_page = entry.base;
gBootstrap.max_page = entry.base + 0x4000; gBootstrap.max_page = entry.base + 0x9000;
gBootstrapEnabled = true; gBootstrapEnabled = true;
return; return;
} }

View File

@ -1,14 +1,12 @@
#include "object/address_space.h" #include "object/address_space.h"
#include "debug/debug.h" #include "debug/debug.h"
#include "memory/kernel_stack_manager.h" #include "memory/kernel_vmm.h"
#include "memory/paging_util.h" #include "memory/paging_util.h"
#include "memory/physical_memory.h" #include "memory/physical_memory.h"
#define K_VMAS_DEBUG 0 #define K_VMAS_DEBUG 0
extern KernelStackManager* gKernelStackManager;
glcr::RefPtr<AddressSpace> AddressSpace::ForRoot() { glcr::RefPtr<AddressSpace> AddressSpace::ForRoot() {
uint64_t cr3 = 0; uint64_t cr3 = 0;
asm volatile("mov %%cr3, %0;" : "=r"(cr3)); asm volatile("mov %%cr3, %0;" : "=r"(cr3));
@ -49,8 +47,8 @@ uint64_t AddressSpace::MapInMemoryObject(
return vaddr; return vaddr;
} }
uint64_t* AddressSpace::AllocateKernelStack() { uint64_t AddressSpace::AllocateKernelStack() {
return gKernelStackManager->AllocateKernelStack(); return KernelVmm::AcquireKernelStack();
} }
bool AddressSpace::HandlePageFault(uint64_t vaddr) { bool AddressSpace::HandlePageFault(uint64_t vaddr) {

View File

@ -75,7 +75,7 @@ class AddressSpace : public KernelObject {
uint64_t MapInMemoryObject(const glcr::RefPtr<MemoryObject>& mem_obj); uint64_t MapInMemoryObject(const glcr::RefPtr<MemoryObject>& mem_obj);
// Kernel Mappings. // Kernel Mappings.
uint64_t* AllocateKernelStack(); uint64_t AllocateKernelStack();
// Returns true if the page fault has been resolved. // Returns true if the page fault has been resolved.
bool HandlePageFault(uint64_t vaddr); bool HandlePageFault(uint64_t vaddr);

View File

@ -30,7 +30,8 @@ glcr::RefPtr<Thread> Thread::Create(Process& proc, uint64_t tid) {
} }
Thread::Thread(Process& proc, uint64_t tid) : process_(proc), id_(tid) { Thread::Thread(Process& proc, uint64_t tid) : process_(proc), id_(tid) {
uint64_t* stack_ptr = proc.vmas()->AllocateKernelStack(); uint64_t* stack_ptr =
reinterpret_cast<uint64_t*>(proc.vmas()->AllocateKernelStack());
// 0: rip // 0: rip
*(stack_ptr) = reinterpret_cast<uint64_t>(thread_init); *(stack_ptr) = reinterpret_cast<uint64_t>(thread_init);
// 1-4: rax, rcx, rdx, rbx // 1-4: rax, rcx, rdx, rbx

View File

@ -24,10 +24,16 @@ extern "C" void zion() {
dbgln("[boot] Init Physical Memory Manager."); dbgln("[boot] Init Physical Memory Manager.");
phys_mem::InitBootstrapPageAllocation(); phys_mem::InitBootstrapPageAllocation();
// - Must happen after BootstrapPageAllocation
// due to the heap using page allocations.
// - Must happen after InitIdt() as the kernel
// stack manager will update ist1.
KernelVmm kvmm; KernelVmm kvmm;
KernelHeap heap;
// Must happen after KernelVmm init as it
// will do allocations to build the free list.
phys_mem::InitPhysicalMemoryManager(); phys_mem::InitPhysicalMemoryManager();
phys_mem::DumpRegions();
dbgln("[boot] Memory allocations available now."); dbgln("[boot] Memory allocations available now.");
@ -38,13 +44,6 @@ extern "C" void zion() {
Apic::Init(); Apic::Init();
ApicTimer::Init(); ApicTimer::Init();
dbgln("[boot] Init Kernel Stack Manager.");
KernelStackManager::Init();
// The KernelStackManager sets Ist1 as a part of initialization so we can use
// it now.
UpdateFaultHandlersToIst1();
dbgln("[boot] Init syscalls."); dbgln("[boot] Init syscalls.");
InitSyscall(); InitSyscall();
@ -55,9 +54,6 @@ extern "C" void zion() {
dbgln("[boot] Loading sys init program."); dbgln("[boot] Loading sys init program.");
LoadInitProgram(); LoadInitProgram();
dbgln("[boot] Allocs during boot:");
heap.DumpDebugData();
dbgln("[boot] Init finished, yielding."); dbgln("[boot] Init finished, yielding.");
gScheduler->Enable(); gScheduler->Enable();
gScheduler->Yield(); gScheduler->Yield();