From f1255cb89b5e1ee3ee746b2b2d0e709df24bf987 Mon Sep 17 00:00:00 2001 From: ergo720 <45463469+ergo720@users.noreply.github.com> Date: Mon, 15 Jul 2019 15:11:54 +0200 Subject: [PATCH] Allow the memory manager to work again with the non-loader approach --- CMakeLists.txt | 4 +- src/common/VerifyAddressRanges.cpp | 186 ------------------- src/common/VerifyAddressRanges.h | 4 - src/common/win32/EmuShared.h | 13 +- src/core/kernel/exports/EmuKrnlHal.cpp | 1 - src/core/kernel/init/CxbxKrnl.cpp | 10 +- src/core/kernel/init/CxbxKrnl.h | 8 +- src/core/kernel/memory-manager/VMManager.cpp | 64 ++++--- src/devices/video/nv2a.cpp | 32 +--- src/emulator/cxbxr-emu.cpp | 9 +- src/gui/WinMain.cpp | 9 +- src/gui/WndMain.cpp | 6 +- src/loader/cxbxr-ldr.cpp | 2 +- 13 files changed, 84 insertions(+), 264 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 08b52d34d..1cc0e8a55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -252,8 +252,6 @@ file (GLOB CXBXR_SOURCE_GUIv1 "${CXBXR_ROOT_DIR}/src/gui/WinMain.cpp" "${CXBXR_ROOT_DIR}/src/gui/Wnd.cpp" "${CXBXR_ROOT_DIR}/src/gui/WndMain.cpp" -# Temporary usage for need ReserveAddressRanges func with cxbx.exe's emulation. - "${CXBXR_ROOT_DIR}/src/common/ReserveAddressRanges.cpp" ) # Emulator (module) @@ -367,6 +365,8 @@ file (GLOB CXBXR_SOURCE_EMU "${CXBXR_ROOT_DIR}/src/devices/video/swizzle.cpp" "${CXBXR_ROOT_DIR}/src/devices/x86/EmuX86.cpp" "${CXBXR_ROOT_DIR}/src/devices/Xbox.cpp" + # Temporary usage for need ReserveAddressRanges func with cxbx.exe's emulation. + "${CXBXR_ROOT_DIR}/src/common/ReserveAddressRanges.cpp" ) add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/projects/cxbx") diff --git a/src/common/VerifyAddressRanges.cpp b/src/common/VerifyAddressRanges.cpp index 99077ec00..f8360f3ce 100644 --- a/src/common/VerifyAddressRanges.cpp +++ b/src/common/VerifyAddressRanges.cpp @@ -37,192 +37,6 @@ bool VerifyBaseAddr() return ((UINT_PTR)GetModuleHandle(nullptr) == CXBX_BASE_ADDR); } -// This array keeps track of which ranges have successfully been reserved. -struct { - int RangeIndex; // = index into XboxAddressRanges[] - uint32_t Start; - int Size; -} ReservedRanges[128]; - -int ReservedRangeCount = 0; - -bool VerifyAddressRange(int index) -{ - uint32_t BaseAddress = XboxAddressRanges[index].Start; - int Size = XboxAddressRanges[index].Size; - bool HadAnyFailure = false; - - // Safeguard against bounds overflow - if (ReservedRangeCount < ARRAY_SIZE(ReservedRanges)) { - // Initialize the reservation of a new range - ReservedRanges[ReservedRangeCount].RangeIndex = index; - ReservedRanges[ReservedRangeCount].Start = BaseAddress; - ReservedRanges[ReservedRangeCount].Size = 0; - } - - // Verify this range in 64 Kb block increments, as they are supposed - // to have been reserved like that too: - bool HadFailure = HadAnyFailure; - const DWORD AllocationProtect = (XboxAddressRanges[index].Start == 0x10000) ? PAGE_EXECUTE_WRITECOPY : XboxAddressRanges[index].InitialMemoryProtection; - MEMORY_BASIC_INFORMATION mbi; - bool Okay; - while (Size > 0) { - // Expected values - PVOID AllocationBase = (PVOID)BaseAddress; - SIZE_T RegionSize = (SIZE_T)(Size > BLOCK_SIZE) ? BLOCK_SIZE : (Size > PAGE_SIZE) ? Size : PAGE_SIZE; - DWORD State = MEM_RESERVE; - DWORD Protect = 0; - DWORD Type = MEM_PRIVATE; -#if 0 - // Allowed deviations - if (XboxAddressRanges[index].Start == 0x10000) { - AllocationBase = (PVOID)0x10000; - State = MEM_COMMIT; - Type = MEM_IMAGE; - // TODO : Either update below to current section layout, or reduce the number of sections - // (by merging them, preferrably into a single section if possible). - // (Note, that merging sections would make the loader smaller, so that's preferrable.) - switch (BaseAddress) { - case 0x10000: // Image Header - RegionSize = PAGE_SIZE; - Protect = PAGE_READONLY; - break; - case 0x11000: // section .textbss - RegionSize = BLOCK_SIZE; - Protect = PAGE_EXECUTE_READWRITE; - break; - case 0x21000: // section .text - RegionSize = 0x2000; - Protect = PAGE_EXECUTE_READ; - break; - case 0x23000: // section .data - RegionSize = PAGE_SIZE; - Protect = PAGE_READONLY; - break; - case 0x24000: // section .idata - RegionSize = 0x0999a000; // == ? - ? - Protect = PAGE_READWRITE; - break; - } - } -#endif - if (BaseAddress == 0x80000000 || BaseAddress == 0xF0000000) { - RegionSize = Size; - Okay = (VirtualQuery((LPVOID)BaseAddress, &mbi, sizeof(mbi)) != 0); - if (Okay) - Okay = (mbi.BaseAddress == (LPVOID)BaseAddress); - if (Okay) - Okay = (mbi.AllocationBase == AllocationBase); - if (Okay) - Okay = (mbi.AllocationProtect == (BaseAddress == 0x80000000 ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE)); - if (Okay) - Okay = (mbi.RegionSize == Size); - if (Okay) - Okay = (mbi.State == MEM_COMMIT); - if (Okay) - Okay = (mbi.Protect == mbi.AllocationProtect); - if (Okay) - Okay = (mbi.Type == MEM_MAPPED); - } - else if (BaseAddress == 0x10000) { - RegionSize = 0; - while (BaseAddress <= 0x07FFFFFF) { - Okay = (VirtualQuery((LPVOID)BaseAddress, &mbi, sizeof(mbi)) != 0); - if (!Okay || mbi.State != MEM_COMMIT || mbi.Type != MEM_IMAGE) { - Okay = false; - break; - } - BaseAddress += mbi.RegionSize; - RegionSize += mbi.RegionSize; - } - if (Okay) { - RegionSize = Size; - } - } - else { - // Verify each block - Okay = (VirtualQuery((LPVOID)BaseAddress, &mbi, sizeof(mbi)) != 0); - if (Okay) - Okay = (mbi.BaseAddress == (LPVOID)BaseAddress); - if (Okay) - Okay = (mbi.AllocationBase == AllocationBase); - if (Okay) - Okay = (mbi.AllocationProtect == AllocationProtect); - if (Okay) - Okay = (mbi.RegionSize == RegionSize); - if (Okay) - Okay = (mbi.State == State); - if (Okay) - Okay = (mbi.Protect == Protect); - if (Okay) - Okay = (mbi.Type == Type); - } - - if (!Okay) { - HadFailure = true; - if (!IsOptionalAddressRange(index)) { - HadAnyFailure = true; - } - } else { - // Safeguard against bounds overflow - if (ReservedRangeCount < ARRAY_SIZE(ReservedRanges)) { - if (HadFailure) { - HadFailure = false; - // Starting a new range - did the previous one have any size? - if (ReservedRanges[ReservedRangeCount].Size > 0) { - // Then start a new range, and copy over the current type - ReservedRangeCount++; - ReservedRanges[ReservedRangeCount].RangeIndex = index; - } - - // Register a new ranges starting address - ReservedRanges[ReservedRangeCount].Start = BaseAddress; - } - - // Accumulate the size of each successfull reservation - ReservedRanges[ReservedRangeCount].Size += RegionSize; - } - } - - if (BaseAddress == 0x80000000 || BaseAddress == 0xF0000000 || XboxAddressRanges[index].Start == 0x10000) { - Size = 0; - } - else { - // Handle the next region - BaseAddress += RegionSize; - Size -= RegionSize; - } - } - - // Safeguard against bounds overflow - if (ReservedRangeCount < ARRAY_SIZE(ReservedRanges)) { - // Keep the current block only if it contains a successfully reserved range - if (ReservedRanges[ReservedRangeCount].Size > 0) { - ReservedRangeCount++; - } - } - - return !HadAnyFailure; -} - -bool VerifyAddressRanges(const int system) -{ - // Loop over all Xbox address ranges - for (int i = 0; i < ARRAY_SIZE(XboxAddressRanges); i++) { - // Skip address ranges that don't match the given flags - if (!AddressRangeMatchesFlags(i, system)) - continue; - - if (!VerifyAddressRange(i)) { - if (!IsOptionalAddressRange(i)) { - return false; - } - } - } - - return true; -} - void UnreserveMemoryRange(const int index) { uint32_t Start = XboxAddressRanges[index].Start; diff --git a/src/common/VerifyAddressRanges.h b/src/common/VerifyAddressRanges.h index 3293a3d20..e224a778c 100644 --- a/src/common/VerifyAddressRanges.h +++ b/src/common/VerifyAddressRanges.h @@ -28,9 +28,5 @@ extern bool VerifyBaseAddr(); -// TODO : extern ReservedRanges[]; -extern int ReservedRangeCount; - -extern bool VerifyAddressRanges(const int system); extern void UnreserveMemoryRange(const int index); extern bool AllocateMemoryRange(const int index); diff --git a/src/common/win32/EmuShared.h b/src/common/win32/EmuShared.h index 897e9abef..e4eed7ddf 100644 --- a/src/common/win32/EmuShared.h +++ b/src/common/win32/EmuShared.h @@ -186,7 +186,13 @@ class EmuShared : public Mutex // ****************************************************************** void GetDebuggingFlag(bool *value) { Lock(); *value = m_bDebugging; Unlock(); } void SetDebuggingFlag(const bool *value) { Lock(); m_bDebugging = *value; Unlock(); } - +#ifndef CXBX_LOADER + // ****************************************************************** + // * Previous Memory Layout value Accessors + // ****************************************************************** + void GetMmLayout(int* value) { Lock(); *value = m_PreviousMmLayout; Unlock(); } + void SetMmLayout(int* value) { Lock(); m_PreviousMmLayout = *value; Unlock(); } +#endif // ****************************************************************** // * Log Level value Accessors // ****************************************************************** @@ -260,7 +266,12 @@ class EmuShared : public Mutex bool m_bDebugging; bool m_bReady_status; bool m_bEmulating_status; +#ifndef CXBX_LOADER + int m_PreviousMmLayout; + int m_Reserved7[3]; +#else int m_Reserved7[4]; +#endif bool m_bFirstLaunch; bool m_bReserved2; bool m_bReserved3; diff --git a/src/core/kernel/exports/EmuKrnlHal.cpp b/src/core/kernel/exports/EmuKrnlHal.cpp index 090da6b0f..af1cd94f6 100644 --- a/src/core/kernel/exports/EmuKrnlHal.cpp +++ b/src/core/kernel/exports/EmuKrnlHal.cpp @@ -562,7 +562,6 @@ XBSYSAPI EXPORTNUM(49) xboxkrnl::VOID DECLSPEC_NORETURN NTAPI xboxkrnl::HalRetur // Relaunch Cxbx, to load another Xbe { - bool bMultiXbe = true; int QuickReboot; g_EmuShared->GetBootFlags(&QuickReboot); QuickReboot |= BOOT_QUICK_REBOOT; diff --git a/src/core/kernel/init/CxbxKrnl.cpp b/src/core/kernel/init/CxbxKrnl.cpp index 0a2a37268..839c5670b 100644 --- a/src/core/kernel/init/CxbxKrnl.cpp +++ b/src/core/kernel/init/CxbxKrnl.cpp @@ -1110,8 +1110,16 @@ void CxbxKrnlMain(int argc, char* argv[], uint32_t blocks_reserved[384]) CxbxKrnl_Xbe = new Xbe(chihiroMediaBoardRom.c_str(), false); } #endif - // Initialize the virtual manager + +#ifndef CXBX_LOADER + // Initialize the memory manager + uint32_t SystemDevBlocksReserved[384] = { 0 }; + g_VMManager.Initialize(0, BootFlags, SystemDevBlocksReserved); +#else + // TODO: Retrieve the system type from the loader and be sure that it doesn't change between quick reboots + // Initialize the memory manager g_VMManager.Initialize(SYSTEM_XBOX, BootFlags, blocks_reserved); +#endif // Commit the memory used by the xbe header size_t HeaderSize = CxbxKrnl_Xbe->m_Header.dwSizeofHeaders; diff --git a/src/core/kernel/init/CxbxKrnl.h b/src/core/kernel/init/CxbxKrnl.h index ea3c92446..d84f977bd 100644 --- a/src/core/kernel/init/CxbxKrnl.h +++ b/src/core/kernel/init/CxbxKrnl.h @@ -149,8 +149,12 @@ extern "C" { // (called "$$XTIMAG") at 0x031C5260+0x00002800, which would // fit in 51 MB. If we ever encounter an even larger XBE, this // value will have to be increased likewise (maybe up to 64 MB -// for XBOX_MEMORY_SIZE or even 128 MB for CHIHIRO_MEMORY_SIZE). -#define XBE_MAX_VA (128 * ONE_MB) +// for XBOX_MEMORY_SIZE or even 128 MB for CHIHIRO_MEMORY_SIZE). +#ifdef CXBX_LOADER +#define XBE_MAX_VA (128 * ONE_MB) +#else +#define XBE_MAX_VA (64 * ONE_MB) +#endif /*! base address of Cxbx host executable, see Cxbx project options, Linker, Advanced, Base Address */ #define CXBX_BASE_ADDR XBE_IMAGE_BASE diff --git a/src/core/kernel/memory-manager/VMManager.cpp b/src/core/kernel/memory-manager/VMManager.cpp index 60fdfe70e..56a63459e 100644 --- a/src/core/kernel/memory-manager/VMManager.cpp +++ b/src/core/kernel/memory-manager/VMManager.cpp @@ -40,6 +40,10 @@ #include "EmuShared.h" #include "core\kernel\exports\EmuKrnl.h" // For InitializeListHead(), etc. #include +// Temporary usage for need ReserveAddressRanges func with cxbx.exe's emulation. +#ifndef CXBX_LOADER +#include "common/ReserveAddressRanges.h" +#endif VMManager g_VMManager; @@ -56,6 +60,23 @@ bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const void VMManager::Initialize(int SystemType, int BootFlags, uint32_t blocks_reserved[384]) { +#ifndef CXBX_LOADER + if ((BootFlags & BOOT_QUICK_REBOOT) == 0) { + SystemType = g_bIsRetail ? SYSTEM_XBOX : g_bIsChihiro ? SYSTEM_CHIHIRO : SYSTEM_DEVKIT; // TODO: Temporary placeholder until loader is functional. + g_EmuShared->SetMmLayout(&SystemType); + } + else { + g_EmuShared->GetMmLayout(&SystemType); + } + + if (!ReserveAddressRanges(SystemType, blocks_reserved)) { + CxbxKrnlCleanup("Failed to reserve required memory ranges!", GetLastError()); + } +#endif + m_MmLayoutChihiro = (SystemType == SYSTEM_CHIHIRO); + m_MmLayoutDebug = (SystemType == SYSTEM_DEVKIT); + m_MmLayoutRetail = (SystemType == SYSTEM_XBOX); + // Set up the critical section to synchronize accesses InitializeCriticalSectionAndSpinCount(&m_CriticalSection, 0x400); @@ -69,10 +90,11 @@ void VMManager::Initialize(int SystemType, int BootFlags, uint32_t blocks_reserv ConstructMemoryRegion(DEVKIT_MEMORY_BASE, DEVKIT_MEMORY_SIZE, DevkitRegion); // Commit all the memory reserved by the loader for the PTs + // We are looping here because memory-reservation happens in 64 KiB increments for (int i = 0; i < 64; i++) { - LPVOID ret = VirtualAlloc((LPVOID)(PAGE_TABLES_BASE + i * (64 * ONE_KB)), 64 * ONE_KB, MEM_COMMIT, PAGE_READWRITE); + LPVOID ret = VirtualAlloc((LPVOID)(PAGE_TABLES_BASE + i * m_AllocationGranularity), m_AllocationGranularity, MEM_COMMIT, PAGE_READWRITE); if (ret != (LPVOID)(PAGE_TABLES_BASE + i * (64 * ONE_KB))) { - CxbxKrnlCleanup("The error was 0x%08X\n", GetLastError()); + CxbxKrnlCleanup("VirtualAlloc failed to commit the memory for the page tables. The error was 0x%08X", GetLastError()); } } @@ -99,11 +121,6 @@ void VMManager::Initialize(int SystemType, int BootFlags, uint32_t blocks_reserv } } - // Ensure that SystemType doesn't change between quick reboots, for example, by ignoring/forbidding changes to it while a title is being emulated - m_MmLayoutChihiro = (SystemType == SYSTEM_CHIHIRO); - m_MmLayoutDebug = (SystemType == SYSTEM_DEVKIT); - m_MmLayoutRetail = (SystemType == SYSTEM_XBOX); - // Set up general memory variables according to the xbe type if (m_MmLayoutChihiro) { @@ -188,10 +205,8 @@ void VMManager::InitializeSystemAllocations() { PFN pfn; PFN pfn_end; - PFN result; PMMPTE PointerPte; PMMPTE EndingPte; - MMPTE TempPte; VAddr addr; @@ -275,24 +290,24 @@ void VMManager::RestorePersistentMemory() { HANDLE handle = OpenFileMapping(FILE_MAP_READ, FALSE, "PersistentMemory"); if (handle == NULL) { - CxbxKrnlCleanup("Couldn't restore persistent memory! OpenFileMapping failed"); + CxbxKrnlCleanup("Couldn't restore persistent memory! OpenFileMapping failed with error 0x%08X", GetLastError()); return; } PersistedMemory* persisted_mem = (PersistedMemory*)MapViewOfFile(handle, FILE_MAP_READ, 0, 0, 0); if (persisted_mem == nullptr) { - CxbxKrnlCleanup("Couldn't restore persistent memory! MapViewOfFile failed with error %08X", GetLastError()); + CxbxKrnlCleanup("Couldn't restore persistent memory! MapViewOfFile failed with error 0x%08X", GetLastError()); return; } if (persisted_mem->LaunchFrameAddresses[0] != 0 && IS_PHYSICAL_ADDRESS(persisted_mem->LaunchFrameAddresses[0])) { xboxkrnl::LaunchDataPage = (xboxkrnl::PLAUNCH_DATA_PAGE)persisted_mem->LaunchFrameAddresses[0]; - DBG_PRINTF("Restored LaunchDataPage\n"); + EmuLog(LOG_LEVEL::INFO, "Restored LaunchDataPage\n"); } if (persisted_mem->LaunchFrameAddresses[1] != 0 && IS_PHYSICAL_ADDRESS(persisted_mem->LaunchFrameAddresses[1])) { xboxkrnl::AvSavedDataAddress = (xboxkrnl::PVOID)persisted_mem->LaunchFrameAddresses[1]; - DBG_PRINTF("Restored Framebuffer\n"); + EmuLog(LOG_LEVEL::INFO, "Restored Framebuffer\n"); } MMPTE pte; @@ -338,7 +353,6 @@ void VMManager::RestorePersistentMemory() if (m_MmLayoutDebug) { m_PhysicalPagesAvailable += 16; m_DebuggerPagesAvailable -= 16; } PFN pfn_end; - PFN result; if (m_MmLayoutRetail || m_MmLayoutDebug) { pfn = XBOX_INSTANCE_PHYSICAL_PAGE; pfn_end = XBOX_INSTANCE_PHYSICAL_PAGE + NV2A_INSTANCE_PAGE_COUNT - 1; @@ -393,12 +407,12 @@ void VMManager::SavePersistentMemory() handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, m_NumPersistentPtes * PAGE_SIZE + m_NumPersistentPtes * 4 * 2 + sizeof(PersistedMemory), "PersistentMemory"); if (handle == NULL) { - CxbxKrnlCleanup("Couldn't persist memory! CreateFileMapping failed"); + CxbxKrnlCleanup("Couldn't persist memory! CreateFileMapping failed with error 0x%08X", GetLastError()); return; } addr = MapViewOfFile(handle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); if (addr == nullptr) { - CxbxKrnlCleanup("Couldn't persist memory! MapViewOfFile failed with error %08X", GetLastError()); + CxbxKrnlCleanup("Couldn't persist memory! MapViewOfFile failed with error 0x%08X", GetLastError()); return; } @@ -407,12 +421,12 @@ void VMManager::SavePersistentMemory() if (xboxkrnl::LaunchDataPage != xbnullptr) { persisted_mem->LaunchFrameAddresses[0] = (VAddr)xboxkrnl::LaunchDataPage; - DBG_PRINTF("Persisted LaunchDataPage\n"); + EmuLog(LOG_LEVEL::INFO, "Persisted LaunchDataPage\n"); } if (xboxkrnl::AvSavedDataAddress != xbnullptr) { persisted_mem->LaunchFrameAddresses[1] = (VAddr)xboxkrnl::AvSavedDataAddress; - DBG_PRINTF("Persisted Framebuffer\n"); + EmuLog(LOG_LEVEL::INFO, "Persisted Framebuffer\n"); } i = 0; @@ -604,14 +618,16 @@ void VMManager::PersistMemory(VAddr addr, size_t Size, bool bPersist) { PointerPte->Hardware.Persist = 1; m_NumPersistentPtes++; - PointerPte++; } + PointerPte++; + } } else { while (PointerPte <= EndingPte) { PointerPte->Hardware.Persist = 0; m_NumPersistentPtes--; - PointerPte++; } + PointerPte++; + } } Unlock(); @@ -1531,7 +1547,7 @@ xboxkrnl::NTSTATUS VMManager::XbAllocateVirtualMemory(VAddr* addr, ULONG ZeroBit if (!VirtualAlloc((void*)AlignedCapturedBase, AlignedCapturedSize, MEM_COMMIT, (ConvertXboxToWinPermissions(PatchXboxPermissions(Protect))) & ~(PAGE_WRITECOMBINE | PAGE_NOCACHE))) { - EmuLog(LOG_LEVEL::DEBUG, "%s: VirtualAlloc failed to commit the memory! The error was %d", __func__, GetLastError()); + EmuLog(LOG_LEVEL::DEBUG, "%s: VirtualAlloc failed to commit the memory! The error was 0x%08X", __func__, GetLastError()); status = STATUS_NO_MEMORY; goto Exit; } @@ -1737,7 +1753,7 @@ xboxkrnl::NTSTATUS VMManager::XbFreeVirtualMemory(VAddr* addr, size_t* Size, DWO { if (!VirtualFree((void*)AlignedCapturedBase, AlignedCapturedSize, MEM_DECOMMIT)) { - EmuLog(LOG_LEVEL::DEBUG, "%s: VirtualFree failed to decommit the memory! The error was %d", __func__, GetLastError()); + EmuLog(LOG_LEVEL::DEBUG, "%s: VirtualFree failed to decommit the memory! The error was 0x%08X", __func__, GetLastError()); } } } @@ -2379,7 +2395,7 @@ void VMManager::UpdateMemoryPermissions(VAddr addr, size_t Size, DWORD Perms) DWORD dummy; if (!VirtualProtect((void*)addr, Size, WindowsPerms & ~(PAGE_WRITECOMBINE | PAGE_NOCACHE), &dummy)) { - EmuLog(LOG_LEVEL::DEBUG, "VirtualProtect failed. The error code was %d", GetLastError()); + EmuLog(LOG_LEVEL::DEBUG, "VirtualProtect failed. The error code was 0x%08X", GetLastError()); } } @@ -2491,7 +2507,7 @@ void VMManager::DestructVMA(VAddr addr, MemoryRegionType Type, size_t Size) if (!ret) { - DBG_PRINTF("Deallocation routine failed with error %d\n", GetLastError()); + EmuLog(LOG_LEVEL::DEBUG, "Deallocation routine failed with error 0x%08X", GetLastError()); } } diff --git a/src/devices/video/nv2a.cpp b/src/devices/video/nv2a.cpp index c6b563e38..02e935d2f 100644 --- a/src/devices/video/nv2a.cpp +++ b/src/devices/video/nv2a.cpp @@ -1128,36 +1128,24 @@ static void nv2a_vblank_thread(NV2AState *d) void CxbxReserveNV2AMemory(NV2AState *d) { - // Reserve NV2A memory : - void *memory = (void *)VirtualAllocEx( - GetCurrentProcess(), - (void *)NV2A_ADDR, - NV2A_SIZE, - MEM_RESERVE, // Don't allocate actual physical storage in memory - PAGE_NOACCESS); // Any access must result in an access violation exception (handled in EmuException/EmuX86_DecodeException) - if (memory == NULL) { - EmuLog(LOG_LEVEL::WARNING, "Couldn't reserve NV2A memory, continuing assuming we'll receive (and handle) access violation exceptions anyway..."); - return; - } + // The NV2A memory was reserved already by the loader! printf("[0x%.4X] INIT: Reserved %d MiB of Xbox NV2A memory at 0x%.8X to 0x%.8X\n", GetCurrentThreadId(), NV2A_SIZE / ONE_MB, NV2A_ADDR, NV2A_ADDR + NV2A_SIZE - 1); - // Allocate PRAMIN Region + // Allocate PRAMIN Region (the loader only reserved this region, it still needs to be committed!) + // We are looping here because memory-reservation happens in 64 KiB increments d->pramin.ramin_size = NV_PRAMIN_SIZE; - d->pramin.ramin_ptr = (uint8_t*)VirtualAllocEx( - GetCurrentProcess(), - (void*)(NV2A_ADDR + NV_PRAMIN_ADDR), - d->pramin.ramin_size, - MEM_COMMIT, // No MEM_RESERVE | - PAGE_READWRITE); - if (d->pramin.ramin_ptr == NULL) { - EmuLog(LOG_LEVEL::WARNING, "Couldn't allocate NV2A PRAMIN memory"); - return; + d->pramin.ramin_ptr = (uint8_t*)(NV2A_ADDR + NV_PRAMIN_ADDR); + for (int i = 0; i < 16; i++) { + LPVOID ret = VirtualAlloc((LPVOID)(NV2A_ADDR + NV_PRAMIN_ADDR + i * 64 * ONE_KB), 64 * ONE_KB, MEM_COMMIT, PAGE_READWRITE); + if (ret != (LPVOID)(NV2A_ADDR + NV_PRAMIN_ADDR + i * 64 * ONE_KB)) { + CxbxKrnlCleanup("VirtualAlloc failed to commit the memory for the nv2a pramin. The error was 0x%08X", GetLastError()); + } } printf("[0x%.4X] INIT: Allocated %d MiB of Xbox NV2A PRAMIN memory at 0x%.8p to 0x%.8p\n", - GetCurrentThreadId(), d->pramin.ramin_size / ONE_MB, d->pramin.ramin_ptr, d->pramin.ramin_ptr + d->pramin.ramin_size - 1); + GetCurrentThreadId(), d->pramin.ramin_size / ONE_MB, (uintptr_t)d->pramin.ramin_ptr, (uintptr_t)d->pramin.ramin_ptr + d->pramin.ramin_size - 1); } /* NV2ADevice */ diff --git a/src/emulator/cxbxr-emu.cpp b/src/emulator/cxbxr-emu.cpp index cc5bfb19c..6a028bc2d 100644 --- a/src/emulator/cxbxr-emu.cpp +++ b/src/emulator/cxbxr-emu.cpp @@ -28,7 +28,7 @@ // cxbxr-emu.cpp : Defines the exported functions for the DLL application. #include "Cxbx.h" // For FUNC_EXPORTS -#include "VerifyAddressRanges.h" // For VerifyBaseAddr() and VerifyAddressRanges() +#include "VerifyAddressRanges.h" // For VerifyBaseAddr() //#include "CxbxKrnl/Emu.h" #include "EmuShared.h" #include "core\kernel\init\CxbxKrnl.h" // For HandleFirstLaunch() and LaunchEmulation() @@ -130,13 +130,6 @@ DWORD WINAPI Emulate(int system, uint32_t blocks_reserved[384]) return EXIT_FAILURE; } - // Before doing anything else that might cause memory fragmentation, - // verify that we still got control over all ranges the loader reserved - if (!VerifyAddressRanges(system)) { - CxbxShowError("Failed to claim required address ranges (which is a requirement for Xbox emulation)"); - return EXIT_FAILURE; - } - LPSTR CommandLine = GetCommandLine(); if (!CommandLine) { CxbxShowError("Couldn't retrieve command line!"); diff --git a/src/gui/WinMain.cpp b/src/gui/WinMain.cpp index df1192861..b2f73d703 100644 --- a/src/gui/WinMain.cpp +++ b/src/gui/WinMain.cpp @@ -35,10 +35,6 @@ #include "common\Settings.hpp" #include -// Temporary usage for need ReserveAddressRanges func with cxbx.exe's emulation. -#ifndef CXBX_LOADER -#include "common/ReserveAddressRanges.h" -#endif // Enable Visual Styles #pragma comment(linker,"\"/manifestdependency:type='win32' \ @@ -82,10 +78,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine if (bHasLoadArgument) { #ifndef CXBX_LOADER - uint32_t SystemDevBlocksReserved[384] = {}; - int system = SYSTEM_XBOX; // TODO: Temporary placeholder until loader is functional. - ReserveAddressRanges(system, SystemDevBlocksReserved); - CxbxKrnlMain(__argc, __argv, SystemDevBlocksReserved); + CxbxKrnlMain(__argc, __argv, nullptr); EmuShared::Cleanup(); return EXIT_SUCCESS; #else diff --git a/src/gui/WndMain.cpp b/src/gui/WndMain.cpp index d34d01a01..88ed4b5df 100644 --- a/src/gui/WndMain.cpp +++ b/src/gui/WndMain.cpp @@ -84,8 +84,6 @@ void MapPersistedMemory() void UnmapPersistedMemory() { - assert(((hPersistedMemory != NULL) == (PersistedMemoryAddr != nullptr)) && "Persistent memory handle and address must both be set (or already unset)!"); - if (hPersistedMemory != NULL) { UnmapViewOfFile(PersistedMemoryAddr); PersistedMemoryAddr = nullptr; @@ -374,7 +372,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP pCMD->dwChildProcID = lParam; // lParam is process ID. std::thread(CrashMonitorWrapper, pCMD).detach(); - g_EmuShared->SetIsEmulating(true); // NOTE: Putting in here raise to low or medium risk due to debugger will launch itself. (Current workaround) g_EmuShared->SetIsReady(true); } @@ -2274,6 +2271,8 @@ void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState / std::string szProcArgsBuffer; CxbxConvertArgToString(szProcArgsBuffer, szExeFileName, m_XbeFilename, hwndParent, g_Settings->m_core.KrnlDebugMode, g_Settings->m_core.szKrnlDebug); + UnmapPersistedMemory(); + if (AttachLocalDebugger) { // Check then close existing debugger monitor. @@ -2363,7 +2362,6 @@ void WndMain::CrashMonitor(DWORD dwChildProcID) g_EmuShared->GetBootFlags(&iBootFlags); if (!iBootFlags) { - UnmapPersistedMemory(); if (dwExitCode == EXIT_SUCCESS) {// StopEmulation return; } diff --git a/src/loader/cxbxr-ldr.cpp b/src/loader/cxbxr-ldr.cpp index 3e0cf8969..bc65e1a8a 100644 --- a/src/loader/cxbxr-ldr.cpp +++ b/src/loader/cxbxr-ldr.cpp @@ -154,7 +154,7 @@ DWORD CALLBACK rawMain() } } - // Marking this as static to avoid an implicit call to memset, which is not availble in the loader + // Marking this as static to avoid an implicit call to memset, which is not available in the loader static uint32_t SystemDevBlocksReserved[384]; if (!ReserveAddressRanges(system, SystemDevBlocksReserved)) {