fix standalone persisted memory support
This commit is contained in:
parent
b20a970b1d
commit
8a33562dc8
|
@ -38,7 +38,6 @@ typedef enum class _IPC_UPDATE_GUI {
|
|||
, XBOX_LED_COLOUR
|
||||
, LOG_ENABLED
|
||||
, KRNL_IS_READY
|
||||
, VM_PERSIST_MEM
|
||||
} IPC_UPDATE_GUI;
|
||||
|
||||
void ipc_send_gui_update(IPC_UPDATE_GUI command, const unsigned int value);
|
||||
|
|
|
@ -65,10 +65,6 @@ void ipc_send_gui_update(IPC_UPDATE_GUI command, const unsigned int value)
|
|||
cmdParam = ID_GUI_STATUS_KRNL_IS_READY;
|
||||
break;
|
||||
|
||||
case IPC_UPDATE_GUI::VM_PERSIST_MEM:
|
||||
cmdParam = ID_GUI_VM_PERSIST_MEM;
|
||||
break;
|
||||
|
||||
default:
|
||||
cmdParam = 0;
|
||||
break;
|
||||
|
|
|
@ -786,6 +786,11 @@ void CxbxKrnlEmulate(uint32_t blocks_reserved[384])
|
|||
// Set up the logging variables for the kernel process during initialization.
|
||||
log_sync_config();
|
||||
|
||||
// When a reboot occur, we need to keep persistent memory buffer open before emulation process shutdown.
|
||||
if ((BootFlags & BOOT_QUICK_REBOOT) != 0) {
|
||||
g_VMManager.GetPersistentMemory();
|
||||
}
|
||||
|
||||
if (CxbxKrnl_hEmuParent != NULL) {
|
||||
ipc_send_gui_update(IPC_UPDATE_GUI::KRNL_IS_READY, static_cast<UINT>(GetCurrentProcessId()));
|
||||
|
||||
|
@ -1771,6 +1776,9 @@ void CxbxKrnlShutDown()
|
|||
// Shutdown the input device manager
|
||||
g_InputDeviceManager.Shutdown();
|
||||
|
||||
// Shutdown the memory manager
|
||||
g_VMManager.Shutdown();
|
||||
|
||||
CxbxUnlockFilePath();
|
||||
|
||||
if (CxbxKrnl_hEmuParent != NULL) {
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "Logging.h"
|
||||
#include "EmuShared.h"
|
||||
#include "core\kernel\exports\EmuKrnl.h" // For InitializeListHead(), etc.
|
||||
#include "common/util/cliConfig.hpp" // For GetSessionID
|
||||
#include <assert.h>
|
||||
// Temporary usage for need ReserveAddressRanges func with cxbx.exe's emulation.
|
||||
#ifndef CXBXR_EMU
|
||||
|
@ -46,9 +47,23 @@
|
|||
#endif
|
||||
|
||||
|
||||
constexpr char str_persistent_memory_s[] = "PersistentMemory-s";
|
||||
VMManager g_VMManager;
|
||||
|
||||
|
||||
void VMManager::Shutdown()
|
||||
{
|
||||
// Can't enable this yet. After the memory is deleted, other parts of cxbxr still run before process termination, and attempt to
|
||||
// access the now deleted memory, causing a crash at shutdown
|
||||
//DestroyMemoryRegions();
|
||||
DeleteCriticalSection(&m_CriticalSection);
|
||||
|
||||
if (m_PersistentMemoryHandle != nullptr) {
|
||||
CloseHandle(m_PersistentMemoryHandle);
|
||||
m_PersistentMemoryHandle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const
|
||||
{
|
||||
assert(base + size == next.base);
|
||||
|
@ -286,15 +301,29 @@ void VMManager::InitializeSystemAllocations()
|
|||
}
|
||||
}
|
||||
|
||||
void VMManager::RestorePersistentMemory()
|
||||
{
|
||||
HANDLE handle = OpenFileMapping(FILE_MAP_READ, FALSE, "PersistentMemory");
|
||||
if (handle == NULL) {
|
||||
CxbxKrnlCleanup("Couldn't restore persistent memory! OpenFileMapping failed with error 0x%08X", GetLastError());
|
||||
void VMManager::GetPersistentMemory()
|
||||
{
|
||||
if (m_PersistentMemoryHandle != nullptr) {
|
||||
CxbxKrnlCleanup("Persistent memory is already opened!");
|
||||
return;
|
||||
}
|
||||
|
||||
PersistedMemory* persisted_mem = (PersistedMemory*)MapViewOfFile(handle, FILE_MAP_READ, 0, 0, 0);
|
||||
std::string persisted_mem_sid = str_persistent_memory_s + std::to_string(cli_config::GetSessionID());
|
||||
m_PersistentMemoryHandle = OpenFileMapping(FILE_MAP_READ, FALSE, persisted_mem_sid.c_str());
|
||||
if (m_PersistentMemoryHandle == nullptr) {
|
||||
CxbxKrnlCleanup("Couldn't open persistent memory! OpenFileMapping failed with error 0x%08X", GetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void VMManager::RestorePersistentMemory()
|
||||
{
|
||||
if (m_PersistentMemoryHandle == nullptr) {
|
||||
CxbxKrnlCleanup("Persistent memory is not open!");
|
||||
return;
|
||||
}
|
||||
|
||||
PersistedMemory* persisted_mem = (PersistedMemory*)MapViewOfFile(m_PersistentMemoryHandle, FILE_MAP_READ, 0, 0, 0);
|
||||
if (persisted_mem == nullptr) {
|
||||
CxbxKrnlCleanup("Couldn't restore persistent memory! MapViewOfFile failed with error 0x%08X", GetLastError());
|
||||
return;
|
||||
|
@ -389,9 +418,8 @@ void VMManager::RestorePersistentMemory()
|
|||
}
|
||||
|
||||
UnmapViewOfFile(persisted_mem);
|
||||
CloseHandle(handle);
|
||||
|
||||
ipc_send_gui_update(IPC_UPDATE_GUI::VM_PERSIST_MEM, 0);
|
||||
CloseHandle(m_PersistentMemoryHandle);
|
||||
m_PersistentMemoryHandle = nullptr;
|
||||
}
|
||||
|
||||
void VMManager::SavePersistentMemory()
|
||||
|
@ -399,7 +427,6 @@ void VMManager::SavePersistentMemory()
|
|||
PersistedMemory* persisted_mem;
|
||||
size_t num_persisted_ptes;
|
||||
std::vector<PMMPTE> cached_persisted_ptes;
|
||||
HANDLE handle;
|
||||
LPVOID addr;
|
||||
PMMPTE PointerPte;
|
||||
PMMPTE EndingPte;
|
||||
|
@ -426,12 +453,13 @@ void VMManager::SavePersistentMemory()
|
|||
PointerPte++;
|
||||
}
|
||||
|
||||
handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, num_persisted_ptes * PAGE_SIZE + num_persisted_ptes * 4 * 2 + sizeof(PersistedMemory), "PersistentMemory");
|
||||
if (handle == NULL) {
|
||||
std::string persistent_mem_sid = str_persistent_memory_s + std::to_string(cli_config::GetSessionID());
|
||||
m_PersistentMemoryHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, num_persisted_ptes * PAGE_SIZE + num_persisted_ptes * 4 * 2 + sizeof(PersistedMemory), persistent_mem_sid.c_str());
|
||||
if (m_PersistentMemoryHandle == NULL) {
|
||||
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);
|
||||
addr = MapViewOfFile(m_PersistentMemoryHandle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
|
||||
if (addr == nullptr) {
|
||||
CxbxKrnlCleanup("Couldn't persist memory! MapViewOfFile failed with error 0x%08X", GetLastError());
|
||||
return;
|
||||
|
@ -461,8 +489,6 @@ void VMManager::SavePersistentMemory()
|
|||
|
||||
assert(i == num_persisted_ptes);
|
||||
|
||||
ipc_send_gui_update(IPC_UPDATE_GUI::VM_PERSIST_MEM, 1);
|
||||
|
||||
Unlock();
|
||||
}
|
||||
|
||||
|
|
|
@ -100,14 +100,8 @@ class VMManager : public PhysicalMemory
|
|||
public:
|
||||
// constructor
|
||||
VMManager() {};
|
||||
// destructor
|
||||
~VMManager()
|
||||
{
|
||||
// DestroyMemoryRegions is not called when emulation ends, but only when the GUI process ends. This is probably because the emu
|
||||
// process is killed with TerminateProcess and so it doesn't have a chance to perform a cleanup...
|
||||
//DestroyMemoryRegions();
|
||||
DeleteCriticalSection(&m_CriticalSection);
|
||||
}
|
||||
// shutdown routine
|
||||
void Shutdown();
|
||||
// initializes the memory manager to the default configuration
|
||||
void Initialize(int SystemType, int BootFlags, uint32_t blocks_reserved[384]);
|
||||
// retrieves memory statistics
|
||||
|
@ -158,6 +152,8 @@ class VMManager : public PhysicalMemory
|
|||
xboxkrnl::NTSTATUS XbVirtualProtect(VAddr* addr, size_t* Size, DWORD* Protect);
|
||||
// xbox implementation of NtQueryVirtualMemory
|
||||
xboxkrnl::NTSTATUS XbVirtualMemoryStatistics(VAddr addr, xboxkrnl::PMEMORY_BASIC_INFORMATION memory_statistics);
|
||||
// get persistent memory from previous process until RestorePersistentMemory is called
|
||||
void GetPersistentMemory();
|
||||
// saves all persisted memory just before a quick reboot
|
||||
void SavePersistentMemory();
|
||||
|
||||
|
@ -171,6 +167,8 @@ class VMManager : public PhysicalMemory
|
|||
DWORD m_AllocationGranularity = 0;
|
||||
// number of bytes reserved with XBOX_MEM_RESERVE by XbAllocateVirtualMemory
|
||||
size_t m_VirtualMemoryBytesReserved = 0;
|
||||
// handle "shared" persistent memory open for reboot process
|
||||
void* m_PersistentMemoryHandle = nullptr;
|
||||
|
||||
// same as AllocateContiguousMemory, but it allows to allocate beyond m_MaxContiguousPfn
|
||||
VAddr AllocateContiguousMemoryInternal(PFN_COUNT NumberOfPages, PFN LowestPfn, PFN HighestPfn, PFN PfnAlignment, DWORD Perms);
|
||||
|
|
|
@ -67,33 +67,6 @@
|
|||
static int gameLogoWidth, gameLogoHeight;
|
||||
static int splashLogoWidth, splashLogoHeight;
|
||||
|
||||
static HANDLE hPersistedMemory = NULL;
|
||||
static LPVOID PersistedMemoryAddr = nullptr;
|
||||
|
||||
void MapPersistedMemory()
|
||||
{
|
||||
assert(((hPersistedMemory == NULL) == (PersistedMemoryAddr == nullptr)) && "Persistent memory handle and address must both be unset (or already set)!");
|
||||
|
||||
if (hPersistedMemory == NULL) {
|
||||
hPersistedMemory = OpenFileMapping(FILE_MAP_READ, FALSE, "PersistentMemory");
|
||||
assert(hPersistedMemory != NULL);
|
||||
|
||||
PersistedMemoryAddr = MapViewOfFile(hPersistedMemory, FILE_MAP_READ, 0, 0, 0);
|
||||
assert(PersistedMemoryAddr != nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void UnmapPersistedMemory()
|
||||
{
|
||||
if (hPersistedMemory != NULL) {
|
||||
UnmapViewOfFile(PersistedMemoryAddr);
|
||||
PersistedMemoryAddr = nullptr;
|
||||
|
||||
CloseHandle(hPersistedMemory);
|
||||
hPersistedMemory = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool g_SaveOnExit = true;
|
||||
|
||||
void ClearSymbolCache(const char sStorageLocation[MAX_PATH])
|
||||
|
@ -377,15 +350,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
g_EmuShared->SetIsReady(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_GUI_VM_PERSIST_MEM: {
|
||||
if (lParam) {
|
||||
MapPersistedMemory();
|
||||
} else {
|
||||
UnmapPersistedMemory();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2293,8 +2257,6 @@ void WndMain::StartEmulation(HWND hwndParent, DebuggerState LocalDebuggerState /
|
|||
}
|
||||
/* Main process to generate emulation command line end. */
|
||||
|
||||
UnmapPersistedMemory();
|
||||
|
||||
if (AttachLocalDebugger) {
|
||||
|
||||
// Check then close existing debugger monitor.
|
||||
|
|
|
@ -194,7 +194,6 @@
|
|||
#define ID_GUI_STATUS_LLE_FLAGS 1097
|
||||
#define ID_GUI_STATUS_XBOX_LED_COLOUR 1098
|
||||
#define ID_GUI_STATUS_LOG_ENABLED 1099
|
||||
#define ID_GUI_VM_PERSIST_MEM 1100
|
||||
#define IDC_AC_MUTE_ON_UNFOCUS_DISABLE 1101
|
||||
#define IDC_XBOX_PORT_0 1158
|
||||
#define IDC_XBOX_PORT_1 1166
|
||||
|
|
Loading…
Reference in New Issue