DeAllocateSystemMemory
This commit is contained in:
parent
ce367788ad
commit
8766aa57bf
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue