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:
Yaya48andClaude Opus 5.5 committed 2026-10-06 22:36:20 +02:00
1 parent 3d12571127
commit ba86a7486c
6 files changed
+114 -4

No files matched your search

+52
View File
@@ -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<s32>(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<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
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
+8
View File
@@ -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:
+15 -2
View File
@@ -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<T>(
m_memory.GetMMIOMapping()->Read<std::make_unsigned_t<T>>(m_system, em_address));
const auto value =
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;
}
// 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;