Allow the memory manager to work again with the non-loader approach
This commit is contained in:
parent
79a3a8d9a6
commit
f1255cb89b
|
@ -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")
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -40,6 +40,10 @@
|
|||
#include "EmuShared.h"
|
||||
#include "core\kernel\exports\EmuKrnl.h" // For InitializeListHead(), etc.
|
||||
#include <assert.h>
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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!");
|
||||
|
|
|
@ -35,10 +35,6 @@
|
|||
#include "common\Settings.hpp"
|
||||
#include <commctrl.h>
|
||||
|
||||
// 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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Reference in New Issue