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
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in new issue
Block a user