IOS LLE: optional Broadway hardware window after a WiiConnect24 shutdown reply (StarletOS phase 11 J1)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
3d12571127
commit
ba86a7486c
6 files changed
+114
-4
No files matched your search
@@ -10,6 +10,8 @@ Source/Core/Core/Config/MainSettings.h -text
|
|||||||
Source/Core/Core/ConfigManager.cpp -text
|
Source/Core/Core/ConfigManager.cpp -text
|
||||||
Source/Core/Core/HW/HW.cpp -text
|
Source/Core/Core/HW/HW.cpp -text
|
||||||
Source/Core/Core/HW/WII_IPC.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.cpp -text
|
||||||
Source/Core/Core/IOS/Starlet/ARMCore.h -text
|
Source/Core/Core/IOS/Starlet/ARMCore.h -text
|
||||||
Source/Core/Core/IOS/Starlet/ARMJitX64.cpp -text
|
Source/Core/Core/IOS/Starlet/ARMJitX64.cpp -text
|
||||||
|
|||||||
@@ -202,8 +202,24 @@ std::string TraceFilesystemPaths(Memory::MemoryManager& memory, u32 command, con
|
|||||||
return {};
|
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)
|
void TraceIPCRequest(Core::System& system, u32 address)
|
||||||
{
|
{
|
||||||
|
if (StarletOSHardwareTraceRequested())
|
||||||
|
CloseHardwareWindow("at the next request");
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
if (memory.GetPointerForRange(address, 0x20) == nullptr)
|
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}{}",
|
NOTICE_LOG_FMT(WII_IPC, "IPCTRACE RQ {:08x} C {} FD {} A {:08x} {:08x} {:08x} {:08x} {:08x}{}",
|
||||||
address, command, static_cast<s32>(fd), arg[0], arg[1], arg[2], arg[3], arg[4],
|
address, command, static_cast<s32>(fd), arg[0], arg[1], arg[2], arg[3], arg[4],
|
||||||
path);
|
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)
|
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),
|
NOTICE_LOG_FMT(WII_IPC, "IPCTRACE RP {:08x} C {} RC {}", address, memory.Read_U32(address + 8),
|
||||||
static_cast<s32>(memory.Read_U32(address + 4)));
|
static_cast<s32>(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
|
} // 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)
|
void WiiIPC::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
{
|
{
|
||||||
// Both IPC message registers are general-purpose read/write registers on
|
// Both IPC message registers are general-purpose read/write registers on
|
||||||
|
|||||||
@@ -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
|
class WiiIPC
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
#include "Core/HW/WII_IPC.h"
|
#include "Core/HW/WII_IPC.h"
|
||||||
#include "Core/IOS/Starlet/Starlet.h"
|
#include "Core/IOS/Starlet/Starlet.h"
|
||||||
#include "Core/IOS/Starlet/StarletMemory.h"
|
#include "Core/IOS/Starlet/StarletMemory.h"
|
||||||
|
#include "Core/HW/WII_IPC.h"
|
||||||
#include "Core/PowerPC/GDBStub.h"
|
#include "Core/PowerPC/GDBStub.h"
|
||||||
#include "Core/PowerPC/JitInterface.h"
|
#include "Core/PowerPC/JitInterface.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
@@ -270,8 +271,12 @@ T MMU::ReadFromHardware(u32 em_address)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return static_cast<T>(
|
const auto value =
|
||||||
m_memory.GetMMIOMapping()->Read<std::make_unsigned_t<T>>(m_system, em_address));
|
m_memory.GetMMIOMapping()->Read<std::make_unsigned_t<T>>(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<T>(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,6 +464,10 @@ void MMU::WriteToHardware(u32 em_address, const u32 data, const u32 size)
|
|||||||
return;
|
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)
|
switch (size)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
@@ -1485,6 +1494,10 @@ u32 MMU::IsOptimizableMMIOAccess(u32 address, u32 access_size) const
|
|||||||
if (m_power_pc.GetMemChecks().HasAny())
|
if (m_power_pc.GetMemChecks().HasAny())
|
||||||
return 0;
|
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)
|
if (!m_ppc_state.msr.DR)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
@@ -48,8 +48,13 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "Source/Core/Core/HW/WII_IPC.cpp",
|
"path": "Source/Core/Core/HW/WII_IPC.cpp",
|
||||||
"sha256": "c3faf948533d494243caa229730dac8a8161144647aad22d219f1b4c9f727030",
|
"sha256": "a2244dabdd1c9334a63c8ddd3f09ce3abe22e86198b1fd45b092cd238379a6c0",
|
||||||
"bytes": 23116
|
"bytes": 24790
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "Source/Core/Core/HW/WII_IPC.h",
|
||||||
|
"sha256": "886a0ca83ff839013a170efd5d3bb9e32c2a8ad327ca5a78985da27b58ae7cf9",
|
||||||
|
"bytes": 4770
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "Source/Core/Core/IOS/Starlet/ARMCore.cpp",
|
"path": "Source/Core/Core/IOS/Starlet/ARMCore.cpp",
|
||||||
@@ -101,6 +106,11 @@
|
|||||||
"sha256": "6d58d81d94b32a647dbc3babea3e943aee307c02d9f1fb8904d8ebaccd22cf05",
|
"sha256": "6d58d81d94b32a647dbc3babea3e943aee307c02d9f1fb8904d8ebaccd22cf05",
|
||||||
"bytes": 16542
|
"bytes": 16542
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "Source/Core/Core/PowerPC/MMU.cpp",
|
||||||
|
"sha256": "25c302b6cf1365abca38f4bcf88666dc25c5799a93534da1f55ae0a0c18dbb68",
|
||||||
|
"bytes": 85125
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "Source/Core/DolphinNoGUI/PlatformHeadless.cpp",
|
"path": "Source/Core/DolphinNoGUI/PlatformHeadless.cpp",
|
||||||
"sha256": "1390cff0a139f0b0a90559e0fda855446d279190827a6c5079718421924f4041",
|
"sha256": "1390cff0a139f0b0a90559e0fda855446d279190827a6c5079718421924f4041",
|
||||||
@@ -198,6 +208,15 @@
|
|||||||
"Source/Core/Core/IOS/Starlet/ARMCore.h",
|
"Source/Core/Core/IOS/Starlet/ARMCore.h",
|
||||||
"Source/Core/Core/IOS/Starlet/ARMJitX64.cpp"
|
"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"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -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
|
- The companion's images use, besides these (16 `smlabb`, 4 `smulbb`), only
|
||||||
`blx`, `clz`, `ldrd`, `strd` among the ARMv5TE additions; those were
|
`blx`, `clz`, `ldrd`, `strd` among the ARMv5TE additions; those were
|
||||||
already handled.
|
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.
|
||||||
Reference in new issue
Block a user