From b2682920467c15f9bca516c5b664e52ab0a286ac Mon Sep 17 00:00:00 2001 From: Gliniak <153369+Gliniak@users.noreply.github.com> Date: Wed, 17 Jun 2026 22:56:54 +0200 Subject: [PATCH] [Kernel] Use single page to store all Vd pointers and structs This is to prevent some titles from reaching out of memory crash --- src/xenia/kernel/xboxkrnl/xboxkrnl_video.cc | 19 ++++++++++--------- src/xenia/memory.cc | 10 ++++++++-- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_video.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_video.cc index f4da2c288..12835232b 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_video.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_video.cc @@ -554,35 +554,36 @@ void RegisterVideoExports(xe::cpu::ExportResolver* export_resolver, KernelState* kernel_state) { auto memory = kernel_state->memory(); + // Allocate single page that stores all pointers instead of separate pages. + const uint32_t baseAllocation = + memory->SystemHeapAlloc(40, 32, kSystemHeapPhysical); // 40 bytes + // VdGlobalDevice (4b) // Pointer to a global D3D device. Games only seem to set this, so we don't // have to do anything. We may want to read it back later, though. - uint32_t pVdGlobalDevice = - memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical); + const uint32_t pVdGlobalDevice = 0x801E6FC4; export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGlobalDevice, pVdGlobalDevice); - xe::store_and_swap(memory->TranslateVirtual(pVdGlobalDevice), 0); + xe::store_and_swap(memory->TranslateVirtual(pVdGlobalDevice), + baseAllocation); // VdGlobalXamDevice (4b) // Pointer to the XAM D3D device, which we don't have. - uint32_t pVdGlobalXamDevice = - memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical); + const uint32_t pVdGlobalXamDevice = 0x801E6FC8; export_resolver->SetVariableMapping( "xboxkrnl.exe", ordinals::VdGlobalXamDevice, pVdGlobalXamDevice); xe::store_and_swap(memory->TranslateVirtual(pVdGlobalXamDevice), 0); // VdGpuClockInMHz (4b) // GPU clock. Xenos is 500MHz. Hope nothing is relying on this timing... - uint32_t pVdGpuClockInMHz = - memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical); + const uint32_t pVdGpuClockInMHz = 0x801D0E94; export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGpuClockInMHz, pVdGpuClockInMHz); xe::store_and_swap(memory->TranslateVirtual(pVdGpuClockInMHz), 500); // VdHSIOCalibrationLock (28b) // CriticalSection. - uint32_t pVdHSIOCalibrationLock = - memory->SystemHeapAlloc(28, 32, kSystemHeapPhysical); + const uint32_t pVdHSIOCalibrationLock = 0x801D1210; export_resolver->SetVariableMapping( "xboxkrnl.exe", ordinals::VdHSIOCalibrationLock, pVdHSIOCalibrationLock); auto hsio_lock = diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index 22ba66aee..a3485f2c1 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -284,10 +284,16 @@ bool Memory::Initialize() { heaps_.vA0000000.Alloc(0x340000, 64 * 1024, kMemoryAllocationReserve, kMemoryProtectNoAccess, true, &unk_phys_alloc); - uint32_t unknown_xex_range; // Probably hypervisor? + // Allocate memory hypervisor and kernel would use + uint32_t hypervisor_range; heaps_.v80000000.Alloc(0x40000, 4 * 1024, kMemoryAllocationCommit, kMemoryProtectRead | kMemoryProtectWrite, false, - &unknown_xex_range); + &hypervisor_range); + + uint32_t kernel_range; + heaps_.v80000000.Alloc(0x1C0000, 4 * 1024, kMemoryAllocationCommit, + kMemoryProtectRead | kMemoryProtectWrite, false, + &kernel_range); // Value taken from 544307D5. Title explicitly access this address and this is // a value underneath it (It's constant between multiple runs)