[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) {
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<uint32_t>(memory->TranslateVirtual(pVdGlobalDevice), 0);
xe::store_and_swap<uint32_t>(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<uint32_t>(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<uint32_t>(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 =

View File

@@ -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)