diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index fe5aba21de..8f315308c7 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -27,7 +27,7 @@ #include "Core/HW/Memmap.h" #include "Core/HW/VideoInterface.h" #include "Core/Host.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/PatchEngine.h" #include "Core/PowerPC/PPCAnalyst.h" #include "Core/PowerPC/PPCSymbolDB.h" diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index d6968294a4..a42da732b5 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -23,7 +23,7 @@ #include "Core/HW/Memmap.h" #include "Core/IOS/ES/ES.h" #include "Core/IOS/ES/Formats.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/PatchEngine.h" #include "Core/PowerPC/PowerPC.h" @@ -289,7 +289,7 @@ bool CBoot::SetupWiiMemory(u64 ios_title_id) Memory::Write_U16(0x8201, 0x000030e6); // Dev console / debug capable Memory::Write_U32(0x00000000, 0x000030f0); // Apploader - if (!IOS::HLE::Reload(ios_title_id)) + if (!IOS::HLE::GetIOS()->BootIOS(ios_title_id)) { return false; } diff --git a/Source/Core/Core/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Boot/Boot_WiiWAD.cpp index 0750af9a8f..adb6e5bdad 100644 --- a/Source/Core/Core/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Boot/Boot_WiiWAD.cpp @@ -16,7 +16,7 @@ #include "Core/Boot/Boot.h" #include "Core/IOS/ES/ES.h" #include "Core/IOS/FS/FileIO.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/PatchEngine.h" #include "DiscIO/NANDContentLoader.h" @@ -88,7 +88,7 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename) return false; IOS::HLE::Device::ES::LoadWAD(_pFilename); - if (!IOS::HLE::BootstrapPPC(ContentLoader)) + if (!IOS::HLE::GetIOS()->BootstrapPPC(ContentLoader)) return false; return true; diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index 82ab438e87..a68a87d731 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -147,7 +147,8 @@ set(SRCS HW/WiiSaveCrypted.cpp IOS/Device.cpp IOS/DeviceStub.cpp - IOS/IPC.cpp + IOS/IOS.cpp + IOS/MemoryValues.cpp IOS/MIOS.cpp IOS/DI/DI.cpp IOS/ES/ES.cpp diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index d886c3bbdd..18622549ba 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -50,7 +50,7 @@ #include "Core/HW/SystemTimers.h" #include "Core/HW/VideoInterface.h" #include "Core/HW/Wiimote.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/Movie.h" #include "Core/NetPlayClient.h" #include "Core/NetPlayProto.h" @@ -952,7 +952,9 @@ void UpdateWantDeterminism(bool initial) bool was_unpaused = Core::PauseAndLock(true); s_wants_determinism = new_want_determinism; - IOS::HLE::UpdateWantDeterminism(new_want_determinism); + const auto ios = IOS::HLE::GetIOS(); + if (ios) + ios->UpdateWantDeterminism(new_want_determinism); Fifo::UpdateWantDeterminism(new_want_determinism); // We need to clear the cache because some parts of the JIT depend on want_determinism, e.g. use // of FMA. diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj index 50f452c4a3..67101bfe4e 100644 --- a/Source/Core/Core/Core.vcxproj +++ b/Source/Core/Core/Core.vcxproj @@ -174,7 +174,8 @@ - + + @@ -431,7 +432,8 @@ - + + diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters index e61dae56fa..6d0b9c9a4a 100644 --- a/Source/Core/Core/Core.vcxproj.filters +++ b/Source/Core/Core/Core.vcxproj.filters @@ -790,7 +790,10 @@ IOS\Network - + + IOS + + IOS @@ -1504,7 +1507,10 @@ IOS - + + IOS + + IOS diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp index 49c7926c07..404b855f16 100644 --- a/Source/Core/Core/HW/DVD/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp @@ -28,7 +28,7 @@ #include "Core/HW/StreamADPCM.h" #include "Core/HW/SystemTimers.h" #include "Core/IOS/DI/DI.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/Movie.h" #include "DiscIO/Enums.h" @@ -1136,7 +1136,7 @@ void FinishExecutingCommand(ReplyType reply_type, DIInterruptType interrupt_type case ReplyType::IOS: { - auto di = IOS::HLE::GetDeviceByName("/dev/di"); + auto di = IOS::HLE::GetIOS()->GetDeviceByName("/dev/di"); if (di) std::static_pointer_cast(di)->FinishIOCtl(interrupt_type); break; diff --git a/Source/Core/Core/HW/HW.cpp b/Source/Core/Core/HW/HW.cpp index 305755872a..b9017b9f21 100644 --- a/Source/Core/Core/HW/HW.cpp +++ b/Source/Core/Core/HW/HW.cpp @@ -21,7 +21,7 @@ #include "Core/HW/SystemTimers.h" #include "Core/HW/VideoInterface.h" #include "Core/HW/WII_IPC.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/Movie.h" #include "Core/State.h" #include "Core/WiiRoot.h" @@ -102,7 +102,7 @@ void DoState(PointerWrap& p) { IOS::DoState(p); p.DoMarker("IOS"); - IOS::HLE::DoState(p); + IOS::HLE::GetIOS()->DoState(p); p.DoMarker("IOS::HLE"); } diff --git a/Source/Core/Core/HW/ProcessorInterface.cpp b/Source/Core/Core/HW/ProcessorInterface.cpp index 2f5ccc9bb5..b88bf05a49 100644 --- a/Source/Core/Core/HW/ProcessorInterface.cpp +++ b/Source/Core/Core/HW/ProcessorInterface.cpp @@ -11,7 +11,7 @@ #include "Core/HW/MMIO.h" #include "Core/HW/ProcessorInterface.h" #include "Core/HW/SystemTimers.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/STM/STM.h" #include "Core/PowerPC/PowerPC.h" @@ -210,22 +210,24 @@ static void ToggleResetButtonCallback(u64 userdata, s64 cyclesLate) static void IOSNotifyResetButtonCallback(u64 userdata, s64 cyclesLate) { - if (SConfig::GetInstance().bWii) - { - auto stm = IOS::HLE::GetDeviceByName("/dev/stm/eventhook"); - if (stm) - std::static_pointer_cast(stm)->ResetButton(); - } + const auto ios = IOS::HLE::GetIOS(); + if (!ios) + return; + + auto stm = ios->GetDeviceByName("/dev/stm/eventhook"); + if (stm) + std::static_pointer_cast(stm)->ResetButton(); } static void IOSNotifyPowerButtonCallback(u64 userdata, s64 cyclesLate) { - if (SConfig::GetInstance().bWii) - { - auto stm = IOS::HLE::GetDeviceByName("/dev/stm/eventhook"); - if (stm) - std::static_pointer_cast(stm)->PowerButton(); - } + const auto ios = IOS::HLE::GetIOS(); + if (!ios) + return; + + auto stm = ios->GetDeviceByName("/dev/stm/eventhook"); + if (stm) + std::static_pointer_cast(stm)->PowerButton(); } void ResetButton_Tap() diff --git a/Source/Core/Core/HW/SystemTimers.cpp b/Source/Core/Core/HW/SystemTimers.cpp index 874b6a3efd..935a65efad 100644 --- a/Source/Core/Core/HW/SystemTimers.cpp +++ b/Source/Core/Core/HW/SystemTimers.cpp @@ -57,7 +57,7 @@ IPC_HLE_PERIOD: For the Wii Remote this is the call schedule: #include "Core/HW/DSP.h" #include "Core/HW/EXI/EXI_DeviceIPL.h" #include "Core/HW/VideoInterface.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/PatchEngine.h" #include "Core/PowerPC/PowerPC.h" #include "VideoCommon/Fifo.h" @@ -112,7 +112,7 @@ static void IPC_HLE_UpdateCallback(u64 userdata, s64 cyclesLate) { if (SConfig::GetInstance().bWii) { - IOS::HLE::UpdateDevices(); + IOS::HLE::GetIOS()->UpdateDevices(); CoreTiming::ScheduleEvent(s_ipc_hle_period - cyclesLate, et_IPC_HLE); } } diff --git a/Source/Core/Core/HW/WII_IPC.cpp b/Source/Core/Core/HW/WII_IPC.cpp index 0a2a8bb5c1..870b251bae 100644 --- a/Source/Core/Core/HW/WII_IPC.cpp +++ b/Source/Core/Core/HW/WII_IPC.cpp @@ -9,7 +9,7 @@ #include "Core/CoreTiming.h" #include "Core/HW/MMIO.h" #include "Core/HW/ProcessorInterface.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" // This is the intercommunication between ARM and PPC. Currently only PPC actually uses it, because // of the IOS HLE @@ -153,8 +153,8 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) MMIO::ComplexWrite([](u32, u32 val) { ctrl.ppc(val); if (ctrl.X1) - HLE::EnqueueRequest(ppc_msg); - HLE::Update(); + HLE::GetIOS()->EnqueueIPCRequest(ppc_msg); + HLE::GetIOS()->UpdateIPC(); CoreTiming::ScheduleEvent(0, updateInterrupts, 0); })); @@ -163,7 +163,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) mmio->Register(base | PPC_IRQFLAG, MMIO::InvalidRead(), MMIO::ComplexWrite([](u32, u32 val) { ppc_irq_flags &= ~val; - HLE::Update(); + HLE::GetIOS()->UpdateIPC(); CoreTiming::ScheduleEvent(0, updateInterrupts, 0); })); @@ -172,7 +172,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) ppc_irq_masks = val; if (ppc_irq_masks & INT_CAUSE_IPC_BROADWAY) // wtf? Reset(); - HLE::Update(); + HLE::GetIOS()->UpdateIPC(); CoreTiming::ScheduleEvent(0, updateInterrupts, 0); })); diff --git a/Source/Core/Core/IOS/DI/DI.cpp b/Source/Core/Core/IOS/DI/DI.cpp index 639038b565..593914bcc2 100644 --- a/Source/Core/Core/IOS/DI/DI.cpp +++ b/Source/Core/Core/IOS/DI/DI.cpp @@ -24,7 +24,7 @@ namespace HLE { namespace Device { -DI::DI(u32 device_id, const std::string& device_name) : Device(device_id, device_name) +DI::DI(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { } @@ -76,7 +76,7 @@ void DI::FinishIOCtl(DVDInterface::DIInterruptType interrupt_type) // This command has been executed, so it's removed from the queue u32 command_address = m_commands_to_execute.front(); m_commands_to_execute.pop_front(); - EnqueueReply(IOCtlRequest{command_address}, interrupt_type); + m_ios.EnqueueIPCReply(IOCtlRequest{command_address}, interrupt_type); // DVDInterface is now ready to execute another command, // so we start executing a command from the queue if there is one diff --git a/Source/Core/Core/IOS/DI/DI.h b/Source/Core/Core/IOS/DI/DI.h index 7c866f5494..d2d302da73 100644 --- a/Source/Core/Core/IOS/DI/DI.h +++ b/Source/Core/Core/IOS/DI/DI.h @@ -9,7 +9,7 @@ #include "Common/CommonTypes.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" class PointerWrap; @@ -27,7 +27,7 @@ namespace Device class DI : public Device { public: - DI(u32 device_id, const std::string& device_name); + DI(Kernel& ios, const std::string& device_name); void DoState(PointerWrap& p) override; diff --git a/Source/Core/Core/IOS/Device.cpp b/Source/Core/Core/IOS/Device.cpp index e407d54777..917da1b8de 100644 --- a/Source/Core/Core/IOS/Device.cpp +++ b/Source/Core/Core/IOS/Device.cpp @@ -10,7 +10,7 @@ #include "Core/HW/Memmap.h" #include "Core/HW/SystemTimers.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" namespace IOS { @@ -26,8 +26,12 @@ OpenRequest::OpenRequest(const u32 address_) : Request(address_) { path = Memory::GetString(Memory::Read_U32(address + 0xc)); flags = static_cast(Memory::Read_U32(address + 0x10)); - uid = GetUIDForPPC(); - gid = GetGIDForPPC(); + const Kernel* ios = GetIOS(); + if (ios) + { + uid = ios->GetUidForPPC(); + gid = ios->GetGidForPPC(); + } } ReadWriteRequest::ReadWriteRequest(const u32 address_) : Request(address_) @@ -129,8 +133,8 @@ void IOCtlVRequest::DumpUnknown(const std::string& description, LogTypes::LOG_TY namespace Device { -Device::Device(const u32 device_id, const std::string& device_name, const DeviceType type) - : m_name(device_name), m_device_id(device_id), m_device_type(type) +Device::Device(Kernel& ios, const std::string& device_name, const DeviceType type) + : m_ios(ios), m_name(device_name), m_device_type(type) { } @@ -143,7 +147,6 @@ void Device::DoState(PointerWrap& p) void Device::DoStateShared(PointerWrap& p) { p.Do(m_name); - p.Do(m_device_id); p.Do(m_device_type); p.Do(m_is_active); } diff --git a/Source/Core/Core/IOS/Device.h b/Source/Core/Core/IOS/Device.h index c8dd0ccf30..c3ca6812c0 100644 --- a/Source/Core/Core/IOS/Device.h +++ b/Source/Core/Core/IOS/Device.h @@ -11,7 +11,7 @@ #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" namespace IOS { @@ -172,7 +172,7 @@ public: OH0, // OH0 child devices which are created dynamically. }; - Device(u32 device_id, const std::string& device_name, DeviceType type = DeviceType::Static); + Device(Kernel& ios, const std::string& device_name, DeviceType type = DeviceType::Static); virtual ~Device() = default; // Release any resources which might interfere with savestating. @@ -181,7 +181,6 @@ public: void DoStateShared(PointerWrap& p); const std::string& GetDeviceName() const { return m_name; } - u32 GetDeviceID() const { return m_device_id; } // Replies to Open and Close requests are sent by the IPC request handler (HandleCommand), // not by the devices themselves. virtual ReturnCode Open(const OpenRequest& request); @@ -199,9 +198,10 @@ public: static IPCCommandResult GetNoReply(); protected: + Kernel& m_ios; + std::string m_name; // STATE_TO_SAVE - u32 m_device_id; DeviceType m_device_type; bool m_is_active = false; diff --git a/Source/Core/Core/IOS/DeviceStub.cpp b/Source/Core/Core/IOS/DeviceStub.cpp index 2502c84769..ea82d09cbc 100644 --- a/Source/Core/Core/IOS/DeviceStub.cpp +++ b/Source/Core/Core/IOS/DeviceStub.cpp @@ -11,10 +11,6 @@ namespace HLE { namespace Device { -Stub::Stub(u32 device_id, const std::string& device_name) : Device(device_id, device_name) -{ -} - ReturnCode Stub::Open(const OpenRequest& request) { WARN_LOG(IOS, "%s faking Open()", m_name.c_str()); diff --git a/Source/Core/Core/IOS/DeviceStub.h b/Source/Core/Core/IOS/DeviceStub.h index b6b60b0248..b61ed28b4e 100644 --- a/Source/Core/Core/IOS/DeviceStub.h +++ b/Source/Core/Core/IOS/DeviceStub.h @@ -8,7 +8,7 @@ #include "Common/CommonTypes.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" namespace IOS { @@ -19,8 +19,8 @@ namespace Device class Stub final : public Device { public: - Stub(u32 device_id, const std::string& device_name); - + // Inherit the constructor from the Device class, since we don't need to do anything special. + using Device::Device; ReturnCode Open(const OpenRequest& request) override; IPCCommandResult IOCtl(const IOCtlRequest& request) override; IPCCommandResult IOCtlV(const IOCtlVRequest& request) override; diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp index 1ff4064c1a..da2a393c5b 100644 --- a/Source/Core/Core/IOS/ES/ES.cpp +++ b/Source/Core/Core/IOS/ES/ES.cpp @@ -55,7 +55,7 @@ static void FinishAllStaleImports() File::CreateDir(import_dir); } -ES::ES(u32 device_id, const std::string& device_name) : Device(device_id, device_name) +ES::ES(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { FinishAllStaleImports(); @@ -155,7 +155,7 @@ IPCCommandResult ES::GetTitleID(const IOCtlVRequest& request) return GetDefaultReply(IPC_SUCCESS); } -static bool UpdateUIDAndGID(const IOS::ES::TMDReader& tmd) +static bool UpdateUIDAndGID(Kernel& kernel, const IOS::ES::TMDReader& tmd) { IOS::ES::UIDSys uid_sys{Common::FromWhichRoot::FROM_SESSION_ROOT}; const u64 title_id = tmd.GetTitleId(); @@ -165,8 +165,8 @@ static bool UpdateUIDAndGID(const IOS::ES::TMDReader& tmd) ERROR_LOG(IOS_ES, "Failed to get UID for title %016" PRIx64, title_id); return false; } - SetUIDForPPC(uid); - SetGIDForPPC(tmd.GetGroupId()); + kernel.SetUidForPPC(uid); + kernel.SetGidForPPC(tmd.GetGroupId()); return true; } @@ -197,7 +197,7 @@ IPCCommandResult ES::SetUID(u32 uid, const IOCtlVRequest& request) if (!tmd.IsValid()) return GetDefaultReply(FS_ENOENT); - if (!UpdateUIDAndGID(tmd)) + if (!UpdateUIDAndGID(m_ios, tmd)) { ERROR_LOG(IOS_ES, "SetUID: Failed to get UID for title %016" PRIx64, title_id); return GetDefaultReply(ES_SHORT_READ); @@ -225,7 +225,7 @@ bool ES::LaunchTitle(u64 title_id, bool skip_reload) bool ES::LaunchIOS(u64 ios_title_id) { - return Reload(ios_title_id); + return m_ios.BootIOS(ios_title_id); } bool ES::LaunchPPCTitle(u64 title_id, bool skip_reload) @@ -266,14 +266,14 @@ bool ES::LaunchPPCTitle(u64 title_id, bool skip_reload) // Note: the UID/GID is also updated for IOS titles, but since we have no guarantee IOS titles // are installed, we can only do this for PPC titles. - if (!UpdateUIDAndGID(s_title_context.tmd)) + if (!UpdateUIDAndGID(m_ios, s_title_context.tmd)) { s_title_context.Clear(); INFO_LOG(IOS_ES, "LaunchPPCTitle: Title context changed: (none)"); return false; } - return BootstrapPPC(content_loader); + return m_ios.BootstrapPPC(content_loader); } void ES::Context::DoState(PointerWrap& p) @@ -555,11 +555,9 @@ IPCCommandResult ES::Launch(const IOCtlVRequest& request) if (!LaunchTitle(TitleID)) return GetDefaultReply(FS_ENOENT); - // Generate a "reply" to the IPC command. ES_LAUNCH is unique because it - // involves restarting IOS; IOS generates two acknowledgements in a row. - // Note: If the launch succeeded, we should not write anything to the command buffer as - // IOS does not even reply unless it failed. - EnqueueCommandAcknowledgement(request.address, 0); + // ES_LAUNCH involves restarting IOS, which results in two acknowledgements in a row + // (one from the previous IOS for this IPC request, and one from the new one as it boots). + // Nothing should be written to the command buffer if the launch succeeded for obvious reasons. return GetNoReply(); } @@ -570,13 +568,12 @@ IPCCommandResult ES::LaunchBC(const IOCtlVRequest& request) // Here, IOS checks the clock speed and prevents ioctlv 0x25 from being used in GC mode. // An alternative way to do this is to check whether the current active IOS is MIOS. - if (GetVersion() == 0x101) + if (m_ios.GetVersion() == 0x101) return GetDefaultReply(ES_EINVAL); if (!LaunchTitle(0x0000000100000100)) return GetDefaultReply(FS_ENOENT); - EnqueueCommandAcknowledgement(request.address, 0); return GetNoReply(); } @@ -633,7 +630,7 @@ s32 ES::DIVerify(const IOS::ES::TMDReader& tmd, const IOS::ES::TicketReader& tic // clear the cache to avoid content access mismatches. DiscIO::CNANDContentManager::Access().ClearCache(); - if (!UpdateUIDAndGID(s_title_context.tmd)) + if (!UpdateUIDAndGID(*GetIOS(), s_title_context.tmd)) { return ES_SHORT_READ; } diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h index e060f51af4..ea3b5de9d4 100644 --- a/Source/Core/Core/IOS/ES/ES.h +++ b/Source/Core/Core/IOS/ES/ES.h @@ -12,7 +12,7 @@ #include "Common/CommonTypes.h" #include "Core/IOS/Device.h" #include "Core/IOS/ES/Formats.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" class PointerWrap; @@ -43,11 +43,11 @@ struct TitleContext class ES final : public Device { public: - ES(u32 device_id, const std::string& device_name); + ES(Kernel& ios, const std::string& device_name); static s32 DIVerify(const IOS::ES::TMDReader& tmd, const IOS::ES::TicketReader& ticket); static void LoadWAD(const std::string& _rContentFile); - static bool LaunchTitle(u64 title_id, bool skip_reload = false); + bool LaunchTitle(u64 title_id, bool skip_reload = false); // Internal implementation of the ES_DECRYPT ioctlv. static void DecryptContent(u32 key_index, u8* iv, u8* input, u32 size, u8* new_iv, u8* output); @@ -265,8 +265,8 @@ private: ContextArray::iterator FindActiveContext(u32 fd); ContextArray::iterator FindInactiveContext(); - static bool LaunchIOS(u64 ios_title_id); - static bool LaunchPPCTitle(u64 title_id, bool skip_reload); + bool LaunchIOS(u64 ios_title_id); + bool LaunchPPCTitle(u64 title_id, bool skip_reload); static TitleContext& GetTitleContext(); static const DiscIO::CNANDContentLoader& AccessContentDevice(u64 title_id); diff --git a/Source/Core/Core/IOS/FS/FS.cpp b/Source/Core/Core/IOS/FS/FS.cpp index 730ecee28f..c23f450cd0 100644 --- a/Source/Core/Core/IOS/FS/FS.cpp +++ b/Source/Core/Core/IOS/FS/FS.cpp @@ -33,7 +33,7 @@ static bool IsValidWiiPath(const std::string& path) namespace Device { -FS::FS(u32 device_id, const std::string& device_name) : Device(device_id, device_name) +FS::FS(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { const std::string tmp_dir = BuildFilename("/tmp"); File::DeleteDirRecursively(tmp_dir); diff --git a/Source/Core/Core/IOS/FS/FS.h b/Source/Core/Core/IOS/FS/FS.h index cec7983df7..d2dd87d7bb 100644 --- a/Source/Core/Core/IOS/FS/FS.h +++ b/Source/Core/Core/IOS/FS/FS.h @@ -8,7 +8,7 @@ #include "Common/CommonTypes.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" class PointerWrap; @@ -32,7 +32,7 @@ namespace Device class FS : public Device { public: - FS(u32 device_id, const std::string& device_name); + FS(Kernel& ios, const std::string& device_name); void DoState(PointerWrap& p) override; diff --git a/Source/Core/Core/IOS/FS/FileIO.cpp b/Source/Core/Core/IOS/FS/FileIO.cpp index 4c11d8267c..dd2f17af60 100644 --- a/Source/Core/Core/IOS/FS/FileIO.cpp +++ b/Source/Core/Core/IOS/FS/FileIO.cpp @@ -15,7 +15,7 @@ #include "Common/NandPaths.h" #include "Core/HW/Memmap.h" #include "Core/IOS/FS/FileIO.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" namespace IOS { @@ -71,14 +71,14 @@ void CreateVirtualFATFilesystem() namespace Device { -FileIO::FileIO(u32 device_id, const std::string& device_name) - : Device(device_id, device_name, DeviceType::FileIO) +FileIO::FileIO(Kernel& ios, const std::string& device_name) + : Device(ios, device_name, DeviceType::FileIO) { } ReturnCode FileIO::Close(u32 fd) { - INFO_LOG(IOS_FILEIO, "FileIO: Close %s (DeviceID=%08x)", m_name.c_str(), m_device_id); + INFO_LOG(IOS_FILEIO, "FileIO: Close %s", m_name.c_str()); m_Mode = 0; // Let go of our pointer to the file, it will automatically close if we are the last handle diff --git a/Source/Core/Core/IOS/FS/FileIO.h b/Source/Core/Core/IOS/FS/FileIO.h index f341208d9c..068eab57c2 100644 --- a/Source/Core/Core/IOS/FS/FileIO.h +++ b/Source/Core/Core/IOS/FS/FileIO.h @@ -9,7 +9,7 @@ #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" class PointerWrap; @@ -30,7 +30,7 @@ namespace Device class FileIO : public Device { public: - FileIO(u32 device_id, const std::string& device_name); + FileIO(Kernel& ios, const std::string& device_name); ReturnCode Close(u32 fd) override; ReturnCode Open(const OpenRequest& request) override; diff --git a/Source/Core/Core/IOS/IOS.cpp b/Source/Core/Core/IOS/IOS.cpp new file mode 100644 index 0000000000..5fce675168 --- /dev/null +++ b/Source/Core/Core/IOS/IOS.cpp @@ -0,0 +1,654 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "Core/IOS/IOS.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Common/Assert.h" +#include "Common/ChunkFile.h" +#include "Common/CommonTypes.h" +#include "Common/Logging/Log.h" +#include "Core/Boot/Boot_DOL.h" +#include "Core/ConfigManager.h" +#include "Core/Core.h" +#include "Core/CoreTiming.h" +#include "Core/HW/Memmap.h" +#include "Core/HW/WII_IPC.h" +#include "Core/IOS/DI/DI.h" +#include "Core/IOS/Device.h" +#include "Core/IOS/DeviceStub.h" +#include "Core/IOS/ES/ES.h" +#include "Core/IOS/FS/FS.h" +#include "Core/IOS/FS/FileIO.h" +#include "Core/IOS/MIOS.h" +#include "Core/IOS/MemoryValues.h" +#include "Core/IOS/Network/IP/Top.h" +#include "Core/IOS/Network/KD/NetKDRequest.h" +#include "Core/IOS/Network/KD/NetKDTime.h" +#include "Core/IOS/Network/NCD/Manage.h" +#include "Core/IOS/Network/SSL.h" +#include "Core/IOS/Network/Socket.h" +#include "Core/IOS/Network/WD/Command.h" +#include "Core/IOS/SDIO/SDIOSlot0.h" +#include "Core/IOS/STM/STM.h" +#include "Core/IOS/USB/Bluetooth/BTEmu.h" +#include "Core/IOS/USB/Bluetooth/BTReal.h" +#include "Core/IOS/USB/OH0/OH0.h" +#include "Core/IOS/USB/OH0/OH0Device.h" +#include "Core/IOS/USB/USB_HID/HIDv4.h" +#include "Core/IOS/USB/USB_KBD.h" +#include "Core/IOS/USB/USB_VEN/VEN.h" +#include "Core/IOS/WFS/WFSI.h" +#include "Core/IOS/WFS/WFSSRV.h" +#include "Core/PowerPC/PowerPC.h" +#include "DiscIO/NANDContentLoader.h" + +namespace IOS +{ +namespace HLE +{ +static std::unique_ptr s_ios; + +constexpr u64 ENQUEUE_REQUEST_FLAG = 0x100000000ULL; +constexpr u64 ENQUEUE_ACKNOWLEDGEMENT_FLAG = 0x200000000ULL; +static CoreTiming::EventType* s_event_enqueue; +static CoreTiming::EventType* s_event_sdio_notify; + +constexpr u32 ADDR_MEM1_SIZE = 0x3100; +constexpr u32 ADDR_MEM1_SIM_SIZE = 0x3104; +constexpr u32 ADDR_MEM1_END = 0x3108; +constexpr u32 ADDR_MEM1_ARENA_BEGIN = 0x310c; +constexpr u32 ADDR_MEM1_ARENA_END = 0x3110; +constexpr u32 ADDR_PH1 = 0x3114; +constexpr u32 ADDR_MEM2_SIZE = 0x3118; +constexpr u32 ADDR_MEM2_SIM_SIZE = 0x311c; +constexpr u32 ADDR_MEM2_END = 0x3120; +constexpr u32 ADDR_MEM2_ARENA_BEGIN = 0x3124; +constexpr u32 ADDR_MEM2_ARENA_END = 0x3128; +constexpr u32 ADDR_PH2 = 0x312c; +constexpr u32 ADDR_IPC_BUFFER_BEGIN = 0x3130; +constexpr u32 ADDR_IPC_BUFFER_END = 0x3134; +constexpr u32 ADDR_HOLLYWOOD_REVISION = 0x3138; +constexpr u32 ADDR_PH3 = 0x313c; +constexpr u32 ADDR_IOS_VERSION = 0x3140; +constexpr u32 ADDR_IOS_DATE = 0x3144; +constexpr u32 ADDR_UNKNOWN_BEGIN = 0x3148; +constexpr u32 ADDR_UNKNOWN_END = 0x314c; +constexpr u32 ADDR_PH4 = 0x3150; +constexpr u32 ADDR_PH5 = 0x3154; +constexpr u32 ADDR_RAM_VENDOR = 0x3158; +constexpr u32 ADDR_BOOT_FLAG = 0x315c; +constexpr u32 ADDR_APPLOADER_FLAG = 0x315d; +constexpr u32 ADDR_DEVKIT_BOOT_PROGRAM_VERSION = 0x315e; +constexpr u32 ADDR_SYSMENU_SYNC = 0x3160; +constexpr u32 PLACEHOLDER = 0xDEADBEEF; + +enum class MemorySetupType +{ + IOSReload, + Full, +}; + +static bool SetupMemory(u64 ios_title_id, MemorySetupType setup_type) +{ + auto target_imv = std::find_if( + GetMemoryValues().begin(), GetMemoryValues().end(), + [&](const MemoryValues& imv) { return imv.ios_number == (ios_title_id & 0xffff); }); + + if (target_imv == GetMemoryValues().end()) + { + ERROR_LOG(IOS, "Unknown IOS version: %016" PRIx64, ios_title_id); + return false; + } + + if (setup_type == MemorySetupType::IOSReload) + { + Memory::Write_U32(target_imv->ios_version, ADDR_IOS_VERSION); + + // These values are written by the IOS kernel as part of its boot process (for IOS28 and newer). + // + // This works in a slightly different way on a real console: older IOS versions (< IOS28) all + // have the same range (933E0000 - 93400000), thus they don't write it at boot and just inherit + // all values. However, the range has changed since IOS28. To make things work properly + // after a reload, newer IOSes always write the legacy range before loading an IOS kernel; + // the new IOS either updates the range (>= IOS28) or inherits it (< IOS28). + // + // We can skip this convoluted process and just write the correct range directly. + Memory::Write_U32(target_imv->mem2_physical_size, ADDR_MEM2_SIZE); + Memory::Write_U32(target_imv->mem2_simulated_size, ADDR_MEM2_SIM_SIZE); + Memory::Write_U32(target_imv->mem2_end, ADDR_MEM2_END); + Memory::Write_U32(target_imv->mem2_arena_begin, ADDR_MEM2_ARENA_BEGIN); + Memory::Write_U32(target_imv->mem2_arena_end, ADDR_MEM2_ARENA_END); + Memory::Write_U32(target_imv->ipc_buffer_begin, ADDR_IPC_BUFFER_BEGIN); + Memory::Write_U32(target_imv->ipc_buffer_end, ADDR_IPC_BUFFER_END); + Memory::Write_U32(target_imv->unknown_begin, ADDR_UNKNOWN_BEGIN); + Memory::Write_U32(target_imv->unknown_end, ADDR_UNKNOWN_END); + + return true; + } + + Memory::Write_U32(target_imv->mem1_physical_size, ADDR_MEM1_SIZE); + Memory::Write_U32(target_imv->mem1_simulated_size, ADDR_MEM1_SIM_SIZE); + Memory::Write_U32(target_imv->mem1_end, ADDR_MEM1_END); + Memory::Write_U32(target_imv->mem1_arena_begin, ADDR_MEM1_ARENA_BEGIN); + Memory::Write_U32(target_imv->mem1_arena_end, ADDR_MEM1_ARENA_END); + Memory::Write_U32(PLACEHOLDER, ADDR_PH1); + Memory::Write_U32(target_imv->mem2_physical_size, ADDR_MEM2_SIZE); + Memory::Write_U32(target_imv->mem2_simulated_size, ADDR_MEM2_SIM_SIZE); + Memory::Write_U32(target_imv->mem2_end, ADDR_MEM2_END); + Memory::Write_U32(target_imv->mem2_arena_begin, ADDR_MEM2_ARENA_BEGIN); + Memory::Write_U32(target_imv->mem2_arena_end, ADDR_MEM2_ARENA_END); + Memory::Write_U32(PLACEHOLDER, ADDR_PH2); + Memory::Write_U32(target_imv->ipc_buffer_begin, ADDR_IPC_BUFFER_BEGIN); + Memory::Write_U32(target_imv->ipc_buffer_end, ADDR_IPC_BUFFER_END); + Memory::Write_U32(target_imv->hollywood_revision, ADDR_HOLLYWOOD_REVISION); + Memory::Write_U32(PLACEHOLDER, ADDR_PH3); + Memory::Write_U32(target_imv->ios_version, ADDR_IOS_VERSION); + Memory::Write_U32(target_imv->ios_date, ADDR_IOS_DATE); + Memory::Write_U32(target_imv->unknown_begin, ADDR_UNKNOWN_BEGIN); + Memory::Write_U32(target_imv->unknown_end, ADDR_UNKNOWN_END); + Memory::Write_U32(PLACEHOLDER, ADDR_PH4); + Memory::Write_U32(PLACEHOLDER, ADDR_PH5); + Memory::Write_U32(target_imv->ram_vendor, ADDR_RAM_VENDOR); + Memory::Write_U8(0xDE, ADDR_BOOT_FLAG); + Memory::Write_U8(0xAD, ADDR_APPLOADER_FLAG); + Memory::Write_U16(0xBEEF, ADDR_DEVKIT_BOOT_PROGRAM_VERSION); + Memory::Write_U32(target_imv->sysmenu_sync, ADDR_SYSMENU_SYNC); + return true; +} + +// IOS used by the latest System Menu (4.3). +constexpr u64 IOS80_TITLE_ID = 0x0000000100000050; +constexpr u64 BC_TITLE_ID = 0x0000000100000100; +constexpr u64 MIOS_TITLE_ID = 0x0000000100000101; + +Kernel::Kernel(u64 title_id) : m_title_id(title_id) +{ + INFO_LOG(IOS, "Starting IOS %016" PRIx64, title_id); + + if (!SetupMemory(title_id, MemorySetupType::IOSReload)) + WARN_LOG(IOS, "No information about this IOS -- cannot set up memory values"); + + if (title_id == MIOS_TITLE_ID) + { + MIOS::Load(); + return; + } + + // IOS re-inits IPC and sends a dummy ack during its boot process. + EnqueueIPCAcknowledgement(0); + + AddStaticDevices(); +} + +Kernel::~Kernel() +{ + CoreTiming::RemoveAllEvents(s_event_enqueue); + + // Close all devices that were opened + for (auto& device : m_fdmap) + { + if (!device) + continue; + device->Close(0); + } + + { + std::lock_guard lock(m_device_map_mutex); + m_device_map.clear(); + } +} + +// The title ID is a u64 where the first 32 bits are used for the title type. +// For IOS title IDs, the type will always be 00000001 (system), and the lower 32 bits +// are used for the IOS major version -- which is what we want here. +u32 Kernel::GetVersion() const +{ + return static_cast(m_title_id); +} + +// Since we don't have actual processes, we keep track of only the PPC's UID/GID. +// These functions roughly correspond to syscalls 0x2b, 0x2c, 0x2d, 0x2e (though only for the PPC). +void Kernel::SetUidForPPC(u32 uid) +{ + m_ppc_uid = uid; +} + +u32 Kernel::GetUidForPPC() const +{ + return m_ppc_uid; +} + +void Kernel::SetGidForPPC(u16 gid) +{ + m_ppc_gid = gid; +} + +u16 Kernel::GetGidForPPC() const +{ + return m_ppc_gid; +} + +// This corresponds to syscall 0x41, which loads a binary from the NAND and bootstraps the PPC. +// Unlike 0x42, IOS will set up some constants in memory before booting the PPC. +bool Kernel::BootstrapPPC(const DiscIO::CNANDContentLoader& content_loader) +{ + if (!content_loader.IsValid()) + return false; + + const auto* content = content_loader.GetContentByIndex(content_loader.GetTMD().GetBootIndex()); + if (!content) + return false; + + const auto dol_loader = std::make_unique(content->m_Data->Get()); + if (!dol_loader->IsValid()) + return false; + + if (!SetupMemory(m_title_id, MemorySetupType::Full)) + return false; + + dol_loader->Load(); + + // NAND titles start with address translation off at 0x3400 (via the PPC bootstub) + // The state of other CPU registers (like the BAT registers) doesn't matter much + // because the realmode code at 0x3400 initializes everything itself anyway. + MSR = 0; + PC = 0x3400; + + return true; +} + +// Similar to syscall 0x42 (ios_boot); this is used to change the current active IOS. +// IOS writes the new version to 0x3140 before restarting, but it does *not* poke any +// of the other constants to the memory. Warning: this resets the kernel instance. +bool Kernel::BootIOS(const u64 ios_title_id) +{ + // A real Wii goes through several steps before getting to MIOS. + // + // * The System Menu detects a GameCube disc and launches BC (1-100) instead of the game. + // * BC (similar to boot1) lowers the clock speed to the Flipper's and then launches boot2. + // * boot2 sees the lowered clock speed and launches MIOS (1-101) instead of the System Menu. + // + // Because we currently don't have boot1 and boot2, and BC is only ever used to launch MIOS + // (indirectly via boot2), we can just launch MIOS when BC is launched. + if (ios_title_id == BC_TITLE_ID) + { + NOTICE_LOG(IOS, "BC: Launching MIOS..."); + return BootIOS(MIOS_TITLE_ID); + } + + // Shut down the active IOS first before switching to the new one. + s_ios.reset(); + s_ios = std::make_unique(ios_title_id); + return true; +} + +void Kernel::AddDevice(std::unique_ptr device) +{ + _assert_(device->GetDeviceType() == Device::Device::DeviceType::Static); + m_device_map[device->GetDeviceName()] = std::move(device); +} + +void Kernel::AddStaticDevices() +{ + std::lock_guard lock(m_device_map_mutex); + _assert_msg_(IOS, m_device_map.empty(), "Reinit called while already initialized"); + + if (!SConfig::GetInstance().m_bt_passthrough_enabled) + AddDevice(std::make_unique(*this, "/dev/usb/oh1/57e/305")); + else + AddDevice(std::make_unique(*this, "/dev/usb/oh1/57e/305")); + + AddDevice(std::make_unique(*this, "/dev/stm/immediate")); + AddDevice(std::make_unique(*this, "/dev/stm/eventhook")); + AddDevice(std::make_unique(*this, "/dev/fs")); + AddDevice(std::make_unique(*this, "/dev/es")); + AddDevice(std::make_unique(*this, "/dev/di")); + AddDevice(std::make_unique(*this, "/dev/net/kd/request")); + AddDevice(std::make_unique(*this, "/dev/net/kd/time")); + AddDevice(std::make_unique(*this, "/dev/net/ncd/manage")); + AddDevice(std::make_unique(*this, "/dev/net/wd/command")); + AddDevice(std::make_unique(*this, "/dev/net/ip/top")); + AddDevice(std::make_unique(*this, "/dev/net/ssl")); + AddDevice(std::make_unique(*this, "/dev/usb/kbd")); + AddDevice(std::make_unique(*this, "/dev/sdio/slot0")); + AddDevice(std::make_unique(*this, "/dev/sdio/slot1")); + AddDevice(std::make_unique(*this, "/dev/usb/hid")); + AddDevice(std::make_unique(*this, "/dev/usb/oh0")); + AddDevice(std::make_unique(*this, "/dev/usb/oh1")); + AddDevice(std::make_unique(*this, "/dev/usb/ven")); + AddDevice(std::make_unique(*this, "/dev/usb/wfssrv")); + AddDevice(std::make_unique(*this, "/dev/wfsi")); +} + +s32 Kernel::GetFreeDeviceID() +{ + for (u32 i = 0; i < IPC_MAX_FDS; i++) + { + if (m_fdmap[i] == nullptr) + { + return i; + } + } + + return -1; +} + +std::shared_ptr Kernel::GetDeviceByName(const std::string& device_name) +{ + std::lock_guard lock(m_device_map_mutex); + const auto iterator = m_device_map.find(device_name); + return iterator != m_device_map.end() ? iterator->second : nullptr; +} + +// Returns the FD for the newly opened device (on success) or an error code. +s32 Kernel::OpenDevice(OpenRequest& request) +{ + const s32 new_fd = GetFreeDeviceID(); + INFO_LOG(IOS, "Opening %s (mode %d, fd %d)", request.path.c_str(), request.flags, new_fd); + if (new_fd < 0 || new_fd >= IPC_MAX_FDS) + { + ERROR_LOG(IOS, "Couldn't get a free fd, too many open files"); + return FS_EFDEXHAUSTED; + } + request.fd = new_fd; + + std::shared_ptr device; + if (request.path.find("/dev/usb/oh0/") == 0 && !GetDeviceByName(request.path)) + { + device = std::make_shared(*this, request.path); + } + else if (request.path.find("/dev/") == 0) + { + device = GetDeviceByName(request.path); + } + else if (request.path.find('/') == 0) + { + device = std::make_shared(*this, request.path); + } + + if (!device) + { + ERROR_LOG(IOS, "Unknown device: %s", request.path.c_str()); + return IPC_ENOENT; + } + + const ReturnCode code = device->Open(request); + if (code < IPC_SUCCESS) + return code; + m_fdmap[new_fd] = device; + return new_fd; +} + +IPCCommandResult Kernel::HandleIPCCommand(const Request& request) +{ + if (request.command == IPC_CMD_OPEN) + { + OpenRequest open_request{request.address}; + const s32 new_fd = OpenDevice(open_request); + return Device::Device::GetDefaultReply(new_fd); + } + + const auto device = (request.fd < IPC_MAX_FDS) ? m_fdmap[request.fd] : nullptr; + if (!device) + return Device::Device::GetDefaultReply(IPC_EINVAL); + + switch (request.command) + { + case IPC_CMD_CLOSE: + m_fdmap[request.fd].reset(); + return Device::Device::GetDefaultReply(device->Close(request.fd)); + case IPC_CMD_READ: + return device->Read(ReadWriteRequest{request.address}); + case IPC_CMD_WRITE: + return device->Write(ReadWriteRequest{request.address}); + case IPC_CMD_SEEK: + return device->Seek(SeekRequest{request.address}); + case IPC_CMD_IOCTL: + return device->IOCtl(IOCtlRequest{request.address}); + case IPC_CMD_IOCTLV: + return device->IOCtlV(IOCtlVRequest{request.address}); + default: + _assert_msg_(IOS, false, "Unexpected command: %x", request.command); + return Device::Device::GetDefaultReply(IPC_EINVAL); + } +} + +void Kernel::ExecuteIPCCommand(const u32 address) +{ + Request request{address}; + IPCCommandResult result = HandleIPCCommand(request); + + if (!result.send_reply) + return; + + // Ensure replies happen in order + const s64 ticks_until_last_reply = m_last_reply_time - CoreTiming::GetTicks(); + if (ticks_until_last_reply > 0) + result.reply_delay_ticks += ticks_until_last_reply; + m_last_reply_time = CoreTiming::GetTicks() + result.reply_delay_ticks; + + EnqueueIPCReply(request, result.return_value, static_cast(result.reply_delay_ticks)); +} + +// Happens AS SOON AS IPC gets a new pointer! +void Kernel::EnqueueIPCRequest(u32 address) +{ + CoreTiming::ScheduleEvent(1000, s_event_enqueue, address | ENQUEUE_REQUEST_FLAG); +} + +// Called to send a reply to an IOS syscall +void Kernel::EnqueueIPCReply(const Request& request, const s32 return_value, int cycles_in_future, + CoreTiming::FromThread from) +{ + Memory::Write_U32(static_cast(return_value), request.address + 4); + // IOS writes back the command that was responded to in the FD field. + Memory::Write_U32(request.command, request.address + 8); + // IOS also overwrites the command type with the reply type. + Memory::Write_U32(IPC_REPLY, request.address); + CoreTiming::ScheduleEvent(cycles_in_future, s_event_enqueue, request.address, from); +} + +void Kernel::EnqueueIPCAcknowledgement(u32 address, int cycles_in_future) +{ + CoreTiming::ScheduleEvent(cycles_in_future, s_event_enqueue, + address | ENQUEUE_ACKNOWLEDGEMENT_FLAG); +} + +void Kernel::HandleIPCEvent(u64 userdata) +{ + if (userdata & ENQUEUE_ACKNOWLEDGEMENT_FLAG) + m_ack_queue.push_back(static_cast(userdata)); + else if (userdata & ENQUEUE_REQUEST_FLAG) + m_request_queue.push_back(static_cast(userdata)); + else + m_reply_queue.push_back(static_cast(userdata)); + + UpdateIPC(); +} + +// This is called every IPC_HLE_PERIOD from SystemTimers.cpp +// Takes care of routing ipc <-> ipc HLE +void Kernel::UpdateIPC() +{ + if (!IsReady()) + return; + + if (m_request_queue.size()) + { + GenerateAck(m_request_queue.front()); + u32 command = m_request_queue.front(); + m_request_queue.pop_front(); + ExecuteIPCCommand(command); + return; + } + + if (m_reply_queue.size()) + { + GenerateReply(m_reply_queue.front()); + DEBUG_LOG(IOS, "<<-- Reply to IPC Request @ 0x%08x", m_reply_queue.front()); + m_reply_queue.pop_front(); + return; + } + + if (m_ack_queue.size()) + { + GenerateAck(m_ack_queue.front()); + WARN_LOG(IOS, "<<-- Double-ack to IPC Request @ 0x%08x", m_ack_queue.front()); + m_ack_queue.pop_front(); + return; + } +} + +void Kernel::UpdateDevices() +{ + // Check if a hardware device must be updated + for (const auto& entry : m_device_map) + { + if (entry.second->IsOpened()) + { + entry.second->Update(); + } + } +} + +void Kernel::UpdateWantDeterminism(const bool new_want_determinism) +{ + WiiSockMan::GetInstance().UpdateWantDeterminism(new_want_determinism); + for (const auto& device : m_device_map) + device.second->UpdateWantDeterminism(new_want_determinism); +} + +void Kernel::SDIO_EventNotify() +{ + // TODO: Potential race condition: If IsRunning() becomes false after + // it's checked, an event may be scheduled after CoreTiming shuts down. + if (SConfig::GetInstance().bWii && Core::IsRunning()) + CoreTiming::ScheduleEvent(0, s_event_sdio_notify, 0, CoreTiming::FromThread::NON_CPU); +} + +void Kernel::DoState(PointerWrap& p) +{ + p.Do(m_request_queue); + p.Do(m_reply_queue); + p.Do(m_last_reply_time); + p.Do(m_title_id); + p.Do(m_ppc_uid); + p.Do(m_ppc_gid); + + if (m_title_id == MIOS_TITLE_ID) + return; + + // We need to make sure all file handles are closed so IOS::HLE::Device::FS::DoState can + // successfully save or re-create /tmp + for (auto& descriptor : m_fdmap) + { + if (descriptor) + descriptor->PrepareForState(p.GetMode()); + } + + for (const auto& entry : m_device_map) + entry.second->DoState(p); + + if (p.GetMode() == PointerWrap::MODE_READ) + { + for (u32 i = 0; i < IPC_MAX_FDS; i++) + { + u32 exists = 0; + p.Do(exists); + if (exists) + { + auto device_type = Device::Device::DeviceType::Static; + p.Do(device_type); + switch (device_type) + { + case Device::Device::DeviceType::Static: + { + std::string device_name; + p.Do(device_name); + m_fdmap[i] = GetDeviceByName(device_name); + break; + } + case Device::Device::DeviceType::FileIO: + m_fdmap[i] = std::make_shared(*this, ""); + m_fdmap[i]->DoState(p); + break; + case Device::Device::DeviceType::OH0: + m_fdmap[i] = std::make_shared(*this, ""); + m_fdmap[i]->DoState(p); + break; + } + } + } + } + else + { + for (auto& descriptor : m_fdmap) + { + u32 exists = descriptor ? 1 : 0; + p.Do(exists); + if (exists) + { + auto device_type = descriptor->GetDeviceType(); + p.Do(device_type); + if (device_type == Device::Device::DeviceType::Static) + { + std::string device_name = descriptor->GetDeviceName(); + p.Do(device_name); + } + else + { + descriptor->DoState(p); + } + } + } + } +} + +void Init() +{ + s_event_enqueue = CoreTiming::RegisterEvent("IPCEvent", [](u64 userdata, s64) { + if (s_ios) + s_ios->HandleIPCEvent(userdata); + }); + + s_event_sdio_notify = CoreTiming::RegisterEvent("SDIO_EventNotify", [](u64, s64) { + if (!s_ios) + return; + + auto device = static_cast(s_ios->GetDeviceByName("/dev/sdio/slot0").get()); + if (device) + device->EventNotify(); + }); + + // Start with IOS80 to simulate part of the Wii boot process. + s_ios = std::make_unique(IOS80_TITLE_ID); + // On a Wii, boot2 launches the system menu IOS, which then launches the system menu + // (which bootstraps the PPC). Bootstrapping the PPC results in memory values being set up. + // This means that the constants in the 0x3100 region are always set up by the time + // a game is launched. This is necessary because booting games from the game list skips + // a significant part of a Wii's boot process. + SetupMemory(IOS80_TITLE_ID, MemorySetupType::Full); +} + +void Shutdown() +{ + s_ios.reset(); +} + +Kernel* GetIOS() +{ + return s_ios.get(); +} +} // namespace HLE +} // namespace IOS diff --git a/Source/Core/Core/IOS/IOS.h b/Source/Core/Core/IOS/IOS.h new file mode 100644 index 0000000000..40db6c09b5 --- /dev/null +++ b/Source/Core/Core/IOS/IOS.h @@ -0,0 +1,120 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "Common/CommonTypes.h" +#include "Core/CoreTiming.h" +#include "Core/HW/SystemTimers.h" + +class PointerWrap; + +namespace DiscIO +{ +class CNANDContentLoader; +} + +namespace IOS +{ +namespace HLE +{ +namespace Device +{ +class Device; +} + +struct Request; +struct OpenRequest; + +struct IPCCommandResult +{ + s32 return_value; + bool send_reply; + u64 reply_delay_ticks; +}; + +enum IPCCommandType : u32 +{ + IPC_CMD_OPEN = 1, + IPC_CMD_CLOSE = 2, + IPC_CMD_READ = 3, + IPC_CMD_WRITE = 4, + IPC_CMD_SEEK = 5, + IPC_CMD_IOCTL = 6, + IPC_CMD_IOCTLV = 7, + // This is used for replies to commands. + IPC_REPLY = 8, +}; + +// HLE for the IOS kernel: IPC, device management, syscalls, and Dolphin-specific, IOS-wide calls. +class Kernel +{ +public: + explicit Kernel(u64 ios_title_id); + ~Kernel(); + + void DoState(PointerWrap& p); + void HandleIPCEvent(u64 userdata); + void UpdateIPC(); + void UpdateDevices(); + void UpdateWantDeterminism(bool new_want_determinism); + + std::shared_ptr GetDeviceByName(const std::string& device_name); + void SDIO_EventNotify(); + + void EnqueueIPCRequest(u32 address); + void EnqueueIPCReply(const Request& request, s32 return_value, int cycles_in_future = 0, + CoreTiming::FromThread from = CoreTiming::FromThread::CPU); + + void SetUidForPPC(u32 uid); + u32 GetUidForPPC() const; + void SetGidForPPC(u16 gid); + u16 GetGidForPPC() const; + + bool BootstrapPPC(const DiscIO::CNANDContentLoader& content_loader); + bool BootIOS(u64 ios_title_id); + u32 GetVersion() const; + +private: + void ExecuteIPCCommand(u32 address); + IPCCommandResult HandleIPCCommand(const Request& request); + void EnqueueIPCAcknowledgement(u32 address, int cycles_in_future = 0); + + void AddDevice(std::unique_ptr device); + void AddStaticDevices(); + s32 GetFreeDeviceID(); + s32 OpenDevice(OpenRequest& request); + + u64 m_title_id = 0; + static constexpr u8 IPC_MAX_FDS = 0x18; + std::map> m_device_map; + std::mutex m_device_map_mutex; + // TODO: make this fdmap per process. + std::array, IPC_MAX_FDS> m_fdmap; + + u32 m_ppc_uid = 0; + u16 m_ppc_gid = 0; + + using IPCMsgQueue = std::deque; + IPCMsgQueue m_request_queue; // ppc -> arm + IPCMsgQueue m_reply_queue; // arm -> ppc + IPCMsgQueue m_ack_queue; // arm -> ppc + u64 m_last_reply_time = 0; +}; + +// Used for controlling and accessing an IOS instance that is tied to emulation. +void Init(); +void Shutdown(); +Kernel* GetIOS(); + +} // namespace HLE +} // namespace IOS diff --git a/Source/Core/Core/IOS/IPC.cpp b/Source/Core/Core/IOS/IPC.cpp deleted file mode 100644 index 2906f207c2..0000000000 --- a/Source/Core/Core/IOS/IPC.cpp +++ /dev/null @@ -1,1041 +0,0 @@ -// Copyright 2008 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -// This is the main Wii IPC file that handles all incoming IPC requests and directs them -// to the right function. -// -// IPC basics (IOS' usage): -// All IPC request handlers will write a return value to 0x04. -// Open: Device file descriptor or error code -// Close: IPC_SUCCESS -// Read: Bytes read -// Write: Bytes written -// Seek: Seek position -// Ioctl: Depends on the handler -// Ioctlv: Depends on the handler -// Replies may be sent immediately or asynchronously for ioctls and ioctlvs. - -#include "Core/IOS/IPC.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Common/Assert.h" -#include "Common/ChunkFile.h" -#include "Common/CommonTypes.h" -#include "Common/Logging/Log.h" -#include "Core/Boot/Boot_DOL.h" -#include "Core/ConfigManager.h" -#include "Core/Core.h" -#include "Core/CoreTiming.h" -#include "Core/HW/Memmap.h" -#include "Core/HW/WII_IPC.h" -#include "Core/IOS/DI/DI.h" -#include "Core/IOS/Device.h" -#include "Core/IOS/DeviceStub.h" -#include "Core/IOS/ES/ES.h" -#include "Core/IOS/FS/FS.h" -#include "Core/IOS/FS/FileIO.h" -#include "Core/IOS/MIOS.h" -#include "Core/IOS/Network/IP/Top.h" -#include "Core/IOS/Network/KD/NetKDRequest.h" -#include "Core/IOS/Network/KD/NetKDTime.h" -#include "Core/IOS/Network/NCD/Manage.h" -#include "Core/IOS/Network/SSL.h" -#include "Core/IOS/Network/Socket.h" -#include "Core/IOS/Network/WD/Command.h" -#include "Core/IOS/SDIO/SDIOSlot0.h" -#include "Core/IOS/STM/STM.h" -#include "Core/IOS/USB/Bluetooth/BTEmu.h" -#include "Core/IOS/USB/Bluetooth/BTReal.h" -#include "Core/IOS/USB/OH0/OH0.h" -#include "Core/IOS/USB/OH0/OH0Device.h" -#include "Core/IOS/USB/USB_HID/HIDv4.h" -#include "Core/IOS/USB/USB_KBD.h" -#include "Core/IOS/USB/USB_VEN/VEN.h" -#include "Core/IOS/WFS/WFSI.h" -#include "Core/IOS/WFS/WFSSRV.h" -#include "Core/PowerPC/PowerPC.h" -#include "DiscIO/NANDContentLoader.h" - -namespace IOS -{ -namespace HLE -{ -static std::map> s_device_map; -static std::mutex s_device_map_mutex; - -// STATE_TO_SAVE -constexpr u8 IPC_MAX_FDS = 0x18; -static std::shared_ptr s_fdmap[IPC_MAX_FDS]; - -using IPCMsgQueue = std::deque; -static IPCMsgQueue s_request_queue; // ppc -> arm -static IPCMsgQueue s_reply_queue; // arm -> ppc -static IPCMsgQueue s_ack_queue; // arm -> ppc - -static CoreTiming::EventType* s_event_enqueue; -static CoreTiming::EventType* s_event_sdio_notify; - -static u64 s_last_reply_time; - -static u64 s_active_title_id; - -static u32 s_ppc_uid; -static u16 s_ppc_gid; - -static constexpr u64 ENQUEUE_REQUEST_FLAG = 0x100000000ULL; -static constexpr u64 ENQUEUE_ACKNOWLEDGEMENT_FLAG = 0x200000000ULL; - -enum class MemorySetupType -{ - IOSReload, - Full, -}; - -struct IosMemoryValues -{ - u16 ios_number; - u32 ios_version; - u32 ios_date; - u32 mem1_physical_size; - u32 mem1_simulated_size; - u32 mem1_end; - u32 mem1_arena_begin; - u32 mem1_arena_end; - u32 mem2_physical_size; - u32 mem2_simulated_size; - u32 mem2_end; - u32 mem2_arena_begin; - u32 mem2_arena_end; - u32 ipc_buffer_begin; - u32 ipc_buffer_end; - u32 hollywood_revision; - u32 ram_vendor; - u32 unknown_begin; - u32 unknown_end; - u32 sysmenu_sync; -}; - -constexpr u32 ADDR_MEM1_SIZE = 0x3100; -constexpr u32 ADDR_MEM1_SIM_SIZE = 0x3104; -constexpr u32 ADDR_MEM1_END = 0x3108; -constexpr u32 ADDR_MEM1_ARENA_BEGIN = 0x310c; -constexpr u32 ADDR_MEM1_ARENA_END = 0x3110; -constexpr u32 ADDR_PH1 = 0x3114; -constexpr u32 ADDR_MEM2_SIZE = 0x3118; -constexpr u32 ADDR_MEM2_SIM_SIZE = 0x311c; -constexpr u32 ADDR_MEM2_END = 0x3120; -constexpr u32 ADDR_MEM2_ARENA_BEGIN = 0x3124; -constexpr u32 ADDR_MEM2_ARENA_END = 0x3128; -constexpr u32 ADDR_PH2 = 0x312c; -constexpr u32 ADDR_IPC_BUFFER_BEGIN = 0x3130; -constexpr u32 ADDR_IPC_BUFFER_END = 0x3134; -constexpr u32 ADDR_HOLLYWOOD_REVISION = 0x3138; -constexpr u32 ADDR_PH3 = 0x313c; -constexpr u32 ADDR_IOS_VERSION = 0x3140; -constexpr u32 ADDR_IOS_DATE = 0x3144; -constexpr u32 ADDR_UNKNOWN_BEGIN = 0x3148; -constexpr u32 ADDR_UNKNOWN_END = 0x314c; -constexpr u32 ADDR_PH4 = 0x3150; -constexpr u32 ADDR_PH5 = 0x3154; -constexpr u32 ADDR_RAM_VENDOR = 0x3158; -constexpr u32 ADDR_BOOT_FLAG = 0x315c; -constexpr u32 ADDR_APPLOADER_FLAG = 0x315d; -constexpr u32 ADDR_DEVKIT_BOOT_PROGRAM_VERSION = 0x315e; -constexpr u32 ADDR_SYSMENU_SYNC = 0x3160; - -constexpr u32 MEM1_SIZE = 0x01800000; -constexpr u32 MEM1_END = 0x81800000; -constexpr u32 MEM1_ARENA_BEGIN = 0x00000000; -constexpr u32 MEM1_ARENA_END = 0x81800000; -constexpr u32 MEM2_SIZE = 0x4000000; -constexpr u32 MEM2_ARENA_BEGIN = 0x90000800; -constexpr u32 HOLLYWOOD_REVISION = 0x00000011; -constexpr u32 PLACEHOLDER = 0xDEADBEEF; -constexpr u32 RAM_VENDOR = 0x0000FF01; -constexpr u32 RAM_VENDOR_MIOS = 0xCAFEBABE; - -// These values were manually extracted from the relevant IOS binaries. -// The writes are usually contained in a single function that -// mostly writes raw literals to the relevant locations. -// e.g. IOS9, version 1034, content id 0x00000006, function at 0xffff6884 -constexpr std::array ios_memory_values = { - {{ - 9, 0x9040a, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, - 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, - RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, - }, - { - 11, 0xb000a, 0x102506, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, - 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, - RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, - }, - { - 12, 0xc020e, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, - 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, - RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, - }, - { - 13, 0xd0408, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, - 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, - RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, - }, - { - 14, 0xe0408, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, - 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, - RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, - }, - { - 15, 0xf0408, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, - 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, - RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, - }, - { - 17, 0x110408, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, - 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, - RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, - }, - { - 20, 0x14000c, 0x102506, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, - 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, - RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, - }, - { - 21, 0x15040f, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, - 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, - RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, - }, - { - 22, 0x16050e, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, - 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, - RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, - }, - { - 28, 0x1c070f, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93800000, MEM2_ARENA_BEGIN, - 0x937E0000, 0x937E0000, 0x93800000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93800000, 0x93820000, 0, - }, - { - 30, 0x1e0a10, 0x40308, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 31, 0x1f0e18, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 33, 0x210e18, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 34, 0x220e18, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 35, 0x230e18, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 36, 0x240e18, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 37, 0x25161f, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 38, 0x26101c, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 40, 0x280911, 0x022308, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 41, 0x290e17, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 43, 0x2b0e17, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 45, 0x2d0e17, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 46, 0x2e0e17, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 48, 0x30101c, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 50, 0x321319, 0x101008, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 51, 0x331219, 0x071108, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 52, 0x34161d, 0x101008, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 53, 0x35161f, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 55, 0x37161f, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 56, 0x38161e, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 57, 0x39171f, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 58, 0x3a1820, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 59, 0x3b1c21, 0x101811, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 60, 0x3c181e, 0x112408, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 61, 0x3d161e, 0x030110, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 62, 0x3e191e, 0x022712, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 70, 0x461a1f, 0x060309, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 80, 0x501b20, 0x030310, MEM1_SIZE, - MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, - MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, - 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, - RAM_VENDOR, 0x93600000, 0x93620000, 0, - }, - { - 257, - 0x707, - 0x82209, - MEM1_SIZE, - MEM1_SIZE, - MEM1_END, - MEM1_ARENA_BEGIN, - MEM1_ARENA_END, - MEM2_SIZE, - MEM2_SIZE, - 0x93600000, - MEM2_ARENA_BEGIN, - 0x935E0000, - 0x935E0000, - 0x93600000, - HOLLYWOOD_REVISION, - RAM_VENDOR_MIOS, - PLACEHOLDER, - PLACEHOLDER, - PLACEHOLDER, - }}}; - -static void EnqueueEvent(u64 userdata, s64 cycles_late = 0) -{ - if (userdata & ENQUEUE_ACKNOWLEDGEMENT_FLAG) - { - s_ack_queue.push_back(static_cast(userdata)); - } - else if (userdata & ENQUEUE_REQUEST_FLAG) - { - s_request_queue.push_back(static_cast(userdata)); - } - else - { - s_reply_queue.push_back(static_cast(userdata)); - } - Update(); -} - -static void SDIO_EventNotify_CPUThread(u64 userdata, s64 cycles_late) -{ - auto device = static_cast(GetDeviceByName("/dev/sdio/slot0").get()); - if (device) - device->EventNotify(); -} - -// The title ID is a u64 where the first 32 bits are used for the title type. -// For IOS title IDs, the type will always be 00000001 (system), and the lower 32 bits -// are used for the IOS major version -- which is what we want here. -u32 GetVersion() -{ - return static_cast(s_active_title_id); -} - -static bool SetupMemory(u64 ios_title_id, MemorySetupType setup_type) -{ - auto target_imv = std::find_if( - ios_memory_values.begin(), ios_memory_values.end(), - [&](const IosMemoryValues& imv) { return imv.ios_number == (ios_title_id & 0xffff); }); - - if (target_imv == ios_memory_values.end()) - { - ERROR_LOG(IOS, "Unknown IOS version: %016" PRIx64, ios_title_id); - return false; - } - - if (setup_type == MemorySetupType::IOSReload) - { - Memory::Write_U32(target_imv->ios_version, ADDR_IOS_VERSION); - - // These values are written by the IOS kernel as part of its boot process (for IOS28 and newer). - // - // This works in a slightly different way on a real console: older IOS versions (< IOS28) all - // have the same range (933E0000 - 93400000), thus they don't write it at boot and just inherit - // all values. However, the range has changed since IOS28. To make things work properly - // after a reload, newer IOSes always write the legacy range before loading an IOS kernel; - // the new IOS either updates the range (>= IOS28) or inherits it (< IOS28). - // - // We can skip this convoluted process and just write the correct range directly. - Memory::Write_U32(target_imv->mem2_physical_size, ADDR_MEM2_SIZE); - Memory::Write_U32(target_imv->mem2_simulated_size, ADDR_MEM2_SIM_SIZE); - Memory::Write_U32(target_imv->mem2_end, ADDR_MEM2_END); - Memory::Write_U32(target_imv->mem2_arena_begin, ADDR_MEM2_ARENA_BEGIN); - Memory::Write_U32(target_imv->mem2_arena_end, ADDR_MEM2_ARENA_END); - Memory::Write_U32(target_imv->ipc_buffer_begin, ADDR_IPC_BUFFER_BEGIN); - Memory::Write_U32(target_imv->ipc_buffer_end, ADDR_IPC_BUFFER_END); - Memory::Write_U32(target_imv->unknown_begin, ADDR_UNKNOWN_BEGIN); - Memory::Write_U32(target_imv->unknown_end, ADDR_UNKNOWN_END); - - return true; - } - - Memory::Write_U32(target_imv->mem1_physical_size, ADDR_MEM1_SIZE); - Memory::Write_U32(target_imv->mem1_simulated_size, ADDR_MEM1_SIM_SIZE); - Memory::Write_U32(target_imv->mem1_end, ADDR_MEM1_END); - Memory::Write_U32(target_imv->mem1_arena_begin, ADDR_MEM1_ARENA_BEGIN); - Memory::Write_U32(target_imv->mem1_arena_end, ADDR_MEM1_ARENA_END); - Memory::Write_U32(PLACEHOLDER, ADDR_PH1); - Memory::Write_U32(target_imv->mem2_physical_size, ADDR_MEM2_SIZE); - Memory::Write_U32(target_imv->mem2_simulated_size, ADDR_MEM2_SIM_SIZE); - Memory::Write_U32(target_imv->mem2_end, ADDR_MEM2_END); - Memory::Write_U32(target_imv->mem2_arena_begin, ADDR_MEM2_ARENA_BEGIN); - Memory::Write_U32(target_imv->mem2_arena_end, ADDR_MEM2_ARENA_END); - Memory::Write_U32(PLACEHOLDER, ADDR_PH2); - Memory::Write_U32(target_imv->ipc_buffer_begin, ADDR_IPC_BUFFER_BEGIN); - Memory::Write_U32(target_imv->ipc_buffer_end, ADDR_IPC_BUFFER_END); - Memory::Write_U32(target_imv->hollywood_revision, ADDR_HOLLYWOOD_REVISION); - Memory::Write_U32(PLACEHOLDER, ADDR_PH3); - Memory::Write_U32(target_imv->ios_version, ADDR_IOS_VERSION); - Memory::Write_U32(target_imv->ios_date, ADDR_IOS_DATE); - Memory::Write_U32(target_imv->unknown_begin, ADDR_UNKNOWN_BEGIN); - Memory::Write_U32(target_imv->unknown_end, ADDR_UNKNOWN_END); - Memory::Write_U32(PLACEHOLDER, ADDR_PH4); - Memory::Write_U32(PLACEHOLDER, ADDR_PH5); - Memory::Write_U32(target_imv->ram_vendor, ADDR_RAM_VENDOR); - Memory::Write_U8(0xDE, ADDR_BOOT_FLAG); - Memory::Write_U8(0xAD, ADDR_APPLOADER_FLAG); - Memory::Write_U16(0xBEEF, ADDR_DEVKIT_BOOT_PROGRAM_VERSION); - Memory::Write_U32(target_imv->sysmenu_sync, ADDR_SYSMENU_SYNC); - return true; -} - -static u32 num_devices; - -template -std::shared_ptr AddDevice(const char* device_name) -{ - auto device = std::make_shared(num_devices, device_name); - _assert_(device->GetDeviceType() == Device::Device::DeviceType::Static); - s_device_map[num_devices] = device; - num_devices++; - return device; -} - -static void AddStaticDevices() -{ - std::lock_guard lock(s_device_map_mutex); - _assert_msg_(IOS, s_device_map.empty(), "Reinit called while already initialized"); - - num_devices = 0; - - // Build hardware devices - if (!SConfig::GetInstance().m_bt_passthrough_enabled) - AddDevice("/dev/usb/oh1/57e/305"); - else - AddDevice("/dev/usb/oh1/57e/305"); - - AddDevice("/dev/stm/immediate"); - AddDevice("/dev/stm/eventhook"); - AddDevice("/dev/fs"); - AddDevice("/dev/es"); - AddDevice("/dev/di"); - AddDevice("/dev/net/kd/request"); - AddDevice("/dev/net/kd/time"); - AddDevice("/dev/net/ncd/manage"); - AddDevice("/dev/net/wd/command"); - AddDevice("/dev/net/ip/top"); - AddDevice("/dev/net/ssl"); - AddDevice("/dev/usb/kbd"); - AddDevice("/dev/sdio/slot0"); - AddDevice("/dev/sdio/slot1"); - AddDevice("/dev/usb/hid"); - AddDevice("/dev/usb/oh0"); - AddDevice("/dev/usb/oh1"); - AddDevice("/dev/usb/ven"); - AddDevice("/dev/usb/wfssrv"); - AddDevice("/dev/wfsi"); -} - -// IOS used by the latest System Menu (4.3). -constexpr u64 IOS80_TITLE_ID = 0x0000000100000050; - -void Init() -{ - s_event_enqueue = CoreTiming::RegisterEvent("IPCEvent", EnqueueEvent); - s_event_sdio_notify = CoreTiming::RegisterEvent("SDIO_EventNotify", SDIO_EventNotify_CPUThread); - - // On a Wii, boot2 launches the system menu IOS, which then launches the system menu - // (which bootstraps the PPC). This means that after a normal boot process, the constants - // in the 0x3100 region will always have been set up. - // This is necessary because booting games from the game list skips a significant part - // of a Wii's boot process. - SetupMemory(IOS80_TITLE_ID, MemorySetupType::Full); -} - -static void Reset() -{ - CoreTiming::RemoveAllEvents(s_event_enqueue); - - // Close all devices that were opened and delete their resources - for (auto& device : s_fdmap) - { - if (!device) - continue; - device->Close(0); - device.reset(); - } - - { - std::lock_guard lock(s_device_map_mutex); - s_device_map.clear(); - } - - s_request_queue.clear(); - s_reply_queue.clear(); - - s_last_reply_time = 0; -} - -void Shutdown() -{ - Reset(); -} - -constexpr u64 BC_TITLE_ID = 0x0000000100000100; -constexpr u64 MIOS_TITLE_ID = 0x0000000100000101; - -// Similar to syscall 0x42 (ios_boot); this is used to change the current active IOS. -// IOS writes the new version to 0x3140 before restarting, but it does *not* poke any -// of the other constants to the memory. -bool Reload(const u64 ios_title_id) -{ - // A real Wii goes through several steps before getting to MIOS. - // - // * The System Menu detects a GameCube disc and launches BC (1-100) instead of the game. - // * BC (similar to boot1) lowers the clock speed to the Flipper's and then launches boot2. - // * boot2 sees the lowered clock speed and launches MIOS (1-101) instead of the System Menu. - // - // Because we currently don't have boot1 and boot2, and BC is only ever used to launch MIOS - // (indirectly via boot2), we can just launch MIOS when BC is launched. - if (ios_title_id == BC_TITLE_ID) - { - NOTICE_LOG(IOS, "BC: Launching MIOS..."); - return Reload(MIOS_TITLE_ID); - } - - if (!SetupMemory(ios_title_id, MemorySetupType::IOSReload)) - return false; - - s_active_title_id = ios_title_id; - Reset(); - - if (ios_title_id == MIOS_TITLE_ID) - { - // MIOS is a special case. It does not have the same syscalls as regular IOSes - // and writes the magic values at a different time (here) in the boot process. - SetupMemory(ios_title_id, MemorySetupType::Full); - return MIOS::Load(); - } - - AddStaticDevices(); - - return true; -} - -// Since we don't have actual processes, we keep track of only the PPC's UID/GID. -// These functions roughly correspond to syscalls 0x2b, 0x2c, 0x2d, 0x2e (though only for the PPC). -void SetUIDForPPC(u32 uid) -{ - s_ppc_uid = uid; -} - -u32 GetUIDForPPC() -{ - return s_ppc_uid; -} - -void SetGIDForPPC(u16 gid) -{ - s_ppc_gid = gid; -} - -u16 GetGIDForPPC() -{ - return s_ppc_gid; -} - -// This corresponds to syscall 0x41, which loads a binary from the NAND and bootstraps the PPC. -// Unlike 0x42, IOS will set up some constants in memory before booting the PPC. -bool BootstrapPPC(const DiscIO::CNANDContentLoader& content_loader) -{ - if (!content_loader.IsValid()) - return false; - - const auto* content = content_loader.GetContentByIndex(content_loader.GetTMD().GetBootIndex()); - if (!content) - return false; - - const auto dol_loader = std::make_unique(content->m_Data->Get()); - if (!dol_loader->IsValid()) - return false; - - if (!SetupMemory(s_active_title_id, MemorySetupType::Full)) - return false; - - dol_loader->Load(); - - // NAND titles start with address translation off at 0x3400 (via the PPC bootstub) - // The state of other CPU registers (like the BAT registers) doesn't matter much - // because the realmode code at 0x3400 initializes everything itself anyway. - MSR = 0; - PC = 0x3400; - - return true; -} - -void SDIO_EventNotify() -{ - // TODO: Potential race condition: If IsRunning() becomes false after - // it's checked, an event may be scheduled after CoreTiming shuts down. - if (SConfig::GetInstance().bWii && Core::IsRunning()) - CoreTiming::ScheduleEvent(0, s_event_sdio_notify, 0, CoreTiming::FromThread::NON_CPU); -} - -static int GetFreeDeviceID() -{ - for (u32 i = 0; i < IPC_MAX_FDS; i++) - { - if (s_fdmap[i] == nullptr) - { - return i; - } - } - - return -1; -} - -std::shared_ptr GetDeviceByName(const std::string& device_name) -{ - std::lock_guard lock(s_device_map_mutex); - for (const auto& entry : s_device_map) - { - if (entry.second && entry.second->GetDeviceName() == device_name) - { - return entry.second; - } - } - - return nullptr; -} - -std::shared_ptr AccessDeviceByID(u32 id) -{ - std::lock_guard lock(s_device_map_mutex); - if (s_device_map.find(id) != s_device_map.end()) - { - return s_device_map[id]; - } - - return nullptr; -} - -void DoState(PointerWrap& p) -{ - p.Do(s_request_queue); - p.Do(s_reply_queue); - p.Do(s_last_reply_time); - p.Do(s_active_title_id); - p.Do(s_ppc_uid); - p.Do(s_ppc_gid); - - if (s_active_title_id == MIOS_TITLE_ID) - return; - - // We need to make sure all file handles are closed so IOS::HLE::Device::FS::DoState can - // successfully save or re-create /tmp - for (auto& descriptor : s_fdmap) - { - if (descriptor) - descriptor->PrepareForState(p.GetMode()); - } - - for (const auto& entry : s_device_map) - entry.second->DoState(p); - - if (p.GetMode() == PointerWrap::MODE_READ) - { - for (u32 i = 0; i < IPC_MAX_FDS; i++) - { - u32 exists = 0; - p.Do(exists); - if (exists) - { - auto device_type = Device::Device::DeviceType::Static; - p.Do(device_type); - switch (device_type) - { - case Device::Device::DeviceType::Static: - { - u32 device_id = 0; - p.Do(device_id); - s_fdmap[i] = AccessDeviceByID(device_id); - break; - } - case Device::Device::DeviceType::FileIO: - s_fdmap[i] = std::make_shared(i, ""); - s_fdmap[i]->DoState(p); - break; - case Device::Device::DeviceType::OH0: - s_fdmap[i] = std::make_shared(i, ""); - s_fdmap[i]->DoState(p); - break; - } - } - } - } - else - { - for (auto& descriptor : s_fdmap) - { - u32 exists = descriptor ? 1 : 0; - p.Do(exists); - if (exists) - { - auto device_type = descriptor->GetDeviceType(); - p.Do(device_type); - if (device_type == Device::Device::DeviceType::Static) - { - u32 hwId = descriptor->GetDeviceID(); - p.Do(hwId); - } - else - { - descriptor->DoState(p); - } - } - } - } -} - -// Returns the FD for the newly opened device (on success) or an error code. -static s32 OpenDevice(OpenRequest& request) -{ - const s32 new_fd = GetFreeDeviceID(); - INFO_LOG(IOS, "Opening %s (mode %d, fd %d)", request.path.c_str(), request.flags, new_fd); - if (new_fd < 0 || new_fd >= IPC_MAX_FDS) - { - ERROR_LOG(IOS, "Couldn't get a free fd, too many open files"); - return FS_EFDEXHAUSTED; - } - request.fd = new_fd; - - std::shared_ptr device; - if (request.path.find("/dev/usb/oh0/") == 0 && !GetDeviceByName(request.path)) - { - device = std::make_shared(new_fd, request.path); - } - else if (request.path.find("/dev/") == 0) - { - device = GetDeviceByName(request.path); - } - else if (request.path.find('/') == 0) - { - device = std::make_shared(new_fd, request.path); - } - - if (!device) - { - ERROR_LOG(IOS, "Unknown device: %s", request.path.c_str()); - return IPC_ENOENT; - } - - const ReturnCode code = device->Open(request); - if (code < IPC_SUCCESS) - return code; - s_fdmap[new_fd] = device; - return new_fd; -} - -static IPCCommandResult HandleCommand(const Request& request) -{ - if (request.command == IPC_CMD_OPEN) - { - OpenRequest open_request{request.address}; - const s32 new_fd = OpenDevice(open_request); - return Device::Device::GetDefaultReply(new_fd); - } - - const auto device = (request.fd < IPC_MAX_FDS) ? s_fdmap[request.fd] : nullptr; - if (!device) - return Device::Device::GetDefaultReply(IPC_EINVAL); - - switch (request.command) - { - case IPC_CMD_CLOSE: - s_fdmap[request.fd].reset(); - return Device::Device::GetDefaultReply(device->Close(request.fd)); - case IPC_CMD_READ: - return device->Read(ReadWriteRequest{request.address}); - case IPC_CMD_WRITE: - return device->Write(ReadWriteRequest{request.address}); - case IPC_CMD_SEEK: - return device->Seek(SeekRequest{request.address}); - case IPC_CMD_IOCTL: - return device->IOCtl(IOCtlRequest{request.address}); - case IPC_CMD_IOCTLV: - return device->IOCtlV(IOCtlVRequest{request.address}); - default: - _assert_msg_(IOS, false, "Unexpected command: %x", request.command); - return Device::Device::GetDefaultReply(IPC_EINVAL); - } -} - -void ExecuteCommand(const u32 address) -{ - Request request{address}; - IPCCommandResult result = HandleCommand(request); - - // Ensure replies happen in order - const s64 ticks_until_last_reply = s_last_reply_time - CoreTiming::GetTicks(); - if (ticks_until_last_reply > 0) - result.reply_delay_ticks += ticks_until_last_reply; - s_last_reply_time = CoreTiming::GetTicks() + result.reply_delay_ticks; - - if (result.send_reply) - EnqueueReply(request, result.return_value, static_cast(result.reply_delay_ticks)); -} - -// Happens AS SOON AS IPC gets a new pointer! -void EnqueueRequest(u32 address) -{ - CoreTiming::ScheduleEvent(1000, s_event_enqueue, address | ENQUEUE_REQUEST_FLAG); -} - -// Called to send a reply to an IOS syscall -void EnqueueReply(const Request& request, const s32 return_value, int cycles_in_future, - CoreTiming::FromThread from) -{ - Memory::Write_U32(static_cast(return_value), request.address + 4); - // IOS writes back the command that was responded to in the FD field. - Memory::Write_U32(request.command, request.address + 8); - // IOS also overwrites the command type with the reply type. - Memory::Write_U32(IPC_REPLY, request.address); - CoreTiming::ScheduleEvent(cycles_in_future, s_event_enqueue, request.address, from); -} - -void EnqueueCommandAcknowledgement(u32 address, int cycles_in_future) -{ - CoreTiming::ScheduleEvent(cycles_in_future, s_event_enqueue, - address | ENQUEUE_ACKNOWLEDGEMENT_FLAG); -} - -// This is called every IPC_HLE_PERIOD from SystemTimers.cpp -// Takes care of routing ipc <-> ipc HLE -void Update() -{ - if (!IsReady()) - return; - - if (s_request_queue.size()) - { - GenerateAck(s_request_queue.front()); - DEBUG_LOG(IOS, "||-- Acknowledge IPC Request @ 0x%08x", s_request_queue.front()); - u32 command = s_request_queue.front(); - s_request_queue.pop_front(); - ExecuteCommand(command); - return; - } - - if (s_reply_queue.size()) - { - GenerateReply(s_reply_queue.front()); - DEBUG_LOG(IOS, "<<-- Reply to IPC Request @ 0x%08x", s_reply_queue.front()); - s_reply_queue.pop_front(); - return; - } - - if (s_ack_queue.size()) - { - GenerateAck(s_ack_queue.front()); - WARN_LOG(IOS, "<<-- Double-ack to IPC Request @ 0x%08x", s_ack_queue.front()); - s_ack_queue.pop_front(); - return; - } -} - -void UpdateDevices() -{ - // Check if a hardware device must be updated - for (const auto& entry : s_device_map) - { - if (entry.second->IsOpened()) - { - entry.second->Update(); - } - } -} - -void UpdateWantDeterminism(const bool new_want_determinism) -{ - WiiSockMan::GetInstance().UpdateWantDeterminism(new_want_determinism); - for (const auto& device : s_device_map) - device.second->UpdateWantDeterminism(new_want_determinism); -} -} // namespace HLE -} // namespace IOS diff --git a/Source/Core/Core/IOS/IPC.h b/Source/Core/Core/IOS/IPC.h deleted file mode 100644 index 0d9e93ad70..0000000000 --- a/Source/Core/Core/IOS/IPC.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2008 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include -#include -#include - -#include "Common/CommonTypes.h" -#include "Core/CoreTiming.h" -#include "Core/HW/SystemTimers.h" - -class PointerWrap; - -namespace DiscIO -{ -class CNANDContentLoader; -} - -namespace IOS -{ -namespace HLE -{ -namespace Device -{ -class Device; -} - -struct Request; - -struct IPCCommandResult -{ - s32 return_value; - bool send_reply; - u64 reply_delay_ticks; -}; - -enum IPCCommandType : u32 -{ - IPC_CMD_OPEN = 1, - IPC_CMD_CLOSE = 2, - IPC_CMD_READ = 3, - IPC_CMD_WRITE = 4, - IPC_CMD_SEEK = 5, - IPC_CMD_IOCTL = 6, - IPC_CMD_IOCTLV = 7, - // This is used for replies to commands. - IPC_REPLY = 8, -}; - -// Init events and devices -void Init(); -// Shutdown -void Shutdown(); - -// Reload IOS (to a possibly different version); write the new version to 0x3140 and set up devices. -bool Reload(u64 ios_title_id); -u32 GetVersion(); - -void SetUIDForPPC(u32 uid); -u32 GetUIDForPPC(); -void SetGIDForPPC(u16 gid); -u16 GetGIDForPPC(); - -bool BootstrapPPC(const DiscIO::CNANDContentLoader& content_loader); - -// Do State -void DoState(PointerWrap& p); - -void SDIO_EventNotify(); - -std::shared_ptr GetDeviceByName(const std::string& device_name); -std::shared_ptr AccessDeviceByID(u32 id); - -// Update -void Update(); - -// Update Devices -void UpdateDevices(); - -void UpdateWantDeterminism(bool new_want_determinism); - -void ExecuteCommand(u32 address); - -void EnqueueRequest(u32 address); -void EnqueueReply(const Request& request, s32 return_value, int cycles_in_future = 0, - CoreTiming::FromThread from = CoreTiming::FromThread::CPU); -void EnqueueCommandAcknowledgement(u32 address, int cycles_in_future = 0); -} // namespace HLE -} // namespace IOS diff --git a/Source/Core/Core/IOS/MemoryValues.cpp b/Source/Core/Core/IOS/MemoryValues.cpp new file mode 100644 index 0000000000..2d0bca4626 --- /dev/null +++ b/Source/Core/Core/IOS/MemoryValues.cpp @@ -0,0 +1,329 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "Core/IOS/MemoryValues.h" +#include "Common/CommonTypes.h" + +namespace IOS +{ +namespace HLE +{ +constexpr u32 MEM1_SIZE = 0x01800000; +constexpr u32 MEM1_END = 0x81800000; +constexpr u32 MEM1_ARENA_BEGIN = 0x00000000; +constexpr u32 MEM1_ARENA_END = 0x81800000; +constexpr u32 MEM2_SIZE = 0x4000000; +constexpr u32 MEM2_ARENA_BEGIN = 0x90000800; +constexpr u32 HOLLYWOOD_REVISION = 0x00000011; +constexpr u32 PLACEHOLDER = 0xDEADBEEF; +constexpr u32 RAM_VENDOR = 0x0000FF01; +constexpr u32 RAM_VENDOR_MIOS = 0xCAFEBABE; + +// These values were manually extracted from the relevant IOS binaries. +// The writes are usually contained in a single function that +// mostly writes raw literals to the relevant locations. +// e.g. IOS9, version 1034, content id 0x00000006, function at 0xffff6884 +constexpr std::array ios_memory_values = { + {{ + 9, 0x9040a, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, + }, + { + 11, 0xb000a, 0x102506, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, + }, + { + 12, 0xc020e, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, + }, + { + 13, 0xd0408, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, + }, + { + 14, 0xe0408, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, + }, + { + 15, 0xf0408, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, + }, + { + 17, 0x110408, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, + }, + { + 20, 0x14000c, 0x102506, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, + }, + { + 21, 0x15040f, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, + }, + { + 22, 0x16050e, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93400000, MEM2_ARENA_BEGIN, + 0x933E0000, 0x933E0000, 0x93400000, HOLLYWOOD_REVISION, + RAM_VENDOR, PLACEHOLDER, PLACEHOLDER, 0, + }, + { + 28, 0x1c070f, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93800000, MEM2_ARENA_BEGIN, + 0x937E0000, 0x937E0000, 0x93800000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93800000, 0x93820000, 0, + }, + { + 30, 0x1e0a10, 0x40308, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 31, 0x1f0e18, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 33, 0x210e18, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 34, 0x220e18, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 35, 0x230e18, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 36, 0x240e18, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 37, 0x25161f, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 38, 0x26101c, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 40, 0x280911, 0x022308, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 41, 0x290e17, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 43, 0x2b0e17, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 45, 0x2d0e17, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 46, 0x2e0e17, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 48, 0x30101c, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 50, 0x321319, 0x101008, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 51, 0x331219, 0x071108, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 52, 0x34161d, 0x101008, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 53, 0x35161f, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 55, 0x37161f, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 56, 0x38161e, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 57, 0x39171f, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 58, 0x3a1820, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 59, 0x3b1c21, 0x101811, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 60, 0x3c181e, 0x112408, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 61, 0x3d161e, 0x030110, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 62, 0x3e191e, 0x022712, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 70, 0x461a1f, 0x060309, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 80, 0x501b20, 0x030310, MEM1_SIZE, + MEM1_SIZE, MEM1_END, MEM1_ARENA_BEGIN, MEM1_ARENA_END, + MEM2_SIZE, MEM2_SIZE, 0x93600000, MEM2_ARENA_BEGIN, + 0x935E0000, 0x935E0000, 0x93600000, HOLLYWOOD_REVISION, + RAM_VENDOR, 0x93600000, 0x93620000, 0, + }, + { + 257, + 0x707, + 0x82209, + MEM1_SIZE, + MEM1_SIZE, + MEM1_END, + MEM1_ARENA_BEGIN, + MEM1_ARENA_END, + MEM2_SIZE, + MEM2_SIZE, + 0x93600000, + MEM2_ARENA_BEGIN, + 0x935E0000, + 0x935E0000, + 0x93600000, + HOLLYWOOD_REVISION, + RAM_VENDOR_MIOS, + PLACEHOLDER, + PLACEHOLDER, + PLACEHOLDER, + }}}; + +const std::array& GetMemoryValues() +{ + return ios_memory_values; +} +} +} diff --git a/Source/Core/Core/IOS/MemoryValues.h b/Source/Core/Core/IOS/MemoryValues.h new file mode 100644 index 0000000000..f2478a9d8a --- /dev/null +++ b/Source/Core/Core/IOS/MemoryValues.h @@ -0,0 +1,41 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "Common/CommonTypes.h" + +namespace IOS +{ +namespace HLE +{ +struct MemoryValues +{ + u16 ios_number; + u32 ios_version; + u32 ios_date; + u32 mem1_physical_size; + u32 mem1_simulated_size; + u32 mem1_end; + u32 mem1_arena_begin; + u32 mem1_arena_end; + u32 mem2_physical_size; + u32 mem2_simulated_size; + u32 mem2_end; + u32 mem2_arena_begin; + u32 mem2_arena_end; + u32 ipc_buffer_begin; + u32 ipc_buffer_end; + u32 hollywood_revision; + u32 ram_vendor; + u32 unknown_begin; + u32 unknown_end; + u32 sysmenu_sync; +}; + +const std::array& GetMemoryValues(); +} +} diff --git a/Source/Core/Core/IOS/Network/IP/Top.cpp b/Source/Core/Core/IOS/Network/IP/Top.cpp index 30288e229b..91e4d81526 100644 --- a/Source/Core/Core/IOS/Network/IP/Top.cpp +++ b/Source/Core/Core/IOS/Network/IP/Top.cpp @@ -61,7 +61,7 @@ namespace HLE { namespace Device { -NetIPTop::NetIPTop(u32 device_id, const std::string& device_name) : Device(device_id, device_name) +NetIPTop::NetIPTop(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { #ifdef _WIN32 int ret = WSAStartup(MAKEWORD(2, 2), &InitData); diff --git a/Source/Core/Core/IOS/Network/IP/Top.h b/Source/Core/Core/IOS/Network/IP/Top.h index 24b9d4ee5e..7d531d3d3c 100644 --- a/Source/Core/Core/IOS/Network/IP/Top.h +++ b/Source/Core/Core/IOS/Network/IP/Top.h @@ -61,7 +61,7 @@ namespace Device class NetIPTop : public Device { public: - NetIPTop(u32 device_id, const std::string& device_name); + NetIPTop(Kernel& ios, const std::string& device_name); virtual ~NetIPTop(); IPCCommandResult IOCtl(const IOCtlRequest& request) override; diff --git a/Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp b/Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp index 0feb9e1393..48c9e27da0 100644 --- a/Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp +++ b/Source/Core/Core/IOS/Network/KD/NetKDRequest.cpp @@ -24,8 +24,7 @@ namespace HLE { namespace Device { -NetKDRequest::NetKDRequest(u32 device_id, const std::string& device_name) - : Device(device_id, device_name) +NetKDRequest::NetKDRequest(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { } diff --git a/Source/Core/Core/IOS/Network/KD/NetKDRequest.h b/Source/Core/Core/IOS/Network/KD/NetKDRequest.h index eeb7c48b31..f35c71bf9e 100644 --- a/Source/Core/Core/IOS/Network/KD/NetKDRequest.h +++ b/Source/Core/Core/IOS/Network/KD/NetKDRequest.h @@ -22,7 +22,7 @@ namespace Device class NetKDRequest : public Device { public: - NetKDRequest(u32 device_id, const std::string& device_name); + NetKDRequest(Kernel& ios, const std::string& device_name); ~NetKDRequest() override; IPCCommandResult IOCtl(const IOCtlRequest& request) override; diff --git a/Source/Core/Core/IOS/Network/KD/NetKDTime.cpp b/Source/Core/Core/IOS/Network/KD/NetKDTime.cpp index a6ce019448..a9f0be3132 100644 --- a/Source/Core/Core/IOS/Network/KD/NetKDTime.cpp +++ b/Source/Core/Core/IOS/Network/KD/NetKDTime.cpp @@ -16,7 +16,7 @@ namespace HLE { namespace Device { -NetKDTime::NetKDTime(u32 device_id, const std::string& device_name) : Device(device_id, device_name) +NetKDTime::NetKDTime(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { } diff --git a/Source/Core/Core/IOS/Network/KD/NetKDTime.h b/Source/Core/Core/IOS/Network/KD/NetKDTime.h index 04cce2d68f..be22e1e3a8 100644 --- a/Source/Core/Core/IOS/Network/KD/NetKDTime.h +++ b/Source/Core/Core/IOS/Network/KD/NetKDTime.h @@ -18,7 +18,7 @@ namespace Device class NetKDTime : public Device { public: - NetKDTime(u32 device_id, const std::string& device_name); + NetKDTime(Kernel& ios, const std::string& device_name); ~NetKDTime() override; IPCCommandResult IOCtl(const IOCtlRequest& request) override; diff --git a/Source/Core/Core/IOS/Network/NCD/Manage.cpp b/Source/Core/Core/IOS/Network/NCD/Manage.cpp index da6ef5978f..410c3bc863 100644 --- a/Source/Core/Core/IOS/Network/NCD/Manage.cpp +++ b/Source/Core/Core/IOS/Network/NCD/Manage.cpp @@ -19,8 +19,7 @@ namespace HLE { namespace Device { -NetNCDManage::NetNCDManage(u32 device_id, const std::string& device_name) - : Device(device_id, device_name) +NetNCDManage::NetNCDManage(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { } diff --git a/Source/Core/Core/IOS/Network/NCD/Manage.h b/Source/Core/Core/IOS/Network/NCD/Manage.h index fbf5df4ac3..c4ce453697 100644 --- a/Source/Core/Core/IOS/Network/NCD/Manage.h +++ b/Source/Core/Core/IOS/Network/NCD/Manage.h @@ -20,7 +20,7 @@ namespace Device class NetNCDManage : public Device { public: - NetNCDManage(u32 device_id, const std::string& device_name); + NetNCDManage(Kernel& ios, const std::string& device_name); IPCCommandResult IOCtlV(const IOCtlVRequest& request) override; diff --git a/Source/Core/Core/IOS/Network/SSL.cpp b/Source/Core/Core/IOS/Network/SSL.cpp index 21e67b41f8..ca3160bee8 100644 --- a/Source/Core/Core/IOS/Network/SSL.cpp +++ b/Source/Core/Core/IOS/Network/SSL.cpp @@ -37,7 +37,7 @@ static constexpr mbedtls_x509_crt_profile mbedtls_x509_crt_profile_wii = { 0, /* No RSA min key size */ }; -NetSSL::NetSSL(u32 device_id, const std::string& device_name) : Device(device_id, device_name) +NetSSL::NetSSL(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { for (WII_SSL& ssl : _SSL) { diff --git a/Source/Core/Core/IOS/Network/SSL.h b/Source/Core/Core/IOS/Network/SSL.h index 91a41600e0..f1f9f4c611 100644 --- a/Source/Core/Core/IOS/Network/SSL.h +++ b/Source/Core/Core/IOS/Network/SSL.h @@ -19,7 +19,7 @@ // clang-format on #include "Common/CommonTypes.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/Device.h" namespace IOS @@ -90,7 +90,7 @@ namespace Device class NetSSL : public Device { public: - NetSSL(u32 device_id, const std::string& device_name); + NetSSL(Kernel& ios, const std::string& device_name); virtual ~NetSSL(); diff --git a/Source/Core/Core/IOS/Network/Socket.cpp b/Source/Core/Core/IOS/Network/Socket.cpp index caf67861ca..3765e3bd75 100644 --- a/Source/Core/Core/IOS/Network/Socket.cpp +++ b/Source/Core/Core/IOS/Network/Socket.cpp @@ -16,7 +16,7 @@ #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/Network/Socket.h" // No Wii socket support while using NetPlay or TAS #ifdef _WIN32 @@ -579,7 +579,8 @@ void WiiSocket::Update(bool read, bool write, bool except) it->is_ssl ? (int)it->ssl_type : (int)it->net_type, ReturnValue, nonBlock, forceNonBlock); - EnqueueReply(it->request, ReturnValue); + // TODO: remove the dependency on a running IOS instance. + GetIOS()->EnqueueIPCReply(it->request, ReturnValue); it = pending_sockops.erase(it); } else diff --git a/Source/Core/Core/IOS/Network/Socket.h b/Source/Core/Core/IOS/Network/Socket.h index acacf48c82..de9d4b4761 100644 --- a/Source/Core/Core/IOS/Network/Socket.h +++ b/Source/Core/Core/IOS/Network/Socket.h @@ -52,7 +52,7 @@ typedef struct pollfd pollfd_t; #include "Common/Logging/Log.h" #include "Common/NonCopyable.h" #include "Core/HW/Memmap.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/Network/IP/Top.h" #include "Core/IOS/Network/SSL.h" @@ -234,7 +234,7 @@ public: { ERROR_LOG(IOS_NET, "DoSock: Error, fd not found (%08x, %08X, %08X)", sock, request.address, type); - EnqueueReply(request, -SO_EBADF); + GetIOS()->EnqueueIPCReply(request, -SO_EBADF); } else { diff --git a/Source/Core/Core/IOS/Network/WD/Command.cpp b/Source/Core/Core/IOS/Network/WD/Command.cpp index 3cbbcf9296..9de91a1291 100644 --- a/Source/Core/Core/IOS/Network/WD/Command.cpp +++ b/Source/Core/Core/IOS/Network/WD/Command.cpp @@ -21,8 +21,7 @@ namespace HLE { namespace Device { -NetWDCommand::NetWDCommand(u32 device_id, const std::string& device_name) - : Device(device_id, device_name) +NetWDCommand::NetWDCommand(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { } diff --git a/Source/Core/Core/IOS/Network/WD/Command.h b/Source/Core/Core/IOS/Network/WD/Command.h index 3b0decc48a..0c9ac96d68 100644 --- a/Source/Core/Core/IOS/Network/WD/Command.h +++ b/Source/Core/Core/IOS/Network/WD/Command.h @@ -18,7 +18,7 @@ namespace Device class NetWDCommand : public Device { public: - NetWDCommand(u32 device_id, const std::string& device_name); + NetWDCommand(Kernel& ios, const std::string& device_name); IPCCommandResult IOCtlV(const IOCtlVRequest& request) override; diff --git a/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp b/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp index 4987fae39b..3884baefdb 100644 --- a/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp +++ b/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp @@ -14,7 +14,7 @@ #include "Common/SDCardUtil.h" #include "Core/ConfigManager.h" #include "Core/HW/Memmap.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/SDIO/SDIOSlot0.h" namespace IOS @@ -23,7 +23,7 @@ namespace HLE { namespace Device { -SDIOSlot0::SDIOSlot0(u32 device_id, const std::string& device_name) : Device(device_id, device_name) +SDIOSlot0::SDIOSlot0(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { } @@ -49,7 +49,7 @@ void SDIOSlot0::EventNotify() if ((SConfig::GetInstance().m_WiiSDCard && m_event->type == EVENT_INSERT) || (!SConfig::GetInstance().m_WiiSDCard && m_event->type == EVENT_REMOVE)) { - EnqueueReply(m_event->request, m_event->type); + m_ios.EnqueueIPCReply(m_event->request, m_event->type); m_event.reset(); } } @@ -302,7 +302,7 @@ u32 SDIOSlot0::ExecuteCommand(const Request& request, u32 _BufferIn, u32 _Buffer // release returns 0 // unknown sd int // technically we do it out of order, oh well - EnqueueReply(m_event->request, EVENT_INVALID); + m_ios.EnqueueIPCReply(m_event->request, EVENT_INVALID); m_event.reset(); break; } diff --git a/Source/Core/Core/IOS/SDIO/SDIOSlot0.h b/Source/Core/Core/IOS/SDIO/SDIOSlot0.h index 116625f29b..55bfabf8da 100644 --- a/Source/Core/Core/IOS/SDIO/SDIOSlot0.h +++ b/Source/Core/Core/IOS/SDIO/SDIOSlot0.h @@ -12,7 +12,7 @@ #include "Common/CommonTypes.h" #include "Common/FileUtil.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" class PointerWrap; @@ -26,7 +26,7 @@ namespace Device class SDIOSlot0 : public Device { public: - SDIOSlot0(u32 device_id, const std::string& device_name); + SDIOSlot0(Kernel& ios, const std::string& device_name); void DoState(PointerWrap& p) override; diff --git a/Source/Core/Core/IOS/STM/STM.cpp b/Source/Core/Core/IOS/STM/STM.cpp index aece7e39fa..b9c02c1f79 100644 --- a/Source/Core/Core/IOS/STM/STM.cpp +++ b/Source/Core/Core/IOS/STM/STM.cpp @@ -39,7 +39,7 @@ IPCCommandResult STMImmediate::IOCtl(const IOCtlRequest& request) break; } Memory::Write_U32(0, s_event_hook_request->buffer_out); - EnqueueReply(*s_event_hook_request, IPC_SUCCESS); + m_ios.EnqueueIPCReply(*s_event_hook_request, IPC_SUCCESS); s_event_hook_request.reset(); break; @@ -109,7 +109,7 @@ void STMEventHook::TriggerEvent(const u32 event) const return; Memory::Write_U32(event, s_event_hook_request->buffer_out); - EnqueueReply(*s_event_hook_request, IPC_SUCCESS); + m_ios.EnqueueIPCReply(*s_event_hook_request, IPC_SUCCESS); s_event_hook_request.reset(); } diff --git a/Source/Core/Core/IOS/STM/STM.h b/Source/Core/Core/IOS/STM/STM.h index 6721e3c28c..e8249ba6b6 100644 --- a/Source/Core/Core/IOS/STM/STM.h +++ b/Source/Core/Core/IOS/STM/STM.h @@ -8,7 +8,7 @@ #include "Common/CommonTypes.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" class PointerWrap; @@ -46,7 +46,7 @@ namespace Device class STMImmediate final : public Device { public: - STMImmediate(u32 device_id, const std::string& device_name) : Device(device_id, device_name) {} + using Device::Device; IPCCommandResult IOCtl(const IOCtlRequest& request) override; }; @@ -54,7 +54,7 @@ public: class STMEventHook final : public Device { public: - STMEventHook(u32 device_id, const std::string& device_name) : Device(device_id, device_name) {} + using Device::Device; ReturnCode Close(u32 fd) override; IPCCommandResult IOCtl(const IOCtlRequest& request) override; void DoState(PointerWrap& p) override; diff --git a/Source/Core/Core/IOS/USB/Bluetooth/BTBase.h b/Source/Core/Core/IOS/USB/Bluetooth/BTBase.h index 55eee82b22..6fd3341122 100644 --- a/Source/Core/Core/IOS/USB/Bluetooth/BTBase.h +++ b/Source/Core/Core/IOS/USB/Bluetooth/BTBase.h @@ -9,7 +9,7 @@ #include "Common/CommonTypes.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" class PointerWrap; class SysConf; @@ -26,7 +26,7 @@ namespace Device class BluetoothBase : public Device { public: - BluetoothBase(u32 device_id, const std::string& device_name) : Device(device_id, device_name) {} + using Device::Device; virtual void UpdateSyncButtonState(bool is_held) {} virtual void TriggerSyncButtonPressedEvent() {} virtual void TriggerSyncButtonHeldEvent() {} diff --git a/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp b/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp index bf6c1c15d6..c0c9379979 100644 --- a/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp +++ b/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.cpp @@ -23,7 +23,7 @@ #include "Core/HW/Wiimote.h" #include "Core/Host.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/USB/Bluetooth/BTEmu.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" @@ -39,8 +39,8 @@ SQueuedEvent::SQueuedEvent(u32 size, u16 handle) : m_size(size), m_connectionHan namespace Device { -BluetoothEmu::BluetoothEmu(u32 device_id, const std::string& device_name) - : BluetoothBase(device_id, device_name) +BluetoothEmu::BluetoothEmu(Kernel& ios, const std::string& device_name) + : BluetoothBase(ios, device_name) { SysConf sysconf{Core::WantsDeterminism() ? Common::FromWhichRoot::FROM_SESSION_ROOT : Common::FromWhichRoot::FROM_CONFIGURED_ROOT}; @@ -105,14 +105,14 @@ BluetoothEmu::~BluetoothEmu() } template -static void DoStateForMessage(PointerWrap& p, std::unique_ptr& message) +static void DoStateForMessage(Kernel& ios, PointerWrap& p, std::unique_ptr& message) { u32 request_address = (message != nullptr) ? message->ios_request.address : 0; p.Do(request_address); if (request_address != 0) { IOCtlVRequest request{request_address}; - message = std::make_unique(request); + message = std::make_unique(ios, request); } } @@ -129,9 +129,9 @@ void BluetoothEmu::DoState(PointerWrap& p) p.Do(m_is_active); p.Do(m_ControllerBD); - DoStateForMessage(p, m_CtrlSetup); - DoStateForMessage(p, m_HCIEndpoint); - DoStateForMessage(p, m_ACLEndpoint); + DoStateForMessage(m_ios, p, m_CtrlSetup); + DoStateForMessage(m_ios, p, m_HCIEndpoint); + DoStateForMessage(m_ios, p, m_ACLEndpoint); p.Do(m_last_ticks); p.DoArray(m_PacketCount); p.Do(m_ScanEnable); @@ -166,7 +166,7 @@ IPCCommandResult BluetoothEmu::IOCtlV(const IOCtlVRequest& request) { case USB::IOCTLV_USBV0_CTRLMSG: // HCI command is received from the stack { - m_CtrlSetup = std::make_unique(request); + m_CtrlSetup = std::make_unique(m_ios, request); // Replies are generated inside ExecuteHCICommandMessage(*m_CtrlSetup); m_CtrlSetup.reset(); @@ -176,7 +176,7 @@ IPCCommandResult BluetoothEmu::IOCtlV(const IOCtlVRequest& request) case USB::IOCTLV_USBV0_BLKMSG: { - const USB::V0BulkMessage ctrl{request}; + const USB::V0BulkMessage ctrl{m_ios, request}; switch (ctrl.endpoint) { case ACL_DATA_OUT: // ACL data is received from the stack @@ -195,7 +195,7 @@ IPCCommandResult BluetoothEmu::IOCtlV(const IOCtlVRequest& request) } case ACL_DATA_IN: // We are given an ACL buffer to fill { - m_ACLEndpoint = std::make_unique(request); + m_ACLEndpoint = std::make_unique(m_ios, request); DEBUG_LOG(IOS_WIIMOTE, "ACL_DATA_IN: 0x%08x ", request.address); send_reply = false; break; @@ -208,10 +208,10 @@ IPCCommandResult BluetoothEmu::IOCtlV(const IOCtlVRequest& request) case USB::IOCTLV_USBV0_INTRMSG: { - const USB::V0IntrMessage ctrl{request}; + const USB::V0IntrMessage ctrl{m_ios, request}; if (ctrl.endpoint == HCI_EVENT) // We are given a HCI buffer to fill { - m_HCIEndpoint = std::make_unique(request); + m_HCIEndpoint = std::make_unique(m_ios, request); DEBUG_LOG(IOS_WIIMOTE, "HCI_EVENT: 0x%08x ", request.address); send_reply = false; } @@ -265,7 +265,7 @@ void BluetoothEmu::SendACLPacket(u16 connection_handle, const u8* data, u32 size // Write the packet to the buffer memcpy(reinterpret_cast(header) + sizeof(hci_acldata_hdr_t), data, header->length); - EnqueueReply(m_ACLEndpoint->ios_request, sizeof(hci_acldata_hdr_t) + size); + m_ios.EnqueueIPCReply(m_ACLEndpoint->ios_request, sizeof(hci_acldata_hdr_t) + size); m_ACLEndpoint.reset(); } else @@ -293,7 +293,7 @@ void BluetoothEmu::AddEventToQueue(const SQueuedEvent& _event) m_HCIEndpoint->FillBuffer(_event.m_buffer, _event.m_size); // Send a reply to indicate HCI buffer is filled - EnqueueReply(m_HCIEndpoint->ios_request, _event.m_size); + m_ios.EnqueueIPCReply(m_HCIEndpoint->ios_request, _event.m_size); m_HCIEndpoint.reset(); } else // push new one, pop oldest @@ -309,7 +309,7 @@ void BluetoothEmu::AddEventToQueue(const SQueuedEvent& _event) m_HCIEndpoint->FillBuffer(event.m_buffer, event.m_size); // Send a reply to indicate HCI buffer is filled - EnqueueReply(m_HCIEndpoint->ios_request, event.m_size); + m_ios.EnqueueIPCReply(m_HCIEndpoint->ios_request, event.m_size); m_HCIEndpoint.reset(); m_EventQueue.pop_front(); } @@ -335,7 +335,7 @@ void BluetoothEmu::Update() m_HCIEndpoint->FillBuffer(event.m_buffer, event.m_size); // Send a reply to indicate HCI buffer is filled - EnqueueReply(m_HCIEndpoint->ios_request, event.m_size); + m_ios.EnqueueIPCReply(m_HCIEndpoint->ios_request, event.m_size); m_HCIEndpoint.reset(); m_EventQueue.pop_front(); } @@ -430,7 +430,7 @@ void BluetoothEmu::ACLPool::WriteToEndpoint(USB::V0BulkMessage& endpoint) m_queue.pop_front(); - EnqueueReply(endpoint.ios_request, sizeof(hci_acldata_hdr_t) + size); + m_ios.EnqueueIPCReply(endpoint.ios_request, sizeof(hci_acldata_hdr_t) + size); } bool BluetoothEmu::SendEventInquiryComplete() @@ -1141,7 +1141,7 @@ void BluetoothEmu::ExecuteHCICommandMessage(const USB::V0CtrlMessage& ctrl_messa } // HCI command is finished, send a reply to command - EnqueueReply(ctrl_message.ios_request, ctrl_message.length); + m_ios.EnqueueIPCReply(ctrl_message.ios_request, ctrl_message.length); } // diff --git a/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.h b/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.h index efb60cf10d..b39e712710 100644 --- a/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.h +++ b/Source/Core/Core/IOS/USB/Bluetooth/BTEmu.h @@ -14,7 +14,7 @@ #include "Common/CommonTypes.h" #include "Core/HW/Wiimote.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/USB/Bluetooth/BTBase.h" #include "Core/IOS/USB/Bluetooth/WiimoteDevice.h" #include "Core/IOS/USB/Bluetooth/hci.h" @@ -45,7 +45,7 @@ namespace Device class BluetoothEmu final : public BluetoothBase { public: - BluetoothEmu(u32 device_id, const std::string& device_name); + BluetoothEmu(Kernel& ios, const std::string& device_name); virtual ~BluetoothEmu(); @@ -78,17 +78,8 @@ private: class ACLPool { - struct Packet - { - u8 data[ACL_PKT_SIZE]; - u16 size; - u16 conn_handle; - }; - - std::deque m_queue; - public: - ACLPool() : m_queue() {} + explicit ACLPool(Kernel& ios) : m_ios(ios), m_queue() {} void Store(const u8* data, const u16 size, const u16 conn_handle); void WriteToEndpoint(USB::V0BulkMessage& endpoint); @@ -96,7 +87,17 @@ private: bool IsEmpty() const { return m_queue.empty(); } // For SaveStates void DoState(PointerWrap& p) { p.Do(m_queue); } - } m_acl_pool; + private: + struct Packet + { + u8 data[ACL_PKT_SIZE]; + u16 size; + u16 conn_handle; + }; + + Kernel& m_ios; + std::deque m_queue; + } m_acl_pool{m_ios}; u32 m_PacketCount[MAX_BBMOTES] = {}; u64 m_last_ticks = 0; diff --git a/Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp b/Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp index 25633158c1..a23c236ab8 100644 --- a/Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp +++ b/Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp @@ -56,8 +56,8 @@ static bool IsBluetoothDevice(const libusb_interface_descriptor& descriptor) namespace Device { -BluetoothReal::BluetoothReal(u32 device_id, const std::string& device_name) - : BluetoothBase(device_id, device_name) +BluetoothReal::BluetoothReal(Kernel& ios, const std::string& device_name) + : BluetoothBase(ios, device_name) { const int ret = libusb_init(&m_libusb_context); if (ret < 0) @@ -179,7 +179,7 @@ IPCCommandResult BluetoothReal::IOCtlV(const IOCtlVRequest& request) case USB::IOCTLV_USBV0_CTRLMSG: { std::lock_guard lk(m_transfers_mutex); - auto cmd = std::make_unique(request); + auto cmd = std::make_unique(m_ios, request); const u16 opcode = Common::swap16(Memory::Read_U16(cmd->data_address)); if (opcode == HCI_CMD_READ_BUFFER_SIZE) { @@ -228,7 +228,7 @@ IPCCommandResult BluetoothReal::IOCtlV(const IOCtlVRequest& request) case USB::IOCTLV_USBV0_INTRMSG: { std::lock_guard lk(m_transfers_mutex); - auto cmd = std::make_unique(request); + auto cmd = std::make_unique(m_ios, request); if (request.request == USB::IOCTLV_USBV0_INTRMSG) { if (m_sync_button_state == SyncButtonState::Pressed) @@ -310,7 +310,7 @@ void BluetoothReal::DoState(PointerWrap& p) // waiting for the previous request to complete. This is usually not an issue as long as // the Bluetooth state is the same (same Wii remote connections). for (const auto& address_to_discard : addresses_to_discard) - EnqueueReply(Request{address_to_discard}, 0); + m_ios.EnqueueIPCReply(Request{address_to_discard}, 0); // Prevent the callbacks from replying to a request that has already been discarded. m_current_transfers.clear(); @@ -452,7 +452,7 @@ void BluetoothReal::FakeVendorCommandReply(USB::V0IntrMessage& ctrl) hci_event.PacketIndicator = 0x01; hci_event.Opcode = m_fake_vendor_command_reply_opcode; Memory::CopyToEmu(ctrl.data_address, &hci_event, sizeof(hci_event)); - EnqueueReply(ctrl.ios_request, static_cast(sizeof(hci_event))); + m_ios.EnqueueIPCReply(ctrl.ios_request, static_cast(sizeof(hci_event))); } // Due to how the widcomm stack which Nintendo uses is coded, we must never @@ -477,7 +477,7 @@ void BluetoothReal::FakeReadBufferSizeReply(USB::V0IntrMessage& ctrl) reply.max_sco_size = SCO_PKT_SIZE; reply.num_sco_pkts = SCO_PKT_NUM; Memory::CopyToEmu(ctrl.data_address + sizeof(hci_event), &reply, sizeof(reply)); - EnqueueReply(ctrl.ios_request, static_cast(sizeof(hci_event) + sizeof(reply))); + m_ios.EnqueueIPCReply(ctrl.ios_request, static_cast(sizeof(hci_event) + sizeof(reply))); } void BluetoothReal::FakeSyncButtonEvent(USB::V0IntrMessage& ctrl, const u8* payload, const u8 size) @@ -488,7 +488,7 @@ void BluetoothReal::FakeSyncButtonEvent(USB::V0IntrMessage& ctrl, const u8* payl hci_event.length = size; Memory::CopyToEmu(ctrl.data_address, &hci_event, sizeof(hci_event)); Memory::CopyToEmu(ctrl.data_address + sizeof(hci_event), payload, size); - EnqueueReply(ctrl.ios_request, static_cast(sizeof(hci_event) + size)); + m_ios.EnqueueIPCReply(ctrl.ios_request, static_cast(sizeof(hci_event) + size)); } // When the red sync button is pressed, a HCI event is generated: @@ -638,7 +638,8 @@ void BluetoothReal::HandleCtrlTransfer(libusb_transfer* tr) } const auto& command = m_current_transfers.at(tr).command; command->FillBuffer(libusb_control_transfer_get_data(tr), tr->actual_length); - EnqueueReply(command->ios_request, tr->actual_length, 0, CoreTiming::FromThread::NON_CPU); + m_ios.EnqueueIPCReply(command->ios_request, tr->actual_length, 0, + CoreTiming::FromThread::NON_CPU); m_current_transfers.erase(tr); } @@ -688,7 +689,8 @@ void BluetoothReal::HandleBulkOrIntrTransfer(libusb_transfer* tr) const auto& command = m_current_transfers.at(tr).command; command->FillBuffer(tr->buffer, tr->actual_length); - EnqueueReply(command->ios_request, tr->actual_length, 0, CoreTiming::FromThread::NON_CPU); + m_ios.EnqueueIPCReply(command->ios_request, tr->actual_length, 0, + CoreTiming::FromThread::NON_CPU); m_current_transfers.erase(tr); } } // namespace Device diff --git a/Source/Core/Core/IOS/USB/Bluetooth/BTReal.h b/Source/Core/Core/IOS/USB/Bluetooth/BTReal.h index 3acc462fc0..8b0fbf91da 100644 --- a/Source/Core/Core/IOS/USB/Bluetooth/BTReal.h +++ b/Source/Core/Core/IOS/USB/Bluetooth/BTReal.h @@ -16,7 +16,7 @@ #include "Common/CommonTypes.h" #include "Common/Flag.h" #include "Common/Timer.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/USB/Bluetooth/BTBase.h" #include "Core/IOS/USB/USBV0.h" @@ -48,7 +48,7 @@ namespace Device class BluetoothReal final : public BluetoothBase { public: - BluetoothReal(u32 device_id, const std::string& device_name); + BluetoothReal(Kernel& ios, const std::string& device_name); ~BluetoothReal() override; ReturnCode Open(const OpenRequest& request) override; diff --git a/Source/Core/Core/IOS/USB/Bluetooth/BTStub.h b/Source/Core/Core/IOS/USB/Bluetooth/BTStub.h index 601d0c146f..9a69a556e8 100644 --- a/Source/Core/Core/IOS/USB/Bluetooth/BTStub.h +++ b/Source/Core/Core/IOS/USB/Bluetooth/BTStub.h @@ -7,7 +7,7 @@ #include #include "Common/CommonTypes.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/USB/Bluetooth/BTBase.h" class PointerWrap; @@ -21,10 +21,7 @@ namespace Device class BluetoothStub final : public BluetoothBase { public: - BluetoothStub(const u32 device_id, const std::string& device_name) - : BluetoothBase(device_id, device_name) - { - } + using BluetoothBase::BluetoothBase; ReturnCode Open(const OpenRequest& request) override; void DoState(PointerWrap& p) override; }; diff --git a/Source/Core/Core/IOS/USB/Bluetooth/WiimoteDevice.cpp b/Source/Core/Core/IOS/USB/Bluetooth/WiimoteDevice.cpp index d374ba7451..4e8d935fcb 100644 --- a/Source/Core/Core/IOS/USB/Bluetooth/WiimoteDevice.cpp +++ b/Source/Core/Core/IOS/USB/Bluetooth/WiimoteDevice.cpp @@ -932,7 +932,7 @@ void Callback_WiimoteInterruptChannel(int _number, u16 _channelID, const void* _ DEBUG_LOG(WIIMOTE, " Channel: %x", _channelID); const auto bt = std::static_pointer_cast( - IOS::HLE::GetDeviceByName("/dev/usb/oh1/57e/305")); + IOS::HLE::GetIOS()->GetDeviceByName("/dev/usb/oh1/57e/305")); if (bt) bt->m_WiiMotes[_number].ReceiveL2capData(_channelID, _pData, _Size); } diff --git a/Source/Core/Core/IOS/USB/Common.cpp b/Source/Core/Core/IOS/USB/Common.cpp index b8fecd5faf..a9627b0974 100644 --- a/Source/Core/Core/IOS/USB/Common.cpp +++ b/Source/Core/Core/IOS/USB/Common.cpp @@ -33,6 +33,11 @@ void TransferCommand::FillBuffer(const u8* src, const size_t size) const Memory::CopyToEmu(data_address, src, size); } +void TransferCommand::OnTransferComplete(s32 return_value) const +{ + m_ios.EnqueueIPCReply(ios_request, return_value, 0, CoreTiming::FromThread::NON_CPU); +} + void IsoMessage::SetPacketReturnValue(const size_t packet_num, const u16 return_value) const { Memory::Write_U16(return_value, static_cast(packet_sizes_addr + packet_num * sizeof(u16))); diff --git a/Source/Core/Core/IOS/USB/Common.h b/Source/Core/Core/IOS/USB/Common.h index 6c9bb13913..9efb6630a1 100644 --- a/Source/Core/Core/IOS/USB/Common.h +++ b/Source/Core/Core/IOS/USB/Common.h @@ -100,15 +100,19 @@ struct TransferCommand Request ios_request; u32 data_address = 0; - TransferCommand(const Request& ios_request_, u32 data_address_) - : ios_request(ios_request_), data_address(data_address_) + TransferCommand(Kernel& ios, const Request& ios_request_, u32 data_address_) + : ios_request(ios_request_), data_address(data_address_), m_ios(ios) { } virtual ~TransferCommand() = default; - // Called after a transfer has completed and before replying to the transfer request. - virtual void OnTransferComplete() const {} + // Called after a transfer has completed to reply to the IPC request. + // This can be overridden for additional processing before replying. + virtual void OnTransferComplete(s32 return_value) const; std::unique_ptr MakeBuffer(size_t size) const; void FillBuffer(const u8* src, size_t size) const; + +private: + Kernel& m_ios; }; struct CtrlMessage : TransferCommand diff --git a/Source/Core/Core/IOS/USB/Host.cpp b/Source/Core/Core/IOS/USB/Host.cpp index 846bb2c645..e440494460 100644 --- a/Source/Core/Core/IOS/USB/Host.cpp +++ b/Source/Core/Core/IOS/USB/Host.cpp @@ -27,7 +27,7 @@ namespace HLE { namespace Device { -USBHost::USBHost(u32 device_id, const std::string& device_name) : Device(device_id, device_name) +USBHost::USBHost(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { #ifdef __LIBUSB__ const int ret = libusb_init(&m_libusb_context); @@ -150,7 +150,7 @@ bool USBHost::AddNewDevices(std::set& new_devices, DeviceChangeHooks& hooks continue; } - auto usb_device = std::make_unique(device, descriptor); + auto usb_device = std::make_unique(m_ios, device, descriptor); if (!ShouldAddDevice(*usb_device)) { libusb_unref_device(device); diff --git a/Source/Core/Core/IOS/USB/Host.h b/Source/Core/Core/IOS/USB/Host.h index 3bdcb2445b..a595743394 100644 --- a/Source/Core/Core/IOS/USB/Host.h +++ b/Source/Core/Core/IOS/USB/Host.h @@ -17,7 +17,7 @@ #include "Common/CommonTypes.h" #include "Common/Flag.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/USB/Common.h" class PointerWrap; @@ -33,7 +33,7 @@ namespace Device class USBHost : public Device { public: - USBHost(u32 device_id, const std::string& device_name); + USBHost(Kernel& ios, const std::string& device_name); virtual ~USBHost(); ReturnCode Open(const OpenRequest& request) override; diff --git a/Source/Core/Core/IOS/USB/LibusbDevice.cpp b/Source/Core/Core/IOS/USB/LibusbDevice.cpp index 69b51e3fba..9b57062336 100644 --- a/Source/Core/Core/IOS/USB/LibusbDevice.cpp +++ b/Source/Core/Core/IOS/USB/LibusbDevice.cpp @@ -15,7 +15,7 @@ #include "Core/CoreTiming.h" #include "Core/HW/Memmap.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/USB/LibusbDevice.h" namespace IOS @@ -24,8 +24,9 @@ namespace HLE { namespace USB { -LibusbDevice::LibusbDevice(libusb_device* device, const libusb_device_descriptor& descriptor) - : m_device(device) +LibusbDevice::LibusbDevice(Kernel& ios, libusb_device* device, + const libusb_device_descriptor& descriptor) + : m_ios(ios), m_device(device) { libusb_ref_device(m_device); m_vid = descriptor.idVendor; @@ -200,14 +201,14 @@ int LibusbDevice::SubmitTransfer(std::unique_ptr cmd) } const int ret = SetAltSetting(static_cast(cmd->value)); if (ret == 0) - EnqueueReply(cmd->ios_request, cmd->length); + m_ios.EnqueueIPCReply(cmd->ios_request, cmd->length); return ret; } case USBHDR(DIR_HOST2DEVICE, TYPE_STANDARD, REC_DEVICE, REQUEST_SET_CONFIGURATION): { const int ret = libusb_set_configuration(m_handle, cmd->value); if (ret == 0) - EnqueueReply(cmd->ios_request, cmd->length); + m_ios.EnqueueIPCReply(cmd->ios_request, cmd->length); return ret; } } @@ -355,8 +356,7 @@ void LibusbDevice::TransferEndpoint::HandleTransfer(libusb_transfer* transfer, return_value = IPC_ENOENT; break; } - cmd.OnTransferComplete(); - EnqueueReply(cmd.ios_request, return_value, 0, CoreTiming::FromThread::NON_CPU); + cmd.OnTransferComplete(return_value); m_transfers.erase(transfer); } diff --git a/Source/Core/Core/IOS/USB/LibusbDevice.h b/Source/Core/Core/IOS/USB/LibusbDevice.h index 331aae2593..54b5a19577 100644 --- a/Source/Core/Core/IOS/USB/LibusbDevice.h +++ b/Source/Core/Core/IOS/USB/LibusbDevice.h @@ -43,7 +43,8 @@ private: class LibusbDevice final : public Device { public: - LibusbDevice(libusb_device* device, const libusb_device_descriptor& device_descriptor); + LibusbDevice(Kernel& ios, libusb_device* device, + const libusb_device_descriptor& device_descriptor); ~LibusbDevice(); DeviceDescriptor GetDeviceDescriptor() const override; std::vector GetConfigurations() const override; @@ -61,6 +62,8 @@ public: int SubmitTransfer(std::unique_ptr message) override; private: + Kernel& m_ios; + std::vector> m_config_descriptors; u16 m_vid = 0; u16 m_pid = 0; diff --git a/Source/Core/Core/IOS/USB/OH0/OH0.cpp b/Source/Core/Core/IOS/USB/OH0/OH0.cpp index 3a9ec8d97e..85760299bd 100644 --- a/Source/Core/Core/IOS/USB/OH0/OH0.cpp +++ b/Source/Core/Core/IOS/USB/OH0/OH0.cpp @@ -25,7 +25,7 @@ namespace HLE { namespace Device { -OH0::OH0(u32 device_id, const std::string& device_name) : USBHost(device_id, device_name) +OH0::OH0(Kernel& ios, const std::string& device_name) : USBHost(ios, device_name) { } @@ -36,7 +36,7 @@ OH0::~OH0() ReturnCode OH0::Open(const OpenRequest& request) { - const u32 ios_major_version = GetVersion(); + const u32 ios_major_version = m_ios.GetVersion(); if (ios_major_version == 57 || ios_major_version == 58 || ios_major_version == 59) return IPC_EACCES; return USBHost::Open(request); @@ -240,7 +240,7 @@ void OH0::TriggerHook(std::map& hooks, T value, const ReturnCode return_ const auto hook = hooks.find(value); if (hook == hooks.end()) return; - EnqueueReply(Request{hook->second}, return_value, 0, CoreTiming::FromThread::ANY); + m_ios.EnqueueIPCReply(Request{hook->second}, return_value, 0, CoreTiming::FromThread::ANY); hooks.erase(hook); } @@ -325,26 +325,26 @@ s32 OH0::SubmitTransfer(USB::Device& device, const IOCtlVRequest& ioctlv) if (!ioctlv.HasNumberOfValidVectors(6, 1) || Common::swap16(Memory::Read_U16(ioctlv.in_vectors[4].address)) != ioctlv.io_vectors[0].size) return IPC_EINVAL; - return device.SubmitTransfer(std::make_unique(ioctlv)); + return device.SubmitTransfer(std::make_unique(m_ios, ioctlv)); case USB::IOCTLV_USBV0_BLKMSG: case USB::IOCTLV_USBV0_LBLKMSG: if (!ioctlv.HasNumberOfValidVectors(2, 1) || Memory::Read_U16(ioctlv.in_vectors[1].address) != ioctlv.io_vectors[0].size) return IPC_EINVAL; - return device.SubmitTransfer( - std::make_unique(ioctlv, ioctlv.request == USB::IOCTLV_USBV0_LBLKMSG)); + return device.SubmitTransfer(std::make_unique( + m_ios, ioctlv, ioctlv.request == USB::IOCTLV_USBV0_LBLKMSG)); case USB::IOCTLV_USBV0_INTRMSG: if (!ioctlv.HasNumberOfValidVectors(2, 1) || Memory::Read_U16(ioctlv.in_vectors[1].address) != ioctlv.io_vectors[0].size) return IPC_EINVAL; - return device.SubmitTransfer(std::make_unique(ioctlv)); + return device.SubmitTransfer(std::make_unique(m_ios, ioctlv)); case USB::IOCTLV_USBV0_ISOMSG: if (!ioctlv.HasNumberOfValidVectors(3, 2)) return IPC_EINVAL; - return device.SubmitTransfer(std::make_unique(ioctlv)); + return device.SubmitTransfer(std::make_unique(m_ios, ioctlv)); default: return IPC_EINVAL; diff --git a/Source/Core/Core/IOS/USB/OH0/OH0.h b/Source/Core/Core/IOS/USB/OH0/OH0.h index df732a8c09..90eb2d6d80 100644 --- a/Source/Core/Core/IOS/USB/OH0/OH0.h +++ b/Source/Core/Core/IOS/USB/OH0/OH0.h @@ -38,7 +38,7 @@ namespace Device class OH0 final : public USBHost { public: - OH0(u32 device_id, const std::string& device_name); + OH0(Kernel& ios, const std::string& device_name); ~OH0() override; ReturnCode Open(const OpenRequest& request) override; diff --git a/Source/Core/Core/IOS/USB/OH0/OH0Device.cpp b/Source/Core/Core/IOS/USB/OH0/OH0Device.cpp index 03b3e7da2c..390a266e41 100644 --- a/Source/Core/Core/IOS/USB/OH0/OH0Device.cpp +++ b/Source/Core/Core/IOS/USB/OH0/OH0Device.cpp @@ -7,7 +7,7 @@ #include #include "Common/ChunkFile.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/USB/OH0/OH0.h" #include "Core/IOS/USB/OH0/OH0Device.h" @@ -37,7 +37,7 @@ static void GetVidPidFromDevicePath(const std::string& device_path, u16& vid, u1 ss >> pid; } -OH0Device::OH0Device(u32 id, const std::string& name) : Device(id, name, DeviceType::OH0) +OH0Device::OH0Device(Kernel& ios, const std::string& name) : Device(ios, name, DeviceType::OH0) { if (!name.empty()) GetVidPidFromDevicePath(name, m_vid, m_pid); @@ -45,7 +45,7 @@ OH0Device::OH0Device(u32 id, const std::string& name) : Device(id, name, DeviceT void OH0Device::DoState(PointerWrap& p) { - m_oh0 = std::static_pointer_cast(GetDeviceByName("/dev/usb/oh0")); + m_oh0 = std::static_pointer_cast(m_ios.GetDeviceByName("/dev/usb/oh0")); p.Do(m_name); p.Do(m_vid); p.Do(m_pid); @@ -54,14 +54,14 @@ void OH0Device::DoState(PointerWrap& p) ReturnCode OH0Device::Open(const OpenRequest& request) { - const u32 ios_major_version = GetVersion(); + const u32 ios_major_version = m_ios.GetVersion(); if (ios_major_version == 57 || ios_major_version == 58 || ios_major_version == 59) return IPC_ENOENT; if (m_vid == 0 && m_pid == 0) return IPC_ENOENT; - m_oh0 = std::static_pointer_cast(GetDeviceByName("/dev/usb/oh0")); + m_oh0 = std::static_pointer_cast(m_ios.GetDeviceByName("/dev/usb/oh0")); ReturnCode return_code; std::tie(return_code, m_device_id) = m_oh0->DeviceOpen(m_vid, m_pid); diff --git a/Source/Core/Core/IOS/USB/OH0/OH0Device.h b/Source/Core/Core/IOS/USB/OH0/OH0Device.h index c66ccc4b2f..a7b193ad25 100644 --- a/Source/Core/Core/IOS/USB/OH0/OH0Device.h +++ b/Source/Core/Core/IOS/USB/OH0/OH0Device.h @@ -22,7 +22,7 @@ class OH0; class OH0Device final : public Device { public: - OH0Device(u32 device_id, const std::string& device_name); + OH0Device(Kernel& ios, const std::string& device_name); ReturnCode Open(const OpenRequest& request) override; ReturnCode Close(u32 fd) override; diff --git a/Source/Core/Core/IOS/USB/USBV0.cpp b/Source/Core/Core/IOS/USB/USBV0.cpp index 3f9e276e4f..da195f2463 100644 --- a/Source/Core/Core/IOS/USB/USBV0.cpp +++ b/Source/Core/Core/IOS/USB/USBV0.cpp @@ -17,8 +17,8 @@ namespace HLE { namespace USB { -V0CtrlMessage::V0CtrlMessage(const IOCtlVRequest& ioctlv) - : CtrlMessage(ioctlv, ioctlv.io_vectors[0].address) +V0CtrlMessage::V0CtrlMessage(Kernel& ios, const IOCtlVRequest& ioctlv) + : CtrlMessage(ios, ioctlv, ioctlv.io_vectors[0].address) { request_type = Memory::Read_U8(ioctlv.in_vectors[0].address); request = Memory::Read_U8(ioctlv.in_vectors[1].address); @@ -27,8 +27,8 @@ V0CtrlMessage::V0CtrlMessage(const IOCtlVRequest& ioctlv) length = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[4].address)); } -V0BulkMessage::V0BulkMessage(const IOCtlVRequest& ioctlv, bool long_length) - : BulkMessage(ioctlv, ioctlv.io_vectors[0].address) +V0BulkMessage::V0BulkMessage(Kernel& ios, const IOCtlVRequest& ioctlv, bool long_length) + : BulkMessage(ios, ioctlv, ioctlv.io_vectors[0].address) { endpoint = Memory::Read_U8(ioctlv.in_vectors[0].address); if (long_length) @@ -37,15 +37,15 @@ V0BulkMessage::V0BulkMessage(const IOCtlVRequest& ioctlv, bool long_length) length = Memory::Read_U16(ioctlv.in_vectors[1].address); } -V0IntrMessage::V0IntrMessage(const IOCtlVRequest& ioctlv) - : IntrMessage(ioctlv, ioctlv.io_vectors[0].address) +V0IntrMessage::V0IntrMessage(Kernel& ios, const IOCtlVRequest& ioctlv) + : IntrMessage(ios, ioctlv, ioctlv.io_vectors[0].address) { endpoint = Memory::Read_U8(ioctlv.in_vectors[0].address); length = Memory::Read_U16(ioctlv.in_vectors[1].address); } -V0IsoMessage::V0IsoMessage(const IOCtlVRequest& ioctlv) - : IsoMessage(ioctlv, ioctlv.io_vectors[1].address) +V0IsoMessage::V0IsoMessage(Kernel& ios, const IOCtlVRequest& ioctlv) + : IsoMessage(ios, ioctlv, ioctlv.io_vectors[1].address) { endpoint = Memory::Read_U8(ioctlv.in_vectors[0].address); length = Memory::Read_U16(ioctlv.in_vectors[1].address); diff --git a/Source/Core/Core/IOS/USB/USBV0.h b/Source/Core/Core/IOS/USB/USBV0.h index 9af2c1308f..eaa80d9f16 100644 --- a/Source/Core/Core/IOS/USB/USBV0.h +++ b/Source/Core/Core/IOS/USB/USBV0.h @@ -41,22 +41,22 @@ enum V0Requests struct V0CtrlMessage final : CtrlMessage { - explicit V0CtrlMessage(const IOCtlVRequest& ioctlv); + V0CtrlMessage(Kernel& ios, const IOCtlVRequest& ioctlv); }; struct V0BulkMessage final : BulkMessage { - explicit V0BulkMessage(const IOCtlVRequest& ioctlv, bool long_length = false); + V0BulkMessage(Kernel& ios, const IOCtlVRequest& ioctlv, bool long_length = false); }; struct V0IntrMessage final : IntrMessage { - explicit V0IntrMessage(const IOCtlVRequest& ioctlv); + V0IntrMessage(Kernel& ios, const IOCtlVRequest& ioctlv); }; struct V0IsoMessage final : IsoMessage { - explicit V0IsoMessage(const IOCtlVRequest& ioctlv); + V0IsoMessage(Kernel& ios, const IOCtlVRequest& ioctlv); }; } // namespace USB } // namespace HLE diff --git a/Source/Core/Core/IOS/USB/USBV4.cpp b/Source/Core/Core/IOS/USB/USBV4.cpp index b28142f1e1..c2b9825cd6 100644 --- a/Source/Core/Core/IOS/USB/USBV4.cpp +++ b/Source/Core/Core/IOS/USB/USBV4.cpp @@ -49,7 +49,7 @@ struct HIDRequest }; #pragma pack(pop) -V4CtrlMessage::V4CtrlMessage(const IOCtlRequest& ioctl) : CtrlMessage(ioctl, -1) +V4CtrlMessage::V4CtrlMessage(Kernel& ios, const IOCtlRequest& ioctl) : CtrlMessage(ios, ioctl, -1) { HIDRequest hid_request; Memory::CopyFromEmu(&hid_request, ioctl.buffer_in, sizeof(hid_request)); @@ -64,7 +64,8 @@ V4CtrlMessage::V4CtrlMessage(const IOCtlRequest& ioctl) : CtrlMessage(ioctl, -1) // Since this is just a standard control request, but with additional requirements // (US for the language and replacing non-ASCII characters with '?'), // we can simply submit it as a usual control request. -V4GetUSStringMessage::V4GetUSStringMessage(const IOCtlRequest& ioctl) : CtrlMessage(ioctl, -1) +V4GetUSStringMessage::V4GetUSStringMessage(Kernel& ios, const IOCtlRequest& ioctl) + : CtrlMessage(ios, ioctl, -1) { HIDRequest hid_request; Memory::CopyFromEmu(&hid_request, ioctl.buffer_in, sizeof(hid_request)); @@ -76,16 +77,17 @@ V4GetUSStringMessage::V4GetUSStringMessage(const IOCtlRequest& ioctl) : CtrlMess data_address = Common::swap32(hid_request.data_addr); } -void V4GetUSStringMessage::OnTransferComplete() const +void V4GetUSStringMessage::OnTransferComplete(s32 return_value) const { const std::locale& c_locale = std::locale::classic(); std::string message = Memory::GetString(data_address); std::replace_if(message.begin(), message.end(), [&c_locale](char c) { return !std::isprint(c, c_locale); }, '?'); Memory::CopyToEmu(data_address, message.c_str(), message.size()); + TransferCommand::OnTransferComplete(return_value); } -V4IntrMessage::V4IntrMessage(const IOCtlRequest& ioctl) : IntrMessage(ioctl, -1) +V4IntrMessage::V4IntrMessage(Kernel& ios, const IOCtlRequest& ioctl) : IntrMessage(ios, ioctl, -1) { HIDRequest hid_request; Memory::CopyFromEmu(&hid_request, ioctl.buffer_in, sizeof(hid_request)); diff --git a/Source/Core/Core/IOS/USB/USBV4.h b/Source/Core/Core/IOS/USB/USBV4.h index 93ccd7ee21..92e23e0a1c 100644 --- a/Source/Core/Core/IOS/USB/USBV4.h +++ b/Source/Core/Core/IOS/USB/USBV4.h @@ -32,18 +32,18 @@ enum V4Requests struct V4CtrlMessage final : CtrlMessage { - explicit V4CtrlMessage(const IOCtlRequest& ioctl); + V4CtrlMessage(Kernel& ios, const IOCtlRequest& ioctl); }; struct V4GetUSStringMessage final : CtrlMessage { - explicit V4GetUSStringMessage(const IOCtlRequest& ioctl); - void OnTransferComplete() const override; + V4GetUSStringMessage(Kernel& ios, const IOCtlRequest& ioctl); + void OnTransferComplete(s32 return_value) const override; }; struct V4IntrMessage final : IntrMessage { - explicit V4IntrMessage(const IOCtlRequest& ioctl); + V4IntrMessage(Kernel& ios, const IOCtlRequest& ioctl); }; } // namespace USB } // namespace HLE diff --git a/Source/Core/Core/IOS/USB/USBV5.cpp b/Source/Core/Core/IOS/USB/USBV5.cpp index bf4fd09399..357676fe08 100644 --- a/Source/Core/Core/IOS/USB/USBV5.cpp +++ b/Source/Core/Core/IOS/USB/USBV5.cpp @@ -16,8 +16,8 @@ namespace HLE { namespace USB { -V5CtrlMessage::V5CtrlMessage(const IOCtlVRequest& ioctlv) - : CtrlMessage(ioctlv, Memory::Read_U32(ioctlv.in_vectors[0].address + 16)) +V5CtrlMessage::V5CtrlMessage(Kernel& ios, const IOCtlVRequest& ioctlv) + : CtrlMessage(ios, ioctlv, Memory::Read_U32(ioctlv.in_vectors[0].address + 16)) { request_type = Memory::Read_U8(ioctlv.in_vectors[0].address + 8); request = Memory::Read_U8(ioctlv.in_vectors[0].address + 9); @@ -26,22 +26,22 @@ V5CtrlMessage::V5CtrlMessage(const IOCtlVRequest& ioctlv) length = Memory::Read_U16(ioctlv.in_vectors[0].address + 14); } -V5BulkMessage::V5BulkMessage(const IOCtlVRequest& ioctlv) - : BulkMessage(ioctlv, Memory::Read_U32(ioctlv.in_vectors[0].address + 8)) +V5BulkMessage::V5BulkMessage(Kernel& ios, const IOCtlVRequest& ioctlv) + : BulkMessage(ios, ioctlv, Memory::Read_U32(ioctlv.in_vectors[0].address + 8)) { length = Memory::Read_U16(ioctlv.in_vectors[0].address + 12); endpoint = Memory::Read_U8(ioctlv.in_vectors[0].address + 18); } -V5IntrMessage::V5IntrMessage(const IOCtlVRequest& ioctlv) - : IntrMessage(ioctlv, Memory::Read_U32(ioctlv.in_vectors[0].address + 8)) +V5IntrMessage::V5IntrMessage(Kernel& ios, const IOCtlVRequest& ioctlv) + : IntrMessage(ios, ioctlv, Memory::Read_U32(ioctlv.in_vectors[0].address + 8)) { length = Memory::Read_U16(ioctlv.in_vectors[0].address + 12); endpoint = Memory::Read_U8(ioctlv.in_vectors[0].address + 14); } -V5IsoMessage::V5IsoMessage(const IOCtlVRequest& ioctlv) - : IsoMessage(ioctlv, Memory::Read_U32(ioctlv.in_vectors[0].address + 8)) +V5IsoMessage::V5IsoMessage(Kernel& ios, const IOCtlVRequest& ioctlv) + : IsoMessage(ios, ioctlv, Memory::Read_U32(ioctlv.in_vectors[0].address + 8)) { num_packets = Memory::Read_U8(ioctlv.in_vectors[0].address + 16); endpoint = Memory::Read_U8(ioctlv.in_vectors[0].address + 17); diff --git a/Source/Core/Core/IOS/USB/USBV5.h b/Source/Core/Core/IOS/USB/USBV5.h index 871d0e7856..2db6c22110 100644 --- a/Source/Core/Core/IOS/USB/USBV5.h +++ b/Source/Core/Core/IOS/USB/USBV5.h @@ -36,22 +36,22 @@ enum V5Requests struct V5CtrlMessage final : CtrlMessage { - explicit V5CtrlMessage(const IOCtlVRequest& ioctlv); + V5CtrlMessage(Kernel& ios, const IOCtlVRequest& ioctlv); }; struct V5BulkMessage final : BulkMessage { - explicit V5BulkMessage(const IOCtlVRequest& ioctlv); + V5BulkMessage(Kernel& ios, const IOCtlVRequest& ioctlv); }; struct V5IntrMessage final : IntrMessage { - explicit V5IntrMessage(const IOCtlVRequest& ioctlv); + V5IntrMessage(Kernel& ios, const IOCtlVRequest& ioctlv); }; struct V5IsoMessage final : IsoMessage { - explicit V5IsoMessage(const IOCtlVRequest& cmd_buffer); + V5IsoMessage(Kernel& ios, const IOCtlVRequest& cmd_buffer); }; } // namespace USB } // namespace HLE diff --git a/Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp b/Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp index e7c87a1c26..897f588809 100644 --- a/Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp +++ b/Source/Core/Core/IOS/USB/USB_HID/HIDv4.cpp @@ -23,8 +23,7 @@ namespace HLE { namespace Device { -USB_HIDv4::USB_HIDv4(u32 device_id, const std::string& device_name) - : USBHost(device_id, device_name) +USB_HIDv4::USB_HIDv4(Kernel& ios, const std::string& device_name) : USBHost(ios, device_name) { } @@ -102,7 +101,7 @@ IPCCommandResult USB_HIDv4::Shutdown(const IOCtlRequest& request) if (m_devicechange_hook_request != 0) { Memory::Write_U32(0xffffffff, m_devicechange_hook_request->buffer_out); - EnqueueReply(*m_devicechange_hook_request, -1); + m_ios.EnqueueIPCReply(*m_devicechange_hook_request, -1); m_devicechange_hook_request.reset(); } return GetDefaultReply(IPC_SUCCESS); @@ -113,12 +112,12 @@ s32 USB_HIDv4::SubmitTransfer(USB::Device& device, const IOCtlRequest& request) switch (request.request) { case USB::IOCTL_USBV4_CTRLMSG: - return device.SubmitTransfer(std::make_unique(request)); + return device.SubmitTransfer(std::make_unique(m_ios, request)); case USB::IOCTL_USBV4_GET_US_STRING: - return device.SubmitTransfer(std::make_unique(request)); + return device.SubmitTransfer(std::make_unique(m_ios, request)); case USB::IOCTL_USBV4_INTRMSG_IN: case USB::IOCTL_USBV4_INTRMSG_OUT: - return device.SubmitTransfer(std::make_unique(request)); + return device.SubmitTransfer(std::make_unique(m_ios, request)); default: return IPC_EINVAL; } @@ -204,7 +203,7 @@ void USB_HIDv4::TriggerDeviceChangeReply() Memory::Write_U32(0xffffffff, dest + offset); } - EnqueueReply(*m_devicechange_hook_request, IPC_SUCCESS, 0, CoreTiming::FromThread::ANY); + m_ios.EnqueueIPCReply(*m_devicechange_hook_request, IPC_SUCCESS, 0, CoreTiming::FromThread::ANY); m_devicechange_hook_request.reset(); } diff --git a/Source/Core/Core/IOS/USB/USB_HID/HIDv4.h b/Source/Core/Core/IOS/USB/USB_HID/HIDv4.h index 4048f3c339..845bebd394 100644 --- a/Source/Core/Core/IOS/USB/USB_HID/HIDv4.h +++ b/Source/Core/Core/IOS/USB/USB_HID/HIDv4.h @@ -11,7 +11,7 @@ #include #include "Common/CommonTypes.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/USB/Host.h" class PointerWrap; @@ -25,7 +25,7 @@ namespace Device class USB_HIDv4 final : public USBHost { public: - USB_HIDv4(u32 device_id, const std::string& device_name); + USB_HIDv4(Kernel& ios, const std::string& device_name); ~USB_HIDv4() override; IPCCommandResult IOCtl(const IOCtlRequest& request) override; diff --git a/Source/Core/Core/IOS/USB/USB_KBD.cpp b/Source/Core/Core/IOS/USB/USB_KBD.cpp index bad439ff96..a9f361a1a7 100644 --- a/Source/Core/Core/IOS/USB/USB_KBD.cpp +++ b/Source/Core/Core/IOS/USB/USB_KBD.cpp @@ -39,7 +39,7 @@ USB_KBD::SMessageData::SMessageData(u32 type, u8 modifiers, u8* pressed_keys) // TODO: support in netplay/movies. -USB_KBD::USB_KBD(u32 device_id, const std::string& device_name) : Device(device_id, device_name) +USB_KBD::USB_KBD(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { } diff --git a/Source/Core/Core/IOS/USB/USB_KBD.h b/Source/Core/Core/IOS/USB/USB_KBD.h index 39cab243da..34917338af 100644 --- a/Source/Core/Core/IOS/USB/USB_KBD.h +++ b/Source/Core/Core/IOS/USB/USB_KBD.h @@ -9,7 +9,7 @@ #include "Common/CommonTypes.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" namespace IOS { @@ -20,7 +20,7 @@ namespace Device class USB_KBD : public Device { public: - USB_KBD(u32 device_id, const std::string& device_name); + USB_KBD(Kernel& ios, const std::string& device_name); ReturnCode Open(const OpenRequest& request) override; IPCCommandResult Write(const ReadWriteRequest& request) override; diff --git a/Source/Core/Core/IOS/USB/USB_VEN/VEN.cpp b/Source/Core/Core/IOS/USB/USB_VEN/VEN.cpp index 303915f92a..f9bb7a1583 100644 --- a/Source/Core/Core/IOS/USB/USB_VEN/VEN.cpp +++ b/Source/Core/Core/IOS/USB/USB_VEN/VEN.cpp @@ -22,7 +22,7 @@ namespace HLE { namespace Device { -USB_VEN::USB_VEN(u32 device_id, const std::string& device_name) : USBHost(device_id, device_name) +USB_VEN::USB_VEN(Kernel& ios, const std::string& device_name) : USBHost(ios, device_name) { } @@ -33,7 +33,7 @@ USB_VEN::~USB_VEN() ReturnCode USB_VEN::Open(const OpenRequest& request) { - const u32 ios_major_version = GetVersion(); + const u32 ios_major_version = m_ios.GetVersion(); if (ios_major_version != 57 && ios_major_version != 58 && ios_major_version != 59) return IPC_ENOENT; return USBHost::Open(request); @@ -197,7 +197,7 @@ IPCCommandResult USB_VEN::Shutdown(const IOCtlRequest& request) std::lock_guard lk{m_devicechange_hook_address_mutex}; if (m_devicechange_hook_request) { - EnqueueReply(*m_devicechange_hook_request, IPC_SUCCESS); + m_ios.EnqueueIPCReply(*m_devicechange_hook_request, IPC_SUCCESS); m_devicechange_hook_request.reset(); } return GetDefaultReply(IPC_SUCCESS); @@ -220,13 +220,13 @@ s32 USB_VEN::SubmitTransfer(USB::Device& device, const IOCtlVRequest& ioctlv) switch (ioctlv.request) { case USB::IOCTLV_USBV5_CTRLMSG: - return device.SubmitTransfer(std::make_unique(ioctlv)); + return device.SubmitTransfer(std::make_unique(m_ios, ioctlv)); case USB::IOCTLV_USBV5_INTRMSG: - return device.SubmitTransfer(std::make_unique(ioctlv)); + return device.SubmitTransfer(std::make_unique(m_ios, ioctlv)); case USB::IOCTLV_USBV5_BULKMSG: - return device.SubmitTransfer(std::make_unique(ioctlv)); + return device.SubmitTransfer(std::make_unique(m_ios, ioctlv)); case USB::IOCTLV_USBV5_ISOMSG: - return device.SubmitTransfer(std::make_unique(ioctlv)); + return device.SubmitTransfer(std::make_unique(m_ios, ioctlv)); default: return IPC_EINVAL; } @@ -326,7 +326,7 @@ void USB_VEN::TriggerDeviceChangeReply() &entry, sizeof(entry)); } - EnqueueReply(*m_devicechange_hook_request, num_devices, 0, CoreTiming::FromThread::ANY); + m_ios.EnqueueIPCReply(*m_devicechange_hook_request, num_devices, 0, CoreTiming::FromThread::ANY); m_devicechange_hook_request.reset(); INFO_LOG(IOS_USB, "%d device(s), including interfaces", num_devices); } diff --git a/Source/Core/Core/IOS/USB/USB_VEN/VEN.h b/Source/Core/Core/IOS/USB/USB_VEN/VEN.h index b35ea15384..ed8d71a8d7 100644 --- a/Source/Core/Core/IOS/USB/USB_VEN/VEN.h +++ b/Source/Core/Core/IOS/USB/USB_VEN/VEN.h @@ -14,7 +14,7 @@ #include "Common/CommonTypes.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/USB/Host.h" class PointerWrap; @@ -28,7 +28,7 @@ namespace Device class USB_VEN final : public USBHost { public: - USB_VEN(u32 device_id, const std::string& device_name); + USB_VEN(Kernel& ios, const std::string& device_name); ~USB_VEN() override; ReturnCode Open(const OpenRequest& request) override; diff --git a/Source/Core/Core/IOS/WFS/WFSI.cpp b/Source/Core/Core/IOS/WFS/WFSI.cpp index 86e4fb492f..c6d26640f7 100644 --- a/Source/Core/Core/IOS/WFS/WFSI.cpp +++ b/Source/Core/Core/IOS/WFS/WFSI.cpp @@ -80,7 +80,7 @@ void ARCUnpacker::Extract(const WriteCallback& callback) namespace Device { -WFSI::WFSI(u32 device_id, const std::string& device_name) : Device(device_id, device_name) +WFSI::WFSI(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { } diff --git a/Source/Core/Core/IOS/WFS/WFSI.h b/Source/Core/Core/IOS/WFS/WFSI.h index 82dfded277..a6494c4f2c 100644 --- a/Source/Core/Core/IOS/WFS/WFSI.h +++ b/Source/Core/Core/IOS/WFS/WFSI.h @@ -13,7 +13,7 @@ #include "Common/CommonTypes.h" #include "Core/IOS/Device.h" #include "Core/IOS/ES/Formats.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" namespace IOS { @@ -39,7 +39,7 @@ namespace Device class WFSI : public Device { public: - WFSI(u32 device_id, const std::string& device_name); + WFSI(Kernel& ios, const std::string& device_name); IPCCommandResult IOCtl(const IOCtlRequest& request) override; diff --git a/Source/Core/Core/IOS/WFS/WFSSRV.cpp b/Source/Core/Core/IOS/WFS/WFSSRV.cpp index 74a67bff2f..54bdd806b7 100644 --- a/Source/Core/Core/IOS/WFS/WFSSRV.cpp +++ b/Source/Core/Core/IOS/WFS/WFSSRV.cpp @@ -27,7 +27,7 @@ std::string NativePath(const std::string& wfs_path) namespace Device { -WFSSRV::WFSSRV(u32 device_id, const std::string& device_name) : Device(device_id, device_name) +WFSSRV::WFSSRV(Kernel& ios, const std::string& device_name) : Device(ios, device_name) { m_device_name = "msc01"; } diff --git a/Source/Core/Core/IOS/WFS/WFSSRV.h b/Source/Core/Core/IOS/WFS/WFSSRV.h index ad540f8de6..097e086f0b 100644 --- a/Source/Core/Core/IOS/WFS/WFSSRV.h +++ b/Source/Core/Core/IOS/WFS/WFSSRV.h @@ -10,7 +10,7 @@ #include "Common/CommonTypes.h" #include "Common/FileUtil.h" #include "Core/IOS/Device.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "DiscIO/Volume.h" namespace IOS @@ -27,7 +27,7 @@ namespace Device class WFSSRV : public Device { public: - WFSSRV(u32 device_id, const std::string& device_name); + WFSSRV(Kernel& ios, const std::string& device_name); IPCCommandResult IOCtl(const IOCtlRequest& request) override; diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp index a4bada72e2..207a047079 100644 --- a/Source/Core/Core/Movie.cpp +++ b/Source/Core/Core/Movie.cpp @@ -533,8 +533,10 @@ void ChangeWiiPads(bool instantly) if (instantly && (s_controllers >> 4) == controllers) return; - const auto bt = std::static_pointer_cast( - IOS::HLE::GetDeviceByName("/dev/usb/oh1/57e/305")); + const auto ios = IOS::HLE::GetIOS(); + const auto bt = ios ? std::static_pointer_cast( + ios->GetDeviceByName("/dev/usb/oh1/57e/305")) : + nullptr; for (int i = 0; i < MAX_WIIMOTES; ++i) { g_wiimote_sources[i] = IsUsingWiimote(i) ? WIIMOTE_SRC_EMU : WIIMOTE_SRC_NONE; diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index fc2418391e..25b65dc8a7 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 82; // Last changed in PR 5333 +static const u32 STATE_VERSION = 83; // Last changed in PR 5340 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list, diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp index d9293a0faa..5c24b65a40 100644 --- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp +++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp @@ -23,7 +23,7 @@ #include "Core/Core.h" #include "Core/HW/Wiimote.h" #include "Core/Host.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/STM/STM.h" #include "Core/IOS/USB/Bluetooth/BTEmu.h" #include "Core/IOS/USB/Bluetooth/WiimoteDevice.h" @@ -139,19 +139,18 @@ bool Host_RendererIsFullscreen() void Host_ConnectWiimote(int wm_idx, bool connect) { - if (Core::IsRunning() && SConfig::GetInstance().bWii && - !SConfig::GetInstance().m_bt_passthrough_enabled) - { - Core::QueueHostJob([=] { - bool was_unpaused = Core::PauseAndLock(true); - const auto bt = std::static_pointer_cast( - IOS::HLE::GetDeviceByName("/dev/usb/oh1/57e/305")); - if (bt) - bt->AccessWiiMote(wm_idx | 0x100)->Activate(connect); - Host_UpdateMainFrame(); - Core::PauseAndLock(false, was_unpaused); - }); - } + Core::QueueHostJob([=] { + const auto ios = IOS::HLE::GetIOS(); + if (!ios || SConfig::GetInstance().m_bt_passthrough_enabled) + return; + bool was_unpaused = Core::PauseAndLock(true); + const auto bt = std::static_pointer_cast( + ios->GetDeviceByName("/dev/usb/oh1/57e/305")); + if (bt) + bt->AccessWiiMote(wm_idx | 0x100)->Activate(connect); + Host_UpdateMainFrame(); + Core::PauseAndLock(false, was_unpaused); + }); } void Host_SetWiiMoteConnectionState(int _State) @@ -241,7 +240,8 @@ class PlatformX11 : public Platform { if (s_shutdown_requested.TestAndClear()) { - const auto stm = IOS::HLE::GetDeviceByName("/dev/stm/eventhook"); + const auto ios = IOS::HLE::GetIOS(); + const auto stm = ios ? ios->GetDeviceByName("/dev/stm/eventhook") : nullptr; if (!s_tried_graceful_shutdown.IsSet() && stm && std::static_pointer_cast(stm)->HasHookInstalled()) { diff --git a/Source/Core/DolphinWX/Config/WiiConfigPane.cpp b/Source/Core/DolphinWX/Config/WiiConfigPane.cpp index 073dd9814d..d91d4875f3 100644 --- a/Source/Core/DolphinWX/Config/WiiConfigPane.cpp +++ b/Source/Core/DolphinWX/Config/WiiConfigPane.cpp @@ -13,7 +13,7 @@ #include "Core/ConfigManager.h" #include "Core/Core.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "DolphinWX/Config/AddUSBDeviceDiag.h" #include "DolphinWX/Config/WiiConfigPane.h" #include "DolphinWX/DolphinSlider.h" @@ -279,7 +279,9 @@ void WiiConfigPane::OnPAL60CheckBoxChanged(wxCommandEvent& event) void WiiConfigPane::OnSDCardCheckBoxChanged(wxCommandEvent& event) { SConfig::GetInstance().m_WiiSDCard = m_sd_card_checkbox->IsChecked(); - IOS::HLE::SDIO_EventNotify(); + const auto ios = IOS::HLE::GetIOS(); + if (ios) + ios->SDIO_EventNotify(); } void WiiConfigPane::OnConnectKeyboardCheckBoxChanged(wxCommandEvent& event) diff --git a/Source/Core/DolphinWX/ControllerConfigDiag.cpp b/Source/Core/DolphinWX/ControllerConfigDiag.cpp index e032b5a18e..005b4a5b6b 100644 --- a/Source/Core/DolphinWX/ControllerConfigDiag.cpp +++ b/Source/Core/DolphinWX/ControllerConfigDiag.cpp @@ -27,7 +27,7 @@ #include "Core/HW/Wiimote.h" #include "Core/HW/WiimoteReal/WiimoteReal.h" #include "Core/HotkeyManager.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/USB/Bluetooth/BTReal.h" #include "Core/NetPlayProto.h" #include "DolphinWX/Config/GCAdapterConfigDiag.h" @@ -543,13 +543,14 @@ void ControllerConfigDiag::OnBluetoothModeChanged(wxCommandEvent& event) void ControllerConfigDiag::OnPassthroughScanButton(wxCommandEvent& event) { - if (!Core::IsRunning()) + const auto ios = IOS::HLE::GetIOS(); + if (!ios) { wxMessageBox(_("A sync can only be triggered when a Wii game is running."), _("Sync Wii Remotes"), wxICON_WARNING); return; } - auto device = IOS::HLE::GetDeviceByName("/dev/usb/oh1/57e/305"); + auto device = ios->GetDeviceByName("/dev/usb/oh1/57e/305"); if (device != nullptr) std::static_pointer_cast(device) ->TriggerSyncButtonPressedEvent(); @@ -557,13 +558,14 @@ void ControllerConfigDiag::OnPassthroughScanButton(wxCommandEvent& event) void ControllerConfigDiag::OnPassthroughResetButton(wxCommandEvent& event) { - if (!Core::IsRunning()) + const auto ios = IOS::HLE::GetIOS(); + if (!ios) { wxMessageBox(_("Saved Wii Remote pairings can only be reset when a Wii game is running."), _("Reset Wii Remote pairings"), wxICON_WARNING); return; } - auto device = IOS::HLE::GetDeviceByName("/dev/usb/oh1/57e/305"); + auto device = ios->GetDeviceByName("/dev/usb/oh1/57e/305"); if (device != nullptr) std::static_pointer_cast(device)->TriggerSyncButtonHeldEvent(); } diff --git a/Source/Core/DolphinWX/Frame.cpp b/Source/Core/DolphinWX/Frame.cpp index 3c47217525..fab9e1ae3f 100644 --- a/Source/Core/DolphinWX/Frame.cpp +++ b/Source/Core/DolphinWX/Frame.cpp @@ -50,7 +50,7 @@ #include "Core/HW/Wiimote.h" #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "Core/HotkeyManager.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/USB/Bluetooth/BTBase.h" #include "Core/Movie.h" #include "Core/State.h" @@ -1278,7 +1278,8 @@ void CFrame::ParseHotkeys() if (SConfig::GetInstance().m_bt_passthrough_enabled) { - auto device = IOS::HLE::GetDeviceByName("/dev/usb/oh1/57e/305"); + const auto ios = IOS::HLE::GetIOS(); + auto device = ios ? ios->GetDeviceByName("/dev/usb/oh1/57e/305") : nullptr; if (device != nullptr) std::static_pointer_cast(device)->UpdateSyncButtonState( IsHotkey(HK_TRIGGER_SYNC_BUTTON, true)); diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index 9dd9c7a9a2..9822aae148 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -42,7 +42,7 @@ #include "Core/HW/Wiimote.h" #include "Core/Host.h" #include "Core/HotkeyManager.h" -#include "Core/IOS/IPC.h" +#include "Core/IOS/IOS.h" #include "Core/IOS/STM/STM.h" #include "Core/IOS/USB/Bluetooth/BTEmu.h" #include "Core/IOS/USB/Bluetooth/WiimoteDevice.h" @@ -880,7 +880,11 @@ void CFrame::DoStop() bool CFrame::TriggerSTMPowerEvent() { - const auto stm = IOS::HLE::GetDeviceByName("/dev/stm/eventhook"); + const auto ios = IOS::HLE::GetIOS(); + if (!ios) + return false; + + const auto stm = ios->GetDeviceByName("/dev/stm/eventhook"); if (!stm || !std::static_pointer_cast(stm)->HasHookInstalled()) return false; @@ -1310,8 +1314,12 @@ void CFrame::ConnectWiimote(int wm_idx, bool connect) !SConfig::GetInstance().m_bt_passthrough_enabled) { bool was_unpaused = Core::PauseAndLock(true); + const auto ios = IOS::HLE::GetIOS(); + if (!ios) + return; + const auto bt = std::static_pointer_cast( - IOS::HLE::GetDeviceByName("/dev/usb/oh1/57e/305")); + ios->GetDeviceByName("/dev/usb/oh1/57e/305")); if (bt) bt->AccessWiiMote(wm_idx | 0x100)->Activate(connect); const char* message = connect ? "Wii Remote %i connected" : "Wii Remote %i disconnected"; @@ -1323,11 +1331,12 @@ void CFrame::ConnectWiimote(int wm_idx, bool connect) void CFrame::OnConnectWiimote(wxCommandEvent& event) { - if (SConfig::GetInstance().m_bt_passthrough_enabled) + const auto ios = IOS::HLE::GetIOS(); + if (!ios || SConfig::GetInstance().m_bt_passthrough_enabled) return; bool was_unpaused = Core::PauseAndLock(true); const auto bt = std::static_pointer_cast( - IOS::HLE::GetDeviceByName("/dev/usb/oh1/57e/305")); + ios->GetDeviceByName("/dev/usb/oh1/57e/305")); const bool is_connected = bt && bt->AccessWiiMote((event.GetId() - IDM_CONNECT_WIIMOTE1) | 0x100)->IsConnected(); ConnectWiimote(event.GetId() - IDM_CONNECT_WIIMOTE1, !is_connected); @@ -1486,8 +1495,10 @@ void CFrame::UpdateGUI() // Tools GetMenuBar()->FindItem(IDM_CHEATS)->Enable(SConfig::GetInstance().bEnableCheats); - const auto bt = std::static_pointer_cast( - IOS::HLE::GetDeviceByName("/dev/usb/oh1/57e/305")); + const auto ios = IOS::HLE::GetIOS(); + const auto bt = ios ? std::static_pointer_cast( + ios->GetDeviceByName("/dev/usb/oh1/57e/305")) : + nullptr; bool ShouldEnableWiimotes = Running && bt && !SConfig::GetInstance().m_bt_passthrough_enabled; GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE1)->Enable(ShouldEnableWiimotes); GetMenuBar()->FindItem(IDM_CONNECT_WIIMOTE2)->Enable(ShouldEnableWiimotes);