From ba86a7486c0ac702e6eac70a70e0c2ac46bc8a24 Mon Sep 17 00:00:00 2001 From: Yaya48 Date: Tue, 6 Oct 2026 22:36:20 +0200 Subject: [PATCH] IOS LLE: optional Broadway hardware window after a WiiConnect24 shutdown reply (StarletOS phase 11 J1) Co-Authored-By: Claude Opus 5.5 --- .gitattributes | 2 ++ Source/Core/Core/HW/WII_IPC.cpp | 52 ++++++++++++++++++++++++++++++++ Source/Core/Core/HW/WII_IPC.h | 8 +++++ Source/Core/Core/PowerPC/MMU.cpp | 17 +++++++++-- docs/StarletOS_Checkpoint.json | 23 ++++++++++++-- docs/StarletOS_Handoff.md | 16 ++++++++++ 6 files changed, 114 insertions(+), 4 deletions(-) diff --git a/.gitattributes b/.gitattributes index 7f4521a7bf..818240dde5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10,6 +10,8 @@ Source/Core/Core/Config/MainSettings.h -text Source/Core/Core/ConfigManager.cpp -text Source/Core/Core/HW/HW.cpp -text Source/Core/Core/HW/WII_IPC.cpp -text +Source/Core/Core/HW/WII_IPC.h -text +Source/Core/Core/PowerPC/MMU.cpp -text Source/Core/Core/IOS/Starlet/ARMCore.cpp -text Source/Core/Core/IOS/Starlet/ARMCore.h -text Source/Core/Core/IOS/Starlet/ARMJitX64.cpp -text diff --git a/Source/Core/Core/HW/WII_IPC.cpp b/Source/Core/Core/HW/WII_IPC.cpp index 3c1d5c7fc5..4ddf3409f2 100644 --- a/Source/Core/Core/HW/WII_IPC.cpp +++ b/Source/Core/Core/HW/WII_IPC.cpp @@ -202,8 +202,24 @@ std::string TraceFilesystemPaths(Memory::MemoryManager& memory, u32 command, con return {}; } +// Phase 11 J1: the shutdown request whose reply opens the hardware window, and the window's +// access count. +u32 s_hardware_trigger = 0; +u32 s_hardware_accesses = 0; +constexpr u32 HARDWARE_WINDOW_LIMIT = 20000; + +void CloseHardwareWindow(const char* why) +{ + if (!g_starletos_hardware_window) + return; + g_starletos_hardware_window = false; + NOTICE_LOG_FMT(WII_IPC, "HWTRACE close {} after {} accesses", why, s_hardware_accesses); +} + void TraceIPCRequest(Core::System& system, u32 address) { + if (StarletOSHardwareTraceRequested()) + CloseHardwareWindow("at the next request"); auto& memory = system.GetMemory(); if (memory.GetPointerForRange(address, 0x20) == nullptr) { @@ -223,6 +239,11 @@ void TraceIPCRequest(Core::System& system, u32 address) NOTICE_LOG_FMT(WII_IPC, "IPCTRACE RQ {:08x} C {} FD {} A {:08x} {:08x} {:08x} {:08x} {:08x}{}", address, command, static_cast(fd), arg[0], arg[1], arg[2], arg[3], arg[4], path); + if (StarletOSHardwareTraceRequested() && command == 6 && arg[0] == 0x28 && arg[2] == 0x20 && + arg[4] == 0x20) + { + s_hardware_trigger = address; + } } void TraceIPCReply(Core::System& system, u32 address) @@ -235,9 +256,40 @@ void TraceIPCReply(Core::System& system, u32 address) } NOTICE_LOG_FMT(WII_IPC, "IPCTRACE RP {:08x} C {} RC {}", address, memory.Read_U32(address + 8), static_cast(memory.Read_U32(address + 4))); + if (StarletOSHardwareTraceRequested() && s_hardware_trigger != 0 && + address == s_hardware_trigger) + { + s_hardware_trigger = 0; + s_hardware_accesses = 0; + g_starletos_hardware_window = true; + NOTICE_LOG_FMT(WII_IPC, "HWTRACE open at the reply {:08x}", address); + } } } // namespace +bool g_starletos_hardware_window = false; + +bool StarletOSHardwareTraceRequested() +{ + static const bool requested = [] { + const char* value = std::getenv("DOLPHIN_HW_WINDOW"); + return IPCTraceEnabled() && value != nullptr && value[0] == '1'; + }(); + return requested; +} + +void TraceStarletOSHardwareAccess(Core::System& system, bool write, u32 address, u32 size, + u64 value) +{ + if (++s_hardware_accesses > HARDWARE_WINDOW_LIMIT) + { + CloseHardwareWindow("at the access limit"); + return; + } + NOTICE_LOG_FMT(WII_IPC, "HWTRACE {} {:08x}/{} {:0{}x} PC {:08x}", write ? 'W' : 'R', address, + size, value, size * 2, system.GetPPCState().pc); +} + void WiiIPC::RegisterMMIO(MMIO::Mapping* mmio, u32 base) { // Both IPC message registers are general-purpose read/write registers on diff --git a/Source/Core/Core/HW/WII_IPC.h b/Source/Core/Core/HW/WII_IPC.h index d3ff168560..d02ef89bd7 100644 --- a/Source/Core/Core/HW/WII_IPC.h +++ b/Source/Core/Core/HW/WII_IPC.h @@ -123,6 +123,14 @@ struct CtrlRegister } }; +// StarletOS phase 11 (J1), emulator only: with DOLPHIN_IPC_TRACE=1 and DOLPHIN_HW_WINDOW=1, +// Broadway's hardware register accesses (MMIO) are logged from the reply to a WiiConnect24 +// shutdown request (IOCTL 0x28, 32-byte input and output) until Broadway's next IPC request. +bool StarletOSHardwareTraceRequested(); +extern bool g_starletos_hardware_window; +void TraceStarletOSHardwareAccess(Core::System& system, bool write, u32 address, u32 size, + u64 value); + class WiiIPC { public: diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp index 73a545694c..73c7fa788c 100644 --- a/Source/Core/Core/PowerPC/MMU.cpp +++ b/Source/Core/Core/PowerPC/MMU.cpp @@ -54,6 +54,7 @@ #include "Core/HW/WII_IPC.h" #include "Core/IOS/Starlet/Starlet.h" #include "Core/IOS/Starlet/StarletMemory.h" +#include "Core/HW/WII_IPC.h" #include "Core/PowerPC/GDBStub.h" #include "Core/PowerPC/JitInterface.h" #include "Core/PowerPC/PowerPC.h" @@ -270,8 +271,12 @@ T MMU::ReadFromHardware(u32 em_address) } else { - return static_cast( - m_memory.GetMMIOMapping()->Read>(m_system, em_address)); + const auto value = + m_memory.GetMMIOMapping()->Read>(m_system, em_address); + // StarletOS phase 11 (J1): Broadway's hardware reads in the IPC trace's window. + if (IOS::g_starletos_hardware_window) [[unlikely]] + IOS::TraceStarletOSHardwareAccess(m_system, false, em_address, sizeof(T), value); + return static_cast(value); } } @@ -459,6 +464,10 @@ void MMU::WriteToHardware(u32 em_address, const u32 data, const u32 size) return; } + // StarletOS phase 11 (J1): Broadway's hardware writes in the IPC trace's window. + if (IOS::g_starletos_hardware_window) [[unlikely]] + IOS::TraceStarletOSHardwareAccess(m_system, true, em_address, size, data); + switch (size) { case 1: @@ -1485,6 +1494,10 @@ u32 MMU::IsOptimizableMMIOAccess(u32 address, u32 access_size) const if (m_power_pc.GetMemChecks().HasAny()) return 0; + // StarletOS phase 11 (J1): no inlined MMIO reads while the hardware window may open. + if (IOS::StarletOSHardwareTraceRequested()) + return 0; + if (!m_ppc_state.msr.DR) return 0; diff --git a/docs/StarletOS_Checkpoint.json b/docs/StarletOS_Checkpoint.json index 7f15e5f432..4273a4afd9 100644 --- a/docs/StarletOS_Checkpoint.json +++ b/docs/StarletOS_Checkpoint.json @@ -48,8 +48,13 @@ }, { "path": "Source/Core/Core/HW/WII_IPC.cpp", - "sha256": "c3faf948533d494243caa229730dac8a8161144647aad22d219f1b4c9f727030", - "bytes": 23116 + "sha256": "a2244dabdd1c9334a63c8ddd3f09ce3abe22e86198b1fd45b092cd238379a6c0", + "bytes": 24790 + }, + { + "path": "Source/Core/Core/HW/WII_IPC.h", + "sha256": "886a0ca83ff839013a170efd5d3bb9e32c2a8ad327ca5a78985da27b58ae7cf9", + "bytes": 4770 }, { "path": "Source/Core/Core/IOS/Starlet/ARMCore.cpp", @@ -101,6 +106,11 @@ "sha256": "6d58d81d94b32a647dbc3babea3e943aee307c02d9f1fb8904d8ebaccd22cf05", "bytes": 16542 }, + { + "path": "Source/Core/Core/PowerPC/MMU.cpp", + "sha256": "25c302b6cf1365abca38f4bcf88666dc25c5799a93534da1f55ae0a0c18dbb68", + "bytes": 85125 + }, { "path": "Source/Core/DolphinNoGUI/PlatformHeadless.cpp", "sha256": "1390cff0a139f0b0a90559e0fda855446d279190827a6c5079718421924f4041", @@ -198,6 +208,15 @@ "Source/Core/Core/IOS/Starlet/ARMCore.h", "Source/Core/Core/IOS/Starlet/ARMJitX64.cpp" ] + }, + { + "recordedAt": "2026-10-06", + "purpose": "StarletOS Phase 11 proposal J1: with DOLPHIN_IPC_TRACE=1 and DOLPHIN_HW_WINDOW=1, Broadway hardware register accesses (MMU MMIO reads and writes, PC) are logged as HWTRACE from the reply to an IOCTL 0x28 32/32 request until the next IPC request; no inlined MMIO reads while requested", + "files": [ + "Source/Core/Core/HW/WII_IPC.cpp", + "Source/Core/Core/HW/WII_IPC.h", + "Source/Core/Core/PowerPC/MMU.cpp" + ] } ] } diff --git a/docs/StarletOS_Handoff.md b/docs/StarletOS_Handoff.md index 94c49684fb..63cb688d20 100644 --- a/docs/StarletOS_Handoff.md +++ b/docs/StarletOS_Handoff.md @@ -233,3 +233,19 @@ creation -106 ("system files corrupted" in the System Menu), in the fork only. - The companion's images use, besides these (16 `smlabb`, 4 `smulbb`), only `blx`, `clz`, `ldrd`, `strd` among the ARMv5TE additions; those were already handled. + +## Broadway hardware window after the WiiConnect24 shutdown — 2026-10-06 + +Companion proposal J1 (approved). With the DSP fix, the companion's System +Menu under Revolution reaches ES LAUNCH in the fork, while on the console it +stops right after the WiiConnect24 shutdown reply (IOCTL 0x28), with no IPC +until then. This lists what Broadway touches in that gap. + +- `DOLPHIN_HW_WINDOW=1` (with `DOLPHIN_IPC_TRACE=1`): the IPC trace remembers + an IOCTL 0x28 with 32-byte input and output; its reply opens a window, and + `MMU::ReadFromHardware`/`WriteToHardware` log each Broadway MMIO access as + `HWTRACE R|W address/size value PC` until Broadway's next IPC request (or + 20000 accesses). `IsOptimizableMMIOAccess` returns 0 while requested, so the + JIT inlines no MMIO read. Nothing changes without the variables. +- `MMU.cpp` and `WII_IPC.h` are now exact integration files (28). +- 96 Starlet tests passed; both builds rebuilt.