Merge pull request #5340 from leoetlino/ios-reorg
IOS: Convert the IOS kernel HLE code to a class
This commit is contained in:
commit
8e2028e8da
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
constexpr u32 ADDR_MEM1_SIZE = 0x3100;
|
||||
constexpr u32 ADDR_MEM1_SIM_SIZE = 0x3104;
|
||||
constexpr u32 ADDR_MEM1_END = 0x3108;
|
||||
constexpr u32 ADDR_MEM1_ARENA_BEGIN = 0x310c;
|
||||
constexpr u32 ADDR_MEM1_ARENA_END = 0x3110;
|
||||
constexpr u32 ADDR_PH1 = 0x3114;
|
||||
constexpr u32 ADDR_MEM2_SIZE = 0x3118;
|
||||
constexpr u32 ADDR_MEM2_SIM_SIZE = 0x311c;
|
||||
constexpr u32 ADDR_MEM2_END = 0x3120;
|
||||
constexpr u32 ADDR_MEM2_ARENA_BEGIN = 0x3124;
|
||||
constexpr u32 ADDR_MEM2_ARENA_END = 0x3128;
|
||||
constexpr u32 ADDR_PH2 = 0x312c;
|
||||
constexpr u32 ADDR_IPC_BUFFER_BEGIN = 0x3130;
|
||||
constexpr u32 ADDR_IPC_BUFFER_END = 0x3134;
|
||||
constexpr u32 ADDR_HOLLYWOOD_REVISION = 0x3138;
|
||||
constexpr u32 ADDR_PH3 = 0x313c;
|
||||
constexpr u32 ADDR_IOS_VERSION = 0x3140;
|
||||
constexpr u32 ADDR_IOS_DATE = 0x3144;
|
||||
constexpr u32 ADDR_UNKNOWN_BEGIN = 0x3148;
|
||||
constexpr u32 ADDR_UNKNOWN_END = 0x314c;
|
||||
constexpr u32 ADDR_PH4 = 0x3150;
|
||||
constexpr u32 ADDR_PH5 = 0x3154;
|
||||
constexpr u32 ADDR_RAM_VENDOR = 0x3158;
|
||||
constexpr u32 ADDR_BOOT_FLAG = 0x315c;
|
||||
constexpr u32 ADDR_APPLOADER_FLAG = 0x315d;
|
||||
constexpr u32 ADDR_DEVKIT_BOOT_PROGRAM_VERSION = 0x315e;
|
||||
constexpr u32 ADDR_SYSMENU_SYNC = 0x3160;
|
||||
constexpr u32 PLACEHOLDER = 0xDEADBEEF;
|
||||
|
||||
enum class MemorySetupType
|
||||
{
|
||||
IOSReload,
|
||||
Full,
|
||||
};
|
||||
|
||||
static bool SetupMemory(u64 ios_title_id, MemorySetupType setup_type)
|
||||
{
|
||||
auto target_imv = std::find_if(
|
||||
GetMemoryValues().begin(), GetMemoryValues().end(),
|
||||
[&](const MemoryValues& imv) { return imv.ios_number == (ios_title_id & 0xffff); });
|
||||
|
||||
if (target_imv == GetMemoryValues().end())
|
||||
{
|
||||
ERROR_LOG(IOS, "Unknown IOS version: %016" PRIx64, ios_title_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (setup_type == MemorySetupType::IOSReload)
|
||||
{
|
||||
Memory::Write_U32(target_imv->ios_version, ADDR_IOS_VERSION);
|
||||
|
||||
// These values are written by the IOS kernel as part of its boot process (for IOS28 and newer).
|
||||
//
|
||||
// This works in a slightly different way on a real console: older IOS versions (< IOS28) all
|
||||
// have the same range (933E0000 - 93400000), thus they don't write it at boot and just inherit
|
||||
// all values. However, the range has changed since IOS28. To make things work properly
|
||||
// after a reload, newer IOSes always write the legacy range before loading an IOS kernel;
|
||||
// the new IOS either updates the range (>= IOS28) or inherits it (< IOS28).
|
||||
//
|
||||
// We can skip this convoluted process and just write the correct range directly.
|
||||
Memory::Write_U32(target_imv->mem2_physical_size, ADDR_MEM2_SIZE);
|
||||
Memory::Write_U32(target_imv->mem2_simulated_size, ADDR_MEM2_SIM_SIZE);
|
||||
Memory::Write_U32(target_imv->mem2_end, ADDR_MEM2_END);
|
||||
Memory::Write_U32(target_imv->mem2_arena_begin, ADDR_MEM2_ARENA_BEGIN);
|
||||
Memory::Write_U32(target_imv->mem2_arena_end, ADDR_MEM2_ARENA_END);
|
||||
Memory::Write_U32(target_imv->ipc_buffer_begin, ADDR_IPC_BUFFER_BEGIN);
|
||||
Memory::Write_U32(target_imv->ipc_buffer_end, ADDR_IPC_BUFFER_END);
|
||||
Memory::Write_U32(target_imv->unknown_begin, ADDR_UNKNOWN_BEGIN);
|
||||
Memory::Write_U32(target_imv->unknown_end, ADDR_UNKNOWN_END);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Memory::Write_U32(target_imv->mem1_physical_size, ADDR_MEM1_SIZE);
|
||||
Memory::Write_U32(target_imv->mem1_simulated_size, ADDR_MEM1_SIM_SIZE);
|
||||
Memory::Write_U32(target_imv->mem1_end, ADDR_MEM1_END);
|
||||
Memory::Write_U32(target_imv->mem1_arena_begin, ADDR_MEM1_ARENA_BEGIN);
|
||||
Memory::Write_U32(target_imv->mem1_arena_end, ADDR_MEM1_ARENA_END);
|
||||
Memory::Write_U32(PLACEHOLDER, ADDR_PH1);
|
||||
Memory::Write_U32(target_imv->mem2_physical_size, ADDR_MEM2_SIZE);
|
||||
Memory::Write_U32(target_imv->mem2_simulated_size, ADDR_MEM2_SIM_SIZE);
|
||||
Memory::Write_U32(target_imv->mem2_end, ADDR_MEM2_END);
|
||||
Memory::Write_U32(target_imv->mem2_arena_begin, ADDR_MEM2_ARENA_BEGIN);
|
||||
Memory::Write_U32(target_imv->mem2_arena_end, ADDR_MEM2_ARENA_END);
|
||||
Memory::Write_U32(PLACEHOLDER, ADDR_PH2);
|
||||
Memory::Write_U32(target_imv->ipc_buffer_begin, ADDR_IPC_BUFFER_BEGIN);
|
||||
Memory::Write_U32(target_imv->ipc_buffer_end, ADDR_IPC_BUFFER_END);
|
||||
Memory::Write_U32(target_imv->hollywood_revision, ADDR_HOLLYWOOD_REVISION);
|
||||
Memory::Write_U32(PLACEHOLDER, ADDR_PH3);
|
||||
Memory::Write_U32(target_imv->ios_version, ADDR_IOS_VERSION);
|
||||
Memory::Write_U32(target_imv->ios_date, ADDR_IOS_DATE);
|
||||
Memory::Write_U32(target_imv->unknown_begin, ADDR_UNKNOWN_BEGIN);
|
||||
Memory::Write_U32(target_imv->unknown_end, ADDR_UNKNOWN_END);
|
||||
Memory::Write_U32(PLACEHOLDER, ADDR_PH4);
|
||||
Memory::Write_U32(PLACEHOLDER, ADDR_PH5);
|
||||
Memory::Write_U32(target_imv->ram_vendor, ADDR_RAM_VENDOR);
|
||||
Memory::Write_U8(0xDE, ADDR_BOOT_FLAG);
|
||||
Memory::Write_U8(0xAD, ADDR_APPLOADER_FLAG);
|
||||
Memory::Write_U16(0xBEEF, ADDR_DEVKIT_BOOT_PROGRAM_VERSION);
|
||||
Memory::Write_U32(target_imv->sysmenu_sync, ADDR_SYSMENU_SYNC);
|
||||
return true;
|
||||
}
|
||||
|
||||
// IOS used by the latest System Menu (4.3).
|
||||
constexpr u64 IOS80_TITLE_ID = 0x0000000100000050;
|
||||
constexpr u64 BC_TITLE_ID = 0x0000000100000100;
|
||||
constexpr u64 MIOS_TITLE_ID = 0x0000000100000101;
|
||||
|
||||
Kernel::Kernel(u64 title_id) : m_title_id(title_id)
|
||||
{
|
||||
INFO_LOG(IOS, "Starting IOS %016" PRIx64, title_id);
|
||||
|
||||
if (!SetupMemory(title_id, MemorySetupType::IOSReload))
|
||||
WARN_LOG(IOS, "No information about this IOS -- cannot set up memory values");
|
||||
|
||||
if (title_id == MIOS_TITLE_ID)
|
||||
{
|
||||
MIOS::Load();
|
||||
return;
|
||||
}
|
||||
|
||||
// IOS re-inits IPC and sends a dummy ack during its boot process.
|
||||
EnqueueIPCAcknowledgement(0);
|
||||
|
||||
AddStaticDevices();
|
||||
}
|
||||
|
||||
Kernel::~Kernel()
|
||||
{
|
||||
CoreTiming::RemoveAllEvents(s_event_enqueue);
|
||||
|
||||
// Close all devices that were opened
|
||||
for (auto& device : m_fdmap)
|
||||
{
|
||||
if (!device)
|
||||
continue;
|
||||
device->Close(0);
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_device_map_mutex);
|
||||
m_device_map.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// The title ID is a u64 where the first 32 bits are used for the title type.
|
||||
// For IOS title IDs, the type will always be 00000001 (system), and the lower 32 bits
|
||||
// are used for the IOS major version -- which is what we want here.
|
||||
u32 Kernel::GetVersion() const
|
||||
{
|
||||
return static_cast<u32>(m_title_id);
|
||||
}
|
||||
|
||||
// Since we don't have actual processes, we keep track of only the PPC's UID/GID.
|
||||
// These functions roughly correspond to syscalls 0x2b, 0x2c, 0x2d, 0x2e (though only for the PPC).
|
||||
void Kernel::SetUidForPPC(u32 uid)
|
||||
{
|
||||
m_ppc_uid = uid;
|
||||
}
|
||||
|
||||
u32 Kernel::GetUidForPPC() const
|
||||
{
|
||||
return m_ppc_uid;
|
||||
}
|
||||
|
||||
void Kernel::SetGidForPPC(u16 gid)
|
||||
{
|
||||
m_ppc_gid = gid;
|
||||
}
|
||||
|
||||
u16 Kernel::GetGidForPPC() const
|
||||
{
|
||||
return m_ppc_gid;
|
||||
}
|
||||
|
||||
// This corresponds to syscall 0x41, which loads a binary from the NAND and bootstraps the PPC.
|
||||
// Unlike 0x42, IOS will set up some constants in memory before booting the PPC.
|
||||
bool Kernel::BootstrapPPC(const DiscIO::CNANDContentLoader& content_loader)
|
||||
{
|
||||
if (!content_loader.IsValid())
|
||||
return false;
|
||||
|
||||
const auto* content = content_loader.GetContentByIndex(content_loader.GetTMD().GetBootIndex());
|
||||
if (!content)
|
||||
return false;
|
||||
|
||||
const auto dol_loader = std::make_unique<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;
|
||||
}
|
||||
|
||||
// Similar to syscall 0x42 (ios_boot); this is used to change the current active IOS.
|
||||
// IOS writes the new version to 0x3140 before restarting, but it does *not* poke any
|
||||
// of the other constants to the memory. Warning: this resets the kernel instance.
|
||||
bool Kernel::BootIOS(const u64 ios_title_id)
|
||||
{
|
||||
// A real Wii goes through several steps before getting to MIOS.
|
||||
//
|
||||
// * The System Menu detects a GameCube disc and launches BC (1-100) instead of the game.
|
||||
// * BC (similar to boot1) lowers the clock speed to the Flipper's and then launches boot2.
|
||||
// * boot2 sees the lowered clock speed and launches MIOS (1-101) instead of the System Menu.
|
||||
//
|
||||
// Because we currently don't have boot1 and boot2, and BC is only ever used to launch MIOS
|
||||
// (indirectly via boot2), we can just launch MIOS when BC is launched.
|
||||
if (ios_title_id == BC_TITLE_ID)
|
||||
{
|
||||
NOTICE_LOG(IOS, "BC: Launching MIOS...");
|
||||
return BootIOS(MIOS_TITLE_ID);
|
||||
}
|
||||
|
||||
// Shut down the active IOS first before switching to the new one.
|
||||
s_ios.reset();
|
||||
s_ios = std::make_unique<Kernel>(ios_title_id);
|
||||
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"));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
// This is called every IPC_HLE_PERIOD from SystemTimers.cpp
|
||||
// Takes care of routing ipc <-> ipc HLE
|
||||
void Kernel::UpdateIPC()
|
||||
{
|
||||
if (!IsReady())
|
||||
return;
|
||||
|
||||
if (m_request_queue.size())
|
||||
{
|
||||
GenerateAck(m_request_queue.front());
|
||||
u32 command = m_request_queue.front();
|
||||
m_request_queue.pop_front();
|
||||
ExecuteIPCCommand(command);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_reply_queue.size())
|
||||
{
|
||||
GenerateReply(m_reply_queue.front());
|
||||
DEBUG_LOG(IOS, "<<-- Reply to IPC Request @ 0x%08x", m_reply_queue.front());
|
||||
m_reply_queue.pop_front();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ack_queue.size())
|
||||
{
|
||||
GenerateAck(m_ack_queue.front());
|
||||
WARN_LOG(IOS, "<<-- Double-ack to IPC Request @ 0x%08x", m_ack_queue.front());
|
||||
m_ack_queue.pop_front();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Kernel::UpdateDevices()
|
||||
{
|
||||
// Check if a hardware device must be updated
|
||||
for (const auto& entry : m_device_map)
|
||||
{
|
||||
if (entry.second->IsOpened())
|
||||
{
|
||||
entry.second->Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Kernel::UpdateWantDeterminism(const bool new_want_determinism)
|
||||
{
|
||||
WiiSockMan::GetInstance().UpdateWantDeterminism(new_want_determinism);
|
||||
for (const auto& device : m_device_map)
|
||||
device.second->UpdateWantDeterminism(new_want_determinism);
|
||||
}
|
||||
|
||||
void Kernel::SDIO_EventNotify()
|
||||
{
|
||||
// TODO: Potential race condition: If IsRunning() becomes false after
|
||||
// it's checked, an event may be scheduled after CoreTiming shuts down.
|
||||
if (SConfig::GetInstance().bWii && Core::IsRunning())
|
||||
CoreTiming::ScheduleEvent(0, s_event_sdio_notify, 0, CoreTiming::FromThread::NON_CPU);
|
||||
}
|
||||
|
||||
void Kernel::DoState(PointerWrap& p)
|
||||
{
|
||||
p.Do(m_request_queue);
|
||||
p.Do(m_reply_queue);
|
||||
p.Do(m_last_reply_time);
|
||||
p.Do(m_title_id);
|
||||
p.Do(m_ppc_uid);
|
||||
p.Do(m_ppc_gid);
|
||||
|
||||
if (m_title_id == MIOS_TITLE_ID)
|
||||
return;
|
||||
|
||||
// We need to make sure all file handles are closed so IOS::HLE::Device::FS::DoState can
|
||||
// successfully save or re-create /tmp
|
||||
for (auto& descriptor : m_fdmap)
|
||||
{
|
||||
if (descriptor)
|
||||
descriptor->PrepareForState(p.GetMode());
|
||||
}
|
||||
|
||||
for (const auto& entry : m_device_map)
|
||||
entry.second->DoState(p);
|
||||
|
||||
if (p.GetMode() == PointerWrap::MODE_READ)
|
||||
{
|
||||
for (u32 i = 0; i < IPC_MAX_FDS; i++)
|
||||
{
|
||||
u32 exists = 0;
|
||||
p.Do(exists);
|
||||
if (exists)
|
||||
{
|
||||
auto device_type = Device::Device::DeviceType::Static;
|
||||
p.Do(device_type);
|
||||
switch (device_type)
|
||||
{
|
||||
case Device::Device::DeviceType::Static:
|
||||
{
|
||||
std::string device_name;
|
||||
p.Do(device_name);
|
||||
m_fdmap[i] = GetDeviceByName(device_name);
|
||||
break;
|
||||
}
|
||||
case Device::Device::DeviceType::FileIO:
|
||||
m_fdmap[i] = std::make_shared<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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
} // namespace HLE
|
||||
} // namespace IOS
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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…
Reference in New Issue