DeAllocateContiguous
This commit is contained in:
parent
bc0e0734ae
commit
2597e88ea4
|
@ -93,14 +93,12 @@ extern "C" {
|
|||
#define CHIHIRO_INSTANCE_PHYSICAL_PAGE 0x07FF0
|
||||
#define XBOX_PFN_DATABASE_PHYSICAL_PAGE 0x03FF0
|
||||
#define CHIHIRO_PFN_DATABASE_PHYSICAL_PAGE 0x07FD0
|
||||
#define PAGE_DIRECTORY_PHYSICAL_ADDRESS 0x0F000
|
||||
#define D3D_PHYSICAL_PAGE 0x00000
|
||||
#define DEBUGKIT_FIRST_UPPER_HALF_PAGE 0x04000
|
||||
#define NV2A_INSTANCE_PAGE_COUNT 16
|
||||
#define XBOX_CONTIGUOUS_MEMORY_LIMIT 0x03FDF
|
||||
#define CHIHIRO_CONTIGUOUS_MEMORY_LIMIT 0x07FCF
|
||||
#define ZERO_PAGE_ADDR 0
|
||||
#define FIRST_PAGE_ADDR PAGE_SIZE
|
||||
#define PAGE_DIRECTORY_PHYSICAL_ADDRESS 0x0F000
|
||||
#define D3D_PHYSICAL_PAGE 0x00000
|
||||
#define DEBUGKIT_FIRST_UPPER_HALF_PAGE X64M_PHYSICAL_PAGE // = 0x4000
|
||||
#define NV2A_INSTANCE_PAGE_COUNT 16
|
||||
#define CONTIGUOUS_MEMORY_BASE SYSTEM_PHYSICAL_MAP // = 0x80000000
|
||||
#define CONTIGUOUS_MEMORY_XBOX_SIZE (64 * ONE_MB)
|
||||
#define CONTIGUOUS_MEMORY_CHIHIRO_SIZE (128 * ONE_MB)
|
||||
|
|
|
@ -236,7 +236,7 @@ XBSYSAPI EXPORTNUM(171) xboxkrnl::VOID NTAPI xboxkrnl::MmFreeContiguousMemory
|
|||
{
|
||||
LOG_FUNC_ONE_ARG(BaseAddress);
|
||||
|
||||
g_VMManager.Deallocate((VAddr)BaseAddress);
|
||||
g_VMManager.DeAllocateContiguous((VAddr)BaseAddress);
|
||||
|
||||
// TODO -oDxbx: Sokoban crashes after this, at reset time (press Black + White to hit this).
|
||||
// Tracing in assembly shows the crash takes place quite a while further, so it's probably
|
||||
|
|
|
@ -186,9 +186,9 @@ void PhysicalMemory::WritePte(PMMPTE pPteStart, PMMPTE pPteEnd, MMPTE Pte, PFN p
|
|||
WRITE_ZERO_PTE(pPteStart);
|
||||
pPteStart++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
while (pPteStart <= pPteEnd)
|
||||
{
|
||||
Pte.Hardware.PFN = pfn;
|
||||
|
@ -196,6 +196,7 @@ void PhysicalMemory::WritePte(PMMPTE pPteStart, PMMPTE pPteEnd, MMPTE Pte, PFN p
|
|||
pPteStart++;
|
||||
pfn++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PhysicalMemory::RemoveFree(PFN_COUNT NumberOfPages, PFN* result, PFN_COUNT PfnAlignment, PFN start, PFN end)
|
||||
|
@ -626,3 +627,12 @@ PFN PhysicalMemory::RemoveAndZeroAnyFreePage(PageType BusyType, PMMPTE pPte)
|
|||
return pfn;
|
||||
}
|
||||
|
||||
bool PhysicalMemory::IsMappable(PFN_COUNT PagesRequested)
|
||||
{
|
||||
if (m_PhysicalPagesAvailable >= PagesRequested) { return true; }
|
||||
else
|
||||
{
|
||||
EmuWarning("Out of physical memory!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -267,6 +267,8 @@ class PhysicalMemory
|
|||
bool AllocatePT(PFN_COUNT PteNumber, VAddr addr);
|
||||
// commit whatever free page is available and zero it
|
||||
PFN RemoveAndZeroAnyFreePage(PageType BusyType, PMMPTE pte);
|
||||
// checks if enough free page are available for the allocation (doesn't account for fragmentation)
|
||||
bool IsMappable(PFN_COUNT PagesRequested);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -135,6 +135,8 @@ void VMManager::DestroyMemoryRegions()
|
|||
for (int i = 0; i < MemoryRegionType::COUNT - 1; ++i)
|
||||
{
|
||||
for (auto it = m_MemoryRegionArray[i].RegionMap.begin(); it != m_MemoryRegionArray[i].RegionMap.end(); ++it)
|
||||
{
|
||||
if (it->second.type != VMAType::Free)
|
||||
{
|
||||
if (it->second.bFragmented)
|
||||
{
|
||||
|
@ -146,6 +148,7 @@ void VMManager::DestroyMemoryRegions()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VMManager::InitializePfnDatabase()
|
||||
|
@ -404,7 +407,7 @@ VAddr VMManager::AllocateSystemMemory(PageType BusyType, DWORD Perms, size_t Siz
|
|||
PteNumber = ROUND_UP_4K(Size) >> PAGE_SHIFT;
|
||||
|
||||
if (bAddGuardPage) { PteNumber++; Size += PAGE_SIZE; }
|
||||
if (m_PhysicalPagesAvailable < PteNumber) { goto Fail; }
|
||||
if (!IsMappable(PteNumber)) { goto Fail; }
|
||||
|
||||
if (RemoveFree(PteNumber, &pfn, 0, 0, m_HighestPage)) // MapViewOfFileEx path
|
||||
{
|
||||
|
@ -469,7 +472,7 @@ VAddr VMManager::AllocateSystemMemory(PageType BusyType, DWORD Perms, size_t Siz
|
|||
PointerPte++;
|
||||
}
|
||||
EndingPte = PointerPte + PteNumber - 1;
|
||||
EndingPfn = pfn + PteNumber;
|
||||
EndingPfn = pfn + PteNumber - 1;
|
||||
|
||||
WritePte(PointerPte, EndingPte, TempPte, pfn);
|
||||
EndingPte->Hardware.GuardOrEnd = 1;
|
||||
|
@ -534,6 +537,7 @@ VAddr VMManager::AllocateContiguous(size_t Size, PAddr LowerAddress, PAddr Highe
|
|||
HigherPfn = HigherAddress >> PAGE_SHIFT;
|
||||
PfnAlignment = Alignment >> PAGE_SHIFT;
|
||||
|
||||
if (!IsMappable(PteNumber)) { goto Fail; }
|
||||
if (HigherPfn > m_MaxContiguousPfn) { HigherPfn = m_MaxContiguousPfn; }
|
||||
if (LowerPfn > HigherPfn) { LowerPfn = HigherPfn; }
|
||||
if (!PfnAlignment) { PfnAlignment = 1; }
|
||||
|
@ -545,17 +549,18 @@ VAddr VMManager::AllocateContiguous(size_t Size, PAddr LowerAddress, PAddr Highe
|
|||
|
||||
assert(CHECK_ALIGNMENT(pfn, PfnAlignment)); // check if the page alignment is correct
|
||||
|
||||
EndingPfn = pfn + PteNumber - 1;
|
||||
|
||||
// check if we have to construct the PT's for this allocation
|
||||
if (!AllocatePT(PteNumber, addr))
|
||||
{
|
||||
InsertFree(pfn, pfn + PteNumber - 1);
|
||||
InsertFree(pfn, EndingPfn);
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
// Finally, write the pte's and the pfn's
|
||||
PointerPte = GetPteAddress(addr);
|
||||
EndingPte = PointerPte + PteNumber - 1;
|
||||
EndingPfn = pfn + PteNumber;
|
||||
|
||||
WritePte(PointerPte, EndingPte, TempPte, pfn);
|
||||
WritePfn(pfn, EndingPfn, PointerPte, PageType::Contiguous, true);
|
||||
|
@ -647,6 +652,45 @@ void VMManager::Deallocate(VAddr addr)
|
|||
Unlock();
|
||||
}
|
||||
|
||||
void VMManager::DeAllocateContiguous(VAddr addr)
|
||||
{
|
||||
LOG_FUNC_BEGIN
|
||||
LOG_FUNC_ARG(addr);
|
||||
LOG_FUNC_END;
|
||||
|
||||
MMPTE TempPte;
|
||||
PMMPTE StartingPte;
|
||||
PMMPTE EndingPte;
|
||||
PFN pfn;
|
||||
PFN EndingPfn;
|
||||
VMAIter it;
|
||||
|
||||
assert(CHECK_ALIGNMENT(addr, PAGE_SIZE)); // all starting addresses from the contiguous region are page aligned
|
||||
|
||||
Lock();
|
||||
|
||||
it = CheckExistenceVMA(addr, MemoryRegionType::Contiguous);
|
||||
|
||||
if (it == m_MemoryRegionArray[MemoryRegionType::Contiguous].RegionMap.end() || it->second.type == VMAType::Free)
|
||||
{
|
||||
Unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
StartingPte = GetPteAddress(addr);
|
||||
EndingPte = StartingPte + (it->second.size >> PAGE_SHIFT) - 1;
|
||||
|
||||
pfn = StartingPte->Hardware.PFN;
|
||||
EndingPfn = pfn + (EndingPte - StartingPte);
|
||||
|
||||
InsertFree(pfn, EndingPfn);
|
||||
WritePfn(pfn, EndingPfn, StartingPte, PageType::Contiguous, true, true);
|
||||
WritePte(StartingPte, EndingPte, TempPte, 0, true);
|
||||
DestructVMA(it, MemoryRegionType::Contiguous);
|
||||
|
||||
Unlock();
|
||||
}
|
||||
|
||||
PFN_COUNT VMManager::DeAllocateSystemMemory(PageType BusyType, VAddr addr, size_t Size /*MemoryRegionType Type*/)
|
||||
{
|
||||
LOG_FUNC_BEGIN
|
||||
|
|
|
@ -140,6 +140,8 @@ class VMManager : public PhysicalMemory
|
|||
VAddr MapDeviceMemory(PAddr Paddr, size_t Size, DWORD Perms);
|
||||
// deallocates memory in the system region
|
||||
PFN_COUNT DeAllocateSystemMemory(PageType BusyType, VAddr addr, size_t Size /*MemoryRegionType Type*/);
|
||||
// deallocates memory in the contiguous region
|
||||
void DeAllocateContiguous(VAddr addr);
|
||||
// deallocate a block of memory
|
||||
void Deallocate(VAddr addr);
|
||||
// changes the protections of a memory region
|
||||
|
|
Loading…
Reference in New Issue