mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-03-12 22:56:52 +01:00
IOS: Convert the IOS kernel HLE code to a class
This changes the main IOS code (roughly the equivalent of the kernel) to a class instead of being a set of free functions + tons of static variables. The reason for this change is that keeping tons of static variables like that prevents us from making an IOS instance and reusing IOS code easily. Converting the IOS code to a class also allows us to mostly decouple IOS from the PPC emulation. The more interesting changes are in Core/IOS/IOS. Everything else is mostly just boring stuff required by this change... * Because the devices themselves call back to the main IOS code for various things (getting the current version, replying to a request, and other syscall-like functions), just like processes in IOS call kernel syscalls, we have to pass a reference to the kernel to anything that uses IOS syscalls. * Change DoState to save device names instead of device IDs to simplify AddDevice() and get rid of an ugly static count. * Change ES_Launch's ack to be sent at IOS boot, now that we can do this properly.
This commit is contained in:
parent
fcc2ed4550
commit
2fc5047d26
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -174,7 +174,8 @@
|
||||
<ClCompile Include="HW\WiiSaveCrypted.cpp" />
|
||||
<ClCompile Include="IOS\Device.cpp" />
|
||||
<ClCompile Include="IOS\DeviceStub.cpp" />
|
||||
<ClCompile Include="IOS\IPC.cpp" />
|
||||
<ClCompile Include="IOS\IOS.cpp" />
|
||||
<ClCompile Include="IOS\MemoryValues.cpp" />
|
||||
<ClCompile Include="IOS\MIOS.cpp" />
|
||||
<ClCompile Include="IOS\DI\DI.cpp" />
|
||||
<ClCompile Include="IOS\ES\ES.cpp" />
|
||||
@ -431,7 +432,8 @@
|
||||
<ClInclude Include="HW\WII_IPC.h" />
|
||||
<ClInclude Include="IOS\Device.h" />
|
||||
<ClInclude Include="IOS\DeviceStub.h" />
|
||||
<ClInclude Include="IOS\IPC.h" />
|
||||
<ClInclude Include="IOS\IOS.h" />
|
||||
<ClInclude Include="IOS\MemoryValues.h" />
|
||||
<ClInclude Include="IOS\MIOS.h" />
|
||||
<ClInclude Include="IOS\DI\DI.h" />
|
||||
<ClInclude Include="IOS\ES\ES.h" />
|
||||
|
@ -790,7 +790,10 @@
|
||||
<ClCompile Include="IOS\Network\ICMPLin.cpp">
|
||||
<Filter>IOS\Network</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IOS\IPC.cpp">
|
||||
<ClCompile Include="IOS\IOS.cpp">
|
||||
<Filter>IOS</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IOS\MemoryValues.cpp">
|
||||
<Filter>IOS</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IOS\MIOS.cpp">
|
||||
@ -1504,7 +1507,10 @@
|
||||
<ClInclude Include="IOS\Device.h">
|
||||
<Filter>IOS</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IOS\IPC.h">
|
||||
<ClInclude Include="IOS\IOS.h">
|
||||
<Filter>IOS</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IOS\MemoryValues.h">
|
||||
<Filter>IOS</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IOS\MIOS.h">
|
||||
|
@ -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<IOS::HLE::Device::DI>(di)->FinishIOCtl(interrupt_type);
|
||||
break;
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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<IOS::HLE::Device::STMEventHook>(stm)->ResetButton();
|
||||
}
|
||||
const auto ios = IOS::HLE::GetIOS();
|
||||
if (!ios)
|
||||
return;
|
||||
|
||||
auto stm = ios->GetDeviceByName("/dev/stm/eventhook");
|
||||
if (stm)
|
||||
std::static_pointer_cast<IOS::HLE::Device::STMEventHook>(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<IOS::HLE::Device::STMEventHook>(stm)->PowerButton();
|
||||
}
|
||||
const auto ios = IOS::HLE::GetIOS();
|
||||
if (!ios)
|
||||
return;
|
||||
|
||||
auto stm = ios->GetDeviceByName("/dev/stm/eventhook");
|
||||
if (stm)
|
||||
std::static_pointer_cast<IOS::HLE::Device::STMEventHook>(stm)->PowerButton();
|
||||
}
|
||||
|
||||
void ResetButton_Tap()
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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, 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<u32>(),
|
||||
MMIO::ComplexWrite<u32>([](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);
|
||||
}));
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<OpenMode>(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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
654
Source/Core/Core/IOS/IOS.cpp
Normal file
654
Source/Core/Core/IOS/IOS.cpp
Normal file
@ -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 <algorithm>
|
||||
#include <array>
|
||||
#include <cinttypes>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#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<Kernel> 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;
|
||||
|
||||
enum class MemorySetupType
|
||||
{
|
||||
IOSReload,
|
||||
Full,
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
// 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<u32>(m_title_id);
|
||||
}
|
||||
|
||||
constexpr u32 PLACEHOLDER = 0xDEADBEEF;
|
||||
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;
|
||||
}
|
||||
|
||||
void Kernel::AddDevice(std::unique_ptr<Device::Device> device)
|
||||
{
|
||||
_assert_(device->GetDeviceType() == Device::Device::DeviceType::Static);
|
||||
m_device_map[device->GetDeviceName()] = std::move(device);
|
||||
}
|
||||
|
||||
void Kernel::AddStaticDevices()
|
||||
{
|
||||
std::lock_guard<std::mutex> 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<Device::BluetoothEmu>(*this, "/dev/usb/oh1/57e/305"));
|
||||
else
|
||||
AddDevice(std::make_unique<Device::BluetoothReal>(*this, "/dev/usb/oh1/57e/305"));
|
||||
|
||||
AddDevice(std::make_unique<Device::STMImmediate>(*this, "/dev/stm/immediate"));
|
||||
AddDevice(std::make_unique<Device::STMEventHook>(*this, "/dev/stm/eventhook"));
|
||||
AddDevice(std::make_unique<Device::FS>(*this, "/dev/fs"));
|
||||
AddDevice(std::make_unique<Device::ES>(*this, "/dev/es"));
|
||||
AddDevice(std::make_unique<Device::DI>(*this, "/dev/di"));
|
||||
AddDevice(std::make_unique<Device::NetKDRequest>(*this, "/dev/net/kd/request"));
|
||||
AddDevice(std::make_unique<Device::NetKDTime>(*this, "/dev/net/kd/time"));
|
||||
AddDevice(std::make_unique<Device::NetNCDManage>(*this, "/dev/net/ncd/manage"));
|
||||
AddDevice(std::make_unique<Device::NetWDCommand>(*this, "/dev/net/wd/command"));
|
||||
AddDevice(std::make_unique<Device::NetIPTop>(*this, "/dev/net/ip/top"));
|
||||
AddDevice(std::make_unique<Device::NetSSL>(*this, "/dev/net/ssl"));
|
||||
AddDevice(std::make_unique<Device::USB_KBD>(*this, "/dev/usb/kbd"));
|
||||
AddDevice(std::make_unique<Device::SDIOSlot0>(*this, "/dev/sdio/slot0"));
|
||||
AddDevice(std::make_unique<Device::Stub>(*this, "/dev/sdio/slot1"));
|
||||
AddDevice(std::make_unique<Device::USB_HIDv4>(*this, "/dev/usb/hid"));
|
||||
AddDevice(std::make_unique<Device::OH0>(*this, "/dev/usb/oh0"));
|
||||
AddDevice(std::make_unique<Device::Stub>(*this, "/dev/usb/oh1"));
|
||||
AddDevice(std::make_unique<Device::USB_VEN>(*this, "/dev/usb/ven"));
|
||||
AddDevice(std::make_unique<Device::WFSSRV>(*this, "/dev/usb/wfssrv"));
|
||||
AddDevice(std::make_unique<Device::WFSI>(*this, "/dev/wfsi"));
|
||||
}
|
||||
|
||||
// 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<std::mutex> lock(m_device_map_mutex);
|
||||
m_device_map.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Kernel::HandleIPCEvent(u64 userdata)
|
||||
{
|
||||
if (userdata & ENQUEUE_ACKNOWLEDGEMENT_FLAG)
|
||||
m_ack_queue.push_back(static_cast<u32>(userdata));
|
||||
else if (userdata & ENQUEUE_REQUEST_FLAG)
|
||||
m_request_queue.push_back(static_cast<u32>(userdata));
|
||||
else
|
||||
m_reply_queue.push_back(static_cast<u32>(userdata));
|
||||
|
||||
UpdateIPC();
|
||||
}
|
||||
|
||||
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<Device::SDIOSlot0*>(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<Kernel>(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();
|
||||
}
|
||||
|
||||
// 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 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<Kernel>(ios_title_id);
|
||||
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 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<CDolLoader>(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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
s32 Kernel::GetFreeDeviceID()
|
||||
{
|
||||
for (u32 i = 0; i < IPC_MAX_FDS; i++)
|
||||
{
|
||||
if (m_fdmap[i] == nullptr)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::shared_ptr<Device::Device> Kernel::GetDeviceByName(const std::string& device_name)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_device_map_mutex);
|
||||
const auto iterator = m_device_map.find(device_name);
|
||||
return iterator != m_device_map.end() ? iterator->second : nullptr;
|
||||
}
|
||||
|
||||
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<Device::FileIO>(*this, "");
|
||||
m_fdmap[i]->DoState(p);
|
||||
break;
|
||||
case Device::Device::DeviceType::OH0:
|
||||
m_fdmap[i] = std::make_shared<Device::OH0Device>(*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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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::Device> device;
|
||||
if (request.path.find("/dev/usb/oh0/") == 0 && !GetDeviceByName(request.path))
|
||||
{
|
||||
device = std::make_shared<Device::OH0Device>(*this, request.path);
|
||||
}
|
||||
else if (request.path.find("/dev/") == 0)
|
||||
{
|
||||
device = GetDeviceByName(request.path);
|
||||
}
|
||||
else if (request.path.find('/') == 0)
|
||||
{
|
||||
device = std::make_shared<Device::FileIO>(*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<int>(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<u32>(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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
} // namespace HLE
|
||||
} // namespace IOS
|
120
Source/Core/Core/IOS/IOS.h
Normal file
120
Source/Core/Core/IOS/IOS.h
Normal file
@ -0,0 +1,120 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<Device::Device> 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::Device> device);
|
||||
void AddStaticDevices();
|
||||
s32 GetFreeDeviceID();
|
||||
s32 OpenDevice(OpenRequest& request);
|
||||
|
||||
u64 m_title_id = 0;
|
||||
static constexpr u8 IPC_MAX_FDS = 0x18;
|
||||
std::map<std::string, std::shared_ptr<Device::Device>> m_device_map;
|
||||
std::mutex m_device_map_mutex;
|
||||
// TODO: make this fdmap per process.
|
||||
std::array<std::shared_ptr<Device::Device>, IPC_MAX_FDS> m_fdmap;
|
||||
|
||||
u32 m_ppc_uid = 0;
|
||||
u16 m_ppc_gid = 0;
|
||||
|
||||
using IPCMsgQueue = std::deque<u32>;
|
||||
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
|
File diff suppressed because it is too large
Load Diff
@ -1,92 +0,0 @@
|
||||
// Copyright 2008 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<Device::Device> GetDeviceByName(const std::string& device_name);
|
||||
std::shared_ptr<Device::Device> 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
|
329
Source/Core/Core/IOS/MemoryValues.cpp
Normal file
329
Source/Core/Core/IOS/MemoryValues.cpp
Normal file
@ -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<MemoryValues, 40> 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<MemoryValues, 40>& GetMemoryValues()
|
||||
{
|
||||
return ios_memory_values;
|
||||
}
|
||||
}
|
||||
}
|
41
Source/Core/Core/IOS/MemoryValues.h
Normal file
41
Source/Core/Core/IOS/MemoryValues.h
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#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<MemoryValues, 40>& GetMemoryValues();
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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() {}
|
||||
|
@ -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 <typename T>
|
||||
static void DoStateForMessage(PointerWrap& p, std::unique_ptr<T>& message)
|
||||
static void DoStateForMessage(Kernel& ios, PointerWrap& p, std::unique_ptr<T>& 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<T>(request);
|
||||
message = std::make_unique<T>(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<USB::V0CtrlMessage>(request);
|
||||
m_CtrlSetup = std::make_unique<USB::V0CtrlMessage>(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<USB::V0BulkMessage>(request);
|
||||
m_ACLEndpoint = std::make_unique<USB::V0BulkMessage>(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<USB::V0IntrMessage>(request);
|
||||
m_HCIEndpoint = std::make_unique<USB::V0IntrMessage>(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<u8*>(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);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -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<Packet> 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<Packet> m_queue;
|
||||
} m_acl_pool{m_ios};
|
||||
|
||||
u32 m_PacketCount[MAX_BBMOTES] = {};
|
||||
u64 m_last_ticks = 0;
|
||||
|
@ -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<std::mutex> lk(m_transfers_mutex);
|
||||
auto cmd = std::make_unique<USB::V0CtrlMessage>(request);
|
||||
auto cmd = std::make_unique<USB::V0CtrlMessage>(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<std::mutex> lk(m_transfers_mutex);
|
||||
auto cmd = std::make_unique<USB::V0IntrMessage>(request);
|
||||
auto cmd = std::make_unique<USB::V0IntrMessage>(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<s32>(sizeof(hci_event)));
|
||||
m_ios.EnqueueIPCReply(ctrl.ios_request, static_cast<s32>(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<s32>(sizeof(hci_event) + sizeof(reply)));
|
||||
m_ios.EnqueueIPCReply(ctrl.ios_request, static_cast<s32>(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<s32>(sizeof(hci_event) + size));
|
||||
m_ios.EnqueueIPCReply(ctrl.ios_request, static_cast<s32>(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
|
||||
|
@ -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;
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include <string>
|
||||
|
||||
#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;
|
||||
};
|
||||
|
@ -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::Device::BluetoothEmu>(
|
||||
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);
|
||||
}
|
||||
|
@ -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<u32>(packet_sizes_addr + packet_num * sizeof(u16)));
|
||||
|
@ -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<u8[]> MakeBuffer(size_t size) const;
|
||||
void FillBuffer(const u8* src, size_t size) const;
|
||||
|
||||
private:
|
||||
Kernel& m_ios;
|
||||
};
|
||||
|
||||
struct CtrlMessage : TransferCommand
|
||||
|
@ -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<u64>& new_devices, DeviceChangeHooks& hooks
|
||||
continue;
|
||||
}
|
||||
|
||||
auto usb_device = std::make_unique<USB::LibusbDevice>(device, descriptor);
|
||||
auto usb_device = std::make_unique<USB::LibusbDevice>(m_ios, device, descriptor);
|
||||
if (!ShouldAddDevice(*usb_device))
|
||||
{
|
||||
libusb_unref_device(device);
|
||||
|
@ -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;
|
||||
|
@ -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<CtrlMessage> cmd)
|
||||
}
|
||||
const int ret = SetAltSetting(static_cast<u8>(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);
|
||||
}
|
||||
|
||||
|
@ -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<ConfigDescriptor> GetConfigurations() const override;
|
||||
@ -61,6 +62,8 @@ public:
|
||||
int SubmitTransfer(std::unique_ptr<IsoMessage> message) override;
|
||||
|
||||
private:
|
||||
Kernel& m_ios;
|
||||
|
||||
std::vector<std::unique_ptr<LibusbConfigDescriptor>> m_config_descriptors;
|
||||
u16 m_vid = 0;
|
||||
u16 m_pid = 0;
|
||||
|
@ -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<T, u32>& 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<USB::V0CtrlMessage>(ioctlv));
|
||||
return device.SubmitTransfer(std::make_unique<USB::V0CtrlMessage>(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<USB::V0BulkMessage>(ioctlv, ioctlv.request == USB::IOCTLV_USBV0_LBLKMSG));
|
||||
return device.SubmitTransfer(std::make_unique<USB::V0BulkMessage>(
|
||||
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<USB::V0IntrMessage>(ioctlv));
|
||||
return device.SubmitTransfer(std::make_unique<USB::V0IntrMessage>(m_ios, ioctlv));
|
||||
|
||||
case USB::IOCTLV_USBV0_ISOMSG:
|
||||
if (!ioctlv.HasNumberOfValidVectors(3, 2))
|
||||
return IPC_EINVAL;
|
||||
return device.SubmitTransfer(std::make_unique<USB::V0IsoMessage>(ioctlv));
|
||||
return device.SubmitTransfer(std::make_unique<USB::V0IsoMessage>(m_ios, ioctlv));
|
||||
|
||||
default:
|
||||
return IPC_EINVAL;
|
||||
|
@ -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;
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include <vector>
|
||||
|
||||
#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<OH0>(GetDeviceByName("/dev/usb/oh0"));
|
||||
m_oh0 = std::static_pointer_cast<OH0>(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<OH0>(GetDeviceByName("/dev/usb/oh0"));
|
||||
m_oh0 = std::static_pointer_cast<OH0>(m_ios.GetDeviceByName("/dev/usb/oh0"));
|
||||
|
||||
ReturnCode return_code;
|
||||
std::tie(return_code, m_device_id) = m_oh0->DeviceOpen(m_vid, m_pid);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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<USB::V4CtrlMessage>(request));
|
||||
return device.SubmitTransfer(std::make_unique<USB::V4CtrlMessage>(m_ios, request));
|
||||
case USB::IOCTL_USBV4_GET_US_STRING:
|
||||
return device.SubmitTransfer(std::make_unique<USB::V4GetUSStringMessage>(request));
|
||||
return device.SubmitTransfer(std::make_unique<USB::V4GetUSStringMessage>(m_ios, request));
|
||||
case USB::IOCTL_USBV4_INTRMSG_IN:
|
||||
case USB::IOCTL_USBV4_INTRMSG_OUT:
|
||||
return device.SubmitTransfer(std::make_unique<USB::V4IntrMessage>(request));
|
||||
return device.SubmitTransfer(std::make_unique<USB::V4IntrMessage>(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();
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <vector>
|
||||
|
||||
#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;
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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<std::mutex> 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<USB::V5CtrlMessage>(ioctlv));
|
||||
return device.SubmitTransfer(std::make_unique<USB::V5CtrlMessage>(m_ios, ioctlv));
|
||||
case USB::IOCTLV_USBV5_INTRMSG:
|
||||
return device.SubmitTransfer(std::make_unique<USB::V5IntrMessage>(ioctlv));
|
||||
return device.SubmitTransfer(std::make_unique<USB::V5IntrMessage>(m_ios, ioctlv));
|
||||
case USB::IOCTLV_USBV5_BULKMSG:
|
||||
return device.SubmitTransfer(std::make_unique<USB::V5BulkMessage>(ioctlv));
|
||||
return device.SubmitTransfer(std::make_unique<USB::V5BulkMessage>(m_ios, ioctlv));
|
||||
case USB::IOCTLV_USBV5_ISOMSG:
|
||||
return device.SubmitTransfer(std::make_unique<USB::V5IsoMessage>(ioctlv));
|
||||
return device.SubmitTransfer(std::make_unique<USB::V5IsoMessage>(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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -533,8 +533,10 @@ void ChangeWiiPads(bool instantly)
|
||||
if (instantly && (s_controllers >> 4) == controllers)
|
||||
return;
|
||||
|
||||
const auto bt = std::static_pointer_cast<IOS::HLE::Device::BluetoothEmu>(
|
||||
IOS::HLE::GetDeviceByName("/dev/usb/oh1/57e/305"));
|
||||
const auto ios = IOS::HLE::GetIOS();
|
||||
const auto bt = ios ? std::static_pointer_cast<IOS::HLE::Device::BluetoothEmu>(
|
||||
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;
|
||||
|
@ -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,
|
||||
|
@ -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::Device::BluetoothEmu>(
|
||||
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::HLE::Device::BluetoothEmu>(
|
||||
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<IOS::HLE::Device::STMEventHook>(stm)->HasHookInstalled())
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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<IOS::HLE::Device::BluetoothBase>(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<IOS::HLE::Device::BluetoothBase>(device)->TriggerSyncButtonHeldEvent();
|
||||
}
|
||||
|
@ -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<IOS::HLE::Device::BluetoothBase>(device)->UpdateSyncButtonState(
|
||||
IsHotkey(HK_TRIGGER_SYNC_BUTTON, true));
|
||||
|
@ -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<IOS::HLE::Device::STMEventHook>(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::Device::BluetoothEmu>(
|
||||
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::Device::BluetoothEmu>(
|
||||
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::Device::BluetoothEmu>(
|
||||
IOS::HLE::GetDeviceByName("/dev/usb/oh1/57e/305"));
|
||||
const auto ios = IOS::HLE::GetIOS();
|
||||
const auto bt = ios ? std::static_pointer_cast<IOS::HLE::Device::BluetoothEmu>(
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user