[Kernel] Use single page to store all Vd pointers and structs

This is to prevent some titles from reaching out of memory crash
This commit is contained in:
Gliniak
2026-06-17 22:56:54 +02:00
committed by Radosław Gliński
parent e7d0e45095
commit b268292046
2 changed files with 18 additions and 11 deletions

View File

@@ -554,35 +554,36 @@ void RegisterVideoExports(xe::cpu::ExportResolver* export_resolver,
KernelState* kernel_state) { KernelState* kernel_state) {
auto memory = kernel_state->memory(); 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) // VdGlobalDevice (4b)
// Pointer to a global D3D device. Games only seem to set this, so we don't // 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. // have to do anything. We may want to read it back later, though.
uint32_t pVdGlobalDevice = const uint32_t pVdGlobalDevice = 0x801E6FC4;
memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGlobalDevice, export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGlobalDevice,
pVdGlobalDevice); pVdGlobalDevice);
xe::store_and_swap<uint32_t>(memory->TranslateVirtual(pVdGlobalDevice), 0); xe::store_and_swap<uint32_t>(memory->TranslateVirtual(pVdGlobalDevice),
baseAllocation);
// VdGlobalXamDevice (4b) // VdGlobalXamDevice (4b)
// Pointer to the XAM D3D device, which we don't have. // Pointer to the XAM D3D device, which we don't have.
uint32_t pVdGlobalXamDevice = const uint32_t pVdGlobalXamDevice = 0x801E6FC8;
memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping( export_resolver->SetVariableMapping(
"xboxkrnl.exe", ordinals::VdGlobalXamDevice, pVdGlobalXamDevice); "xboxkrnl.exe", ordinals::VdGlobalXamDevice, pVdGlobalXamDevice);
xe::store_and_swap<uint32_t>(memory->TranslateVirtual(pVdGlobalXamDevice), 0); xe::store_and_swap<uint32_t>(memory->TranslateVirtual(pVdGlobalXamDevice), 0);
// VdGpuClockInMHz (4b) // VdGpuClockInMHz (4b)
// GPU clock. Xenos is 500MHz. Hope nothing is relying on this timing... // GPU clock. Xenos is 500MHz. Hope nothing is relying on this timing...
uint32_t pVdGpuClockInMHz = const uint32_t pVdGpuClockInMHz = 0x801D0E94;
memory->SystemHeapAlloc(4, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGpuClockInMHz, export_resolver->SetVariableMapping("xboxkrnl.exe", ordinals::VdGpuClockInMHz,
pVdGpuClockInMHz); pVdGpuClockInMHz);
xe::store_and_swap<uint32_t>(memory->TranslateVirtual(pVdGpuClockInMHz), 500); xe::store_and_swap<uint32_t>(memory->TranslateVirtual(pVdGpuClockInMHz), 500);
// VdHSIOCalibrationLock (28b) // VdHSIOCalibrationLock (28b)
// CriticalSection. // CriticalSection.
uint32_t pVdHSIOCalibrationLock = const uint32_t pVdHSIOCalibrationLock = 0x801D1210;
memory->SystemHeapAlloc(28, 32, kSystemHeapPhysical);
export_resolver->SetVariableMapping( export_resolver->SetVariableMapping(
"xboxkrnl.exe", ordinals::VdHSIOCalibrationLock, pVdHSIOCalibrationLock); "xboxkrnl.exe", ordinals::VdHSIOCalibrationLock, pVdHSIOCalibrationLock);
auto hsio_lock = auto hsio_lock =

View File

@@ -284,10 +284,16 @@ bool Memory::Initialize() {
heaps_.vA0000000.Alloc(0x340000, 64 * 1024, kMemoryAllocationReserve, heaps_.vA0000000.Alloc(0x340000, 64 * 1024, kMemoryAllocationReserve,
kMemoryProtectNoAccess, true, &unk_phys_alloc); 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, heaps_.v80000000.Alloc(0x40000, 4 * 1024, kMemoryAllocationCommit,
kMemoryProtectRead | kMemoryProtectWrite, false, 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 // Value taken from 544307D5. Title explicitly access this address and this is
// a value underneath it (It's constant between multiple runs) // a value underneath it (It's constant between multiple runs)