From 8766aa57bfc75eb454d879b73bca9ceded0abbd4 Mon Sep 17 00:00:00 2001 From: ergo720 Date: Fri, 2 Mar 2018 17:32:38 +0100 Subject: [PATCH] DeAllocateSystemMemory --- import/OpenXDK/include/xboxkrnl/mm.h | 2 +- src/CxbxKrnl/CxbxKrnl.h | 2 +- src/CxbxKrnl/EmuKrnlMm.cpp | 8 +-- src/CxbxKrnl/PhysicalMemory.cpp | 82 ++++++++++------------------ src/CxbxKrnl/PhysicalMemory.h | 14 +---- src/CxbxKrnl/VMManager.cpp | 51 +++++++++++++++-- src/CxbxKrnl/VMManager.h | 8 +-- 7 files changed, 87 insertions(+), 80 deletions(-) diff --git a/import/OpenXDK/include/xboxkrnl/mm.h b/import/OpenXDK/include/xboxkrnl/mm.h index d7521ecbb..1eb61fc8f 100644 --- a/import/OpenXDK/include/xboxkrnl/mm.h +++ b/import/OpenXDK/include/xboxkrnl/mm.h @@ -86,7 +86,7 @@ XBSYSAPI EXPORTNUM(171) VOID NTAPI MmFreeContiguousMemory // ****************************************************************** // * MmFreeSystemMemory // ****************************************************************** -XBSYSAPI EXPORTNUM(172) NTSTATUS NTAPI MmFreeSystemMemory +XBSYSAPI EXPORTNUM(172) ULONG NTAPI MmFreeSystemMemory ( PVOID BaseAddress, ULONG NumberOfBytes diff --git a/src/CxbxKrnl/CxbxKrnl.h b/src/CxbxKrnl/CxbxKrnl.h index 6eaf8ddf9..9e8a26ee5 100644 --- a/src/CxbxKrnl/CxbxKrnl.h +++ b/src/CxbxKrnl/CxbxKrnl.h @@ -157,7 +157,7 @@ extern "C" { #define HIGHEST_USER_ADDRESS 0x7FFEFFFF #define HIGHEST_VAD_ADDRESS HIGHEST_USER_ADDRESS - X64KB // for NtAllocateVirtualMemory -#define PAGE_DIRECTORY_BASE 0xC0300000 +#define PAGE_DIRECTORY_BASE 0xC0300000 #define PAGE_TABLES_BASE 0xC0000000 #define PAGE_TABLES_SIZE 4 * ONE_MB #define PAGE_TABLES_END PAGE_TABLES_BASE + PAGE_TABLES_SIZE - 1 diff --git a/src/CxbxKrnl/EmuKrnlMm.cpp b/src/CxbxKrnl/EmuKrnlMm.cpp index 57545aee5..6c878c8b6 100644 --- a/src/CxbxKrnl/EmuKrnlMm.cpp +++ b/src/CxbxKrnl/EmuKrnlMm.cpp @@ -220,7 +220,7 @@ XBSYSAPI EXPORTNUM(170) xboxkrnl::VOID NTAPI xboxkrnl::MmDeleteKernelStack VAddr StackBottom = (VAddr)StackBase - ActualSize; - g_VMManager.DeallocateStack(StackBottom); + g_VMManager.DeAllocateSystemMemory(StackBottom, ActualSize); } // ****************************************************************** @@ -247,7 +247,7 @@ XBSYSAPI EXPORTNUM(171) xboxkrnl::VOID NTAPI xboxkrnl::MmFreeContiguousMemory // ****************************************************************** // * 0x00AC - MmFreeSystemMemory() // ****************************************************************** -XBSYSAPI EXPORTNUM(172) xboxkrnl::NTSTATUS NTAPI xboxkrnl::MmFreeSystemMemory +XBSYSAPI EXPORTNUM(172) xboxkrnl::ULONG NTAPI xboxkrnl::MmFreeSystemMemory ( PVOID BaseAddress, ULONG NumberOfBytes @@ -258,9 +258,9 @@ XBSYSAPI EXPORTNUM(172) xboxkrnl::NTSTATUS NTAPI xboxkrnl::MmFreeSystemMemory LOG_FUNC_ARG(NumberOfBytes) LOG_FUNC_END; - g_VMManager.Deallocate((VAddr)BaseAddress); + ULONG FreedPagesNumber = g_VMManager.DeAllocateSystemMemory((VAddr)BaseAddress, NumberOfBytes); - RETURN(STATUS_SUCCESS); + RETURN(FreedPagesNumber); } // ****************************************************************** diff --git a/src/CxbxKrnl/PhysicalMemory.cpp b/src/CxbxKrnl/PhysicalMemory.cpp index 5e6567b04..5d2ff7b1f 100644 --- a/src/CxbxKrnl/PhysicalMemory.cpp +++ b/src/CxbxKrnl/PhysicalMemory.cpp @@ -53,11 +53,6 @@ void FillMemoryUlong(void* Destination, size_t Length, ULONG Long) } } -PMEMORY_STATUS PhysicalMemory::GetError() const -{ - return m_Status; -} - void PhysicalMemory::InitializePageDirectory() { PMMPTE pPde; @@ -121,10 +116,26 @@ void PhysicalMemory::InitializePageDirectory() // correctly implemented. So, for now, we keep on ignoring this allocation } -void PhysicalMemory::WritePfn(PFN pfn_start, PFN pfn_end, PMMPTE pPte, PageType BusyType, bool bContiguous) +void PhysicalMemory::WritePfn(PFN pfn_start, PFN pfn_end, PMMPTE pPte, PageType BusyType, bool bContiguous, bool bZero) { XBOX_PFN TempPF; + if (bZero) + { + TempPF.Default = 0; + while (pfn_start <= pfn_end) + { + if (g_bIsRetail || g_bIsDebug) { + *XBOX_PFN_ELEMENT(pfn_start) = TempPF; + } + else { *CHIHIRO_PFN_ELEMENT(pfn_start) = TempPF; } + + m_PagesByUsage[BusyType]--; + pfn_start++; + } + return; + } + if (bContiguous) { // In the contiguous region we construct the pfn as a pte @@ -166,8 +177,18 @@ void PhysicalMemory::WritePfn(PFN pfn_start, PFN pfn_end, PMMPTE pPte, PageType } } -void PhysicalMemory::WritePte(PMMPTE pPteStart, PMMPTE pPteEnd, MMPTE Pte, PFN pfn) +void PhysicalMemory::WritePte(PMMPTE pPteStart, PMMPTE pPteEnd, MMPTE Pte, PFN pfn, bool bZero) { + if (bZero) + { + while (pPteStart <= pPteEnd) + { + WRITE_ZERO_PTE(pPteStart); + pPteStart++; + } + return; + } + while (pPteStart <= pPteEnd) { Pte.Hardware.PFN = pfn; @@ -489,7 +510,7 @@ PFN PhysicalMemory::RemoveAndZeroAnyFreePage(PageType BusyType, PMMPTE pPte) assert(pPte); // NOTE: for now this doesn't require a check for success but if called from other callers it will... - RemoveFree(1, &pfn, 0, m_HighestPage); + RemoveFree(1, &pfn, 0, 0, m_HighestPage); // Fill the page with zeros FillMemoryUlong((void*)CONVERT_PFN_TO_CONTIGUOUS_PHYSICAL(pfn), PAGE_SIZE, 0); @@ -500,48 +521,3 @@ PFN PhysicalMemory::RemoveAndZeroAnyFreePage(PageType BusyType, PMMPTE pPte) return pfn; } -void PhysicalMemory::ShrinkPhysicalAllocation(PAddr addr, size_t offset, bool bFragmentedMap, bool bStart) -{ - if (!offset) { return; } // nothing to do - - if (bFragmentedMap) - { - auto it = std::prev(m_Fragmented_mem_map.upper_bound(addr)); - PAddr old_base = it->first; - size_t old_size = it->second; - m_Fragmented_mem_map.erase(old_base); - - if (old_size - offset) - { - if (bStart) { m_Fragmented_mem_map.emplace(old_base + offset, old_size - offset); } - else { m_Fragmented_mem_map.emplace(old_base, old_size - offset); } - } - - m_PhysicalMemoryInUse -= offset; - } - else - { - auto it = m_Mem_map.lower_bound(addr); - PAddr old_base = it->first; - size_t old_size = it->second; - m_Mem_map.erase(old_base); - - if (old_size - offset) - { - if (bStart) { m_Mem_map.emplace(old_base + offset, old_size - offset); } - else { m_Mem_map.emplace(old_base, old_size - offset); } - } - - m_PhysicalMemoryInUse -= offset; - } -} - -void PhysicalMemory::SetError(PMEMORY_STATUS err) -{ - m_Status = err; -} - -void PhysicalMemory::ClearError() -{ - m_Status = PMEMORY_SUCCESS; -} diff --git a/src/CxbxKrnl/PhysicalMemory.h b/src/CxbxKrnl/PhysicalMemory.h index 2ddb2ce69..21a7caf71 100644 --- a/src/CxbxKrnl/PhysicalMemory.h +++ b/src/CxbxKrnl/PhysicalMemory.h @@ -238,8 +238,6 @@ class PhysicalMemory protected: // doubly linked list tracking the free physical pages xboxkrnl::LIST_ENTRY FreeList = { &FreeList , &FreeList }; - // current error status code of the PhysicalMemory class - PMEMORY_STATUS m_Status = PMEMORY_SUCCESS; // highest pfn available for contiguous allocations PAddr m_MaxContiguousPfn = XBOX_CONTIGUOUS_MEMORY_LIMIT; // the size of memory occupied by the PFN/NV2A instance memory @@ -265,9 +263,9 @@ class PhysicalMemory // set up the page directory void InitializePageDirectory(); // write a contiguous range of pfn's - void WritePfn(PFN pfn_start, PFN pfn_end, PMMPTE pPte, PageType BusyType, bool bContiguous); + void WritePfn(PFN pfn_start, PFN pfn_end, PMMPTE pPte, PageType BusyType, bool bContiguous, bool bZero = false); // write a contiguous range of pte's - void WritePte(PMMPTE pPteStart, PMMPTE pPteEnd, MMPTE Pte, PFN pfn); + void WritePte(PMMPTE pPteStart, PMMPTE pPteEnd, MMPTE Pte, PFN pfn, bool bZero = false); // commit a contiguous number of pages bool RemoveFree(PFN_COUNT NumberOfPages, PFN* result, PFN_COUNT PfnAlignment, PFN start, PFN end); // release a contiguous number of pages @@ -278,14 +276,6 @@ class PhysicalMemory bool AllocatePT(PFN_COUNT PteNumber, VAddr addr); // commit whatever free page is available and zero it PFN RemoveAndZeroAnyFreePage(PageType BusyType, PMMPTE pte); - // shrinks the size af an allocation - void ShrinkPhysicalAllocation(PAddr addr, size_t offset, bool bFragmentedMap, bool bStart); - // retrieves the current error code of the PhysicalMemory class - PMEMORY_STATUS GetError() const; - // sets the error code of the PhysicalMemory class - void SetError(PMEMORY_STATUS err); - // clears the error code of the PhysicalMemory class - void ClearError(); }; #endif diff --git a/src/CxbxKrnl/VMManager.cpp b/src/CxbxKrnl/VMManager.cpp index cbacc86b4..8a0827626 100644 --- a/src/CxbxKrnl/VMManager.cpp +++ b/src/CxbxKrnl/VMManager.cpp @@ -619,14 +619,57 @@ void VMManager::Deallocate(VAddr addr) Unlock(); } -void VMManager::DeallocateStack(VAddr addr) +PFN_COUNT VMManager::DeAllocateSystemMemory(VAddr addr, size_t Size /*MemoryRegionType Type*/) { - LOG_FUNC_ONE_ARG(addr); + LOG_FUNC_BEGIN + LOG_FUNC_ARG(addr); + LOG_FUNC_ARG(Size); + LOG_FUNC_END; + + MMPTE TempPte; + PMMPTE StartingPte; + PMMPTE EndingPte; + PFN pfn; + PFN EndingPfn; + PFN_COUNT PteNumber; + + assert(CHECK_ALIGNMENT(addr, PAGE_SIZE)); // all starting addresses from the system region are page aligned Lock(); - ReprotectVMARange(addr, PAGE_SIZE, PAGE_EXECUTE_READWRITE); - UnmapRange(addr); + + StartingPte = GetPteAddress(addr); + + if (Size != 0) + { + EndingPte = StartingPte + (ROUND_UP_4K(Size) >> PAGE_SHIFT) - 1; + } + else + { + VMAIter it = GetVMAIterator(addr, MemoryRegionType::System); + if (it->second.type != VMAType::Free && it->first <= addr && it->first + it->second.size > addr) + { + Size = it->second.size; + EndingPte = StartingPte + (ROUND_UP_4K(Size) >> PAGE_SHIFT) - 1; + } + else + { + DbgPrintf("Failed to locate the requested system allocation\n"); + Unlock(); + RETURN(NULL); + } + } + + pfn = StartingPte->Hardware.PFN; + EndingPfn = pfn + (EndingPte - StartingPte); + + InsertFree(pfn, EndingPfn); + WritePte(StartingPte, EndingPte, TempPte, 0, true); + WritePfn(pfn, EndingPfn, StartingPte, PageType::SystemMemory, false, true); + + PteNumber = EndingPte - StartingPte + 1; + Unlock(); + RETURN(PteNumber); } void VMManager::Protect(VAddr target, size_t size, DWORD new_perms) diff --git a/src/CxbxKrnl/VMManager.h b/src/CxbxKrnl/VMManager.h index af441abaa..ac7d828d3 100644 --- a/src/CxbxKrnl/VMManager.h +++ b/src/CxbxKrnl/VMManager.h @@ -55,12 +55,10 @@ enum VMAType { // vma represents an unmapped region of the address space Free, - // memory reserved by XbAllocateVirtualMemory + // memory reserved by XbAllocateVirtualMemory or by MmMapIoSpace Reserved, // vma represents allocated memory Allocated, - // mark this vma as non-mergeable - Lock, }; @@ -139,10 +137,10 @@ class VMManager : public PhysicalMemory VAddr AllocateContiguous(size_t Size, PAddr LowerAddress, PAddr HigherAddress, ULONG Alignment, DWORD Perms); // maps device memory in the system memory region VAddr MapDeviceMemory(PAddr Paddr, size_t Size, DWORD Perms); + // deallocates memory in the system region + PFN_COUNT DeAllocateSystemMemory(VAddr addr, size_t Size /*MemoryRegionType Type*/); // deallocate a block of memory void Deallocate(VAddr addr); - // deallocate stack memory - void DeallocateStack(VAddr addr); // changes the protections of a memory region void Protect(VAddr target, size_t size, DWORD new_perms); // query if a VAddr is valid