diff --git a/zion/common/gdt.cpp b/zion/common/gdt.cpp index e793c6b..493c72f 100644 --- a/zion/common/gdt.cpp +++ b/zion/common/gdt.cpp @@ -93,8 +93,6 @@ void InitGdt() { : "rax"); } -void SetIst1(uint64_t* ist1) { - gTaskStateSegment.ist1 = reinterpret_cast(ist1); -} +void SetIst1(uint64_t ist1) { gTaskStateSegment.ist1 = ist1; } void SetRsp0(uint64_t rsp0) { gTaskStateSegment.rsp0 = rsp0; } diff --git a/zion/common/gdt.h b/zion/common/gdt.h index 0d55869..ef2bf97 100644 --- a/zion/common/gdt.h +++ b/zion/common/gdt.h @@ -4,6 +4,6 @@ void InitGdt(); -void SetIst1(uint64_t* ist1); +void SetIst1(uint64_t ist1); void SetRsp0(uint64_t rsp0); diff --git a/zion/memory/kernel_stack_manager.cpp b/zion/memory/kernel_stack_manager.cpp index 8ec8448..085e33f 100644 --- a/zion/memory/kernel_stack_manager.cpp +++ b/zion/memory/kernel_stack_manager.cpp @@ -2,30 +2,28 @@ #include "common/gdt.h" #include "debug/debug.h" +#include "interrupt/interrupt.h" #include "memory/paging_util.h" #define KERNEL_STACK_START 0xFFFFFFFF'90000000 #define KERNEL_STACK_LIMIT 0xFFFFFFFF'9FFFFFFF #define KERNEL_STACK_OFFSET 0x4000 -KernelStackManager* gKernelStackManager; - -void KernelStackManager::Init() { - gKernelStackManager = new KernelStackManager(); - - SetIst1(gKernelStackManager->AllocateKernelStack()); -} - KernelStackManager::KernelStackManager() : 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; if (next_stack_addr_ >= KERNEL_STACK_LIMIT) { panic("No more kernelstack space"); } EnsureResident(next_stack_addr_ - 0x3000, 0x3000); - return reinterpret_cast(next_stack_addr_) - 1; + return next_stack_addr_ - 8; } void KernelStackManager::FreeKernelStack(uint64_t stack_base) { diff --git a/zion/memory/kernel_stack_manager.h b/zion/memory/kernel_stack_manager.h index be20134..b331c92 100644 --- a/zion/memory/kernel_stack_manager.h +++ b/zion/memory/kernel_stack_manager.h @@ -14,14 +14,15 @@ // class. class KernelStackManager { public: - static void Init(); + KernelStackManager(); - uint64_t* AllocateKernelStack(); + void SetupInterruptStack(); + + uint64_t AllocateKernelStack(); void FreeKernelStack(uint64_t stack_base); private: - KernelStackManager(); uint64_t next_stack_addr_; uint64_t freed_stack_cnt_ = 0; }; diff --git a/zion/memory/kernel_vmm.cpp b/zion/memory/kernel_vmm.cpp index 54a2a41..2f4fe32 100644 --- a/zion/memory/kernel_vmm.cpp +++ b/zion/memory/kernel_vmm.cpp @@ -13,12 +13,18 @@ KernelVmm::KernelVmm() { panic("KernelVmm double init."); } gKernelVmm = this; + stack_manager_ = glcr::MakeUnique(); + stack_manager_->SetupInterruptStack(); } uint64_t KernelVmm::AcquireSlabHeapRegion(uint64_t 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 next_slab = next_slab_heap_page_; if (next_slab >= kKernelBuddyHeapEnd) { diff --git a/zion/memory/kernel_vmm.h b/zion/memory/kernel_vmm.h index dfa983c..186bf50 100644 --- a/zion/memory/kernel_vmm.h +++ b/zion/memory/kernel_vmm.h @@ -3,15 +3,25 @@ #include #include "memory/constants.h" +#include "memory/kernel_heap.h" +#include "memory/kernel_stack_manager.h" class KernelVmm { public: 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 AcquireKernelStack(); + + static void FreeKernelStack(uint64_t); + private: uint64_t next_slab_heap_page_ = kKernelSlabHeapStart; + KernelHeap heap_; + glcr::UniquePtr stack_manager_; uint64_t AcquireSlabHeapRegionInternal(uint64_t slab_size_bytes); }; diff --git a/zion/memory/physical_memory.cpp b/zion/memory/physical_memory.cpp index 63fbcf1..c1d6393 100644 --- a/zion/memory/physical_memory.cpp +++ b/zion/memory/physical_memory.cpp @@ -153,10 +153,10 @@ void InitBootstrapPageAllocation() { // if we limit the number of pages this should be fine. // Currently set to the minimum of 3 for one kernel heap allocation: // PageDirectory + PageTable + Page - if (entry.type == 0 && entry.length >= 0x5000) { + if (entry.type == 0 && entry.length >= 0x9000) { gBootstrap.init_page = entry.base; gBootstrap.next_page = entry.base; - gBootstrap.max_page = entry.base + 0x4000; + gBootstrap.max_page = entry.base + 0x9000; gBootstrapEnabled = true; return; } diff --git a/zion/object/address_space.cpp b/zion/object/address_space.cpp index bb83399..f142772 100644 --- a/zion/object/address_space.cpp +++ b/zion/object/address_space.cpp @@ -1,14 +1,12 @@ #include "object/address_space.h" #include "debug/debug.h" -#include "memory/kernel_stack_manager.h" +#include "memory/kernel_vmm.h" #include "memory/paging_util.h" #include "memory/physical_memory.h" #define K_VMAS_DEBUG 0 -extern KernelStackManager* gKernelStackManager; - glcr::RefPtr AddressSpace::ForRoot() { uint64_t cr3 = 0; asm volatile("mov %%cr3, %0;" : "=r"(cr3)); @@ -49,8 +47,8 @@ uint64_t AddressSpace::MapInMemoryObject( return vaddr; } -uint64_t* AddressSpace::AllocateKernelStack() { - return gKernelStackManager->AllocateKernelStack(); +uint64_t AddressSpace::AllocateKernelStack() { + return KernelVmm::AcquireKernelStack(); } bool AddressSpace::HandlePageFault(uint64_t vaddr) { diff --git a/zion/object/address_space.h b/zion/object/address_space.h index 36571cc..55ecddf 100644 --- a/zion/object/address_space.h +++ b/zion/object/address_space.h @@ -75,7 +75,7 @@ class AddressSpace : public KernelObject { uint64_t MapInMemoryObject(const glcr::RefPtr& mem_obj); // Kernel Mappings. - uint64_t* AllocateKernelStack(); + uint64_t AllocateKernelStack(); // Returns true if the page fault has been resolved. bool HandlePageFault(uint64_t vaddr); diff --git a/zion/object/thread.cpp b/zion/object/thread.cpp index f9c7629..d61c3a3 100644 --- a/zion/object/thread.cpp +++ b/zion/object/thread.cpp @@ -30,7 +30,8 @@ glcr::RefPtr Thread::Create(Process& proc, uint64_t 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(proc.vmas()->AllocateKernelStack()); // 0: rip *(stack_ptr) = reinterpret_cast(thread_init); // 1-4: rax, rcx, rdx, rbx diff --git a/zion/zion.cpp b/zion/zion.cpp index 1484695..da8a9fb 100644 --- a/zion/zion.cpp +++ b/zion/zion.cpp @@ -24,10 +24,16 @@ extern "C" void zion() { dbgln("[boot] Init Physical Memory Manager."); 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; - KernelHeap heap; + + // Must happen after KernelVmm init as it + // will do allocations to build the free list. phys_mem::InitPhysicalMemoryManager(); - phys_mem::DumpRegions(); dbgln("[boot] Memory allocations available now."); @@ -38,13 +44,6 @@ extern "C" void zion() { Apic::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."); InitSyscall(); @@ -55,9 +54,6 @@ extern "C" void zion() { dbgln("[boot] Loading sys init program."); LoadInitProgram(); - dbgln("[boot] Allocs during boot:"); - heap.DumpDebugData(); - dbgln("[boot] Init finished, yielding."); gScheduler->Enable(); gScheduler->Yield();