diff --git a/xtoskrnl/includes/mm/kpool.hh b/xtoskrnl/includes/mm/kpool.hh index 2e94881..58afda6 100644 --- a/xtoskrnl/includes/mm/kpool.hh +++ b/xtoskrnl/includes/mm/kpool.hh @@ -21,13 +21,12 @@ namespace MM STATIC UCHAR ProcessorStructuresData[MAXIMUM_PROCESSORS][KPROCESSOR_STRUCTURES_SIZE]; public: - STATIC XTAPI XTSTATUS AllocateKernelStack(IN PVOID *Stack, - IN BOOLEAN LargeStack, - IN UCHAR SystemNode); + STATIC XTAPI XTSTATUS AllocateKernelStack(OUT PVOID *Stack, + IN ULONG StackSize); STATIC XTAPI XTSTATUS AllocateProcessorStructures(IN ULONG CpuNumber, - OUT PVOID *StructuresData); + OUT PVOID *StructuresData); STATIC XTAPI VOID FreeKernelStack(IN PVOID Stack, - IN BOOLEAN LargeStack); + IN ULONG StackSize); STATIC XTAPI VOID FreeProcessorStructures(IN PVOID StructuresData); }; } diff --git a/xtoskrnl/mm/kpool.cc b/xtoskrnl/mm/kpool.cc index 190c7da..eb7f228 100644 --- a/xtoskrnl/mm/kpool.cc +++ b/xtoskrnl/mm/kpool.cc @@ -27,12 +27,68 @@ */ XTAPI XTSTATUS -MM::KernelPool::AllocateKernelStack(IN PVOID *Stack, - IN BOOLEAN LargeStack, - IN UCHAR SystemNode) +MM::KernelPool::AllocateKernelStack(OUT PVOID *Stack, + IN ULONG StackSize) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PFN_COUNT StackPtes, StackPages; + PMMPTE PointerPte, StackPte; + MMPTE TempPte, InvalidPte; + PFN_NUMBER PageFrameIndex; + ULONG Index; + + /* Initialize the output stack pointer to NULLPTR */ + *Stack = NULLPTR; + + /* Convert the requested stack size into a page count */ + StackPtes = SIZE_TO_PAGES(StackSize); + StackPages = StackPtes; + + /* Reserve PTEs for the stack pages, plus a guard page */ + StackPte = MM::Pte::ReserveSystemPtes(StackPtes + 1, SystemPteSpace, 0); + if(!StackPte) + { + /* Failed to reserve PTEs for the new kernel stack */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Set up a template for an invalid PTE */ + MM::Paging::SetPte(&InvalidPte, 0, 0x18); + + /* Set up a template for a valid, writable stack PTE */ + MM::Paging::ClearPte(&TempPte); + MM::Paging::SetPte(&TempPte, 0, MM_PTE_READWRITE | MM_PTE_CACHE_ENABLE); + + /* Acquire the PFN database lock and raise runlevel to DISPATCH_LEVEL */ + KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL); + KE::QueuedSpinLockGuard SpinLock(SystemSpaceLock); + + /* Start iterating from the base of the reserved PTE block */ + PointerPte = StackPte; + + /* Loop through each page of the stack that needs to be allocated */ + for(Index = 0; Index < StackPages; Index++) + { + /* Advance to the next PTE */ + PointerPte = MM::Paging::GetNextPte(PointerPte); + + /* Allocate a physical page and temporarily mark the PTE as invalid */ + PageFrameIndex = MM::Pfn::AllocatePhysicalPage(MM::Colors::GetNextColor()); + *PointerPte = InvalidPte; + + /* Associate the physical page with its corresponding PTE in the PFN database */ + MM::Pfn::LinkPfnToPte(PageFrameIndex, PointerPte, 1); + + /* Make the PTE valid, mapping the virtual address to the physical page */ + MM::Paging::SetPte(&TempPte, PageFrameIndex, 0); + *PointerPte = TempPte; + } + + /* Zero the newly allocated stack memory, skipping the guard page */ + RTL::Memory::ZeroMemory(MM::Paging::GetPteVirtualAddress(MM::Paging::GetNextPte(StackPte)), MM_PAGE_SIZE * StackPtes); + + /* Return a pointer to the top of the new stack */ + *Stack = MM::Paging::GetPteVirtualAddress(MM::Paging::AdvancePte(StackPte, StackPtes + 1)); + return STATUS_SUCCESS; } /** @@ -96,7 +152,7 @@ MM::KernelPool::AllocateProcessorStructures(IN ULONG CpuNumber, XTAPI VOID MM::KernelPool::FreeKernelStack(IN PVOID Stack, - IN BOOLEAN LargeStack) + IN ULONG StackSize) { UNIMPLEMENTED; }