From efa0a8bb395a16d2457b8d07d8d50951ad12a873 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Sat, 1 Nov 2025 00:13:08 +0100 Subject: [PATCH] [XBDM] Added sketchy implementation of DmPMCGetCounterName and DmPMCInstallAndStart --- src/xenia/kernel/kernel_state.cc | 44 ++++++++++++++++++++++++++++++ src/xenia/kernel/kernel_state.h | 3 ++ src/xenia/kernel/xbdm/xbdm_misc.cc | 17 ++++++++++++ src/xenia/kernel/xbdm/xbdm_misc.h | 1 + 4 files changed, 65 insertions(+) diff --git a/src/xenia/kernel/kernel_state.cc b/src/xenia/kernel/kernel_state.cc index 03b89580f..b073df207 100644 --- a/src/xenia/kernel/kernel_state.cc +++ b/src/xenia/kernel/kernel_state.cc @@ -1523,5 +1523,49 @@ void KernelState::InitializeKernelGuestGlobals() { offsetof32(KernelGuestGlobals, IoDeviceObjectType)}}; xboxkrnl::xeKeSetEvent(&block->UsbdBootEnumerationDoneEvent, 1, 0); } + +void KernelState::InitializeXbdmCpuCounters() { + constexpr uint32_t counters_base_address = 0x91F00000; + + // These are not confirmed and there seems to be multiple types of counters, + // but no idea how they're switched. For now this seems to be good enough. + constexpr std::array xbdm_counters = { + "load-hit-stores (S)", + "instructions committed", + "i-cache miss cycles", + "core 0 L2 data misses", + "core 0 L2 data misses", + "core 0 L2 data misses", + "core 0 L2 data misses", + "core 0 L2 data misses", + "core 0 L2 data misses", + "core 0 L2 data misses", + "core 0 L2 data misses", + "core 0 L2 data misses", + "core 0 L2 data misses", + "core 0 L2 data misses", + "core 0 L2 data misses", + "core 0 L2 data misses", + "Bad counter number - must be 0-15."}; + + auto xbdm_range = memory_->LookupHeap(counters_base_address); + if (!xbdm_range->AllocFixed( + counters_base_address, 0x1000, 0, + kMemoryAllocationCommit | kMemoryAllocationReserve, + kMemoryProtectRead | kMemoryProtectWrite)) { + return; + } + + uint32_t address = counters_base_address; + + for (size_t i = 0; i < xbdm_counters.size(); i++) { + xbdm_counters_address[i] = address; + const std::string entry = xbdm_counters[i]; + std::memcpy(memory_->TranslateVirtual(address), entry.c_str(), + entry.size()); + address += static_cast(entry.size()) + 1; + } +} + } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/kernel_state.h b/src/xenia/kernel/kernel_state.h index b6ee873ac..8095c3fa7 100644 --- a/src/xenia/kernel/kernel_state.h +++ b/src/xenia/kernel/kernel_state.h @@ -323,6 +323,9 @@ class KernelState { uint32_t interrupt_callback_data, uint32_t source, uint32_t cpu); + void InitializeXbdmCpuCounters(); + std::array xbdm_counters_address = {}; + private: void LoadKernelModule(object_ref kernel_module); void InitializeProcess(X_KPROCESS* process, uint32_t type, char unk_18, diff --git a/src/xenia/kernel/xbdm/xbdm_misc.cc b/src/xenia/kernel/xbdm/xbdm_misc.cc index 91dba8550..58c837896 100644 --- a/src/xenia/kernel/xbdm/xbdm_misc.cc +++ b/src/xenia/kernel/xbdm/xbdm_misc.cc @@ -468,6 +468,23 @@ DECLARE_XBDM_EXPORT1(DmSetDumpMode, kDebug, kStub); dword_result_t DmIsFastCAPEnabled_entry() { return XBDM_UNSUCCESSFUL; } DECLARE_XBDM_EXPORT1(DmIsFastCAPEnabled, kDebug, kStub); +dword_result_t DmPMCInstallAndStart_entry(dword_t group_setup) { + // Not initialized, so let's initialize it + if (kernel_state()->xbdm_counters_address[0] == 0) { + kernel_state()->InitializeXbdmCpuCounters(); + } + return XBDM_SUCCESSFUL; +} +DECLARE_XBDM_EXPORT1(DmPMCInstallAndStart, kDebug, kSketchy); + +dword_result_t DmPMCGetCounterName_entry(dword_t counter_id) { + // This returns pointer to already preallocated string with counter names. + // We should make allocation somewhere during xbdm initialization once + return kernel_state()->xbdm_counters_address + [counter_id < 0x10 ? static_cast(counter_id) : 0x10]; +} +DECLARE_XBDM_EXPORT1(DmPMCGetCounterName, kDebug, kSketchy); + void __CAP_Start_Profiling_entry(dword_t a1, dword_t a2) {} DECLARE_XBDM_EXPORT1(__CAP_Start_Profiling, kDebug, kStub); diff --git a/src/xenia/kernel/xbdm/xbdm_misc.h b/src/xenia/kernel/xbdm/xbdm_misc.h index eaa639f79..2abca5de7 100644 --- a/src/xenia/kernel/xbdm/xbdm_misc.h +++ b/src/xenia/kernel/xbdm/xbdm_misc.h @@ -26,6 +26,7 @@ static constexpr char DmXboxName[] = "Xbox360Name"; #define XBDM_UNSUCCESSFUL 0x82DA0000 #define XBDM_FASTCAPENABLED 0x82DA0007 #define XBDM_ALREADYEXISTS 0x82DA0010 +#define XBDM_UNKNOWNFAILURE 0x82DA002C #define XBDM_ENDOFLIST 0x82DA0104 #define XBDM_BUFFER_TOO_SMALL 0x82DA0105