Merge pull request #11787 from AdmiralCurtiss/ios-emulationkernel
IOS: Leverage Kernel/EmulationKernel difference for passing System to most IOS devices.
This commit is contained in:
commit
89154c858b
|
@ -41,7 +41,8 @@ namespace IOS::HLE
|
||||||
{
|
{
|
||||||
CoreTiming::EventType* DIDevice::s_finish_executing_di_command;
|
CoreTiming::EventType* DIDevice::s_finish_executing_di_command;
|
||||||
|
|
||||||
DIDevice::DIDevice(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
|
DIDevice::DIDevice(EmulationKernel& ios, const std::string& device_name)
|
||||||
|
: EmulationDevice(ios, device_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ std::optional<IPCReply> DIDevice::IOCtl(const IOCtlRequest& request)
|
||||||
// asynchronously. The rest are also treated as async to match this. Only one command can be
|
// asynchronously. The rest are also treated as async to match this. Only one command can be
|
||||||
// executed at a time, so commands are queued until DVDInterface is ready to handle them.
|
// executed at a time, so commands are queued until DVDInterface is ready to handle them.
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
const u8 command = memory.Read_U8(request.buffer_in);
|
const u8 command = memory.Read_U8(request.buffer_in);
|
||||||
if (request.request != command)
|
if (request.request != command)
|
||||||
|
@ -105,12 +106,13 @@ void DIDevice::ProcessQueuedIOCtl()
|
||||||
m_executing_command = {m_commands_to_execute.front()};
|
m_executing_command = {m_commands_to_execute.front()};
|
||||||
m_commands_to_execute.pop_front();
|
m_commands_to_execute.pop_front();
|
||||||
|
|
||||||
IOCtlRequest request{m_executing_command->m_request_address};
|
auto& system = GetSystem();
|
||||||
|
IOCtlRequest request{system, m_executing_command->m_request_address};
|
||||||
auto finished = StartIOCtl(request);
|
auto finished = StartIOCtl(request);
|
||||||
if (finished)
|
if (finished)
|
||||||
{
|
{
|
||||||
Core::System::GetInstance().GetCoreTiming().ScheduleEvent(
|
system.GetCoreTiming().ScheduleEvent(IPC_OVERHEAD_TICKS, s_finish_executing_di_command,
|
||||||
IPC_OVERHEAD_TICKS, s_finish_executing_di_command, static_cast<u64>(finished.value()));
|
static_cast<u64>(finished.value()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +126,7 @@ std::optional<DIDevice::DIResult> DIDevice::WriteIfFits(const IOCtlRequest& requ
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.Write_U32(value, request.buffer_out);
|
memory.Write_U32(value, request.buffer_out);
|
||||||
return DIResult::Success;
|
return DIResult::Success;
|
||||||
|
@ -150,7 +152,7 @@ std::optional<DIDevice::DIResult> DIDevice::StartIOCtl(const IOCtlRequest& reque
|
||||||
return DIResult::SecurityError;
|
return DIResult::SecurityError;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
auto* mmio = memory.GetMMIOMapping();
|
auto* mmio = memory.GetMMIOMapping();
|
||||||
|
|
||||||
|
@ -561,7 +563,7 @@ std::optional<DIDevice::DIResult> DIDevice::StartDMATransfer(u32 command_length,
|
||||||
return DIResult::BadArgument;
|
return DIResult::BadArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto* mmio = system.GetMemory().GetMMIOMapping();
|
auto* mmio = system.GetMemory().GetMMIOMapping();
|
||||||
mmio->Write<u32>(ADDRESS_DIMAR, request.buffer_out);
|
mmio->Write<u32>(ADDRESS_DIMAR, request.buffer_out);
|
||||||
m_last_length = command_length;
|
m_last_length = command_length;
|
||||||
|
@ -585,7 +587,8 @@ std::optional<DIDevice::DIResult> DIDevice::StartImmediateTransfer(const IOCtlRe
|
||||||
|
|
||||||
m_executing_command->m_copy_diimmbuf = write_to_buf;
|
m_executing_command->m_copy_diimmbuf = write_to_buf;
|
||||||
|
|
||||||
Core::System::GetInstance().GetDVDInterface().ExecuteCommand(DVD::ReplyType::IOS);
|
auto& system = GetSystem();
|
||||||
|
system.GetDVDInterface().ExecuteCommand(DVD::ReplyType::IOS);
|
||||||
// Reply will be posted when done by FinishIOCtl.
|
// Reply will be posted when done by FinishIOCtl.
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -649,15 +652,15 @@ void DIDevice::FinishDICommand(DIResult result)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
auto* mmio = memory.GetMMIOMapping();
|
auto* mmio = memory.GetMMIOMapping();
|
||||||
|
|
||||||
IOCtlRequest request{m_executing_command->m_request_address};
|
IOCtlRequest request{system, m_executing_command->m_request_address};
|
||||||
if (m_executing_command->m_copy_diimmbuf)
|
if (m_executing_command->m_copy_diimmbuf)
|
||||||
memory.Write_U32(mmio->Read<u32>(ADDRESS_DIIMMBUF), request.buffer_out);
|
memory.Write_U32(mmio->Read<u32>(ADDRESS_DIIMMBUF), request.buffer_out);
|
||||||
|
|
||||||
m_ios.EnqueueIPCReply(request, static_cast<s32>(result));
|
GetEmulationKernel().EnqueueIPCReply(request, static_cast<s32>(result));
|
||||||
|
|
||||||
m_executing_command.reset();
|
m_executing_command.reset();
|
||||||
|
|
||||||
|
@ -683,7 +686,7 @@ std::optional<IPCReply> DIDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
return IPCReply{static_cast<s32>(DIResult::BadArgument)};
|
return IPCReply{static_cast<s32>(DIResult::BadArgument)};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u8 command = memory.Read_U8(request.in_vectors[0].address);
|
const u8 command = memory.Read_U8(request.in_vectors[0].address);
|
||||||
|
@ -742,17 +745,17 @@ std::optional<IPCReply> DIDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
case DIIoctl::DVDLowGetNoDiscOpenPartitionParams:
|
case DIIoctl::DVDLowGetNoDiscOpenPartitionParams:
|
||||||
ERROR_LOG_FMT(IOS_DI, "DVDLowGetNoDiscOpenPartitionParams - dummied out");
|
ERROR_LOG_FMT(IOS_DI, "DVDLowGetNoDiscOpenPartitionParams - dummied out");
|
||||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_DI);
|
request.DumpUnknown(system, GetDeviceName(), Common::Log::LogType::IOS_DI);
|
||||||
break;
|
break;
|
||||||
case DIIoctl::DVDLowNoDiscOpenPartition:
|
case DIIoctl::DVDLowNoDiscOpenPartition:
|
||||||
ERROR_LOG_FMT(IOS_DI, "DVDLowNoDiscOpenPartition - dummied out");
|
ERROR_LOG_FMT(IOS_DI, "DVDLowNoDiscOpenPartition - dummied out");
|
||||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_DI);
|
request.DumpUnknown(system, GetDeviceName(), Common::Log::LogType::IOS_DI);
|
||||||
break;
|
break;
|
||||||
case DIIoctl::DVDLowGetNoDiscBufferSizes:
|
case DIIoctl::DVDLowGetNoDiscBufferSizes:
|
||||||
ERROR_LOG_FMT(IOS_DI, "DVDLowGetNoDiscBufferSizes - dummied out");
|
ERROR_LOG_FMT(IOS_DI, "DVDLowGetNoDiscBufferSizes - dummied out");
|
||||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_DIFFERENT_PARTITION_COMMAND);
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_DI);
|
request.DumpUnknown(system, GetDeviceName(), Common::Log::LogType::IOS_DI);
|
||||||
break;
|
break;
|
||||||
case DIIoctl::DVDLowOpenPartitionWithTmdAndTicket:
|
case DIIoctl::DVDLowOpenPartitionWithTmdAndTicket:
|
||||||
ERROR_LOG_FMT(IOS_DI, "DVDLowOpenPartitionWithTmdAndTicket - not implemented");
|
ERROR_LOG_FMT(IOS_DI, "DVDLowOpenPartitionWithTmdAndTicket - not implemented");
|
||||||
|
@ -764,7 +767,7 @@ std::optional<IPCReply> DIDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ERROR_LOG_FMT(IOS_DI, "Unknown ioctlv {:#04x}", request.request);
|
ERROR_LOG_FMT(IOS_DI, "Unknown ioctlv {:#04x}", request.request);
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_DI);
|
request.DumpUnknown(system, GetDeviceName(), Common::Log::LogType::IOS_DI);
|
||||||
}
|
}
|
||||||
return IPCReply{static_cast<s32>(return_value)};
|
return IPCReply{static_cast<s32>(return_value)};
|
||||||
}
|
}
|
||||||
|
@ -804,7 +807,7 @@ void DIDevice::ResetDIRegisters()
|
||||||
{
|
{
|
||||||
// Clear transfer complete and error interrupts (normally r/z, but here we just directly write
|
// Clear transfer complete and error interrupts (normally r/z, but here we just directly write
|
||||||
// zero)
|
// zero)
|
||||||
auto& di = Core::System::GetInstance().GetDVDInterface();
|
auto& di = GetSystem().GetDVDInterface();
|
||||||
di.ClearInterrupt(DVD::DIInterruptType::TCINT);
|
di.ClearInterrupt(DVD::DIInterruptType::TCINT);
|
||||||
di.ClearInterrupt(DVD::DIInterruptType::DEINT);
|
di.ClearInterrupt(DVD::DIInterruptType::DEINT);
|
||||||
// Enable transfer complete and error interrupts, and disable cover interrupt
|
// Enable transfer complete and error interrupts, and disable cover interrupt
|
||||||
|
|
|
@ -35,10 +35,10 @@ void Init();
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
class DIDevice : public Device
|
class DIDevice : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DIDevice(Kernel& ios, const std::string& device_name);
|
DIDevice(EmulationKernel& ios, const std::string& device_name);
|
||||||
|
|
||||||
static void InterruptFromDVDInterface(DVD::DIInterruptType interrupt_type);
|
static void InterruptFromDVDInterface(DVD::DIInterruptType interrupt_type);
|
||||||
static DiscIO::Partition GetCurrentPartition();
|
static DiscIO::Partition GetCurrentPartition();
|
||||||
|
|
|
@ -16,17 +16,15 @@
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
Request::Request(const u32 address_) : address(address_)
|
Request::Request(Core::System& system, const u32 address_) : address(address_)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
command = static_cast<IPCCommandType>(memory.Read_U32(address));
|
command = static_cast<IPCCommandType>(memory.Read_U32(address));
|
||||||
fd = memory.Read_U32(address + 8);
|
fd = memory.Read_U32(address + 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenRequest::OpenRequest(const u32 address_) : Request(address_)
|
OpenRequest::OpenRequest(Core::System& system, const u32 address_) : Request(system, address_)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
path = memory.GetString(memory.Read_U32(address + 0xc));
|
path = memory.GetString(memory.Read_U32(address + 0xc));
|
||||||
flags = static_cast<OpenMode>(memory.Read_U32(address + 0x10));
|
flags = static_cast<OpenMode>(memory.Read_U32(address + 0x10));
|
||||||
|
@ -38,25 +36,23 @@ OpenRequest::OpenRequest(const u32 address_) : Request(address_)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadWriteRequest::ReadWriteRequest(const u32 address_) : Request(address_)
|
ReadWriteRequest::ReadWriteRequest(Core::System& system, const u32 address_)
|
||||||
|
: Request(system, address_)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
buffer = memory.Read_U32(address + 0xc);
|
buffer = memory.Read_U32(address + 0xc);
|
||||||
size = memory.Read_U32(address + 0x10);
|
size = memory.Read_U32(address + 0x10);
|
||||||
}
|
}
|
||||||
|
|
||||||
SeekRequest::SeekRequest(const u32 address_) : Request(address_)
|
SeekRequest::SeekRequest(Core::System& system, const u32 address_) : Request(system, address_)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
offset = memory.Read_U32(address + 0xc);
|
offset = memory.Read_U32(address + 0xc);
|
||||||
mode = static_cast<SeekMode>(memory.Read_U32(address + 0x10));
|
mode = static_cast<SeekMode>(memory.Read_U32(address + 0x10));
|
||||||
}
|
}
|
||||||
|
|
||||||
IOCtlRequest::IOCtlRequest(const u32 address_) : Request(address_)
|
IOCtlRequest::IOCtlRequest(Core::System& system, const u32 address_) : Request(system, address_)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
request = memory.Read_U32(address + 0x0c);
|
request = memory.Read_U32(address + 0x0c);
|
||||||
buffer_in = memory.Read_U32(address + 0x10);
|
buffer_in = memory.Read_U32(address + 0x10);
|
||||||
|
@ -65,9 +61,8 @@ IOCtlRequest::IOCtlRequest(const u32 address_) : Request(address_)
|
||||||
buffer_out_size = memory.Read_U32(address + 0x1c);
|
buffer_out_size = memory.Read_U32(address + 0x1c);
|
||||||
}
|
}
|
||||||
|
|
||||||
IOCtlVRequest::IOCtlVRequest(const u32 address_) : Request(address_)
|
IOCtlVRequest::IOCtlVRequest(Core::System& system, const u32 address_) : Request(system, address_)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
request = memory.Read_U32(address + 0x0c);
|
request = memory.Read_U32(address + 0x0c);
|
||||||
const u32 in_number = memory.Read_U32(address + 0x10);
|
const u32 in_number = memory.Read_U32(address + 0x10);
|
||||||
|
@ -114,10 +109,9 @@ void IOCtlRequest::Log(std::string_view device_name, Common::Log::LogType type,
|
||||||
device_name, fd, request, buffer_in_size, buffer_out_size);
|
device_name, fd, request, buffer_in_size, buffer_out_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IOCtlRequest::Dump(const std::string& description, Common::Log::LogType type,
|
void IOCtlRequest::Dump(Core::System& system, const std::string& description,
|
||||||
Common::Log::LogLevel level) const
|
Common::Log::LogType type, Common::Log::LogLevel level) const
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
Log("===== " + description, type, level);
|
Log("===== " + description, type, level);
|
||||||
|
@ -127,16 +121,15 @@ void IOCtlRequest::Dump(const std::string& description, Common::Log::LogType typ
|
||||||
HexDump(memory.GetPointer(buffer_out), buffer_out_size));
|
HexDump(memory.GetPointer(buffer_out), buffer_out_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void IOCtlRequest::DumpUnknown(const std::string& description, Common::Log::LogType type,
|
void IOCtlRequest::DumpUnknown(Core::System& system, const std::string& description,
|
||||||
Common::Log::LogLevel level) const
|
Common::Log::LogType type, Common::Log::LogLevel level) const
|
||||||
{
|
{
|
||||||
Dump("Unknown IOCtl - " + description, type, level);
|
Dump(system, "Unknown IOCtl - " + description, type, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IOCtlVRequest::Dump(std::string_view description, Common::Log::LogType type,
|
void IOCtlVRequest::Dump(Core::System& system, std::string_view description,
|
||||||
Common::Log::LogLevel level) const
|
Common::Log::LogType type, Common::Log::LogLevel level) const
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
GENERIC_LOG_FMT(type, level, "===== {} (fd {}) - IOCtlV {:#x} ({} in, {} io)", description, fd,
|
GENERIC_LOG_FMT(type, level, "===== {} (fd {}) - IOCtlV {:#x} ({} in, {} io)", description, fd,
|
||||||
|
@ -154,10 +147,10 @@ void IOCtlVRequest::Dump(std::string_view description, Common::Log::LogType type
|
||||||
GENERIC_LOG_FMT(type, level, "io[{}] (size={:#x})", i++, vector.size);
|
GENERIC_LOG_FMT(type, level, "io[{}] (size={:#x})", i++, vector.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IOCtlVRequest::DumpUnknown(const std::string& description, Common::Log::LogType type,
|
void IOCtlVRequest::DumpUnknown(Core::System& system, const std::string& description,
|
||||||
Common::Log::LogLevel level) const
|
Common::Log::LogType type, Common::Log::LogLevel level) const
|
||||||
{
|
{
|
||||||
Dump("Unknown IOCtlV - " + description, type, level);
|
Dump(system, "Unknown IOCtlV - " + description, type, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::Device(Kernel& ios, const std::string& device_name, const DeviceType type)
|
Device::Device(Kernel& ios, const std::string& device_name, const DeviceType type)
|
||||||
|
|
|
@ -13,6 +13,11 @@
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Core/IOS/IOS.h"
|
#include "Core/IOS/IOS.h"
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
enum ReturnCode : s32
|
enum ReturnCode : s32
|
||||||
|
@ -77,7 +82,7 @@ struct Request
|
||||||
u32 address = 0;
|
u32 address = 0;
|
||||||
IPCCommandType command = IPC_CMD_OPEN;
|
IPCCommandType command = IPC_CMD_OPEN;
|
||||||
u32 fd = 0;
|
u32 fd = 0;
|
||||||
explicit Request(u32 address);
|
Request(Core::System& system, u32 address);
|
||||||
virtual ~Request() = default;
|
virtual ~Request() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,14 +102,14 @@ struct OpenRequest final : Request
|
||||||
// but they are set after they reach IOS and are dispatched to the appropriate module.
|
// but they are set after they reach IOS and are dispatched to the appropriate module.
|
||||||
u32 uid = 0;
|
u32 uid = 0;
|
||||||
u16 gid = 0;
|
u16 gid = 0;
|
||||||
explicit OpenRequest(u32 address);
|
OpenRequest(Core::System& system, u32 address);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ReadWriteRequest final : Request
|
struct ReadWriteRequest final : Request
|
||||||
{
|
{
|
||||||
u32 buffer = 0;
|
u32 buffer = 0;
|
||||||
u32 size = 0;
|
u32 size = 0;
|
||||||
explicit ReadWriteRequest(u32 address);
|
ReadWriteRequest(Core::System& system, u32 address);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SeekMode : s32
|
enum SeekMode : s32
|
||||||
|
@ -118,7 +123,7 @@ struct SeekRequest final : Request
|
||||||
{
|
{
|
||||||
u32 offset = 0;
|
u32 offset = 0;
|
||||||
SeekMode mode = IOS_SEEK_SET;
|
SeekMode mode = IOS_SEEK_SET;
|
||||||
explicit SeekRequest(u32 address);
|
SeekRequest(Core::System& system, u32 address);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IOCtlRequest final : Request
|
struct IOCtlRequest final : Request
|
||||||
|
@ -129,12 +134,13 @@ struct IOCtlRequest final : Request
|
||||||
// Contrary to the name, the output buffer can also be used for input.
|
// Contrary to the name, the output buffer can also be used for input.
|
||||||
u32 buffer_out = 0;
|
u32 buffer_out = 0;
|
||||||
u32 buffer_out_size = 0;
|
u32 buffer_out_size = 0;
|
||||||
explicit IOCtlRequest(u32 address);
|
IOCtlRequest(Core::System& system, u32 address);
|
||||||
void Log(std::string_view description, Common::Log::LogType type = Common::Log::LogType::IOS,
|
void Log(std::string_view description, Common::Log::LogType type = Common::Log::LogType::IOS,
|
||||||
Common::Log::LogLevel level = Common::Log::LogLevel::LINFO) const;
|
Common::Log::LogLevel level = Common::Log::LogLevel::LINFO) const;
|
||||||
void Dump(const std::string& description, Common::Log::LogType type = Common::Log::LogType::IOS,
|
void Dump(Core::System& system, const std::string& description,
|
||||||
|
Common::Log::LogType type = Common::Log::LogType::IOS,
|
||||||
Common::Log::LogLevel level = Common::Log::LogLevel::LINFO) const;
|
Common::Log::LogLevel level = Common::Log::LogLevel::LINFO) const;
|
||||||
void DumpUnknown(const std::string& description,
|
void DumpUnknown(Core::System& system, const std::string& description,
|
||||||
Common::Log::LogType type = Common::Log::LogType::IOS,
|
Common::Log::LogType type = Common::Log::LogType::IOS,
|
||||||
Common::Log::LogLevel level = Common::Log::LogLevel::LERROR) const;
|
Common::Log::LogLevel level = Common::Log::LogLevel::LERROR) const;
|
||||||
};
|
};
|
||||||
|
@ -159,11 +165,12 @@ struct IOCtlVRequest final : Request
|
||||||
/// Returns the specified vector or nullptr if the index is out of bounds.
|
/// Returns the specified vector or nullptr if the index is out of bounds.
|
||||||
const IOVector* GetVector(size_t index) const;
|
const IOVector* GetVector(size_t index) const;
|
||||||
|
|
||||||
explicit IOCtlVRequest(u32 address);
|
IOCtlVRequest(Core::System& system, u32 address);
|
||||||
bool HasNumberOfValidVectors(size_t in_count, size_t io_count) const;
|
bool HasNumberOfValidVectors(size_t in_count, size_t io_count) const;
|
||||||
void Dump(std::string_view description, Common::Log::LogType type = Common::Log::LogType::IOS,
|
void Dump(Core::System& system, std::string_view description,
|
||||||
|
Common::Log::LogType type = Common::Log::LogType::IOS,
|
||||||
Common::Log::LogLevel level = Common::Log::LogLevel::LINFO) const;
|
Common::Log::LogLevel level = Common::Log::LogLevel::LINFO) const;
|
||||||
void DumpUnknown(const std::string& description,
|
void DumpUnknown(Core::System& system, const std::string& description,
|
||||||
Common::Log::LogType type = Common::Log::LogType::IOS,
|
Common::Log::LogType type = Common::Log::LogType::IOS,
|
||||||
Common::Log::LogLevel level = Common::Log::LogLevel::LERROR) const;
|
Common::Log::LogLevel level = Common::Log::LogLevel::LERROR) const;
|
||||||
};
|
};
|
||||||
|
@ -214,4 +221,22 @@ protected:
|
||||||
private:
|
private:
|
||||||
std::optional<IPCReply> Unsupported(const Request& request);
|
std::optional<IPCReply> Unsupported(const Request& request);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Helper class for Devices that we know are only ever instantiated under an EmulationKernel.
|
||||||
|
// Deriving a Device from this allows it to access EmulationKernel-only features without runtime
|
||||||
|
// overhead, since it will know that the m_ios instance is an EmulationKernel.
|
||||||
|
class EmulationDevice : public Device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EmulationDevice(EmulationKernel& ios, const std::string& device_name,
|
||||||
|
DeviceType type = DeviceType::Static)
|
||||||
|
: Device(ios, device_name, type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EmulationKernel& GetEmulationKernel() const { return static_cast<EmulationKernel&>(m_ios); }
|
||||||
|
|
||||||
|
Core::System& GetSystem() const { return GetEmulationKernel().GetSystem(); }
|
||||||
|
};
|
||||||
} // namespace IOS::HLE
|
} // namespace IOS::HLE
|
||||||
|
|
|
@ -40,7 +40,7 @@ enum
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
IPCReply GetVersion(const IOCtlVRequest& request)
|
IPCReply GetVersion(Core::System& system, const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
if (!request.HasNumberOfValidVectors(0, 1))
|
if (!request.HasNumberOfValidVectors(0, 1))
|
||||||
{
|
{
|
||||||
|
@ -49,7 +49,6 @@ IPCReply GetVersion(const IOCtlVRequest& request)
|
||||||
|
|
||||||
const auto length = std::min(size_t(request.io_vectors[0].size), Common::GetScmDescStr().size());
|
const auto length = std::min(size_t(request.io_vectors[0].size), Common::GetScmDescStr().size());
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.Memset(request.io_vectors[0].address, 0, request.io_vectors[0].size);
|
memory.Memset(request.io_vectors[0].address, 0, request.io_vectors[0].size);
|
||||||
memory.CopyToEmu(request.io_vectors[0].address, Common::GetScmDescStr().data(), length);
|
memory.CopyToEmu(request.io_vectors[0].address, Common::GetScmDescStr().data(), length);
|
||||||
|
@ -57,7 +56,7 @@ IPCReply GetVersion(const IOCtlVRequest& request)
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCReply GetCPUSpeed(const IOCtlVRequest& request)
|
IPCReply GetCPUSpeed(Core::System& system, const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
if (!request.HasNumberOfValidVectors(0, 1))
|
if (!request.HasNumberOfValidVectors(0, 1))
|
||||||
{
|
{
|
||||||
|
@ -74,14 +73,13 @@ IPCReply GetCPUSpeed(const IOCtlVRequest& request)
|
||||||
|
|
||||||
const u32 core_clock = u32(float(SystemTimers::GetTicksPerSecond()) * oc);
|
const u32 core_clock = u32(float(SystemTimers::GetTicksPerSecond()) * oc);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.Write_U32(core_clock, request.io_vectors[0].address);
|
memory.Write_U32(core_clock, request.io_vectors[0].address);
|
||||||
|
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCReply GetSpeedLimit(const IOCtlVRequest& request)
|
IPCReply GetSpeedLimit(Core::System& system, const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
// get current speed limit
|
// get current speed limit
|
||||||
if (!request.HasNumberOfValidVectors(0, 1))
|
if (!request.HasNumberOfValidVectors(0, 1))
|
||||||
|
@ -96,14 +94,13 @@ IPCReply GetSpeedLimit(const IOCtlVRequest& request)
|
||||||
|
|
||||||
const u32 speed_percent = Config::Get(Config::MAIN_EMULATION_SPEED) * 100;
|
const u32 speed_percent = Config::Get(Config::MAIN_EMULATION_SPEED) * 100;
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.Write_U32(speed_percent, request.io_vectors[0].address);
|
memory.Write_U32(speed_percent, request.io_vectors[0].address);
|
||||||
|
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCReply SetSpeedLimit(const IOCtlVRequest& request)
|
IPCReply SetSpeedLimit(Core::System& system, const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
// set current speed limit
|
// set current speed limit
|
||||||
if (!request.HasNumberOfValidVectors(1, 0))
|
if (!request.HasNumberOfValidVectors(1, 0))
|
||||||
|
@ -116,7 +113,6 @@ IPCReply SetSpeedLimit(const IOCtlVRequest& request)
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
const float speed = float(memory.Read_U32(request.in_vectors[0].address)) / 100.0f;
|
const float speed = float(memory.Read_U32(request.in_vectors[0].address)) / 100.0f;
|
||||||
Config::SetCurrent(Config::MAIN_EMULATION_SPEED, speed);
|
Config::SetCurrent(Config::MAIN_EMULATION_SPEED, speed);
|
||||||
|
@ -124,7 +120,7 @@ IPCReply SetSpeedLimit(const IOCtlVRequest& request)
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCReply GetRealProductCode(const IOCtlVRequest& request)
|
IPCReply GetRealProductCode(Core::System& system, const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
if (!request.HasNumberOfValidVectors(0, 1))
|
if (!request.HasNumberOfValidVectors(0, 1))
|
||||||
{
|
{
|
||||||
|
@ -150,14 +146,13 @@ IPCReply GetRealProductCode(const IOCtlVRequest& request)
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
return IPCReply(IPC_ENOENT);
|
return IPCReply(IPC_ENOENT);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.Memset(request.io_vectors[0].address, 0, request.io_vectors[0].size);
|
memory.Memset(request.io_vectors[0].address, 0, request.io_vectors[0].size);
|
||||||
memory.CopyToEmu(request.io_vectors[0].address, code.c_str(), length);
|
memory.CopyToEmu(request.io_vectors[0].address, code.c_str(), length);
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCReply SetDiscordClient(const IOCtlVRequest& request)
|
IPCReply SetDiscordClient(Core::System& system, const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
if (!Config::Get(Config::MAIN_USE_DISCORD_PRESENCE))
|
if (!Config::Get(Config::MAIN_USE_DISCORD_PRESENCE))
|
||||||
return IPCReply(IPC_EACCES);
|
return IPCReply(IPC_EACCES);
|
||||||
|
@ -165,7 +160,6 @@ IPCReply SetDiscordClient(const IOCtlVRequest& request)
|
||||||
if (!request.HasNumberOfValidVectors(1, 0))
|
if (!request.HasNumberOfValidVectors(1, 0))
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
std::string new_client_id =
|
std::string new_client_id =
|
||||||
memory.GetString(request.in_vectors[0].address, request.in_vectors[0].size);
|
memory.GetString(request.in_vectors[0].address, request.in_vectors[0].size);
|
||||||
|
@ -175,7 +169,7 @@ IPCReply SetDiscordClient(const IOCtlVRequest& request)
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCReply SetDiscordPresence(const IOCtlVRequest& request)
|
IPCReply SetDiscordPresence(Core::System& system, const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
if (!Config::Get(Config::MAIN_USE_DISCORD_PRESENCE))
|
if (!Config::Get(Config::MAIN_USE_DISCORD_PRESENCE))
|
||||||
return IPCReply(IPC_EACCES);
|
return IPCReply(IPC_EACCES);
|
||||||
|
@ -183,7 +177,6 @@ IPCReply SetDiscordPresence(const IOCtlVRequest& request)
|
||||||
if (!request.HasNumberOfValidVectors(10, 0))
|
if (!request.HasNumberOfValidVectors(10, 0))
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
std::string details = memory.GetString(request.in_vectors[0].address, request.in_vectors[0].size);
|
std::string details = memory.GetString(request.in_vectors[0].address, request.in_vectors[0].size);
|
||||||
|
@ -242,7 +235,7 @@ IPCReply DolphinDevice::GetElapsedTime(const IOCtlVRequest& request) const
|
||||||
// have issues.
|
// have issues.
|
||||||
const u32 milliseconds = static_cast<u32>(m_timer.ElapsedMs());
|
const u32 milliseconds = static_cast<u32>(m_timer.ElapsedMs());
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.Write_U32(milliseconds, request.io_vectors[0].address);
|
memory.Write_U32(milliseconds, request.io_vectors[0].address);
|
||||||
|
|
||||||
|
@ -261,7 +254,7 @@ IPCReply DolphinDevice::GetSystemTime(const IOCtlVRequest& request) const
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
// Write Unix timestamp in milliseconds to memory address
|
// Write Unix timestamp in milliseconds to memory address
|
||||||
|
@ -272,7 +265,8 @@ IPCReply DolphinDevice::GetSystemTime(const IOCtlVRequest& request) const
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
DolphinDevice::DolphinDevice(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
|
DolphinDevice::DolphinDevice(EmulationKernel& ios, const std::string& device_name)
|
||||||
|
: EmulationDevice(ios, device_name)
|
||||||
{
|
{
|
||||||
m_timer.Start();
|
m_timer.Start();
|
||||||
}
|
}
|
||||||
|
@ -287,19 +281,19 @@ std::optional<IPCReply> DolphinDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
case IOCTL_DOLPHIN_GET_ELAPSED_TIME:
|
case IOCTL_DOLPHIN_GET_ELAPSED_TIME:
|
||||||
return GetElapsedTime(request);
|
return GetElapsedTime(request);
|
||||||
case IOCTL_DOLPHIN_GET_VERSION:
|
case IOCTL_DOLPHIN_GET_VERSION:
|
||||||
return GetVersion(request);
|
return GetVersion(GetSystem(), request);
|
||||||
case IOCTL_DOLPHIN_GET_SPEED_LIMIT:
|
case IOCTL_DOLPHIN_GET_SPEED_LIMIT:
|
||||||
return GetSpeedLimit(request);
|
return GetSpeedLimit(GetSystem(), request);
|
||||||
case IOCTL_DOLPHIN_SET_SPEED_LIMIT:
|
case IOCTL_DOLPHIN_SET_SPEED_LIMIT:
|
||||||
return SetSpeedLimit(request);
|
return SetSpeedLimit(GetSystem(), request);
|
||||||
case IOCTL_DOLPHIN_GET_CPU_SPEED:
|
case IOCTL_DOLPHIN_GET_CPU_SPEED:
|
||||||
return GetCPUSpeed(request);
|
return GetCPUSpeed(GetSystem(), request);
|
||||||
case IOCTL_DOLPHIN_GET_REAL_PRODUCTCODE:
|
case IOCTL_DOLPHIN_GET_REAL_PRODUCTCODE:
|
||||||
return GetRealProductCode(request);
|
return GetRealProductCode(GetSystem(), request);
|
||||||
case IOCTL_DOLPHIN_DISCORD_SET_CLIENT:
|
case IOCTL_DOLPHIN_DISCORD_SET_CLIENT:
|
||||||
return SetDiscordClient(request);
|
return SetDiscordClient(GetSystem(), request);
|
||||||
case IOCTL_DOLPHIN_DISCORD_SET_PRESENCE:
|
case IOCTL_DOLPHIN_DISCORD_SET_PRESENCE:
|
||||||
return SetDiscordPresence(request);
|
return SetDiscordPresence(GetSystem(), request);
|
||||||
case IOCTL_DOLPHIN_DISCORD_RESET:
|
case IOCTL_DOLPHIN_DISCORD_RESET:
|
||||||
return ResetDiscord(request);
|
return ResetDiscord(request);
|
||||||
case IOCTL_DOLPHIN_GET_SYSTEM_TIME:
|
case IOCTL_DOLPHIN_GET_SYSTEM_TIME:
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
class DolphinDevice final : public Device
|
class DolphinDevice final : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DolphinDevice(Kernel& ios, const std::string& device_name);
|
DolphinDevice(EmulationKernel& ios, const std::string& device_name);
|
||||||
std::optional<IPCReply> IOCtlV(const IOCtlVRequest& request) override;
|
std::optional<IPCReply> IOCtlV(const IOCtlVRequest& request) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -702,7 +702,7 @@ std::optional<IPCReply> ESDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
case IOCTL_ES_UNKNOWN_42:
|
case IOCTL_ES_UNKNOWN_42:
|
||||||
PanicAlertFmt("IOS-ES: Unimplemented ioctlv {:#x} ({} in vectors, {} io vectors)",
|
PanicAlertFmt("IOS-ES: Unimplemented ioctlv {:#x} ({} in vectors, {} io vectors)",
|
||||||
request.request, request.in_vectors.size(), request.io_vectors.size());
|
request.request, request.in_vectors.size(), request.io_vectors.size());
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_ES,
|
request.DumpUnknown(Core::System::GetInstance(), GetDeviceName(), Common::Log::LogType::IOS_ES,
|
||||||
Common::Log::LogLevel::LERROR);
|
Common::Log::LogLevel::LERROR);
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
|
|
|
@ -319,7 +319,8 @@ Kernel::Kernel(u64 title_id) : m_title_id(title_id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
EmulationKernel::EmulationKernel(u64 title_id) : Kernel(title_id)
|
EmulationKernel::EmulationKernel(Core::System& system, u64 title_id)
|
||||||
|
: Kernel(title_id), m_system(system)
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(IOS, "Starting IOS {:016x}", title_id);
|
INFO_LOG_FMT(IOS, "Starting IOS {:016x}", title_id);
|
||||||
|
|
||||||
|
@ -364,7 +365,7 @@ std::shared_ptr<ESDevice> Kernel::GetES()
|
||||||
return std::static_pointer_cast<ESDevice>(m_device_map.at("/dev/es"));
|
return std::static_pointer_cast<ESDevice>(m_device_map.at("/dev/es"));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<WiiSockMan> Kernel::GetSocketManager()
|
std::shared_ptr<WiiSockMan> EmulationKernel::GetSocketManager()
|
||||||
{
|
{
|
||||||
return m_socket_manager;
|
return m_socket_manager;
|
||||||
}
|
}
|
||||||
|
@ -462,11 +463,11 @@ private:
|
||||||
std::vector<u8> m_bytes;
|
std::vector<u8> m_bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void FinishIOSBoot(u64 ios_title_id)
|
static void FinishIOSBoot(Core::System& system, u64 ios_title_id)
|
||||||
{
|
{
|
||||||
// Shut down the active IOS first before switching to the new one.
|
// Shut down the active IOS first before switching to the new one.
|
||||||
s_ios.reset();
|
s_ios.reset();
|
||||||
s_ios = std::make_unique<EmulationKernel>(ios_title_id);
|
s_ios = std::make_unique<EmulationKernel>(system, ios_title_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr SystemTimers::TimeBaseTick GetIOSBootTicks(u32 version)
|
static constexpr SystemTimers::TimeBaseTick GetIOSBootTicks(u32 version)
|
||||||
|
@ -515,7 +516,7 @@ bool Kernel::BootIOS(Core::System& system, const u64 ios_title_id, HangPPC hang_
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FinishIOSBoot(ios_title_id);
|
FinishIOSBoot(system, ios_title_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -546,7 +547,7 @@ void Kernel::AddCoreDevices()
|
||||||
AddDevice(std::make_unique<ESDevice>(*this, "/dev/es"));
|
AddDevice(std::make_unique<ESDevice>(*this, "/dev/es"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kernel::AddStaticDevices()
|
void EmulationKernel::AddStaticDevices()
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_device_map_mutex);
|
std::lock_guard lock(m_device_map_mutex);
|
||||||
|
|
||||||
|
@ -623,7 +624,7 @@ void Kernel::AddStaticDevices()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 Kernel::GetFreeDeviceID()
|
s32 EmulationKernel::GetFreeDeviceID()
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < IPC_MAX_FDS; i++)
|
for (u32 i = 0; i < IPC_MAX_FDS; i++)
|
||||||
{
|
{
|
||||||
|
@ -649,7 +650,7 @@ std::shared_ptr<Device> EmulationKernel::GetDeviceByName(std::string_view device
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the FD for the newly opened device (on success) or an error code.
|
// Returns the FD for the newly opened device (on success) or an error code.
|
||||||
std::optional<IPCReply> Kernel::OpenDevice(OpenRequest& request)
|
std::optional<IPCReply> EmulationKernel::OpenDevice(OpenRequest& request)
|
||||||
{
|
{
|
||||||
const s32 new_fd = GetFreeDeviceID();
|
const s32 new_fd = GetFreeDeviceID();
|
||||||
INFO_LOG_FMT(IOS, "Opening {} (mode {}, fd {})", request.path, static_cast<u32>(request.flags),
|
INFO_LOG_FMT(IOS, "Opening {} (mode {}, fd {})", request.path, static_cast<u32>(request.flags),
|
||||||
|
@ -691,14 +692,14 @@ std::optional<IPCReply> Kernel::OpenDevice(OpenRequest& request)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<IPCReply> Kernel::HandleIPCCommand(const Request& request)
|
std::optional<IPCReply> EmulationKernel::HandleIPCCommand(const Request& request)
|
||||||
{
|
{
|
||||||
if (request.command < IPC_CMD_OPEN || request.command > IPC_CMD_IOCTLV)
|
if (request.command < IPC_CMD_OPEN || request.command > IPC_CMD_IOCTLV)
|
||||||
return IPCReply{IPC_EINVAL, 978_tbticks};
|
return IPCReply{IPC_EINVAL, 978_tbticks};
|
||||||
|
|
||||||
if (request.command == IPC_CMD_OPEN)
|
if (request.command == IPC_CMD_OPEN)
|
||||||
{
|
{
|
||||||
OpenRequest open_request{request.address};
|
OpenRequest open_request{GetSystem(), request.address};
|
||||||
return OpenDevice(open_request);
|
return OpenDevice(open_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,19 +717,19 @@ std::optional<IPCReply> Kernel::HandleIPCCommand(const Request& request)
|
||||||
ret = device->Close(request.fd);
|
ret = device->Close(request.fd);
|
||||||
break;
|
break;
|
||||||
case IPC_CMD_READ:
|
case IPC_CMD_READ:
|
||||||
ret = device->Read(ReadWriteRequest{request.address});
|
ret = device->Read(ReadWriteRequest{GetSystem(), request.address});
|
||||||
break;
|
break;
|
||||||
case IPC_CMD_WRITE:
|
case IPC_CMD_WRITE:
|
||||||
ret = device->Write(ReadWriteRequest{request.address});
|
ret = device->Write(ReadWriteRequest{GetSystem(), request.address});
|
||||||
break;
|
break;
|
||||||
case IPC_CMD_SEEK:
|
case IPC_CMD_SEEK:
|
||||||
ret = device->Seek(SeekRequest{request.address});
|
ret = device->Seek(SeekRequest{GetSystem(), request.address});
|
||||||
break;
|
break;
|
||||||
case IPC_CMD_IOCTL:
|
case IPC_CMD_IOCTL:
|
||||||
ret = device->IOCtl(IOCtlRequest{request.address});
|
ret = device->IOCtl(IOCtlRequest{GetSystem(), request.address});
|
||||||
break;
|
break;
|
||||||
case IPC_CMD_IOCTLV:
|
case IPC_CMD_IOCTLV:
|
||||||
ret = device->IOCtlV(IOCtlVRequest{request.address});
|
ret = device->IOCtlV(IOCtlVRequest{GetSystem(), request.address});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT_MSG(IOS, false, "Unexpected command: {:#x}", static_cast<u32>(request.command));
|
ASSERT_MSG(IOS, false, "Unexpected command: {:#x}", static_cast<u32>(request.command));
|
||||||
|
@ -747,17 +748,16 @@ std::optional<IPCReply> Kernel::HandleIPCCommand(const Request& request)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kernel::ExecuteIPCCommand(const u32 address)
|
void EmulationKernel::ExecuteIPCCommand(const u32 address)
|
||||||
{
|
{
|
||||||
Request request{address};
|
Request request{GetSystem(), address};
|
||||||
std::optional<IPCReply> result = HandleIPCCommand(request);
|
std::optional<IPCReply> result = HandleIPCCommand(request);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Ensure replies happen in order
|
// Ensure replies happen in order
|
||||||
auto& system = Core::System::GetInstance();
|
auto& core_timing = GetSystem().GetCoreTiming();
|
||||||
auto& core_timing = system.GetCoreTiming();
|
|
||||||
const s64 ticks_until_last_reply = m_last_reply_time - core_timing.GetTicks();
|
const s64 ticks_until_last_reply = m_last_reply_time - core_timing.GetTicks();
|
||||||
if (ticks_until_last_reply > 0)
|
if (ticks_until_last_reply > 0)
|
||||||
result->reply_delay_ticks += ticks_until_last_reply;
|
result->reply_delay_ticks += ticks_until_last_reply;
|
||||||
|
@ -767,20 +767,20 @@ void Kernel::ExecuteIPCCommand(const u32 address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Happens AS SOON AS IPC gets a new pointer!
|
// Happens AS SOON AS IPC gets a new pointer!
|
||||||
void Kernel::EnqueueIPCRequest(u32 address)
|
void EmulationKernel::EnqueueIPCRequest(u32 address)
|
||||||
{
|
{
|
||||||
// Based on hardware tests, IOS takes between 5µs and 10µs to acknowledge an IPC request.
|
// Based on hardware tests, IOS takes between 5µs and 10µs to acknowledge an IPC request.
|
||||||
// Console 1: 456 TB ticks before ACK
|
// Console 1: 456 TB ticks before ACK
|
||||||
// Console 2: 658 TB ticks before ACK
|
// Console 2: 658 TB ticks before ACK
|
||||||
Core::System::GetInstance().GetCoreTiming().ScheduleEvent(500_tbticks, s_event_enqueue,
|
GetSystem().GetCoreTiming().ScheduleEvent(500_tbticks, s_event_enqueue,
|
||||||
address | ENQUEUE_REQUEST_FLAG);
|
address | ENQUEUE_REQUEST_FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called to send a reply to an IOS syscall
|
// Called to send a reply to an IOS syscall
|
||||||
void Kernel::EnqueueIPCReply(const Request& request, const s32 return_value, s64 cycles_in_future,
|
void EmulationKernel::EnqueueIPCReply(const Request& request, const s32 return_value,
|
||||||
CoreTiming::FromThread from)
|
s64 cycles_in_future, CoreTiming::FromThread from)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.Write_U32(static_cast<u32>(return_value), request.address + 4);
|
memory.Write_U32(static_cast<u32>(return_value), request.address + 4);
|
||||||
// IOS writes back the command that was responded to in the FD field.
|
// IOS writes back the command that was responded to in the FD field.
|
||||||
|
@ -790,7 +790,7 @@ void Kernel::EnqueueIPCReply(const Request& request, const s32 return_value, s64
|
||||||
system.GetCoreTiming().ScheduleEvent(cycles_in_future, s_event_enqueue, request.address, from);
|
system.GetCoreTiming().ScheduleEvent(cycles_in_future, s_event_enqueue, request.address, from);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kernel::HandleIPCEvent(u64 userdata)
|
void EmulationKernel::HandleIPCEvent(u64 userdata)
|
||||||
{
|
{
|
||||||
if (userdata & ENQUEUE_REQUEST_FLAG)
|
if (userdata & ENQUEUE_REQUEST_FLAG)
|
||||||
m_request_queue.push_back(static_cast<u32>(userdata));
|
m_request_queue.push_back(static_cast<u32>(userdata));
|
||||||
|
@ -800,7 +800,7 @@ void Kernel::HandleIPCEvent(u64 userdata)
|
||||||
UpdateIPC();
|
UpdateIPC();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kernel::UpdateIPC()
|
void EmulationKernel::UpdateIPC()
|
||||||
{
|
{
|
||||||
if (m_ipc_paused || !IsReady())
|
if (m_ipc_paused || !IsReady())
|
||||||
return;
|
return;
|
||||||
|
@ -824,7 +824,7 @@ void Kernel::UpdateIPC()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kernel::UpdateDevices()
|
void EmulationKernel::UpdateDevices()
|
||||||
{
|
{
|
||||||
// Check if a hardware device must be updated
|
// Check if a hardware device must be updated
|
||||||
for (const auto& entry : m_device_map)
|
for (const auto& entry : m_device_map)
|
||||||
|
@ -836,7 +836,7 @@ void Kernel::UpdateDevices()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kernel::UpdateWantDeterminism(const bool new_want_determinism)
|
void EmulationKernel::UpdateWantDeterminism(const bool new_want_determinism)
|
||||||
{
|
{
|
||||||
if (m_socket_manager)
|
if (m_socket_manager)
|
||||||
m_socket_manager->UpdateWantDeterminism(new_want_determinism);
|
m_socket_manager->UpdateWantDeterminism(new_want_determinism);
|
||||||
|
@ -844,7 +844,7 @@ void Kernel::UpdateWantDeterminism(const bool new_want_determinism)
|
||||||
device.second->UpdateWantDeterminism(new_want_determinism);
|
device.second->UpdateWantDeterminism(new_want_determinism);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kernel::DoState(PointerWrap& p)
|
void EmulationKernel::DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
p.Do(m_request_queue);
|
p.Do(m_request_queue);
|
||||||
p.Do(m_reply_queue);
|
p.Do(m_reply_queue);
|
||||||
|
@ -954,15 +954,15 @@ void Init()
|
||||||
s_event_finish_ppc_bootstrap =
|
s_event_finish_ppc_bootstrap =
|
||||||
core_timing.RegisterEvent("IOSFinishPPCBootstrap", FinishPPCBootstrap);
|
core_timing.RegisterEvent("IOSFinishPPCBootstrap", FinishPPCBootstrap);
|
||||||
|
|
||||||
s_event_finish_ios_boot =
|
s_event_finish_ios_boot = core_timing.RegisterEvent(
|
||||||
core_timing.RegisterEvent("IOSFinishIOSBoot", [](Core::System& system_, u64 ios_title_id,
|
"IOSFinishIOSBoot",
|
||||||
s64) { FinishIOSBoot(ios_title_id); });
|
[](Core::System& system_, u64 ios_title_id, s64) { FinishIOSBoot(system_, ios_title_id); });
|
||||||
|
|
||||||
DIDevice::s_finish_executing_di_command =
|
DIDevice::s_finish_executing_di_command =
|
||||||
core_timing.RegisterEvent("FinishDICommand", DIDevice::FinishDICommandCallback);
|
core_timing.RegisterEvent("FinishDICommand", DIDevice::FinishDICommandCallback);
|
||||||
|
|
||||||
// Start with IOS80 to simulate part of the Wii boot process.
|
// Start with IOS80 to simulate part of the Wii boot process.
|
||||||
s_ios = std::make_unique<EmulationKernel>(Titles::SYSTEM_MENU_IOS);
|
s_ios = std::make_unique<EmulationKernel>(system, Titles::SYSTEM_MENU_IOS);
|
||||||
// On a Wii, boot2 launches the system menu IOS, which then launches the system menu
|
// 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.
|
// (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
|
// This means that the constants in the 0x3100 region are always set up by the time
|
||||||
|
|
|
@ -119,25 +119,12 @@ public:
|
||||||
explicit Kernel(IOSC::ConsoleType console_type = IOSC::ConsoleType::Retail);
|
explicit Kernel(IOSC::ConsoleType console_type = IOSC::ConsoleType::Retail);
|
||||||
virtual ~Kernel();
|
virtual ~Kernel();
|
||||||
|
|
||||||
void DoState(PointerWrap& p);
|
|
||||||
void HandleIPCEvent(u64 userdata);
|
|
||||||
void UpdateIPC();
|
|
||||||
void UpdateDevices();
|
|
||||||
void UpdateWantDeterminism(bool new_want_determinism);
|
|
||||||
|
|
||||||
// These are *always* part of the IOS kernel and always available.
|
// These are *always* part of the IOS kernel and always available.
|
||||||
// They are also the only available resource managers even before loading any module.
|
// They are also the only available resource managers even before loading any module.
|
||||||
std::shared_ptr<FS::FileSystem> GetFS();
|
std::shared_ptr<FS::FileSystem> GetFS();
|
||||||
std::shared_ptr<FSDevice> GetFSDevice();
|
std::shared_ptr<FSDevice> GetFSDevice();
|
||||||
std::shared_ptr<ESDevice> GetES();
|
std::shared_ptr<ESDevice> GetES();
|
||||||
|
|
||||||
// This is only available on an EmulationKernel if the IOS features require it.
|
|
||||||
std::shared_ptr<WiiSockMan> GetSocketManager();
|
|
||||||
|
|
||||||
void EnqueueIPCRequest(u32 address);
|
|
||||||
void EnqueueIPCReply(const Request& request, s32 return_value, s64 cycles_in_future = 0,
|
|
||||||
CoreTiming::FromThread from = CoreTiming::FromThread::CPU);
|
|
||||||
|
|
||||||
void SetUidForPPC(u32 uid);
|
void SetUidForPPC(u32 uid);
|
||||||
u32 GetUidForPPC() const;
|
u32 GetUidForPPC() const;
|
||||||
void SetGidForPPC(u16 gid);
|
void SetGidForPPC(u16 gid);
|
||||||
|
@ -154,15 +141,9 @@ public:
|
||||||
protected:
|
protected:
|
||||||
explicit Kernel(u64 title_id);
|
explicit Kernel(u64 title_id);
|
||||||
|
|
||||||
void ExecuteIPCCommand(u32 address);
|
|
||||||
std::optional<IPCReply> HandleIPCCommand(const Request& request);
|
|
||||||
|
|
||||||
void AddDevice(std::unique_ptr<Device> device);
|
void AddDevice(std::unique_ptr<Device> device);
|
||||||
void AddCoreDevices();
|
void AddCoreDevices();
|
||||||
void AddStaticDevices();
|
|
||||||
std::shared_ptr<Device> GetDeviceByName(std::string_view device_name);
|
std::shared_ptr<Device> GetDeviceByName(std::string_view device_name);
|
||||||
s32 GetFreeDeviceID();
|
|
||||||
std::optional<IPCReply> OpenDevice(OpenRequest& request);
|
|
||||||
|
|
||||||
bool m_is_responsible_for_nand_root = false;
|
bool m_is_responsible_for_nand_root = false;
|
||||||
u64 m_title_id = 0;
|
u64 m_title_id = 0;
|
||||||
|
@ -187,15 +168,40 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
// HLE for an IOS tied to emulation: base kernel which may have additional modules loaded.
|
// HLE for an IOS tied to emulation: base kernel which may have additional modules loaded.
|
||||||
class EmulationKernel : public Kernel
|
class EmulationKernel final : public Kernel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit EmulationKernel(u64 ios_title_id);
|
EmulationKernel(Core::System& system, u64 ios_title_id);
|
||||||
~EmulationKernel();
|
~EmulationKernel();
|
||||||
|
|
||||||
// Get a resource manager by name.
|
// Get a resource manager by name.
|
||||||
// This only works for devices which are part of the device map.
|
// This only works for devices which are part of the device map.
|
||||||
std::shared_ptr<Device> GetDeviceByName(std::string_view device_name);
|
std::shared_ptr<Device> GetDeviceByName(std::string_view device_name);
|
||||||
|
|
||||||
|
void DoState(PointerWrap& p);
|
||||||
|
void UpdateDevices();
|
||||||
|
void UpdateWantDeterminism(bool new_want_determinism);
|
||||||
|
|
||||||
|
std::shared_ptr<WiiSockMan> GetSocketManager();
|
||||||
|
|
||||||
|
void HandleIPCEvent(u64 userdata);
|
||||||
|
void UpdateIPC();
|
||||||
|
|
||||||
|
void EnqueueIPCRequest(u32 address);
|
||||||
|
void EnqueueIPCReply(const Request& request, s32 return_value, s64 cycles_in_future = 0,
|
||||||
|
CoreTiming::FromThread from = CoreTiming::FromThread::CPU);
|
||||||
|
|
||||||
|
Core::System& GetSystem() const { return m_system; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Core::System& m_system;
|
||||||
|
|
||||||
|
void ExecuteIPCCommand(u32 address);
|
||||||
|
std::optional<IPCReply> HandleIPCCommand(const Request& request);
|
||||||
|
|
||||||
|
void AddStaticDevices();
|
||||||
|
s32 GetFreeDeviceID();
|
||||||
|
std::optional<IPCReply> OpenDevice(OpenRequest& request);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Used for controlling and accessing an IOS instance that is tied to emulation.
|
// Used for controlling and accessing an IOS instance that is tied to emulation.
|
||||||
|
|
|
@ -62,8 +62,8 @@ enum SOResultCode : s32
|
||||||
SO_ERROR_HOST_NOT_FOUND = -305,
|
SO_ERROR_HOST_NOT_FOUND = -305,
|
||||||
};
|
};
|
||||||
|
|
||||||
NetIPTopDevice::NetIPTopDevice(Kernel& ios, const std::string& device_name)
|
NetIPTopDevice::NetIPTopDevice(EmulationKernel& ios, const std::string& device_name)
|
||||||
: Device(ios, device_name)
|
: EmulationDevice(ios, device_name)
|
||||||
{
|
{
|
||||||
m_work_queue.Reset("Network Worker", [this](AsyncTask task) {
|
m_work_queue.Reset("Network Worker", [this](AsyncTask task) {
|
||||||
const IPCReply reply = task.handler();
|
const IPCReply reply = task.handler();
|
||||||
|
@ -330,7 +330,7 @@ std::optional<IPCReply> NetIPTopDevice::IOCtl(const IOCtlRequest& request)
|
||||||
case IOCTL_SO_ICMPCANCEL:
|
case IOCTL_SO_ICMPCANCEL:
|
||||||
return HandleICMPCancelRequest(request);
|
return HandleICMPCancelRequest(request);
|
||||||
default:
|
default:
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_NET);
|
request.DumpUnknown(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_NET);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +352,7 @@ std::optional<IPCReply> NetIPTopDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
case IOCTLV_SO_ICMPPING:
|
case IOCTLV_SO_ICMPPING:
|
||||||
return HandleICMPPingRequest(request);
|
return HandleICMPPingRequest(request);
|
||||||
default:
|
default:
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_NET);
|
request.DumpUnknown(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_NET);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,11 +366,11 @@ void NetIPTopDevice::Update()
|
||||||
while (!m_async_replies.empty())
|
while (!m_async_replies.empty())
|
||||||
{
|
{
|
||||||
const auto& reply = m_async_replies.front();
|
const auto& reply = m_async_replies.front();
|
||||||
GetIOS()->EnqueueIPCReply(reply.request, reply.return_value);
|
GetEmulationKernel().EnqueueIPCReply(reply.request, reply.return_value);
|
||||||
m_async_replies.pop();
|
m_async_replies.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_ios.GetSocketManager()->Update();
|
GetEmulationKernel().GetSocketManager()->Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleInitInterfaceRequest(const IOCtlRequest& request)
|
IPCReply NetIPTopDevice::HandleInitInterfaceRequest(const IOCtlRequest& request)
|
||||||
|
@ -381,14 +381,14 @@ IPCReply NetIPTopDevice::HandleInitInterfaceRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleSocketRequest(const IOCtlRequest& request)
|
IPCReply NetIPTopDevice::HandleSocketRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u32 af = memory.Read_U32(request.buffer_in);
|
const u32 af = memory.Read_U32(request.buffer_in);
|
||||||
const u32 type = memory.Read_U32(request.buffer_in + 4);
|
const u32 type = memory.Read_U32(request.buffer_in + 4);
|
||||||
const u32 prot = memory.Read_U32(request.buffer_in + 8);
|
const u32 prot = memory.Read_U32(request.buffer_in + 8);
|
||||||
|
|
||||||
const s32 return_value = m_ios.GetSocketManager()->NewSocket(af, type, prot);
|
const s32 return_value = GetEmulationKernel().GetSocketManager()->NewSocket(af, type, prot);
|
||||||
INFO_LOG_FMT(IOS_NET,
|
INFO_LOG_FMT(IOS_NET,
|
||||||
"IOCTL_SO_SOCKET "
|
"IOCTL_SO_SOCKET "
|
||||||
"Socket: {:08x} ({},{},{}), BufferIn: ({:08x}, {}), BufferOut: ({:08x}, {})",
|
"Socket: {:08x} ({},{},{}), BufferIn: ({:08x}, {}), BufferOut: ({:08x}, {})",
|
||||||
|
@ -400,23 +400,24 @@ IPCReply NetIPTopDevice::HandleSocketRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleICMPSocketRequest(const IOCtlRequest& request)
|
IPCReply NetIPTopDevice::HandleICMPSocketRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u32 pf = memory.Read_U32(request.buffer_in);
|
const u32 pf = memory.Read_U32(request.buffer_in);
|
||||||
|
|
||||||
const s32 return_value = m_ios.GetSocketManager()->NewSocket(pf, SOCK_RAW, IPPROTO_ICMP);
|
const s32 return_value =
|
||||||
|
GetEmulationKernel().GetSocketManager()->NewSocket(pf, SOCK_RAW, IPPROTO_ICMP);
|
||||||
INFO_LOG_FMT(IOS_NET, "IOCTL_SO_ICMPSOCKET({:x}) {}", pf, return_value);
|
INFO_LOG_FMT(IOS_NET, "IOCTL_SO_ICMPSOCKET({:x}) {}", pf, return_value);
|
||||||
return IPCReply(return_value);
|
return IPCReply(return_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleCloseRequest(const IOCtlRequest& request)
|
IPCReply NetIPTopDevice::HandleCloseRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u32 fd = memory.Read_U32(request.buffer_in);
|
const u32 fd = memory.Read_U32(request.buffer_in);
|
||||||
const s32 return_value = m_ios.GetSocketManager()->DeleteSocket(fd);
|
const s32 return_value = GetEmulationKernel().GetSocketManager()->DeleteSocket(fd);
|
||||||
const char* const close_fn =
|
const char* const close_fn =
|
||||||
request.request == IOCTL_SO_ICMPCLOSE ? "IOCTL_SO_ICMPCLOSE" : "IOCTL_SO_CLOSE";
|
request.request == IOCTL_SO_ICMPCLOSE ? "IOCTL_SO_ICMPCLOSE" : "IOCTL_SO_CLOSE";
|
||||||
|
|
||||||
|
@ -427,11 +428,12 @@ IPCReply NetIPTopDevice::HandleCloseRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
std::optional<IPCReply> NetIPTopDevice::HandleDoSockRequest(const IOCtlRequest& request)
|
std::optional<IPCReply> NetIPTopDevice::HandleDoSockRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u32 fd = memory.Read_U32(request.buffer_in);
|
const u32 fd = memory.Read_U32(request.buffer_in);
|
||||||
m_ios.GetSocketManager()->DoSock(fd, request, static_cast<NET_IOCTL>(request.request));
|
GetEmulationKernel().GetSocketManager()->DoSock(fd, request,
|
||||||
|
static_cast<NET_IOCTL>(request.request));
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,12 +446,12 @@ IPCReply NetIPTopDevice::HandleShutdownRequest(const IOCtlRequest& request)
|
||||||
return IPCReply(-SO_EINVAL);
|
return IPCReply(-SO_EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u32 fd = memory.Read_U32(request.buffer_in);
|
const u32 fd = memory.Read_U32(request.buffer_in);
|
||||||
const u32 how = memory.Read_U32(request.buffer_in + 4);
|
const u32 how = memory.Read_U32(request.buffer_in + 4);
|
||||||
const s32 return_value = m_ios.GetSocketManager()->ShutdownSocket(fd, how);
|
const s32 return_value = GetEmulationKernel().GetSocketManager()->ShutdownSocket(fd, how);
|
||||||
|
|
||||||
INFO_LOG_FMT(IOS_NET, "IOCTL_SO_SHUTDOWN(fd={}, how={}) = {}", fd, how, return_value);
|
INFO_LOG_FMT(IOS_NET, "IOCTL_SO_SHUTDOWN(fd={}, how={}) = {}", fd, how, return_value);
|
||||||
return IPCReply(return_value);
|
return IPCReply(return_value);
|
||||||
|
@ -457,12 +459,12 @@ IPCReply NetIPTopDevice::HandleShutdownRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleListenRequest(const IOCtlRequest& request)
|
IPCReply NetIPTopDevice::HandleListenRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
u32 fd = memory.Read_U32(request.buffer_in);
|
u32 fd = memory.Read_U32(request.buffer_in);
|
||||||
u32 BACKLOG = memory.Read_U32(request.buffer_in + 0x04);
|
u32 BACKLOG = memory.Read_U32(request.buffer_in + 0x04);
|
||||||
auto socket_manager = m_ios.GetSocketManager();
|
auto socket_manager = GetEmulationKernel().GetSocketManager();
|
||||||
u32 ret = listen(socket_manager->GetHostSocket(fd), BACKLOG);
|
u32 ret = listen(socket_manager->GetHostSocket(fd), BACKLOG);
|
||||||
|
|
||||||
request.Log(GetDeviceName(), Common::Log::LogType::IOS_WC24);
|
request.Log(GetDeviceName(), Common::Log::LogType::IOS_WC24);
|
||||||
|
@ -471,7 +473,7 @@ IPCReply NetIPTopDevice::HandleListenRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleGetSockOptRequest(const IOCtlRequest& request)
|
IPCReply NetIPTopDevice::HandleGetSockOptRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
u32 fd = memory.Read_U32(request.buffer_out);
|
u32 fd = memory.Read_U32(request.buffer_out);
|
||||||
|
@ -487,7 +489,7 @@ IPCReply NetIPTopDevice::HandleGetSockOptRequest(const IOCtlRequest& request)
|
||||||
u8 optval[20];
|
u8 optval[20];
|
||||||
u32 optlen = 4;
|
u32 optlen = 4;
|
||||||
|
|
||||||
auto socket_manager = m_ios.GetSocketManager();
|
auto socket_manager = GetEmulationKernel().GetSocketManager();
|
||||||
int ret = getsockopt(socket_manager->GetHostSocket(fd), nat_level, nat_optname, (char*)&optval,
|
int ret = getsockopt(socket_manager->GetHostSocket(fd), nat_level, nat_optname, (char*)&optval,
|
||||||
(socklen_t*)&optlen);
|
(socklen_t*)&optlen);
|
||||||
const s32 return_value = socket_manager->GetNetErrorCode(ret, "SO_GETSOCKOPT", false);
|
const s32 return_value = socket_manager->GetNetErrorCode(ret, "SO_GETSOCKOPT", false);
|
||||||
|
@ -508,7 +510,7 @@ IPCReply NetIPTopDevice::HandleGetSockOptRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleSetSockOptRequest(const IOCtlRequest& request)
|
IPCReply NetIPTopDevice::HandleSetSockOptRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u32 fd = memory.Read_U32(request.buffer_in);
|
const u32 fd = memory.Read_U32(request.buffer_in);
|
||||||
|
@ -539,7 +541,7 @@ IPCReply NetIPTopDevice::HandleSetSockOptRequest(const IOCtlRequest& request)
|
||||||
const int nat_level = MapWiiSockOptLevelToNative(level);
|
const int nat_level = MapWiiSockOptLevelToNative(level);
|
||||||
const int nat_optname = MapWiiSockOptNameToNative(optname);
|
const int nat_optname = MapWiiSockOptNameToNative(optname);
|
||||||
|
|
||||||
auto socket_manager = m_ios.GetSocketManager();
|
auto socket_manager = GetEmulationKernel().GetSocketManager();
|
||||||
const int ret = setsockopt(socket_manager->GetHostSocket(fd), nat_level, nat_optname,
|
const int ret = setsockopt(socket_manager->GetHostSocket(fd), nat_level, nat_optname,
|
||||||
reinterpret_cast<char*>(optval), optlen);
|
reinterpret_cast<char*>(optval), optlen);
|
||||||
return IPCReply(socket_manager->GetNetErrorCode(ret, "SO_SETSOCKOPT", false));
|
return IPCReply(socket_manager->GetNetErrorCode(ret, "SO_SETSOCKOPT", false));
|
||||||
|
@ -547,7 +549,7 @@ IPCReply NetIPTopDevice::HandleSetSockOptRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleGetSockNameRequest(const IOCtlRequest& request)
|
IPCReply NetIPTopDevice::HandleGetSockNameRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
u32 fd = memory.Read_U32(request.buffer_in);
|
u32 fd = memory.Read_U32(request.buffer_in);
|
||||||
|
@ -556,7 +558,8 @@ IPCReply NetIPTopDevice::HandleGetSockNameRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
sockaddr sa;
|
sockaddr sa;
|
||||||
socklen_t sa_len = sizeof(sa);
|
socklen_t sa_len = sizeof(sa);
|
||||||
const int ret = getsockname(m_ios.GetSocketManager()->GetHostSocket(fd), &sa, &sa_len);
|
const int ret =
|
||||||
|
getsockname(GetEmulationKernel().GetSocketManager()->GetHostSocket(fd), &sa, &sa_len);
|
||||||
|
|
||||||
if (request.buffer_out_size < 2 + sizeof(sa.sa_data))
|
if (request.buffer_out_size < 2 + sizeof(sa.sa_data))
|
||||||
WARN_LOG_FMT(IOS_NET, "IOCTL_SO_GETSOCKNAME output buffer is too small. Truncating");
|
WARN_LOG_FMT(IOS_NET, "IOCTL_SO_GETSOCKNAME output buffer is too small. Truncating");
|
||||||
|
@ -576,14 +579,15 @@ IPCReply NetIPTopDevice::HandleGetSockNameRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleGetPeerNameRequest(const IOCtlRequest& request)
|
IPCReply NetIPTopDevice::HandleGetPeerNameRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
u32 fd = memory.Read_U32(request.buffer_in);
|
u32 fd = memory.Read_U32(request.buffer_in);
|
||||||
|
|
||||||
sockaddr sa;
|
sockaddr sa;
|
||||||
socklen_t sa_len = sizeof(sa);
|
socklen_t sa_len = sizeof(sa);
|
||||||
const int ret = getpeername(m_ios.GetSocketManager()->GetHostSocket(fd), &sa, &sa_len);
|
const int ret =
|
||||||
|
getpeername(GetEmulationKernel().GetSocketManager()->GetHostSocket(fd), &sa, &sa_len);
|
||||||
|
|
||||||
if (request.buffer_out_size < 2 + sizeof(sa.sa_data))
|
if (request.buffer_out_size < 2 + sizeof(sa.sa_data))
|
||||||
WARN_LOG_FMT(IOS_NET, "IOCTL_SO_GETPEERNAME output buffer is too small. Truncating");
|
WARN_LOG_FMT(IOS_NET, "IOCTL_SO_GETPEERNAME output buffer is too small. Truncating");
|
||||||
|
@ -613,7 +617,7 @@ IPCReply NetIPTopDevice::HandleGetHostIDRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleInetAToNRequest(const IOCtlRequest& request)
|
IPCReply NetIPTopDevice::HandleInetAToNRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const std::string hostname = memory.GetString(request.buffer_in);
|
const std::string hostname = memory.GetString(request.buffer_in);
|
||||||
|
@ -645,7 +649,7 @@ IPCReply NetIPTopDevice::HandleInetAToNRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleInetPToNRequest(const IOCtlRequest& request)
|
IPCReply NetIPTopDevice::HandleInetPToNRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const std::string address = memory.GetString(request.buffer_in);
|
const std::string address = memory.GetString(request.buffer_in);
|
||||||
|
@ -655,7 +659,7 @@ IPCReply NetIPTopDevice::HandleInetPToNRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleInetNToPRequest(const IOCtlRequest& request)
|
IPCReply NetIPTopDevice::HandleInetNToPRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
// u32 af = memory.Read_U32(BufferIn);
|
// u32 af = memory.Read_U32(BufferIn);
|
||||||
|
@ -674,12 +678,12 @@ IPCReply NetIPTopDevice::HandleInetNToPRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
std::optional<IPCReply> NetIPTopDevice::HandlePollRequest(const IOCtlRequest& request)
|
std::optional<IPCReply> NetIPTopDevice::HandlePollRequest(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto sm = m_ios.GetSocketManager();
|
auto sm = GetEmulationKernel().GetSocketManager();
|
||||||
|
|
||||||
if (!request.buffer_in || !request.buffer_out)
|
if (!request.buffer_in || !request.buffer_out)
|
||||||
return IPCReply(-SO_EINVAL);
|
return IPCReply(-SO_EINVAL);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
// Negative timeout indicates wait forever
|
// Negative timeout indicates wait forever
|
||||||
|
@ -726,7 +730,7 @@ IPCReply NetIPTopDevice::HandleGetHostByNameRequest(const IOCtlRequest& request)
|
||||||
return IPCReply(-1);
|
return IPCReply(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const std::string hostname = memory.GetString(request.buffer_in);
|
const std::string hostname = memory.GetString(request.buffer_in);
|
||||||
|
@ -814,7 +818,7 @@ IPCReply NetIPTopDevice::HandleICMPCancelRequest(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleGetInterfaceOptRequest(const IOCtlVRequest& request)
|
IPCReply NetIPTopDevice::HandleGetInterfaceOptRequest(const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u32 param = memory.Read_U32(request.in_vectors[0].address);
|
const u32 param = memory.Read_U32(request.in_vectors[0].address);
|
||||||
|
@ -1007,27 +1011,27 @@ IPCReply NetIPTopDevice::HandleGetInterfaceOptRequest(const IOCtlVRequest& reque
|
||||||
|
|
||||||
std::optional<IPCReply> NetIPTopDevice::HandleSendToRequest(const IOCtlVRequest& request)
|
std::optional<IPCReply> NetIPTopDevice::HandleSendToRequest(const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
u32 fd = memory.Read_U32(request.in_vectors[1].address);
|
u32 fd = memory.Read_U32(request.in_vectors[1].address);
|
||||||
m_ios.GetSocketManager()->DoSock(fd, request, IOCTLV_SO_SENDTO);
|
GetEmulationKernel().GetSocketManager()->DoSock(fd, request, IOCTLV_SO_SENDTO);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<IPCReply> NetIPTopDevice::HandleRecvFromRequest(const IOCtlVRequest& request)
|
std::optional<IPCReply> NetIPTopDevice::HandleRecvFromRequest(const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
u32 fd = memory.Read_U32(request.in_vectors[0].address);
|
u32 fd = memory.Read_U32(request.in_vectors[0].address);
|
||||||
m_ios.GetSocketManager()->DoSock(fd, request, IOCTLV_SO_RECVFROM);
|
GetEmulationKernel().GetSocketManager()->DoSock(fd, request, IOCTLV_SO_RECVFROM);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCReply NetIPTopDevice::HandleGetAddressInfoRequest(const IOCtlVRequest& request)
|
IPCReply NetIPTopDevice::HandleGetAddressInfoRequest(const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
addrinfo hints;
|
addrinfo hints;
|
||||||
|
@ -1113,7 +1117,8 @@ IPCReply NetIPTopDevice::HandleGetAddressInfoRequest(const IOCtlVRequest& reques
|
||||||
ret = SO_ERROR_HOST_NOT_FOUND;
|
ret = SO_ERROR_HOST_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
request.Dump(GetDeviceName(), Common::Log::LogType::IOS_NET, Common::Log::LogLevel::LINFO);
|
request.Dump(system, GetDeviceName(), Common::Log::LogType::IOS_NET,
|
||||||
|
Common::Log::LogLevel::LINFO);
|
||||||
return IPCReply(ret);
|
return IPCReply(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1127,7 +1132,7 @@ IPCReply NetIPTopDevice::HandleICMPPingRequest(const IOCtlVRequest& request)
|
||||||
u32 ip;
|
u32 ip;
|
||||||
} ip_info;
|
} ip_info;
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u32 fd = memory.Read_U32(request.in_vectors[0].address);
|
const u32 fd = memory.Read_U32(request.in_vectors[0].address);
|
||||||
|
@ -1176,7 +1181,7 @@ IPCReply NetIPTopDevice::HandleICMPPingRequest(const IOCtlVRequest& request)
|
||||||
icmp_length = 22;
|
icmp_length = 22;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto socket_manager = m_ios.GetSocketManager();
|
auto socket_manager = GetEmulationKernel().GetSocketManager();
|
||||||
int ret = icmp_echo_req(socket_manager->GetHostSocket(fd), &addr, data, icmp_length);
|
int ret = icmp_echo_req(socket_manager->GetHostSocket(fd), &addr, data, icmp_length);
|
||||||
if (ret == icmp_length)
|
if (ret == icmp_length)
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,10 +63,10 @@ enum NET_IOCTL
|
||||||
IOCTL_SO_ICMPCLOSE
|
IOCTL_SO_ICMPCLOSE
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetIPTopDevice : public Device
|
class NetIPTopDevice : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NetIPTopDevice(Kernel& ios, const std::string& device_name);
|
NetIPTopDevice(EmulationKernel& ios, const std::string& device_name);
|
||||||
|
|
||||||
void DoState(PointerWrap& p) override;
|
void DoState(PointerWrap& p) override;
|
||||||
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
||||||
|
|
|
@ -147,8 +147,8 @@ s32 NWC24MakeUserID(u64* nwc24_id, u32 hollywood_id, u16 id_ctr, HardwareModel h
|
||||||
}
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
NetKDRequestDevice::NetKDRequestDevice(Kernel& ios, const std::string& device_name)
|
NetKDRequestDevice::NetKDRequestDevice(EmulationKernel& ios, const std::string& device_name)
|
||||||
: Device(ios, device_name), config{ios.GetFS()}, m_dl_list{ios.GetFS()}
|
: EmulationDevice(ios, device_name), config{ios.GetFS()}, m_dl_list{ios.GetFS()}
|
||||||
{
|
{
|
||||||
m_work_queue.Reset("WiiConnect24 Worker", [this](AsyncTask task) {
|
m_work_queue.Reset("WiiConnect24 Worker", [this](AsyncTask task) {
|
||||||
const IPCReply reply = task.handler();
|
const IPCReply reply = task.handler();
|
||||||
|
@ -161,7 +161,7 @@ NetKDRequestDevice::NetKDRequestDevice(Kernel& ios, const std::string& device_na
|
||||||
|
|
||||||
NetKDRequestDevice::~NetKDRequestDevice()
|
NetKDRequestDevice::~NetKDRequestDevice()
|
||||||
{
|
{
|
||||||
auto socket_manager = m_ios.GetSocketManager();
|
auto socket_manager = GetEmulationKernel().GetSocketManager();
|
||||||
if (socket_manager)
|
if (socket_manager)
|
||||||
socket_manager->Clean();
|
socket_manager->Clean();
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ void NetKDRequestDevice::Update()
|
||||||
while (!m_async_replies.empty())
|
while (!m_async_replies.empty())
|
||||||
{
|
{
|
||||||
const auto& reply = m_async_replies.front();
|
const auto& reply = m_async_replies.front();
|
||||||
GetIOS()->EnqueueIPCReply(reply.request, reply.return_value);
|
GetEmulationKernel().EnqueueIPCReply(reply.request, reply.return_value);
|
||||||
m_async_replies.pop();
|
m_async_replies.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,7 +236,7 @@ NWC24::ErrorCode NetKDRequestDevice::KDDownload(const u16 entry_index,
|
||||||
IPCReply NetKDRequestDevice::HandleNWC24DownloadNowEx(const IOCtlRequest& request)
|
IPCReply NetKDRequestDevice::HandleNWC24DownloadNowEx(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
m_dl_list.ReadDlList();
|
m_dl_list.ReadDlList();
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
const u32 flags = memory.Read_U32(request.buffer_in);
|
const u32 flags = memory.Read_U32(request.buffer_in);
|
||||||
// Nintendo converts the entry ID between a u32 and u16
|
// Nintendo converts the entry ID between a u32 and u16
|
||||||
|
@ -321,7 +321,7 @@ std::optional<IPCReply> NetKDRequestDevice::IOCtl(const IOCtlRequest& request)
|
||||||
IOCTL_NWC24_REQUEST_SHUTDOWN = 0x28,
|
IOCTL_NWC24_REQUEST_SHUTDOWN = 0x28,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
s32 return_value = 0;
|
s32 return_value = 0;
|
||||||
switch (request.request)
|
switch (request.request)
|
||||||
|
@ -350,7 +350,7 @@ std::optional<IPCReply> NetKDRequestDevice::IOCtl(const IOCtlRequest& request)
|
||||||
|
|
||||||
case IOCTL_NWC24_CLEANUP_SOCKET:
|
case IOCTL_NWC24_CLEANUP_SOCKET:
|
||||||
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_CLEANUP_SOCKET");
|
INFO_LOG_FMT(IOS_WC24, "NET_KD_REQ: IOCTL_NWC24_CLEANUP_SOCKET");
|
||||||
m_ios.GetSocketManager()->Clean();
|
GetEmulationKernel().GetSocketManager()->Clean();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IOCTL_NWC24_LOCK_SOCKET: // WiiMenu
|
case IOCTL_NWC24_LOCK_SOCKET: // WiiMenu
|
||||||
|
@ -454,7 +454,7 @@ std::optional<IPCReply> NetKDRequestDevice::IOCtl(const IOCtlRequest& request)
|
||||||
// SOGetInterfaceOpt(0xfffe,0xc001); // DHCP lease time remaining?
|
// SOGetInterfaceOpt(0xfffe,0xc001); // DHCP lease time remaining?
|
||||||
// SOGetInterfaceOpt(0xfffe,0x1003); // Error
|
// SOGetInterfaceOpt(0xfffe,0x1003); // Error
|
||||||
// Call /dev/net/ip/top 0x1b (SOCleanup), it closes all sockets
|
// Call /dev/net/ip/top 0x1b (SOCleanup), it closes all sockets
|
||||||
m_ios.GetSocketManager()->Clean();
|
GetEmulationKernel().GetSocketManager()->Clean();
|
||||||
return_value = IPC_SUCCESS;
|
return_value = IPC_SUCCESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,10 @@ constexpr const char DL_CNT_PATH[] = "/" WII_WC24CONF_DIR "/dlcnt.bin";
|
||||||
// KD is the IOS module responsible for implementing WiiConnect24 functionality.
|
// KD is the IOS module responsible for implementing WiiConnect24 functionality.
|
||||||
// It can perform HTTPS downloads, send and receive mail via SMTP, and execute a
|
// It can perform HTTPS downloads, send and receive mail via SMTP, and execute a
|
||||||
// JavaScript-like language while the Wii is in standby mode.
|
// JavaScript-like language while the Wii is in standby mode.
|
||||||
class NetKDRequestDevice : public Device
|
class NetKDRequestDevice : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NetKDRequestDevice(Kernel& ios, const std::string& device_name);
|
NetKDRequestDevice(EmulationKernel& ios, const std::string& device_name);
|
||||||
IPCReply HandleNWC24DownloadNowEx(const IOCtlRequest& request);
|
IPCReply HandleNWC24DownloadNowEx(const IOCtlRequest& request);
|
||||||
NWC24::ErrorCode KDDownload(const u16 entry_index, const std::optional<u8> subtask_id);
|
NWC24::ErrorCode KDDownload(const u16 entry_index, const std::optional<u8> subtask_id);
|
||||||
~NetKDRequestDevice() override;
|
~NetKDRequestDevice() override;
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
NetKDTimeDevice::NetKDTimeDevice(Kernel& ios, const std::string& device_name)
|
NetKDTimeDevice::NetKDTimeDevice(EmulationKernel& ios, const std::string& device_name)
|
||||||
: Device(ios, device_name)
|
: EmulationDevice(ios, device_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ std::optional<IPCReply> NetKDTimeDevice::IOCtl(const IOCtlRequest& request)
|
||||||
// TODO Writes stuff to /shared2/nwc24/misc.bin
|
// TODO Writes stuff to /shared2/nwc24/misc.bin
|
||||||
u32 update_misc = 0;
|
u32 update_misc = 0;
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
switch (request.request)
|
switch (request.request)
|
||||||
|
@ -78,7 +78,7 @@ std::optional<IPCReply> NetKDTimeDevice::IOCtl(const IOCtlRequest& request)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_WC24);
|
request.DumpUnknown(system, GetDeviceName(), Common::Log::LogType::IOS_WC24);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,8 +91,7 @@ u64 NetKDTimeDevice::GetAdjustedUTC() const
|
||||||
{
|
{
|
||||||
using namespace ExpansionInterface;
|
using namespace ExpansionInterface;
|
||||||
|
|
||||||
const time_t current_time =
|
const time_t current_time = CEXIIPL::GetEmulatedTime(GetSystem(), CEXIIPL::UNIX_EPOCH);
|
||||||
CEXIIPL::GetEmulatedTime(Core::System::GetInstance(), CEXIIPL::UNIX_EPOCH);
|
|
||||||
tm* const gm_time = gmtime(¤t_time);
|
tm* const gm_time = gmtime(¤t_time);
|
||||||
const u32 emulated_time = mktime(gm_time);
|
const u32 emulated_time = mktime(gm_time);
|
||||||
return u64(s64(emulated_time) + utcdiff);
|
return u64(s64(emulated_time) + utcdiff);
|
||||||
|
@ -102,8 +101,7 @@ void NetKDTimeDevice::SetAdjustedUTC(u64 wii_utc)
|
||||||
{
|
{
|
||||||
using namespace ExpansionInterface;
|
using namespace ExpansionInterface;
|
||||||
|
|
||||||
const time_t current_time =
|
const time_t current_time = CEXIIPL::GetEmulatedTime(GetSystem(), CEXIIPL::UNIX_EPOCH);
|
||||||
CEXIIPL::GetEmulatedTime(Core::System::GetInstance(), CEXIIPL::UNIX_EPOCH);
|
|
||||||
tm* const gm_time = gmtime(¤t_time);
|
tm* const gm_time = gmtime(¤t_time);
|
||||||
const u32 emulated_time = mktime(gm_time);
|
const u32 emulated_time = mktime(gm_time);
|
||||||
utcdiff = s64(emulated_time - wii_utc);
|
utcdiff = s64(emulated_time - wii_utc);
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
class NetKDTimeDevice : public Device
|
class NetKDTimeDevice : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NetKDTimeDevice(Kernel& ios, const std::string& device_name);
|
NetKDTimeDevice(EmulationKernel& ios, const std::string& device_name);
|
||||||
~NetKDTimeDevice() override;
|
~NetKDTimeDevice() override;
|
||||||
|
|
||||||
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
NetNCDManageDevice::NetNCDManageDevice(Kernel& ios, const std::string& device_name)
|
NetNCDManageDevice::NetNCDManageDevice(EmulationKernel& ios, const std::string& device_name)
|
||||||
: Device(ios, device_name)
|
: EmulationDevice(ios, device_name)
|
||||||
{
|
{
|
||||||
config.ReadConfig(ios.GetFS().get());
|
config.ReadConfig(ios.GetFS().get());
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ std::optional<IPCReply> NetNCDManageDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
u32 common_result = 0;
|
u32 common_result = 0;
|
||||||
u32 common_vector = 0;
|
u32 common_vector = 0;
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
switch (request.request)
|
switch (request.request)
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
// Interface for reading and changing network configuration (probably some other stuff as well)
|
// Interface for reading and changing network configuration (probably some other stuff as well)
|
||||||
class NetNCDManageDevice : public Device
|
class NetNCDManageDevice : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NetNCDManageDevice(Kernel& ios, const std::string& device_name);
|
NetNCDManageDevice(EmulationKernel& ios, const std::string& device_name);
|
||||||
|
|
||||||
std::optional<IPCReply> IOCtlV(const IOCtlVRequest& request) override;
|
std::optional<IPCReply> IOCtlV(const IOCtlVRequest& request) override;
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,8 @@ int SSLRecv(void* ctx, unsigned char* buf, size_t len)
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NetSSLDevice::NetSSLDevice(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
|
NetSSLDevice::NetSSLDevice(EmulationKernel& ios, const std::string& device_name)
|
||||||
|
: EmulationDevice(ios, device_name)
|
||||||
{
|
{
|
||||||
for (WII_SSL& ssl : _SSL)
|
for (WII_SSL& ssl : _SSL)
|
||||||
{
|
{
|
||||||
|
@ -496,7 +497,7 @@ std::optional<IPCReply> NetSSLDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
WII_SSL* ssl = &_SSL[sslID];
|
WII_SSL* ssl = &_SSL[sslID];
|
||||||
mbedtls_ssl_setup(&ssl->ctx, &ssl->config);
|
mbedtls_ssl_setup(&ssl->ctx, &ssl->config);
|
||||||
ssl->sockfd = memory.Read_U32(BufferOut2);
|
ssl->sockfd = memory.Read_U32(BufferOut2);
|
||||||
ssl->hostfd = m_ios.GetSocketManager()->GetHostSocket(ssl->sockfd);
|
ssl->hostfd = GetEmulationKernel().GetSocketManager()->GetHostSocket(ssl->sockfd);
|
||||||
INFO_LOG_FMT(IOS_SSL, "IOCTLV_NET_SSL_CONNECT socket = {}", ssl->sockfd);
|
INFO_LOG_FMT(IOS_SSL, "IOCTLV_NET_SSL_CONNECT socket = {}", ssl->sockfd);
|
||||||
mbedtls_ssl_set_bio(&ssl->ctx, ssl, SSLSendWithoutSNI, SSLRecv, nullptr);
|
mbedtls_ssl_set_bio(&ssl->ctx, ssl, SSLSendWithoutSNI, SSLRecv, nullptr);
|
||||||
WriteReturnValue(SSL_OK, BufferIn);
|
WriteReturnValue(SSL_OK, BufferIn);
|
||||||
|
@ -519,7 +520,8 @@ std::optional<IPCReply> NetSSLDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
int sslID = memory.Read_U32(BufferOut) - 1;
|
int sslID = memory.Read_U32(BufferOut) - 1;
|
||||||
if (IsSSLIDValid(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
m_ios.GetSocketManager()->DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_DOHANDSHAKE);
|
GetEmulationKernel().GetSocketManager()->DoSock(_SSL[sslID].sockfd, request,
|
||||||
|
IOCTLV_NET_SSL_DOHANDSHAKE);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -533,7 +535,8 @@ std::optional<IPCReply> NetSSLDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
const int sslID = memory.Read_U32(BufferOut) - 1;
|
const int sslID = memory.Read_U32(BufferOut) - 1;
|
||||||
if (IsSSLIDValid(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
m_ios.GetSocketManager()->DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_WRITE);
|
GetEmulationKernel().GetSocketManager()->DoSock(_SSL[sslID].sockfd, request,
|
||||||
|
IOCTLV_NET_SSL_WRITE);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -556,7 +559,8 @@ std::optional<IPCReply> NetSSLDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
int sslID = memory.Read_U32(BufferOut) - 1;
|
int sslID = memory.Read_U32(BufferOut) - 1;
|
||||||
if (IsSSLIDValid(sslID))
|
if (IsSSLIDValid(sslID))
|
||||||
{
|
{
|
||||||
m_ios.GetSocketManager()->DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_READ);
|
GetEmulationKernel().GetSocketManager()->DoSock(_SSL[sslID].sockfd, request,
|
||||||
|
IOCTLV_NET_SSL_READ);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -615,7 +619,7 @@ std::optional<IPCReply> NetSSLDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_SSL);
|
request.DumpUnknown(system, GetDeviceName(), Common::Log::LogType::IOS_SSL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SSL return codes are written to BufferIn
|
// SSL return codes are written to BufferIn
|
||||||
|
|
|
@ -79,10 +79,10 @@ struct WII_SSL
|
||||||
bool active = false;
|
bool active = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetSSLDevice : public Device
|
class NetSSLDevice : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NetSSLDevice(Kernel& ios, const std::string& device_name);
|
NetSSLDevice(EmulationKernel& ios, const std::string& device_name);
|
||||||
|
|
||||||
virtual ~NetSSLDevice();
|
virtual ~NetSSLDevice();
|
||||||
|
|
||||||
|
|
|
@ -260,7 +260,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
|
||||||
IPCCommandType ct = it->request.command;
|
IPCCommandType ct = it->request.command;
|
||||||
if (!it->is_ssl && ct == IPC_CMD_IOCTL)
|
if (!it->is_ssl && ct == IPC_CMD_IOCTL)
|
||||||
{
|
{
|
||||||
IOCtlRequest ioctl{it->request.address};
|
IOCtlRequest ioctl{system, it->request.address};
|
||||||
switch (it->net_type)
|
switch (it->net_type)
|
||||||
{
|
{
|
||||||
case IOCTL_SO_FCNTL:
|
case IOCTL_SO_FCNTL:
|
||||||
|
@ -351,7 +351,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
|
||||||
}
|
}
|
||||||
else if (ct == IPC_CMD_IOCTLV)
|
else if (ct == IPC_CMD_IOCTLV)
|
||||||
{
|
{
|
||||||
IOCtlVRequest ioctlv{it->request.address};
|
IOCtlVRequest ioctlv{system, it->request.address};
|
||||||
u32 BufferIn = 0, BufferIn2 = 0;
|
u32 BufferIn = 0, BufferIn2 = 0;
|
||||||
u32 BufferInSize = 0, BufferInSize2 = 0;
|
u32 BufferInSize = 0, BufferInSize2 = 0;
|
||||||
u32 BufferOut = 0, BufferOut2 = 0;
|
u32 BufferOut = 0, BufferOut2 = 0;
|
||||||
|
@ -1042,8 +1042,8 @@ void WiiSockMan::UpdatePollCommands()
|
||||||
pending_polls.erase(
|
pending_polls.erase(
|
||||||
std::remove_if(
|
std::remove_if(
|
||||||
pending_polls.begin(), pending_polls.end(),
|
pending_polls.begin(), pending_polls.end(),
|
||||||
[&memory, this](PollCommand& pcmd) {
|
[&system, &memory, this](PollCommand& pcmd) {
|
||||||
const auto request = Request(pcmd.request_addr);
|
const auto request = Request(system, pcmd.request_addr);
|
||||||
auto& pfds = pcmd.wii_fds;
|
auto& pfds = pcmd.wii_fds;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
|
|
@ -61,8 +61,8 @@ NetWDCommandDevice::Status NetWDCommandDevice::GetTargetStatusForMode(WD::Mode m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NetWDCommandDevice::NetWDCommandDevice(Kernel& ios, const std::string& device_name)
|
NetWDCommandDevice::NetWDCommandDevice(EmulationKernel& ios, const std::string& device_name)
|
||||||
: Device(ios, device_name)
|
: EmulationDevice(ios, device_name)
|
||||||
{
|
{
|
||||||
// TODO: use the MPCH setting in setting.txt to determine this value.
|
// TODO: use the MPCH setting in setting.txt to determine this value.
|
||||||
m_nitro_enabled_channels = LegalNitroChannelMask;
|
m_nitro_enabled_channels = LegalNitroChannelMask;
|
||||||
|
@ -87,6 +87,8 @@ void NetWDCommandDevice::Update()
|
||||||
|
|
||||||
void NetWDCommandDevice::ProcessRecvRequests()
|
void NetWDCommandDevice::ProcessRecvRequests()
|
||||||
{
|
{
|
||||||
|
auto& system = GetSystem();
|
||||||
|
|
||||||
// Because we currently do not actually emulate the wireless driver, we have no frames
|
// Because we currently do not actually emulate the wireless driver, we have no frames
|
||||||
// and no notification data that could be used to reply to requests.
|
// and no notification data that could be used to reply to requests.
|
||||||
// Therefore, requests are left pending to simulate the situation where there is nothing to send.
|
// Therefore, requests are left pending to simulate the situation where there is nothing to send.
|
||||||
|
@ -117,7 +119,7 @@ void NetWDCommandDevice::ProcessRecvRequests()
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO_LOG_FMT(IOS_NET, "Processed request {:08x} (result {:08x})", request, result);
|
INFO_LOG_FMT(IOS_NET, "Processed request {:08x} (result {:08x})", request, result);
|
||||||
m_ios.EnqueueIPCReply(Request{request}, result);
|
GetEmulationKernel().EnqueueIPCReply(Request{system, request}, result);
|
||||||
queue.pop_front();
|
queue.pop_front();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -234,7 +236,7 @@ IPCReply NetWDCommandDevice::SetLinkState(const IOCtlVRequest& request)
|
||||||
if (!vector || vector->address == 0)
|
if (!vector || vector->address == 0)
|
||||||
return IPCReply(u32(ResultCode::IllegalParameter));
|
return IPCReply(u32(ResultCode::IllegalParameter));
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
const u32 state = memory.Read_U32(vector->address);
|
const u32 state = memory.Read_U32(vector->address);
|
||||||
INFO_LOG_FMT(IOS_NET, "WD_SetLinkState called (state={}, mode={})", state, m_mode);
|
INFO_LOG_FMT(IOS_NET, "WD_SetLinkState called (state={}, mode={})", state, m_mode);
|
||||||
|
@ -282,7 +284,7 @@ IPCReply NetWDCommandDevice::Disassociate(const IOCtlVRequest& request)
|
||||||
if (!vector || vector->address == 0)
|
if (!vector || vector->address == 0)
|
||||||
return IPCReply(u32(ResultCode::IllegalParameter));
|
return IPCReply(u32(ResultCode::IllegalParameter));
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
Common::MACAddress mac;
|
Common::MACAddress mac;
|
||||||
|
@ -315,7 +317,7 @@ IPCReply NetWDCommandDevice::GetInfo(const IOCtlVRequest& request) const
|
||||||
if (!vector || vector->address == 0)
|
if (!vector || vector->address == 0)
|
||||||
return IPCReply(u32(ResultCode::IllegalParameter));
|
return IPCReply(u32(ResultCode::IllegalParameter));
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.CopyToEmu(vector->address, &m_info, sizeof(m_info));
|
memory.CopyToEmu(vector->address, &m_info, sizeof(m_info));
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
|
@ -342,7 +344,7 @@ std::optional<IPCReply> NetWDCommandDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
// XXX - unused
|
// XXX - unused
|
||||||
// ScanInfo *scan = (ScanInfo *)memory.GetPointer(request.in_vectors.at(0).m_Address);
|
// ScanInfo *scan = (ScanInfo *)memory.GetPointer(request.in_vectors.at(0).m_Address);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
u16* results = (u16*)memory.GetPointer(request.io_vectors.at(0).address);
|
u16* results = (u16*)memory.GetPointer(request.io_vectors.at(0).address);
|
||||||
// first u16 indicates number of BSSInfo following
|
// first u16 indicates number of BSSInfo following
|
||||||
|
@ -388,7 +390,8 @@ std::optional<IPCReply> NetWDCommandDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
case IOCTLV_WD_CHANGE_VTSF:
|
case IOCTLV_WD_CHANGE_VTSF:
|
||||||
default:
|
default:
|
||||||
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_WD_UNIMPLEMENTED_IOCTL);
|
DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::USES_WD_UNIMPLEMENTED_IOCTL);
|
||||||
request.Dump(GetDeviceName(), Common::Log::LogType::IOS_NET, Common::Log::LogLevel::LWARNING);
|
request.Dump(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_NET,
|
||||||
|
Common::Log::LogLevel::LWARNING);
|
||||||
}
|
}
|
||||||
|
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
|
|
|
@ -39,7 +39,7 @@ constexpr bool IsValidMode(Mode mode)
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
class NetWDCommandDevice : public Device
|
class NetWDCommandDevice : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class ResultCode : u32
|
enum class ResultCode : u32
|
||||||
|
@ -50,7 +50,7 @@ public:
|
||||||
DriverError = 0x80008003,
|
DriverError = 0x80008003,
|
||||||
};
|
};
|
||||||
|
|
||||||
NetWDCommandDevice(Kernel& ios, const std::string& device_name);
|
NetWDCommandDevice(EmulationKernel& ios, const std::string& device_name);
|
||||||
|
|
||||||
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
||||||
std::optional<IPCReply> Close(u32 fd) override;
|
std::optional<IPCReply> Close(u32 fd) override;
|
||||||
|
|
|
@ -25,8 +25,9 @@
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
SDIOSlot0Device::SDIOSlot0Device(Kernel& ios, const std::string& device_name)
|
SDIOSlot0Device::SDIOSlot0Device(EmulationKernel& ios, const std::string& device_name)
|
||||||
: Device(ios, device_name), m_sdhc_supported(HasFeature(ios.GetVersion(), Feature::SDv2))
|
: EmulationDevice(ios, device_name),
|
||||||
|
m_sdhc_supported(HasFeature(ios.GetVersion(), Feature::SDv2))
|
||||||
{
|
{
|
||||||
if (!Config::Get(Config::MAIN_ALLOW_SD_WRITES))
|
if (!Config::Get(Config::MAIN_ALLOW_SD_WRITES))
|
||||||
INFO_LOG_FMT(IOS_SD, "Writes to SD card disabled by user");
|
INFO_LOG_FMT(IOS_SD, "Writes to SD card disabled by user");
|
||||||
|
@ -83,7 +84,7 @@ void SDIOSlot0Device::EventNotify()
|
||||||
else
|
else
|
||||||
INFO_LOG_FMT(IOS_SD, "Notifying PPC of SD card removal");
|
INFO_LOG_FMT(IOS_SD, "Notifying PPC of SD card removal");
|
||||||
|
|
||||||
m_ios.EnqueueIPCReply(m_event->request, m_event->type);
|
GetEmulationKernel().EnqueueIPCReply(m_event->request, m_event->type);
|
||||||
m_event.reset();
|
m_event.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +130,7 @@ std::optional<IPCReply> SDIOSlot0Device::Close(u32 fd)
|
||||||
|
|
||||||
std::optional<IPCReply> SDIOSlot0Device::IOCtl(const IOCtlRequest& request)
|
std::optional<IPCReply> SDIOSlot0Device::IOCtl(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.Memset(request.buffer_out, 0, request.buffer_out_size);
|
memory.Memset(request.buffer_out, 0, request.buffer_out_size);
|
||||||
|
|
||||||
|
@ -190,7 +191,7 @@ s32 SDIOSlot0Device::ExecuteCommand(const Request& request, u32 buffer_in, u32 b
|
||||||
u32 pad0;
|
u32 pad0;
|
||||||
} req;
|
} req;
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
req.command = memory.Read_U32(buffer_in + 0);
|
req.command = memory.Read_U32(buffer_in + 0);
|
||||||
|
@ -345,7 +346,7 @@ s32 SDIOSlot0Device::ExecuteCommand(const Request& request, u32 buffer_in, u32 b
|
||||||
// release returns 0
|
// release returns 0
|
||||||
// unknown sd int
|
// unknown sd int
|
||||||
// technically we do it out of order, oh well
|
// technically we do it out of order, oh well
|
||||||
m_ios.EnqueueIPCReply(m_event->request, EVENT_INVALID);
|
GetEmulationKernel().EnqueueIPCReply(m_event->request, EVENT_INVALID);
|
||||||
m_event.reset();
|
m_event.reset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -360,7 +361,7 @@ s32 SDIOSlot0Device::ExecuteCommand(const Request& request, u32 buffer_in, u32 b
|
||||||
|
|
||||||
IPCReply SDIOSlot0Device::WriteHCRegister(const IOCtlRequest& request)
|
IPCReply SDIOSlot0Device::WriteHCRegister(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u32 reg = memory.Read_U32(request.buffer_in);
|
const u32 reg = memory.Read_U32(request.buffer_in);
|
||||||
|
@ -395,7 +396,7 @@ IPCReply SDIOSlot0Device::WriteHCRegister(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply SDIOSlot0Device::ReadHCRegister(const IOCtlRequest& request)
|
IPCReply SDIOSlot0Device::ReadHCRegister(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u32 reg = memory.Read_U32(request.buffer_in);
|
const u32 reg = memory.Read_U32(request.buffer_in);
|
||||||
|
@ -418,7 +419,7 @@ IPCReply SDIOSlot0Device::ResetCard(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(IOS_SD, "IOCTL_RESETCARD");
|
INFO_LOG_FMT(IOS_SD, "IOCTL_RESETCARD");
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
// Returns 16bit RCA and 16bit 0s (meaning success)
|
// Returns 16bit RCA and 16bit 0s (meaning success)
|
||||||
|
@ -431,7 +432,7 @@ IPCReply SDIOSlot0Device::SetClk(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(IOS_SD, "IOCTL_SETCLK");
|
INFO_LOG_FMT(IOS_SD, "IOCTL_SETCLK");
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
// libogc only sets it to 1 and makes sure the return isn't negative...
|
// libogc only sets it to 1 and makes sure the return isn't negative...
|
||||||
|
@ -445,7 +446,7 @@ IPCReply SDIOSlot0Device::SetClk(const IOCtlRequest& request)
|
||||||
|
|
||||||
std::optional<IPCReply> SDIOSlot0Device::SendCommand(const IOCtlRequest& request)
|
std::optional<IPCReply> SDIOSlot0Device::SendCommand(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
INFO_LOG_FMT(IOS_SD, "IOCTL_SENDCMD {:x} IPC:{:08x}", memory.Read_U32(request.buffer_in),
|
INFO_LOG_FMT(IOS_SD, "IOCTL_SENDCMD {:x} IPC:{:08x}", memory.Read_U32(request.buffer_in),
|
||||||
|
@ -497,7 +498,7 @@ IPCReply SDIOSlot0Device::GetStatus(const IOCtlRequest& request)
|
||||||
(status & CARD_INSERTED) ? "inserted" : "not present",
|
(status & CARD_INSERTED) ? "inserted" : "not present",
|
||||||
(status & CARD_INITIALIZED) ? " and initialized" : "");
|
(status & CARD_INITIALIZED) ? " and initialized" : "");
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.Write_U32(status, request.buffer_out);
|
memory.Write_U32(status, request.buffer_out);
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
|
@ -505,7 +506,7 @@ IPCReply SDIOSlot0Device::GetStatus(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply SDIOSlot0Device::GetOCRegister(const IOCtlRequest& request)
|
IPCReply SDIOSlot0Device::GetOCRegister(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u32 ocr = GetOCRegister();
|
const u32 ocr = GetOCRegister();
|
||||||
|
@ -517,7 +518,7 @@ IPCReply SDIOSlot0Device::GetOCRegister(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply SDIOSlot0Device::SendCommand(const IOCtlVRequest& request)
|
IPCReply SDIOSlot0Device::SendCommand(const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
DEBUG_LOG_FMT(IOS_SD, "IOCTLV_SENDCMD {:#010x}", memory.Read_U32(request.in_vectors[0].address));
|
DEBUG_LOG_FMT(IOS_SD, "IOCTLV_SENDCMD {:#010x}", memory.Read_U32(request.in_vectors[0].address));
|
||||||
|
|
|
@ -18,10 +18,10 @@ class PointerWrap;
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
// The front SD slot
|
// The front SD slot
|
||||||
class SDIOSlot0Device : public Device
|
class SDIOSlot0Device : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SDIOSlot0Device(Kernel& ios, const std::string& device_name);
|
SDIOSlot0Device(EmulationKernel& ios, const std::string& device_name);
|
||||||
~SDIOSlot0Device() override;
|
~SDIOSlot0Device() override;
|
||||||
|
|
||||||
void DoState(PointerWrap& p) override;
|
void DoState(PointerWrap& p) override;
|
||||||
|
|
|
@ -18,7 +18,7 @@ static std::unique_ptr<IOCtlRequest> s_event_hook_request;
|
||||||
|
|
||||||
std::optional<IPCReply> STMImmediateDevice::IOCtl(const IOCtlRequest& request)
|
std::optional<IPCReply> STMImmediateDevice::IOCtl(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
s32 return_value = IPC_SUCCESS;
|
s32 return_value = IPC_SUCCESS;
|
||||||
|
@ -37,7 +37,7 @@ std::optional<IPCReply> STMImmediateDevice::IOCtl(const IOCtlRequest& request)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
memory.Write_U32(0, s_event_hook_request->buffer_out);
|
memory.Write_U32(0, s_event_hook_request->buffer_out);
|
||||||
m_ios.EnqueueIPCReply(*s_event_hook_request, IPC_SUCCESS);
|
GetEmulationKernel().EnqueueIPCReply(*s_event_hook_request, IPC_SUCCESS);
|
||||||
s_event_hook_request.reset();
|
s_event_hook_request.reset();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ std::optional<IPCReply> STMImmediateDevice::IOCtl(const IOCtlRequest& request)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_STM);
|
request.DumpUnknown(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_STM);
|
||||||
}
|
}
|
||||||
|
|
||||||
return IPCReply(return_value);
|
return IPCReply(return_value);
|
||||||
|
@ -79,7 +79,7 @@ std::optional<IPCReply> STMEventHookDevice::IOCtl(const IOCtlRequest& request)
|
||||||
return IPCReply(IPC_EEXIST);
|
return IPCReply(IPC_EEXIST);
|
||||||
|
|
||||||
// IOCTL_STM_EVENTHOOK waits until the reset button or power button is pressed.
|
// IOCTL_STM_EVENTHOOK waits until the reset button or power button is pressed.
|
||||||
s_event_hook_request = std::make_unique<IOCtlRequest>(request.address);
|
s_event_hook_request = std::make_unique<IOCtlRequest>(GetSystem(), request.address);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,9 +89,13 @@ void STMEventHookDevice::DoState(PointerWrap& p)
|
||||||
u32 address = s_event_hook_request ? s_event_hook_request->address : 0;
|
u32 address = s_event_hook_request ? s_event_hook_request->address : 0;
|
||||||
p.Do(address);
|
p.Do(address);
|
||||||
if (address != 0)
|
if (address != 0)
|
||||||
s_event_hook_request = std::make_unique<IOCtlRequest>(address);
|
{
|
||||||
|
s_event_hook_request = std::make_unique<IOCtlRequest>(GetSystem(), address);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
s_event_hook_request.reset();
|
s_event_hook_request.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool STMEventHookDevice::HasHookInstalled() const
|
bool STMEventHookDevice::HasHookInstalled() const
|
||||||
|
@ -105,10 +109,10 @@ void STMEventHookDevice::TriggerEvent(const u32 event) const
|
||||||
if (!m_is_active || !s_event_hook_request)
|
if (!m_is_active || !s_event_hook_request)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.Write_U32(event, s_event_hook_request->buffer_out);
|
memory.Write_U32(event, s_event_hook_request->buffer_out);
|
||||||
m_ios.EnqueueIPCReply(*s_event_hook_request, IPC_SUCCESS);
|
GetEmulationKernel().EnqueueIPCReply(*s_event_hook_request, IPC_SUCCESS);
|
||||||
s_event_hook_request.reset();
|
s_event_hook_request.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,18 +38,18 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
// The /dev/stm/immediate
|
// The /dev/stm/immediate
|
||||||
class STMImmediateDevice final : public Device
|
class STMImmediateDevice final : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Device::Device;
|
using EmulationDevice::EmulationDevice;
|
||||||
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The /dev/stm/eventhook
|
// The /dev/stm/eventhook
|
||||||
class STMEventHookDevice final : public Device
|
class STMEventHookDevice final : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Device::Device;
|
using EmulationDevice::EmulationDevice;
|
||||||
~STMEventHookDevice() override;
|
~STMEventHookDevice() override;
|
||||||
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
||||||
void DoState(PointerWrap& p) override;
|
void DoState(PointerWrap& p) override;
|
||||||
|
|
|
@ -18,10 +18,10 @@ namespace IOS::HLE
|
||||||
void BackUpBTInfoSection(const SysConf* sysconf);
|
void BackUpBTInfoSection(const SysConf* sysconf);
|
||||||
void RestoreBTInfoSection(SysConf* sysconf);
|
void RestoreBTInfoSection(SysConf* sysconf);
|
||||||
|
|
||||||
class BluetoothBaseDevice : public Device
|
class BluetoothBaseDevice : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Device::Device;
|
using EmulationDevice::EmulationDevice;
|
||||||
virtual void UpdateSyncButtonState(bool is_held) {}
|
virtual void UpdateSyncButtonState(bool is_held) {}
|
||||||
virtual void TriggerSyncButtonPressedEvent() {}
|
virtual void TriggerSyncButtonPressedEvent() {}
|
||||||
virtual void TriggerSyncButtonHeldEvent() {}
|
virtual void TriggerSyncButtonHeldEvent() {}
|
||||||
|
|
|
@ -36,7 +36,7 @@ SQueuedEvent::SQueuedEvent(u32 size_, u16 handle) : size(size_), connection_hand
|
||||||
PanicAlertFmt("SQueuedEvent: The size is too large.");
|
PanicAlertFmt("SQueuedEvent: The size is too large.");
|
||||||
}
|
}
|
||||||
|
|
||||||
BluetoothEmuDevice::BluetoothEmuDevice(Kernel& ios, const std::string& device_name)
|
BluetoothEmuDevice::BluetoothEmuDevice(EmulationKernel& ios, const std::string& device_name)
|
||||||
: BluetoothBaseDevice(ios, device_name)
|
: BluetoothBaseDevice(ios, device_name)
|
||||||
{
|
{
|
||||||
SysConf sysconf{ios.GetFS()};
|
SysConf sysconf{ios.GetFS()};
|
||||||
|
@ -81,13 +81,13 @@ BluetoothEmuDevice::BluetoothEmuDevice(Kernel& ios, const std::string& device_na
|
||||||
BluetoothEmuDevice::~BluetoothEmuDevice() = default;
|
BluetoothEmuDevice::~BluetoothEmuDevice() = default;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void DoStateForMessage(Kernel& ios, PointerWrap& p, std::unique_ptr<T>& message)
|
static void DoStateForMessage(EmulationKernel& ios, PointerWrap& p, std::unique_ptr<T>& message)
|
||||||
{
|
{
|
||||||
u32 request_address = (message != nullptr) ? message->ios_request.address : 0;
|
u32 request_address = (message != nullptr) ? message->ios_request.address : 0;
|
||||||
p.Do(request_address);
|
p.Do(request_address);
|
||||||
if (request_address != 0)
|
if (request_address != 0)
|
||||||
{
|
{
|
||||||
IOCtlVRequest request{request_address};
|
IOCtlVRequest request{ios.GetSystem(), request_address};
|
||||||
message = std::make_unique<T>(ios, request);
|
message = std::make_unique<T>(ios, request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,8 +105,8 @@ void BluetoothEmuDevice::DoState(PointerWrap& p)
|
||||||
|
|
||||||
Device::DoState(p);
|
Device::DoState(p);
|
||||||
p.Do(m_controller_bd);
|
p.Do(m_controller_bd);
|
||||||
DoStateForMessage(m_ios, p, m_hci_endpoint);
|
DoStateForMessage(GetEmulationKernel(), p, m_hci_endpoint);
|
||||||
DoStateForMessage(m_ios, p, m_acl_endpoint);
|
DoStateForMessage(GetEmulationKernel(), p, m_acl_endpoint);
|
||||||
p.Do(m_last_ticks);
|
p.Do(m_last_ticks);
|
||||||
p.DoArray(m_packet_count);
|
p.DoArray(m_packet_count);
|
||||||
p.Do(m_scan_enable);
|
p.Do(m_scan_enable);
|
||||||
|
@ -152,19 +152,19 @@ std::optional<IPCReply> BluetoothEmuDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
case USB::IOCTLV_USBV0_CTRLMSG: // HCI command is received from the stack
|
case USB::IOCTLV_USBV0_CTRLMSG: // HCI command is received from the stack
|
||||||
{
|
{
|
||||||
// Replies are generated inside
|
// Replies are generated inside
|
||||||
ExecuteHCICommandMessage(USB::V0CtrlMessage(m_ios, request));
|
ExecuteHCICommandMessage(USB::V0CtrlMessage(GetEmulationKernel(), request));
|
||||||
send_reply = false;
|
send_reply = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case USB::IOCTLV_USBV0_BLKMSG:
|
case USB::IOCTLV_USBV0_BLKMSG:
|
||||||
{
|
{
|
||||||
const USB::V0BulkMessage ctrl{m_ios, request};
|
const USB::V0BulkMessage ctrl{GetEmulationKernel(), request};
|
||||||
switch (ctrl.endpoint)
|
switch (ctrl.endpoint)
|
||||||
{
|
{
|
||||||
case ACL_DATA_OUT: // ACL data is received from the stack
|
case ACL_DATA_OUT: // ACL data is received from the stack
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
// This is the ACL datapath from CPU to Wii Remote
|
// This is the ACL datapath from CPU to Wii Remote
|
||||||
|
@ -181,7 +181,7 @@ std::optional<IPCReply> BluetoothEmuDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
}
|
}
|
||||||
case ACL_DATA_IN: // We are given an ACL buffer to fill
|
case ACL_DATA_IN: // We are given an ACL buffer to fill
|
||||||
{
|
{
|
||||||
m_acl_endpoint = std::make_unique<USB::V0BulkMessage>(m_ios, request);
|
m_acl_endpoint = std::make_unique<USB::V0BulkMessage>(GetEmulationKernel(), request);
|
||||||
DEBUG_LOG_FMT(IOS_WIIMOTE, "ACL_DATA_IN: {:#010x}", request.address);
|
DEBUG_LOG_FMT(IOS_WIIMOTE, "ACL_DATA_IN: {:#010x}", request.address);
|
||||||
send_reply = false;
|
send_reply = false;
|
||||||
break;
|
break;
|
||||||
|
@ -194,10 +194,10 @@ std::optional<IPCReply> BluetoothEmuDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
|
|
||||||
case USB::IOCTLV_USBV0_INTRMSG:
|
case USB::IOCTLV_USBV0_INTRMSG:
|
||||||
{
|
{
|
||||||
const USB::V0IntrMessage ctrl{m_ios, request};
|
const USB::V0IntrMessage ctrl{GetEmulationKernel(), request};
|
||||||
if (ctrl.endpoint == HCI_EVENT) // We are given a HCI buffer to fill
|
if (ctrl.endpoint == HCI_EVENT) // We are given a HCI buffer to fill
|
||||||
{
|
{
|
||||||
m_hci_endpoint = std::make_unique<USB::V0IntrMessage>(m_ios, request);
|
m_hci_endpoint = std::make_unique<USB::V0IntrMessage>(GetEmulationKernel(), request);
|
||||||
DEBUG_LOG_FMT(IOS_WIIMOTE, "HCI_EVENT: {:#010x}", request.address);
|
DEBUG_LOG_FMT(IOS_WIIMOTE, "HCI_EVENT: {:#010x}", request.address);
|
||||||
send_reply = false;
|
send_reply = false;
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ std::optional<IPCReply> BluetoothEmuDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_WIIMOTE);
|
request.DumpUnknown(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_WIIMOTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!send_reply)
|
if (!send_reply)
|
||||||
|
@ -247,7 +247,7 @@ void BluetoothEmuDevice::SendACLPacket(const bdaddr_t& source, const u8* data, u
|
||||||
DEBUG_LOG_FMT(IOS_WIIMOTE, "ACL endpoint valid, sending packet to {:08x}",
|
DEBUG_LOG_FMT(IOS_WIIMOTE, "ACL endpoint valid, sending packet to {:08x}",
|
||||||
m_acl_endpoint->ios_request.address);
|
m_acl_endpoint->ios_request.address);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
hci_acldata_hdr_t* header =
|
hci_acldata_hdr_t* header =
|
||||||
|
@ -258,7 +258,8 @@ void BluetoothEmuDevice::SendACLPacket(const bdaddr_t& source, const u8* data, u
|
||||||
// Write the packet to the buffer
|
// Write the packet to the buffer
|
||||||
memcpy(reinterpret_cast<u8*>(header) + sizeof(hci_acldata_hdr_t), data, header->length);
|
memcpy(reinterpret_cast<u8*>(header) + sizeof(hci_acldata_hdr_t), data, header->length);
|
||||||
|
|
||||||
m_ios.EnqueueIPCReply(m_acl_endpoint->ios_request, sizeof(hci_acldata_hdr_t) + size);
|
GetEmulationKernel().EnqueueIPCReply(m_acl_endpoint->ios_request,
|
||||||
|
sizeof(hci_acldata_hdr_t) + size);
|
||||||
m_acl_endpoint.reset();
|
m_acl_endpoint.reset();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -287,7 +288,7 @@ void BluetoothEmuDevice::AddEventToQueue(const SQueuedEvent& event)
|
||||||
m_hci_endpoint->FillBuffer(event.buffer, event.size);
|
m_hci_endpoint->FillBuffer(event.buffer, event.size);
|
||||||
|
|
||||||
// Send a reply to indicate HCI buffer is filled
|
// Send a reply to indicate HCI buffer is filled
|
||||||
m_ios.EnqueueIPCReply(m_hci_endpoint->ios_request, event.size);
|
GetEmulationKernel().EnqueueIPCReply(m_hci_endpoint->ios_request, event.size);
|
||||||
m_hci_endpoint.reset();
|
m_hci_endpoint.reset();
|
||||||
}
|
}
|
||||||
else // push new one, pop oldest
|
else // push new one, pop oldest
|
||||||
|
@ -304,7 +305,7 @@ void BluetoothEmuDevice::AddEventToQueue(const SQueuedEvent& event)
|
||||||
m_hci_endpoint->FillBuffer(queued_event.buffer, queued_event.size);
|
m_hci_endpoint->FillBuffer(queued_event.buffer, queued_event.size);
|
||||||
|
|
||||||
// Send a reply to indicate HCI buffer is filled
|
// Send a reply to indicate HCI buffer is filled
|
||||||
m_ios.EnqueueIPCReply(m_hci_endpoint->ios_request, queued_event.size);
|
GetEmulationKernel().EnqueueIPCReply(m_hci_endpoint->ios_request, queued_event.size);
|
||||||
m_hci_endpoint.reset();
|
m_hci_endpoint.reset();
|
||||||
m_event_queue.pop_front();
|
m_event_queue.pop_front();
|
||||||
}
|
}
|
||||||
|
@ -330,7 +331,7 @@ void BluetoothEmuDevice::Update()
|
||||||
m_hci_endpoint->FillBuffer(event.buffer, event.size);
|
m_hci_endpoint->FillBuffer(event.buffer, event.size);
|
||||||
|
|
||||||
// Send a reply to indicate HCI buffer is filled
|
// Send a reply to indicate HCI buffer is filled
|
||||||
m_ios.EnqueueIPCReply(m_hci_endpoint->ios_request, event.size);
|
GetEmulationKernel().EnqueueIPCReply(m_hci_endpoint->ios_request, event.size);
|
||||||
m_hci_endpoint.reset();
|
m_hci_endpoint.reset();
|
||||||
m_event_queue.pop_front();
|
m_event_queue.pop_front();
|
||||||
}
|
}
|
||||||
|
@ -346,7 +347,7 @@ void BluetoothEmuDevice::Update()
|
||||||
wiimote->Update();
|
wiimote->Update();
|
||||||
|
|
||||||
const u64 interval = SystemTimers::GetTicksPerSecond() / Wiimote::UPDATE_FREQ;
|
const u64 interval = SystemTimers::GetTicksPerSecond() / Wiimote::UPDATE_FREQ;
|
||||||
const u64 now = Core::System::GetInstance().GetCoreTiming().GetTicks();
|
const u64 now = GetSystem().GetCoreTiming().GetTicks();
|
||||||
|
|
||||||
if (now - m_last_ticks > interval)
|
if (now - m_last_ticks > interval)
|
||||||
{
|
{
|
||||||
|
@ -427,7 +428,7 @@ void BluetoothEmuDevice::ACLPool::WriteToEndpoint(const USB::V0BulkMessage& endp
|
||||||
DEBUG_LOG_FMT(IOS_WIIMOTE, "ACL packet being written from queue to {:08x}",
|
DEBUG_LOG_FMT(IOS_WIIMOTE, "ACL packet being written from queue to {:08x}",
|
||||||
endpoint.ios_request.address);
|
endpoint.ios_request.address);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = m_ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
hci_acldata_hdr_t* header = (hci_acldata_hdr_t*)memory.GetPointer(endpoint.data_address);
|
hci_acldata_hdr_t* header = (hci_acldata_hdr_t*)memory.GetPointer(endpoint.data_address);
|
||||||
|
@ -966,7 +967,7 @@ bool BluetoothEmuDevice::SendEventConPacketTypeChange(u16 connection_handle, u16
|
||||||
// This is called from the USB::IOCTLV_USBV0_CTRLMSG Ioctlv
|
// This is called from the USB::IOCTLV_USBV0_CTRLMSG Ioctlv
|
||||||
void BluetoothEmuDevice::ExecuteHCICommandMessage(const USB::V0CtrlMessage& ctrl_message)
|
void BluetoothEmuDevice::ExecuteHCICommandMessage(const USB::V0CtrlMessage& ctrl_message)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u8* input = memory.GetPointer(ctrl_message.data_address + 3);
|
const u8* input = memory.GetPointer(ctrl_message.data_address + 3);
|
||||||
|
@ -1149,7 +1150,7 @@ void BluetoothEmuDevice::ExecuteHCICommandMessage(const USB::V0CtrlMessage& ctrl
|
||||||
}
|
}
|
||||||
|
|
||||||
// HCI command is finished, send a reply to command
|
// HCI command is finished, send a reply to command
|
||||||
m_ios.EnqueueIPCReply(ctrl_message.ios_request, ctrl_message.length);
|
GetEmulationKernel().EnqueueIPCReply(ctrl_message.ios_request, ctrl_message.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -39,7 +39,7 @@ struct SQueuedEvent
|
||||||
class BluetoothEmuDevice final : public BluetoothBaseDevice
|
class BluetoothEmuDevice final : public BluetoothBaseDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BluetoothEmuDevice(Kernel& ios, const std::string& device_name);
|
BluetoothEmuDevice(EmulationKernel& ios, const std::string& device_name);
|
||||||
|
|
||||||
virtual ~BluetoothEmuDevice();
|
virtual ~BluetoothEmuDevice();
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ private:
|
||||||
class ACLPool
|
class ACLPool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ACLPool(Kernel& ios) : m_ios(ios), m_queue() {}
|
explicit ACLPool(EmulationKernel& ios) : m_ios(ios), m_queue() {}
|
||||||
void Store(const u8* data, const u16 size, const u16 conn_handle);
|
void Store(const u8* data, const u16 size, const u16 conn_handle);
|
||||||
|
|
||||||
void WriteToEndpoint(const USB::V0BulkMessage& endpoint);
|
void WriteToEndpoint(const USB::V0BulkMessage& endpoint);
|
||||||
|
@ -91,9 +91,9 @@ private:
|
||||||
u16 conn_handle;
|
u16 conn_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
Kernel& m_ios;
|
EmulationKernel& m_ios;
|
||||||
std::deque<Packet> m_queue;
|
std::deque<Packet> m_queue;
|
||||||
} m_acl_pool{m_ios};
|
} m_acl_pool{GetEmulationKernel()};
|
||||||
|
|
||||||
u32 m_packet_count[MAX_BBMOTES] = {};
|
u32 m_packet_count[MAX_BBMOTES] = {};
|
||||||
u64 m_last_ticks = 0;
|
u64 m_last_ticks = 0;
|
||||||
|
|
|
@ -60,7 +60,7 @@ static bool IsBluetoothDevice(const libusb_interface_descriptor& descriptor)
|
||||||
descriptor.bInterfaceProtocol == PROTOCOL_BLUETOOTH;
|
descriptor.bInterfaceProtocol == PROTOCOL_BLUETOOTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
BluetoothRealDevice::BluetoothRealDevice(Kernel& ios, const std::string& device_name)
|
BluetoothRealDevice::BluetoothRealDevice(EmulationKernel& ios, const std::string& device_name)
|
||||||
: BluetoothBaseDevice(ios, device_name)
|
: BluetoothBaseDevice(ios, device_name)
|
||||||
{
|
{
|
||||||
LoadLinkKeys();
|
LoadLinkKeys();
|
||||||
|
@ -214,11 +214,11 @@ std::optional<IPCReply> BluetoothRealDevice::IOCtlV(const IOCtlVRequest& request
|
||||||
// HCI commands to the Bluetooth adapter
|
// HCI commands to the Bluetooth adapter
|
||||||
case USB::IOCTLV_USBV0_CTRLMSG:
|
case USB::IOCTLV_USBV0_CTRLMSG:
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
std::lock_guard lk(m_transfers_mutex);
|
std::lock_guard lk(m_transfers_mutex);
|
||||||
auto cmd = std::make_unique<USB::V0CtrlMessage>(m_ios, request);
|
auto cmd = std::make_unique<USB::V0CtrlMessage>(GetEmulationKernel(), request);
|
||||||
const u16 opcode = Common::swap16(memory.Read_U16(cmd->data_address));
|
const u16 opcode = Common::swap16(memory.Read_U16(cmd->data_address));
|
||||||
if (opcode == HCI_CMD_READ_BUFFER_SIZE)
|
if (opcode == HCI_CMD_READ_BUFFER_SIZE)
|
||||||
{
|
{
|
||||||
|
@ -263,7 +263,7 @@ std::optional<IPCReply> BluetoothRealDevice::IOCtlV(const IOCtlVRequest& request
|
||||||
case USB::IOCTLV_USBV0_INTRMSG:
|
case USB::IOCTLV_USBV0_INTRMSG:
|
||||||
{
|
{
|
||||||
std::lock_guard lk(m_transfers_mutex);
|
std::lock_guard lk(m_transfers_mutex);
|
||||||
auto cmd = std::make_unique<USB::V0IntrMessage>(m_ios, request);
|
auto cmd = std::make_unique<USB::V0IntrMessage>(GetEmulationKernel(), request);
|
||||||
if (request.request == USB::IOCTLV_USBV0_INTRMSG)
|
if (request.request == USB::IOCTLV_USBV0_INTRMSG)
|
||||||
{
|
{
|
||||||
if (m_sync_button_state == SyncButtonState::Pressed)
|
if (m_sync_button_state == SyncButtonState::Pressed)
|
||||||
|
@ -347,8 +347,9 @@ void BluetoothRealDevice::DoState(PointerWrap& p)
|
||||||
// On load, discard any pending transfer to make sure the emulated software is not stuck
|
// On load, discard any pending transfer to make sure the emulated software is not stuck
|
||||||
// waiting for the previous request to complete. This is usually not an issue as long as
|
// 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).
|
// the Bluetooth state is the same (same Wii Remote connections).
|
||||||
|
auto& system = GetSystem();
|
||||||
for (const auto& address_to_discard : addresses_to_discard)
|
for (const auto& address_to_discard : addresses_to_discard)
|
||||||
m_ios.EnqueueIPCReply(Request{address_to_discard}, 0);
|
GetEmulationKernel().EnqueueIPCReply(Request{system, address_to_discard}, 0);
|
||||||
|
|
||||||
// Prevent the callbacks from replying to a request that has already been discarded.
|
// Prevent the callbacks from replying to a request that has already been discarded.
|
||||||
m_current_transfers.clear();
|
m_current_transfers.clear();
|
||||||
|
@ -494,7 +495,7 @@ bool BluetoothRealDevice::SendHCIStoreLinkKeyCommand()
|
||||||
|
|
||||||
void BluetoothRealDevice::FakeVendorCommandReply(USB::V0IntrMessage& ctrl)
|
void BluetoothRealDevice::FakeVendorCommandReply(USB::V0IntrMessage& ctrl)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
SHCIEventCommand hci_event;
|
SHCIEventCommand hci_event;
|
||||||
|
@ -504,7 +505,7 @@ void BluetoothRealDevice::FakeVendorCommandReply(USB::V0IntrMessage& ctrl)
|
||||||
hci_event.PacketIndicator = 0x01;
|
hci_event.PacketIndicator = 0x01;
|
||||||
hci_event.Opcode = m_fake_vendor_command_reply_opcode;
|
hci_event.Opcode = m_fake_vendor_command_reply_opcode;
|
||||||
memory.CopyToEmu(ctrl.data_address, &hci_event, sizeof(hci_event));
|
memory.CopyToEmu(ctrl.data_address, &hci_event, sizeof(hci_event));
|
||||||
m_ios.EnqueueIPCReply(ctrl.ios_request, static_cast<s32>(sizeof(hci_event)));
|
GetEmulationKernel().EnqueueIPCReply(ctrl.ios_request, static_cast<s32>(sizeof(hci_event)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Due to how the widcomm stack which Nintendo uses is coded, we must never
|
// Due to how the widcomm stack which Nintendo uses is coded, we must never
|
||||||
|
@ -514,7 +515,7 @@ void BluetoothRealDevice::FakeVendorCommandReply(USB::V0IntrMessage& ctrl)
|
||||||
// (including Wiimote disconnects and "event mismatch" warning messages).
|
// (including Wiimote disconnects and "event mismatch" warning messages).
|
||||||
void BluetoothRealDevice::FakeReadBufferSizeReply(USB::V0IntrMessage& ctrl)
|
void BluetoothRealDevice::FakeReadBufferSizeReply(USB::V0IntrMessage& ctrl)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
SHCIEventCommand hci_event;
|
SHCIEventCommand hci_event;
|
||||||
|
@ -532,13 +533,14 @@ void BluetoothRealDevice::FakeReadBufferSizeReply(USB::V0IntrMessage& ctrl)
|
||||||
reply.max_sco_size = SCO_PKT_SIZE;
|
reply.max_sco_size = SCO_PKT_SIZE;
|
||||||
reply.num_sco_pkts = SCO_PKT_NUM;
|
reply.num_sco_pkts = SCO_PKT_NUM;
|
||||||
memory.CopyToEmu(ctrl.data_address + sizeof(hci_event), &reply, sizeof(reply));
|
memory.CopyToEmu(ctrl.data_address + sizeof(hci_event), &reply, sizeof(reply));
|
||||||
m_ios.EnqueueIPCReply(ctrl.ios_request, static_cast<s32>(sizeof(hci_event) + sizeof(reply)));
|
GetEmulationKernel().EnqueueIPCReply(ctrl.ios_request,
|
||||||
|
static_cast<s32>(sizeof(hci_event) + sizeof(reply)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothRealDevice::FakeSyncButtonEvent(USB::V0IntrMessage& ctrl, const u8* payload,
|
void BluetoothRealDevice::FakeSyncButtonEvent(USB::V0IntrMessage& ctrl, const u8* payload,
|
||||||
const u8 size)
|
const u8 size)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
hci_event_hdr_t hci_event;
|
hci_event_hdr_t hci_event;
|
||||||
|
@ -547,7 +549,8 @@ void BluetoothRealDevice::FakeSyncButtonEvent(USB::V0IntrMessage& ctrl, const u8
|
||||||
hci_event.length = size;
|
hci_event.length = size;
|
||||||
memory.CopyToEmu(ctrl.data_address, &hci_event, sizeof(hci_event));
|
memory.CopyToEmu(ctrl.data_address, &hci_event, sizeof(hci_event));
|
||||||
memory.CopyToEmu(ctrl.data_address + sizeof(hci_event), payload, size);
|
memory.CopyToEmu(ctrl.data_address + sizeof(hci_event), payload, size);
|
||||||
m_ios.EnqueueIPCReply(ctrl.ios_request, static_cast<s32>(sizeof(hci_event) + size));
|
GetEmulationKernel().EnqueueIPCReply(ctrl.ios_request,
|
||||||
|
static_cast<s32>(sizeof(hci_event) + size));
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the red sync button is pressed, a HCI event is generated:
|
// When the red sync button is pressed, a HCI event is generated:
|
||||||
|
@ -694,7 +697,8 @@ void BluetoothRealDevice::HandleCtrlTransfer(libusb_transfer* tr)
|
||||||
}
|
}
|
||||||
const auto& command = m_current_transfers.at(tr).command;
|
const auto& command = m_current_transfers.at(tr).command;
|
||||||
command->FillBuffer(libusb_control_transfer_get_data(tr), tr->actual_length);
|
command->FillBuffer(libusb_control_transfer_get_data(tr), tr->actual_length);
|
||||||
m_ios.EnqueueIPCReply(command->ios_request, tr->actual_length, 0, CoreTiming::FromThread::ANY);
|
GetEmulationKernel().EnqueueIPCReply(command->ios_request, tr->actual_length, 0,
|
||||||
|
CoreTiming::FromThread::ANY);
|
||||||
m_current_transfers.erase(tr);
|
m_current_transfers.erase(tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -743,7 +747,8 @@ void BluetoothRealDevice::HandleBulkOrIntrTransfer(libusb_transfer* tr)
|
||||||
|
|
||||||
const auto& command = m_current_transfers.at(tr).command;
|
const auto& command = m_current_transfers.at(tr).command;
|
||||||
command->FillBuffer(tr->buffer, tr->actual_length);
|
command->FillBuffer(tr->buffer, tr->actual_length);
|
||||||
m_ios.EnqueueIPCReply(command->ios_request, tr->actual_length, 0, CoreTiming::FromThread::ANY);
|
GetEmulationKernel().EnqueueIPCReply(command->ios_request, tr->actual_length, 0,
|
||||||
|
CoreTiming::FromThread::ANY);
|
||||||
m_current_transfers.erase(tr);
|
m_current_transfers.erase(tr);
|
||||||
}
|
}
|
||||||
} // namespace IOS::HLE
|
} // namespace IOS::HLE
|
||||||
|
|
|
@ -42,7 +42,7 @@ using linkkey_t = std::array<u8, 16>;
|
||||||
class BluetoothRealDevice final : public BluetoothBaseDevice
|
class BluetoothRealDevice final : public BluetoothBaseDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BluetoothRealDevice(Kernel& ios, const std::string& device_name);
|
BluetoothRealDevice(EmulationKernel& ios, const std::string& device_name);
|
||||||
~BluetoothRealDevice() override;
|
~BluetoothRealDevice() override;
|
||||||
|
|
||||||
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
||||||
|
|
|
@ -19,7 +19,7 @@ std::unique_ptr<u8[]> TransferCommand::MakeBuffer(const size_t size) const
|
||||||
{
|
{
|
||||||
ASSERT_MSG(IOS_USB, data_address != 0, "Invalid data_address");
|
ASSERT_MSG(IOS_USB, data_address != 0, "Invalid data_address");
|
||||||
auto buffer = std::make_unique<u8[]>(size);
|
auto buffer = std::make_unique<u8[]>(size);
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = m_ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.CopyFromEmu(buffer.get(), data_address, size);
|
memory.CopyFromEmu(buffer.get(), data_address, size);
|
||||||
return buffer;
|
return buffer;
|
||||||
|
@ -28,7 +28,7 @@ std::unique_ptr<u8[]> TransferCommand::MakeBuffer(const size_t size) const
|
||||||
void TransferCommand::FillBuffer(const u8* src, const size_t size) const
|
void TransferCommand::FillBuffer(const u8* src, const size_t size) const
|
||||||
{
|
{
|
||||||
ASSERT_MSG(IOS_USB, size == 0 || data_address != 0, "Invalid data_address");
|
ASSERT_MSG(IOS_USB, size == 0 || data_address != 0, "Invalid data_address");
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = m_ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.CopyToEmu(data_address, src, size);
|
memory.CopyToEmu(data_address, src, size);
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ void TransferCommand::ScheduleTransferCompletion(s32 return_value, u32 expected_
|
||||||
|
|
||||||
void IsoMessage::SetPacketReturnValue(const size_t packet_num, const u16 return_value) const
|
void IsoMessage::SetPacketReturnValue(const size_t packet_num, const u16 return_value) const
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = m_ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.Write_U16(return_value, static_cast<u32>(packet_sizes_addr + packet_num * sizeof(u16)));
|
memory.Write_U16(return_value, static_cast<u32>(packet_sizes_addr + packet_num * sizeof(u16)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ struct TransferCommand
|
||||||
Request ios_request;
|
Request ios_request;
|
||||||
u32 data_address = 0;
|
u32 data_address = 0;
|
||||||
|
|
||||||
TransferCommand(Kernel& ios, const Request& ios_request_, u32 data_address_)
|
TransferCommand(EmulationKernel& ios, const Request& ios_request_, u32 data_address_)
|
||||||
: ios_request(ios_request_), data_address(data_address_), m_ios(ios)
|
: ios_request(ios_request_), data_address(data_address_), m_ios(ios)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -113,8 +113,8 @@ struct TransferCommand
|
||||||
std::unique_ptr<u8[]> MakeBuffer(size_t size) const;
|
std::unique_ptr<u8[]> MakeBuffer(size_t size) const;
|
||||||
void FillBuffer(const u8* src, size_t size) const;
|
void FillBuffer(const u8* src, size_t size) const;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
Kernel& m_ios;
|
EmulationKernel& m_ios;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CtrlMessage : TransferCommand
|
struct CtrlMessage : TransferCommand
|
||||||
|
|
|
@ -471,7 +471,7 @@ const std::map<const std::pair<const u16, const u16>, const char*> list_skylande
|
||||||
{{3503, 0x0000}, "Kaos Trophy"},
|
{{3503, 0x0000}, "Kaos Trophy"},
|
||||||
};
|
};
|
||||||
|
|
||||||
SkylanderUSB::SkylanderUSB(Kernel& ios, const std::string& device_name) : m_ios(ios)
|
SkylanderUSB::SkylanderUSB(EmulationKernel& ios, const std::string& device_name) : m_ios(ios)
|
||||||
{
|
{
|
||||||
m_vid = 0x1430;
|
m_vid = 0x1430;
|
||||||
m_pid = 0x150;
|
m_pid = 0x150;
|
||||||
|
@ -600,7 +600,7 @@ int SkylanderUSB::SubmitTransfer(std::unique_ptr<CtrlMessage> cmd)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Skylander Portal Requests
|
// Skylander Portal Requests
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = m_ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
u8* buf = memory.GetPointerForRange(cmd->data_address, cmd->length);
|
u8* buf = memory.GetPointerForRange(cmd->data_address, cmd->length);
|
||||||
if (cmd->length == 0 || buf == nullptr)
|
if (cmd->length == 0 || buf == nullptr)
|
||||||
|
@ -892,7 +892,7 @@ int SkylanderUSB::SubmitTransfer(std::unique_ptr<IntrMessage> cmd)
|
||||||
DEBUG_LOG_FMT(IOS_USB, "[{:04x}:{:04x} {}] Interrupt: length={} endpoint={}", m_vid, m_pid,
|
DEBUG_LOG_FMT(IOS_USB, "[{:04x}:{:04x} {}] Interrupt: length={} endpoint={}", m_vid, m_pid,
|
||||||
m_active_interface, cmd->length, cmd->endpoint);
|
m_active_interface, cmd->length, cmd->endpoint);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = m_ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
u8* buf = memory.GetPointerForRange(cmd->data_address, cmd->length);
|
u8* buf = memory.GetPointerForRange(cmd->data_address, cmd->length);
|
||||||
if (cmd->length == 0 || buf == nullptr)
|
if (cmd->length == 0 || buf == nullptr)
|
||||||
|
|
|
@ -23,7 +23,7 @@ extern const std::map<const std::pair<const u16, const u16>, const char*> list_s
|
||||||
class SkylanderUSB final : public Device
|
class SkylanderUSB final : public Device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SkylanderUSB(Kernel& ios, const std::string& device_name);
|
SkylanderUSB(EmulationKernel& ios, const std::string& device_name);
|
||||||
~SkylanderUSB();
|
~SkylanderUSB();
|
||||||
DeviceDescriptor GetDeviceDescriptor() const override;
|
DeviceDescriptor GetDeviceDescriptor() const override;
|
||||||
std::vector<ConfigDescriptor> GetConfigurations() const override;
|
std::vector<ConfigDescriptor> GetConfigurations() const override;
|
||||||
|
@ -43,7 +43,7 @@ public:
|
||||||
s32 expected_count, u64 expected_time_us);
|
s32 expected_count, u64 expected_time_us);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Kernel& m_ios;
|
EmulationKernel& m_ios;
|
||||||
u16 m_vid = 0;
|
u16 m_vid = 0;
|
||||||
u16 m_pid = 0;
|
u16 m_pid = 0;
|
||||||
u8 m_active_interface = 0;
|
u8 m_active_interface = 0;
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
USBHost::USBHost(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
|
USBHost::USBHost(EmulationKernel& ios, const std::string& device_name)
|
||||||
|
: EmulationDevice(ios, device_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +138,8 @@ bool USBHost::AddNewDevices(std::set<u64>& new_devices, DeviceChangeHooks& hooks
|
||||||
if (whitelist.count({descriptor.idVendor, descriptor.idProduct}) == 0)
|
if (whitelist.count({descriptor.idVendor, descriptor.idProduct}) == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto usb_device = std::make_unique<USB::LibusbDevice>(m_ios, device, descriptor);
|
auto usb_device =
|
||||||
|
std::make_unique<USB::LibusbDevice>(GetEmulationKernel(), device, descriptor);
|
||||||
if (!ShouldAddDevice(*usb_device))
|
if (!ShouldAddDevice(*usb_device))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -190,7 +192,8 @@ void USBHost::AddEmulatedDevices(std::set<u64>& new_devices, DeviceChangeHooks&
|
||||||
{
|
{
|
||||||
if (Config::Get(Config::MAIN_EMULATE_SKYLANDER_PORTAL) && !NetPlay::IsNetPlayRunning())
|
if (Config::Get(Config::MAIN_EMULATE_SKYLANDER_PORTAL) && !NetPlay::IsNetPlayRunning())
|
||||||
{
|
{
|
||||||
auto skylanderportal = std::make_unique<USB::SkylanderUSB>(m_ios, "Skylander Portal");
|
auto skylanderportal =
|
||||||
|
std::make_unique<USB::SkylanderUSB>(GetEmulationKernel(), "Skylander Portal");
|
||||||
if (ShouldAddDevice(*skylanderportal))
|
if (ShouldAddDevice(*skylanderportal))
|
||||||
{
|
{
|
||||||
const u64 skyid = skylanderportal->GetId();
|
const u64 skyid = skylanderportal->GetId();
|
||||||
|
|
|
@ -26,10 +26,10 @@ class PointerWrap;
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
// Common base class for USB host devices (such as /dev/usb/oh0 and /dev/usb/ven).
|
// Common base class for USB host devices (such as /dev/usb/oh0 and /dev/usb/ven).
|
||||||
class USBHost : public Device
|
class USBHost : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
USBHost(Kernel& ios, const std::string& device_name);
|
USBHost(EmulationKernel& ios, const std::string& device_name);
|
||||||
virtual ~USBHost();
|
virtual ~USBHost();
|
||||||
|
|
||||||
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
namespace IOS::HLE::USB
|
namespace IOS::HLE::USB
|
||||||
{
|
{
|
||||||
LibusbDevice::LibusbDevice(Kernel& ios, libusb_device* device,
|
LibusbDevice::LibusbDevice(EmulationKernel& ios, libusb_device* device,
|
||||||
const libusb_device_descriptor& descriptor)
|
const libusb_device_descriptor& descriptor)
|
||||||
: m_ios(ios), m_device(device)
|
: m_ios(ios), m_device(device)
|
||||||
{
|
{
|
||||||
|
@ -249,7 +249,7 @@ int LibusbDevice::SubmitTransfer(std::unique_ptr<CtrlMessage> cmd)
|
||||||
libusb_fill_control_setup(buffer.get(), cmd->request_type, cmd->request, cmd->value, cmd->index,
|
libusb_fill_control_setup(buffer.get(), cmd->request_type, cmd->request, cmd->value, cmd->index,
|
||||||
cmd->length);
|
cmd->length);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = m_ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.CopyFromEmu(buffer.get() + LIBUSB_CONTROL_SETUP_SIZE, cmd->data_address, cmd->length);
|
memory.CopyFromEmu(buffer.get() + LIBUSB_CONTROL_SETUP_SIZE, cmd->data_address, cmd->length);
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace IOS::HLE::USB
|
||||||
class LibusbDevice final : public Device
|
class LibusbDevice final : public Device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LibusbDevice(Kernel& ios, libusb_device* device,
|
LibusbDevice(EmulationKernel& ios, libusb_device* device,
|
||||||
const libusb_device_descriptor& device_descriptor);
|
const libusb_device_descriptor& device_descriptor);
|
||||||
~LibusbDevice();
|
~LibusbDevice();
|
||||||
DeviceDescriptor GetDeviceDescriptor() const override;
|
DeviceDescriptor GetDeviceDescriptor() const override;
|
||||||
|
@ -46,7 +46,7 @@ public:
|
||||||
int SubmitTransfer(std::unique_ptr<IsoMessage> message) override;
|
int SubmitTransfer(std::unique_ptr<IsoMessage> message) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Kernel& m_ios;
|
EmulationKernel& m_ios;
|
||||||
|
|
||||||
std::vector<LibusbUtils::ConfigDescriptor> m_config_descriptors;
|
std::vector<LibusbUtils::ConfigDescriptor> m_config_descriptors;
|
||||||
u16 m_vid = 0;
|
u16 m_vid = 0;
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
OH0::OH0(Kernel& ios, const std::string& device_name) : USBHost(ios, device_name)
|
OH0::OH0(EmulationKernel& ios, const std::string& device_name) : USBHost(ios, device_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ IPCReply OH0::CancelInsertionHook(const IOCtlRequest& request)
|
||||||
if (!request.buffer_in || request.buffer_in_size != 4)
|
if (!request.buffer_in || request.buffer_in_size != 4)
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
// IOS assigns random IDs, but ours are simply the VID + PID (see RegisterInsertionHookWithID)
|
// IOS assigns random IDs, but ours are simply the VID + PID (see RegisterInsertionHookWithID)
|
||||||
|
@ -108,7 +108,7 @@ IPCReply OH0::GetDeviceList(const IOCtlVRequest& request) const
|
||||||
if (!request.HasNumberOfValidVectors(2, 2))
|
if (!request.HasNumberOfValidVectors(2, 2))
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u8 max_entries_count = memory.Read_U8(request.in_vectors[0].address);
|
const u8 max_entries_count = memory.Read_U8(request.in_vectors[0].address);
|
||||||
|
@ -140,12 +140,13 @@ IPCReply OH0::GetRhDesca(const IOCtlRequest& request) const
|
||||||
if (!request.buffer_out || request.buffer_out_size != 4)
|
if (!request.buffer_out || request.buffer_out_size != 4)
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
// Based on a hardware test, this ioctl seems to return a constant value
|
// Based on a hardware test, this ioctl seems to return a constant value
|
||||||
memory.Write_U32(0x02000302, request.buffer_out);
|
memory.Write_U32(0x02000302, request.buffer_out);
|
||||||
request.Dump(GetDeviceName(), Common::Log::LogType::IOS_USB, Common::Log::LogLevel::LWARNING);
|
request.Dump(system, GetDeviceName(), Common::Log::LogType::IOS_USB,
|
||||||
|
Common::Log::LogLevel::LWARNING);
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +156,8 @@ IPCReply OH0::GetRhPortStatus(const IOCtlVRequest& request) const
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
ERROR_LOG_FMT(IOS_USB, "Unimplemented IOCtlV: IOCTLV_USBV0_GETRHPORTSTATUS");
|
ERROR_LOG_FMT(IOS_USB, "Unimplemented IOCtlV: IOCTLV_USBV0_GETRHPORTSTATUS");
|
||||||
request.Dump(GetDeviceName(), Common::Log::LogType::IOS_USB, Common::Log::LogLevel::LERROR);
|
request.Dump(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_USB,
|
||||||
|
Common::Log::LogLevel::LERROR);
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +167,8 @@ IPCReply OH0::SetRhPortStatus(const IOCtlVRequest& request)
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
ERROR_LOG_FMT(IOS_USB, "Unimplemented IOCtlV: IOCTLV_USBV0_SETRHPORTSTATUS");
|
ERROR_LOG_FMT(IOS_USB, "Unimplemented IOCtlV: IOCTLV_USBV0_SETRHPORTSTATUS");
|
||||||
request.Dump(GetDeviceName(), Common::Log::LogType::IOS_USB, Common::Log::LogLevel::LERROR);
|
request.Dump(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_USB,
|
||||||
|
Common::Log::LogLevel::LERROR);
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +187,7 @@ std::optional<IPCReply> OH0::RegisterInsertionHook(const IOCtlVRequest& request)
|
||||||
if (!request.HasNumberOfValidVectors(2, 0))
|
if (!request.HasNumberOfValidVectors(2, 0))
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u16 vid = memory.Read_U16(request.in_vectors[0].address);
|
const u16 vid = memory.Read_U16(request.in_vectors[0].address);
|
||||||
|
@ -203,7 +206,7 @@ std::optional<IPCReply> OH0::RegisterInsertionHookWithID(const IOCtlVRequest& re
|
||||||
if (!request.HasNumberOfValidVectors(3, 1))
|
if (!request.HasNumberOfValidVectors(3, 1))
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
std::lock_guard lock{m_hooks_mutex};
|
std::lock_guard lock{m_hooks_mutex};
|
||||||
|
@ -224,7 +227,8 @@ std::optional<IPCReply> OH0::RegisterClassChangeHook(const IOCtlVRequest& reques
|
||||||
if (!request.HasNumberOfValidVectors(1, 0))
|
if (!request.HasNumberOfValidVectors(1, 0))
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
WARN_LOG_FMT(IOS_USB, "Unimplemented IOCtlV: USB::IOCTLV_USBV0_DEVICECLASSCHANGE (no reply)");
|
WARN_LOG_FMT(IOS_USB, "Unimplemented IOCtlV: USB::IOCTLV_USBV0_DEVICECLASSCHANGE (no reply)");
|
||||||
request.Dump(GetDeviceName(), Common::Log::LogType::IOS_USB, Common::Log::LogLevel::LWARNING);
|
request.Dump(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_USB,
|
||||||
|
Common::Log::LogLevel::LWARNING);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +255,8 @@ void OH0::TriggerHook(std::map<T, u32>& hooks, T value, const ReturnCode return_
|
||||||
const auto hook = hooks.find(value);
|
const auto hook = hooks.find(value);
|
||||||
if (hook == hooks.end())
|
if (hook == hooks.end())
|
||||||
return;
|
return;
|
||||||
m_ios.EnqueueIPCReply(Request{hook->second}, return_value, 0, CoreTiming::FromThread::ANY);
|
GetEmulationKernel().EnqueueIPCReply(Request{GetSystem(), hook->second}, return_value, 0,
|
||||||
|
CoreTiming::FromThread::ANY);
|
||||||
hooks.erase(hook);
|
hooks.erase(hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,7 +328,7 @@ std::optional<IPCReply> OH0::DeviceIOCtlV(const u64 device_id, const IOCtlVReque
|
||||||
return HandleTransfer(device, request.request,
|
return HandleTransfer(device, request.request,
|
||||||
[&, this]() { return SubmitTransfer(*device, request); });
|
[&, this]() { return SubmitTransfer(*device, request); });
|
||||||
case USB::IOCTLV_USBV0_UNKNOWN_32:
|
case USB::IOCTLV_USBV0_UNKNOWN_32:
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_USB);
|
request.DumpUnknown(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_USB);
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
default:
|
default:
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
@ -332,7 +337,7 @@ std::optional<IPCReply> OH0::DeviceIOCtlV(const u64 device_id, const IOCtlVReque
|
||||||
|
|
||||||
s32 OH0::SubmitTransfer(USB::Device& device, const IOCtlVRequest& ioctlv)
|
s32 OH0::SubmitTransfer(USB::Device& device, const IOCtlVRequest& ioctlv)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
switch (ioctlv.request)
|
switch (ioctlv.request)
|
||||||
|
@ -341,7 +346,8 @@ s32 OH0::SubmitTransfer(USB::Device& device, const IOCtlVRequest& ioctlv)
|
||||||
if (!ioctlv.HasNumberOfValidVectors(6, 1) ||
|
if (!ioctlv.HasNumberOfValidVectors(6, 1) ||
|
||||||
Common::swap16(memory.Read_U16(ioctlv.in_vectors[4].address)) != ioctlv.io_vectors[0].size)
|
Common::swap16(memory.Read_U16(ioctlv.in_vectors[4].address)) != ioctlv.io_vectors[0].size)
|
||||||
return IPC_EINVAL;
|
return IPC_EINVAL;
|
||||||
return device.SubmitTransfer(std::make_unique<USB::V0CtrlMessage>(m_ios, ioctlv));
|
return device.SubmitTransfer(
|
||||||
|
std::make_unique<USB::V0CtrlMessage>(GetEmulationKernel(), ioctlv));
|
||||||
|
|
||||||
case USB::IOCTLV_USBV0_BLKMSG:
|
case USB::IOCTLV_USBV0_BLKMSG:
|
||||||
case USB::IOCTLV_USBV0_LBLKMSG:
|
case USB::IOCTLV_USBV0_LBLKMSG:
|
||||||
|
@ -349,18 +355,19 @@ s32 OH0::SubmitTransfer(USB::Device& device, const IOCtlVRequest& ioctlv)
|
||||||
memory.Read_U16(ioctlv.in_vectors[1].address) != ioctlv.io_vectors[0].size)
|
memory.Read_U16(ioctlv.in_vectors[1].address) != ioctlv.io_vectors[0].size)
|
||||||
return IPC_EINVAL;
|
return IPC_EINVAL;
|
||||||
return device.SubmitTransfer(std::make_unique<USB::V0BulkMessage>(
|
return device.SubmitTransfer(std::make_unique<USB::V0BulkMessage>(
|
||||||
m_ios, ioctlv, ioctlv.request == USB::IOCTLV_USBV0_LBLKMSG));
|
GetEmulationKernel(), ioctlv, ioctlv.request == USB::IOCTLV_USBV0_LBLKMSG));
|
||||||
|
|
||||||
case USB::IOCTLV_USBV0_INTRMSG:
|
case USB::IOCTLV_USBV0_INTRMSG:
|
||||||
if (!ioctlv.HasNumberOfValidVectors(2, 1) ||
|
if (!ioctlv.HasNumberOfValidVectors(2, 1) ||
|
||||||
memory.Read_U16(ioctlv.in_vectors[1].address) != ioctlv.io_vectors[0].size)
|
memory.Read_U16(ioctlv.in_vectors[1].address) != ioctlv.io_vectors[0].size)
|
||||||
return IPC_EINVAL;
|
return IPC_EINVAL;
|
||||||
return device.SubmitTransfer(std::make_unique<USB::V0IntrMessage>(m_ios, ioctlv));
|
return device.SubmitTransfer(
|
||||||
|
std::make_unique<USB::V0IntrMessage>(GetEmulationKernel(), ioctlv));
|
||||||
|
|
||||||
case USB::IOCTLV_USBV0_ISOMSG:
|
case USB::IOCTLV_USBV0_ISOMSG:
|
||||||
if (!ioctlv.HasNumberOfValidVectors(3, 2))
|
if (!ioctlv.HasNumberOfValidVectors(3, 2))
|
||||||
return IPC_EINVAL;
|
return IPC_EINVAL;
|
||||||
return device.SubmitTransfer(std::make_unique<USB::V0IsoMessage>(m_ios, ioctlv));
|
return device.SubmitTransfer(std::make_unique<USB::V0IsoMessage>(GetEmulationKernel(), ioctlv));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return IPC_EINVAL;
|
return IPC_EINVAL;
|
||||||
|
|
|
@ -33,7 +33,7 @@ struct DeviceInfo
|
||||||
class OH0 final : public USBHost
|
class OH0 final : public USBHost
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OH0(Kernel& ios, const std::string& device_name);
|
OH0(EmulationKernel& ios, const std::string& device_name);
|
||||||
~OH0() override;
|
~OH0() override;
|
||||||
|
|
||||||
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
||||||
|
|
|
@ -35,7 +35,8 @@ static void GetVidPidFromDevicePath(const std::string& device_path, u16& vid, u1
|
||||||
ss >> pid;
|
ss >> pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
OH0Device::OH0Device(Kernel& ios, const std::string& name) : Device(ios, name, DeviceType::OH0)
|
OH0Device::OH0Device(EmulationKernel& ios, const std::string& name)
|
||||||
|
: EmulationDevice(ios, name, DeviceType::OH0)
|
||||||
{
|
{
|
||||||
if (!name.empty())
|
if (!name.empty())
|
||||||
GetVidPidFromDevicePath(name, m_vid, m_pid);
|
GetVidPidFromDevicePath(name, m_vid, m_pid);
|
||||||
|
@ -43,7 +44,7 @@ OH0Device::OH0Device(Kernel& ios, const std::string& name) : Device(ios, name, D
|
||||||
|
|
||||||
void OH0Device::DoState(PointerWrap& p)
|
void OH0Device::DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
m_oh0 = std::static_pointer_cast<OH0>(GetIOS()->GetDeviceByName("/dev/usb/oh0"));
|
m_oh0 = std::static_pointer_cast<OH0>(GetEmulationKernel().GetDeviceByName("/dev/usb/oh0"));
|
||||||
Device::DoState(p);
|
Device::DoState(p);
|
||||||
p.Do(m_vid);
|
p.Do(m_vid);
|
||||||
p.Do(m_pid);
|
p.Do(m_pid);
|
||||||
|
@ -55,7 +56,7 @@ std::optional<IPCReply> OH0Device::Open(const OpenRequest& request)
|
||||||
if (m_vid == 0 && m_pid == 0)
|
if (m_vid == 0 && m_pid == 0)
|
||||||
return IPCReply(IPC_ENOENT);
|
return IPCReply(IPC_ENOENT);
|
||||||
|
|
||||||
m_oh0 = std::static_pointer_cast<OH0>(GetIOS()->GetDeviceByName("/dev/usb/oh0"));
|
m_oh0 = std::static_pointer_cast<OH0>(GetEmulationKernel().GetDeviceByName("/dev/usb/oh0"));
|
||||||
|
|
||||||
ReturnCode return_code;
|
ReturnCode return_code;
|
||||||
std::tie(return_code, m_device_id) = m_oh0->DeviceOpen(m_vid, m_pid);
|
std::tie(return_code, m_device_id) = m_oh0->DeviceOpen(m_vid, m_pid);
|
||||||
|
|
|
@ -14,10 +14,10 @@ class PointerWrap;
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
class OH0;
|
class OH0;
|
||||||
class OH0Device final : public Device
|
class OH0Device final : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OH0Device(Kernel& ios, const std::string& device_name);
|
OH0Device(EmulationKernel& ios, const std::string& device_name);
|
||||||
|
|
||||||
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
||||||
std::optional<IPCReply> Close(u32 fd) override;
|
std::optional<IPCReply> Close(u32 fd) override;
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
|
|
||||||
namespace IOS::HLE::USB
|
namespace IOS::HLE::USB
|
||||||
{
|
{
|
||||||
V0CtrlMessage::V0CtrlMessage(Kernel& ios, const IOCtlVRequest& ioctlv)
|
V0CtrlMessage::V0CtrlMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv)
|
||||||
: CtrlMessage(ios, ioctlv, ioctlv.io_vectors[0].address)
|
: CtrlMessage(ios, ioctlv, ioctlv.io_vectors[0].address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
request_type = memory.Read_U8(ioctlv.in_vectors[0].address);
|
request_type = memory.Read_U8(ioctlv.in_vectors[0].address);
|
||||||
request = memory.Read_U8(ioctlv.in_vectors[1].address);
|
request = memory.Read_U8(ioctlv.in_vectors[1].address);
|
||||||
|
@ -25,10 +25,10 @@ V0CtrlMessage::V0CtrlMessage(Kernel& ios, const IOCtlVRequest& ioctlv)
|
||||||
length = Common::swap16(memory.Read_U16(ioctlv.in_vectors[4].address));
|
length = Common::swap16(memory.Read_U16(ioctlv.in_vectors[4].address));
|
||||||
}
|
}
|
||||||
|
|
||||||
V0BulkMessage::V0BulkMessage(Kernel& ios, const IOCtlVRequest& ioctlv, bool long_length)
|
V0BulkMessage::V0BulkMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv, bool long_length)
|
||||||
: BulkMessage(ios, ioctlv, ioctlv.io_vectors[0].address)
|
: BulkMessage(ios, ioctlv, ioctlv.io_vectors[0].address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
endpoint = memory.Read_U8(ioctlv.in_vectors[0].address);
|
endpoint = memory.Read_U8(ioctlv.in_vectors[0].address);
|
||||||
if (long_length)
|
if (long_length)
|
||||||
|
@ -37,19 +37,19 @@ V0BulkMessage::V0BulkMessage(Kernel& ios, const IOCtlVRequest& ioctlv, bool long
|
||||||
length = memory.Read_U16(ioctlv.in_vectors[1].address);
|
length = memory.Read_U16(ioctlv.in_vectors[1].address);
|
||||||
}
|
}
|
||||||
|
|
||||||
V0IntrMessage::V0IntrMessage(Kernel& ios, const IOCtlVRequest& ioctlv)
|
V0IntrMessage::V0IntrMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv)
|
||||||
: IntrMessage(ios, ioctlv, ioctlv.io_vectors[0].address)
|
: IntrMessage(ios, ioctlv, ioctlv.io_vectors[0].address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
endpoint = memory.Read_U8(ioctlv.in_vectors[0].address);
|
endpoint = memory.Read_U8(ioctlv.in_vectors[0].address);
|
||||||
length = memory.Read_U16(ioctlv.in_vectors[1].address);
|
length = memory.Read_U16(ioctlv.in_vectors[1].address);
|
||||||
}
|
}
|
||||||
|
|
||||||
V0IsoMessage::V0IsoMessage(Kernel& ios, const IOCtlVRequest& ioctlv)
|
V0IsoMessage::V0IsoMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv)
|
||||||
: IsoMessage(ios, ioctlv, ioctlv.io_vectors[1].address)
|
: IsoMessage(ios, ioctlv, ioctlv.io_vectors[1].address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
endpoint = memory.Read_U8(ioctlv.in_vectors[0].address);
|
endpoint = memory.Read_U8(ioctlv.in_vectors[0].address);
|
||||||
length = memory.Read_U16(ioctlv.in_vectors[1].address);
|
length = memory.Read_U16(ioctlv.in_vectors[1].address);
|
||||||
|
|
|
@ -38,22 +38,22 @@ enum V0Requests
|
||||||
|
|
||||||
struct V0CtrlMessage final : CtrlMessage
|
struct V0CtrlMessage final : CtrlMessage
|
||||||
{
|
{
|
||||||
V0CtrlMessage(Kernel& ios, const IOCtlVRequest& ioctlv);
|
V0CtrlMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct V0BulkMessage final : BulkMessage
|
struct V0BulkMessage final : BulkMessage
|
||||||
{
|
{
|
||||||
V0BulkMessage(Kernel& ios, const IOCtlVRequest& ioctlv, bool long_length = false);
|
V0BulkMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv, bool long_length = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct V0IntrMessage final : IntrMessage
|
struct V0IntrMessage final : IntrMessage
|
||||||
{
|
{
|
||||||
V0IntrMessage(Kernel& ios, const IOCtlVRequest& ioctlv);
|
V0IntrMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct V0IsoMessage final : IsoMessage
|
struct V0IsoMessage final : IsoMessage
|
||||||
{
|
{
|
||||||
V0IsoMessage(Kernel& ios, const IOCtlVRequest& ioctlv);
|
V0IsoMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv);
|
||||||
};
|
};
|
||||||
} // namespace USB
|
} // namespace USB
|
||||||
} // namespace IOS::HLE
|
} // namespace IOS::HLE
|
||||||
|
|
|
@ -46,9 +46,10 @@ struct HIDRequest
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
V4CtrlMessage::V4CtrlMessage(Kernel& ios, const IOCtlRequest& ioctl) : CtrlMessage(ios, ioctl, 0)
|
V4CtrlMessage::V4CtrlMessage(EmulationKernel& ios, const IOCtlRequest& ioctl)
|
||||||
|
: CtrlMessage(ios, ioctl, 0)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
HIDRequest hid_request;
|
HIDRequest hid_request;
|
||||||
|
@ -64,10 +65,10 @@ V4CtrlMessage::V4CtrlMessage(Kernel& ios, const IOCtlRequest& ioctl) : CtrlMessa
|
||||||
// Since this is just a standard control request, but with additional requirements
|
// Since this is just a standard control request, but with additional requirements
|
||||||
// (US for the language and replacing non-ASCII characters with '?'),
|
// (US for the language and replacing non-ASCII characters with '?'),
|
||||||
// we can simply submit it as a usual control request.
|
// we can simply submit it as a usual control request.
|
||||||
V4GetUSStringMessage::V4GetUSStringMessage(Kernel& ios, const IOCtlRequest& ioctl)
|
V4GetUSStringMessage::V4GetUSStringMessage(EmulationKernel& ios, const IOCtlRequest& ioctl)
|
||||||
: CtrlMessage(ios, ioctl, 0)
|
: CtrlMessage(ios, ioctl, 0)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
HIDRequest hid_request;
|
HIDRequest hid_request;
|
||||||
|
@ -82,7 +83,7 @@ V4GetUSStringMessage::V4GetUSStringMessage(Kernel& ios, const IOCtlRequest& ioct
|
||||||
|
|
||||||
void V4GetUSStringMessage::OnTransferComplete(s32 return_value) const
|
void V4GetUSStringMessage::OnTransferComplete(s32 return_value) const
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = m_ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
std::string message = memory.GetString(data_address);
|
std::string message = memory.GetString(data_address);
|
||||||
|
@ -91,9 +92,10 @@ void V4GetUSStringMessage::OnTransferComplete(s32 return_value) const
|
||||||
TransferCommand::OnTransferComplete(return_value);
|
TransferCommand::OnTransferComplete(return_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
V4IntrMessage::V4IntrMessage(Kernel& ios, const IOCtlRequest& ioctl) : IntrMessage(ios, ioctl, 0)
|
V4IntrMessage::V4IntrMessage(EmulationKernel& ios, const IOCtlRequest& ioctl)
|
||||||
|
: IntrMessage(ios, ioctl, 0)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
HIDRequest hid_request;
|
HIDRequest hid_request;
|
||||||
|
|
|
@ -29,18 +29,18 @@ enum V4Requests
|
||||||
|
|
||||||
struct V4CtrlMessage final : CtrlMessage
|
struct V4CtrlMessage final : CtrlMessage
|
||||||
{
|
{
|
||||||
V4CtrlMessage(Kernel& ios, const IOCtlRequest& ioctl);
|
V4CtrlMessage(EmulationKernel& ios, const IOCtlRequest& ioctl);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct V4GetUSStringMessage final : CtrlMessage
|
struct V4GetUSStringMessage final : CtrlMessage
|
||||||
{
|
{
|
||||||
V4GetUSStringMessage(Kernel& ios, const IOCtlRequest& ioctl);
|
V4GetUSStringMessage(EmulationKernel& ios, const IOCtlRequest& ioctl);
|
||||||
void OnTransferComplete(s32 return_value) const override;
|
void OnTransferComplete(s32 return_value) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct V4IntrMessage final : IntrMessage
|
struct V4IntrMessage final : IntrMessage
|
||||||
{
|
{
|
||||||
V4IntrMessage(Kernel& ios, const IOCtlRequest& ioctl);
|
V4IntrMessage(EmulationKernel& ios, const IOCtlRequest& ioctl);
|
||||||
};
|
};
|
||||||
} // namespace USB
|
} // namespace USB
|
||||||
} // namespace IOS::HLE
|
} // namespace IOS::HLE
|
||||||
|
|
|
@ -19,10 +19,10 @@ namespace IOS::HLE
|
||||||
{
|
{
|
||||||
namespace USB
|
namespace USB
|
||||||
{
|
{
|
||||||
V5CtrlMessage::V5CtrlMessage(Kernel& ios, const IOCtlVRequest& ioctlv)
|
V5CtrlMessage::V5CtrlMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv)
|
||||||
: CtrlMessage(ios, ioctlv, ioctlv.GetVector(1)->address)
|
: CtrlMessage(ios, ioctlv, ioctlv.GetVector(1)->address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
request_type = memory.Read_U8(ioctlv.in_vectors[0].address + 8);
|
request_type = memory.Read_U8(ioctlv.in_vectors[0].address + 8);
|
||||||
request = memory.Read_U8(ioctlv.in_vectors[0].address + 9);
|
request = memory.Read_U8(ioctlv.in_vectors[0].address + 9);
|
||||||
|
@ -31,28 +31,28 @@ V5CtrlMessage::V5CtrlMessage(Kernel& ios, const IOCtlVRequest& ioctlv)
|
||||||
length = static_cast<u16>(ioctlv.GetVector(1)->size);
|
length = static_cast<u16>(ioctlv.GetVector(1)->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
V5BulkMessage::V5BulkMessage(Kernel& ios, const IOCtlVRequest& ioctlv)
|
V5BulkMessage::V5BulkMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv)
|
||||||
: BulkMessage(ios, ioctlv, ioctlv.GetVector(1)->address)
|
: BulkMessage(ios, ioctlv, ioctlv.GetVector(1)->address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
length = ioctlv.GetVector(1)->size;
|
length = ioctlv.GetVector(1)->size;
|
||||||
endpoint = memory.Read_U8(ioctlv.in_vectors[0].address + 18);
|
endpoint = memory.Read_U8(ioctlv.in_vectors[0].address + 18);
|
||||||
}
|
}
|
||||||
|
|
||||||
V5IntrMessage::V5IntrMessage(Kernel& ios, const IOCtlVRequest& ioctlv)
|
V5IntrMessage::V5IntrMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv)
|
||||||
: IntrMessage(ios, ioctlv, ioctlv.GetVector(1)->address)
|
: IntrMessage(ios, ioctlv, ioctlv.GetVector(1)->address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
length = ioctlv.GetVector(1)->size;
|
length = ioctlv.GetVector(1)->size;
|
||||||
endpoint = memory.Read_U8(ioctlv.in_vectors[0].address + 14);
|
endpoint = memory.Read_U8(ioctlv.in_vectors[0].address + 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
V5IsoMessage::V5IsoMessage(Kernel& ios, const IOCtlVRequest& ioctlv)
|
V5IsoMessage::V5IsoMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv)
|
||||||
: IsoMessage(ios, ioctlv, ioctlv.GetVector(2)->address)
|
: IsoMessage(ios, ioctlv, ioctlv.GetVector(2)->address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = ios.GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
num_packets = memory.Read_U8(ioctlv.in_vectors[0].address + 16);
|
num_packets = memory.Read_U8(ioctlv.in_vectors[0].address + 16);
|
||||||
endpoint = memory.Read_U8(ioctlv.in_vectors[0].address + 17);
|
endpoint = memory.Read_U8(ioctlv.in_vectors[0].address + 17);
|
||||||
|
@ -98,9 +98,13 @@ void USBV5ResourceManager::DoState(PointerWrap& p)
|
||||||
u32 hook_address = m_devicechange_hook_request ? m_devicechange_hook_request->address : 0;
|
u32 hook_address = m_devicechange_hook_request ? m_devicechange_hook_request->address : 0;
|
||||||
p.Do(hook_address);
|
p.Do(hook_address);
|
||||||
if (hook_address != 0)
|
if (hook_address != 0)
|
||||||
m_devicechange_hook_request = std::make_unique<IOCtlRequest>(hook_address);
|
{
|
||||||
|
m_devicechange_hook_request = std::make_unique<IOCtlRequest>(GetSystem(), hook_address);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
m_devicechange_hook_request.reset();
|
m_devicechange_hook_request.reset();
|
||||||
|
}
|
||||||
|
|
||||||
p.Do(m_usbv5_devices);
|
p.Do(m_usbv5_devices);
|
||||||
USBHost::DoState(p);
|
USBHost::DoState(p);
|
||||||
|
@ -108,7 +112,7 @@ void USBV5ResourceManager::DoState(PointerWrap& p)
|
||||||
|
|
||||||
USBV5ResourceManager::USBV5Device* USBV5ResourceManager::GetUSBV5Device(u32 in_buffer)
|
USBV5ResourceManager::USBV5Device* USBV5ResourceManager::GetUSBV5Device(u32 in_buffer)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
const u8 index = memory.Read_U8(in_buffer + offsetof(DeviceID, index));
|
const u8 index = memory.Read_U8(in_buffer + offsetof(DeviceID, index));
|
||||||
const u16 number = memory.Read_U16(in_buffer + offsetof(DeviceID, number));
|
const u16 number = memory.Read_U16(in_buffer + offsetof(DeviceID, number));
|
||||||
|
@ -129,7 +133,7 @@ std::optional<IPCReply> USBV5ResourceManager::GetDeviceChange(const IOCtlRequest
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
std::lock_guard lk{m_devicechange_hook_address_mutex};
|
std::lock_guard lk{m_devicechange_hook_address_mutex};
|
||||||
m_devicechange_hook_request = std::make_unique<IOCtlRequest>(request.address);
|
m_devicechange_hook_request = std::make_unique<IOCtlRequest>(GetSystem(), request.address);
|
||||||
// If there are pending changes, the reply is sent immediately (instead of on device
|
// If there are pending changes, the reply is sent immediately (instead of on device
|
||||||
// insertion/removal).
|
// insertion/removal).
|
||||||
if (m_has_pending_changes)
|
if (m_has_pending_changes)
|
||||||
|
@ -146,7 +150,7 @@ IPCReply USBV5ResourceManager::SetAlternateSetting(USBV5Device& device, const IO
|
||||||
if (!host_device->AttachAndChangeInterface(device.interface_number))
|
if (!host_device->AttachAndChangeInterface(device.interface_number))
|
||||||
return IPCReply(-1);
|
return IPCReply(-1);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
const u8 alt_setting = memory.Read_U8(request.buffer_in + 2 * sizeof(s32));
|
const u8 alt_setting = memory.Read_U8(request.buffer_in + 2 * sizeof(s32));
|
||||||
|
|
||||||
|
@ -165,7 +169,7 @@ IPCReply USBV5ResourceManager::Shutdown(const IOCtlRequest& request)
|
||||||
std::lock_guard lk{m_devicechange_hook_address_mutex};
|
std::lock_guard lk{m_devicechange_hook_address_mutex};
|
||||||
if (m_devicechange_hook_request)
|
if (m_devicechange_hook_request)
|
||||||
{
|
{
|
||||||
m_ios.EnqueueIPCReply(*m_devicechange_hook_request, IPC_SUCCESS);
|
GetEmulationKernel().EnqueueIPCReply(*m_devicechange_hook_request, IPC_SUCCESS);
|
||||||
m_devicechange_hook_request.reset();
|
m_devicechange_hook_request.reset();
|
||||||
}
|
}
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
|
@ -173,7 +177,7 @@ IPCReply USBV5ResourceManager::Shutdown(const IOCtlRequest& request)
|
||||||
|
|
||||||
IPCReply USBV5ResourceManager::SuspendResume(USBV5Device& device, const IOCtlRequest& request)
|
IPCReply USBV5ResourceManager::SuspendResume(USBV5Device& device, const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const auto host_device = GetDeviceById(device.host_id);
|
const auto host_device = GetDeviceById(device.host_id);
|
||||||
|
@ -248,7 +252,7 @@ void USBV5ResourceManager::TriggerDeviceChangeReply()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
std::lock_guard lock{m_usbv5_devices_mutex};
|
std::lock_guard lock{m_usbv5_devices_mutex};
|
||||||
|
@ -288,7 +292,8 @@ void USBV5ResourceManager::TriggerDeviceChangeReply()
|
||||||
++num_devices;
|
++num_devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ios.EnqueueIPCReply(*m_devicechange_hook_request, num_devices, 0, CoreTiming::FromThread::ANY);
|
GetEmulationKernel().EnqueueIPCReply(*m_devicechange_hook_request, num_devices, 0,
|
||||||
|
CoreTiming::FromThread::ANY);
|
||||||
m_devicechange_hook_request.reset();
|
m_devicechange_hook_request.reset();
|
||||||
INFO_LOG_FMT(IOS_USB, "{} USBv5 device(s), including interfaces", num_devices);
|
INFO_LOG_FMT(IOS_USB, "{} USBv5 device(s), including interfaces", num_devices);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,22 +43,22 @@ enum V5Requests
|
||||||
|
|
||||||
struct V5CtrlMessage final : CtrlMessage
|
struct V5CtrlMessage final : CtrlMessage
|
||||||
{
|
{
|
||||||
V5CtrlMessage(Kernel& ios, const IOCtlVRequest& ioctlv);
|
V5CtrlMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct V5BulkMessage final : BulkMessage
|
struct V5BulkMessage final : BulkMessage
|
||||||
{
|
{
|
||||||
V5BulkMessage(Kernel& ios, const IOCtlVRequest& ioctlv);
|
V5BulkMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct V5IntrMessage final : IntrMessage
|
struct V5IntrMessage final : IntrMessage
|
||||||
{
|
{
|
||||||
V5IntrMessage(Kernel& ios, const IOCtlVRequest& ioctlv);
|
V5IntrMessage(EmulationKernel& ios, const IOCtlVRequest& ioctlv);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct V5IsoMessage final : IsoMessage
|
struct V5IsoMessage final : IsoMessage
|
||||||
{
|
{
|
||||||
V5IsoMessage(Kernel& ios, const IOCtlVRequest& cmd_buffer);
|
V5IsoMessage(EmulationKernel& ios, const IOCtlVRequest& cmd_buffer);
|
||||||
};
|
};
|
||||||
} // namespace USB
|
} // namespace USB
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
USB_HIDv4::USB_HIDv4(Kernel& ios, const std::string& device_name) : USBHost(ios, device_name)
|
USB_HIDv4::USB_HIDv4(EmulationKernel& ios, const std::string& device_name)
|
||||||
|
: USBHost(ios, device_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ USB_HIDv4::~USB_HIDv4()
|
||||||
|
|
||||||
std::optional<IPCReply> USB_HIDv4::IOCtl(const IOCtlRequest& request)
|
std::optional<IPCReply> USB_HIDv4::IOCtl(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
request.Log(GetDeviceName(), Common::Log::LogType::IOS_USB);
|
request.Log(GetDeviceName(), Common::Log::LogType::IOS_USB);
|
||||||
|
@ -64,7 +65,7 @@ std::optional<IPCReply> USB_HIDv4::IOCtl(const IOCtlRequest& request)
|
||||||
[&, this]() { return SubmitTransfer(*device, request); });
|
[&, this]() { return SubmitTransfer(*device, request); });
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_USB);
|
request.DumpUnknown(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_USB);
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +75,7 @@ IPCReply USB_HIDv4::CancelInterrupt(const IOCtlRequest& request)
|
||||||
if (request.buffer_in == 0 || request.buffer_in_size != 8)
|
if (request.buffer_in == 0 || request.buffer_in_size != 8)
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
auto device = GetDeviceByIOSID(memory.Read_U32(request.buffer_in));
|
auto device = GetDeviceByIOSID(memory.Read_U32(request.buffer_in));
|
||||||
|
@ -90,7 +91,7 @@ std::optional<IPCReply> USB_HIDv4::GetDeviceChange(const IOCtlRequest& request)
|
||||||
if (request.buffer_out == 0 || request.buffer_out_size != 0x600)
|
if (request.buffer_out == 0 || request.buffer_out_size != 0x600)
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
m_devicechange_hook_request = std::make_unique<IOCtlRequest>(request.address);
|
m_devicechange_hook_request = std::make_unique<IOCtlRequest>(GetSystem(), request.address);
|
||||||
// On the first call, the reply is sent immediately (instead of on device insertion/removal)
|
// On the first call, the reply is sent immediately (instead of on device insertion/removal)
|
||||||
if (m_devicechange_first_call)
|
if (m_devicechange_first_call)
|
||||||
{
|
{
|
||||||
|
@ -105,10 +106,10 @@ IPCReply USB_HIDv4::Shutdown(const IOCtlRequest& request)
|
||||||
std::lock_guard lk{m_devicechange_hook_address_mutex};
|
std::lock_guard lk{m_devicechange_hook_address_mutex};
|
||||||
if (m_devicechange_hook_request != nullptr)
|
if (m_devicechange_hook_request != nullptr)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.Write_U32(0xffffffff, m_devicechange_hook_request->buffer_out);
|
memory.Write_U32(0xffffffff, m_devicechange_hook_request->buffer_out);
|
||||||
m_ios.EnqueueIPCReply(*m_devicechange_hook_request, -1);
|
GetEmulationKernel().EnqueueIPCReply(*m_devicechange_hook_request, -1);
|
||||||
m_devicechange_hook_request.reset();
|
m_devicechange_hook_request.reset();
|
||||||
}
|
}
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
|
@ -119,12 +120,15 @@ s32 USB_HIDv4::SubmitTransfer(USB::Device& device, const IOCtlRequest& request)
|
||||||
switch (request.request)
|
switch (request.request)
|
||||||
{
|
{
|
||||||
case USB::IOCTL_USBV4_CTRLMSG:
|
case USB::IOCTL_USBV4_CTRLMSG:
|
||||||
return device.SubmitTransfer(std::make_unique<USB::V4CtrlMessage>(m_ios, request));
|
return device.SubmitTransfer(
|
||||||
|
std::make_unique<USB::V4CtrlMessage>(GetEmulationKernel(), request));
|
||||||
case USB::IOCTL_USBV4_GET_US_STRING:
|
case USB::IOCTL_USBV4_GET_US_STRING:
|
||||||
return device.SubmitTransfer(std::make_unique<USB::V4GetUSStringMessage>(m_ios, request));
|
return device.SubmitTransfer(
|
||||||
|
std::make_unique<USB::V4GetUSStringMessage>(GetEmulationKernel(), request));
|
||||||
case USB::IOCTL_USBV4_INTRMSG_IN:
|
case USB::IOCTL_USBV4_INTRMSG_IN:
|
||||||
case USB::IOCTL_USBV4_INTRMSG_OUT:
|
case USB::IOCTL_USBV4_INTRMSG_OUT:
|
||||||
return device.SubmitTransfer(std::make_unique<USB::V4IntrMessage>(m_ios, request));
|
return device.SubmitTransfer(
|
||||||
|
std::make_unique<USB::V4IntrMessage>(GetEmulationKernel(), request));
|
||||||
default:
|
default:
|
||||||
return IPC_EINVAL;
|
return IPC_EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -136,9 +140,13 @@ void USB_HIDv4::DoState(PointerWrap& p)
|
||||||
u32 hook_address = m_devicechange_hook_request ? m_devicechange_hook_request->address : 0;
|
u32 hook_address = m_devicechange_hook_request ? m_devicechange_hook_request->address : 0;
|
||||||
p.Do(hook_address);
|
p.Do(hook_address);
|
||||||
if (hook_address != 0)
|
if (hook_address != 0)
|
||||||
m_devicechange_hook_request = std::make_unique<IOCtlRequest>(hook_address);
|
{
|
||||||
|
m_devicechange_hook_request = std::make_unique<IOCtlRequest>(GetSystem(), hook_address);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
m_devicechange_hook_request.reset();
|
m_devicechange_hook_request.reset();
|
||||||
|
}
|
||||||
|
|
||||||
p.Do(m_ios_ids);
|
p.Do(m_ios_ids);
|
||||||
p.Do(m_device_ids);
|
p.Do(m_device_ids);
|
||||||
|
@ -191,7 +199,7 @@ void USB_HIDv4::TriggerDeviceChangeReply()
|
||||||
if (!m_devicechange_hook_request)
|
if (!m_devicechange_hook_request)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -213,7 +221,8 @@ void USB_HIDv4::TriggerDeviceChangeReply()
|
||||||
memory.Write_U32(0xffffffff, dest + offset);
|
memory.Write_U32(0xffffffff, dest + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ios.EnqueueIPCReply(*m_devicechange_hook_request, IPC_SUCCESS, 0, CoreTiming::FromThread::ANY);
|
GetEmulationKernel().EnqueueIPCReply(*m_devicechange_hook_request, IPC_SUCCESS, 0,
|
||||||
|
CoreTiming::FromThread::ANY);
|
||||||
m_devicechange_hook_request.reset();
|
m_devicechange_hook_request.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace IOS::HLE
|
||||||
class USB_HIDv4 final : public USBHost
|
class USB_HIDv4 final : public USBHost
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
USB_HIDv4(Kernel& ios, const std::string& device_name);
|
USB_HIDv4(EmulationKernel& ios, const std::string& device_name);
|
||||||
~USB_HIDv4() override;
|
~USB_HIDv4() override;
|
||||||
|
|
||||||
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
||||||
|
|
|
@ -25,7 +25,7 @@ USB_HIDv5::~USB_HIDv5()
|
||||||
|
|
||||||
std::optional<IPCReply> USB_HIDv5::IOCtl(const IOCtlRequest& request)
|
std::optional<IPCReply> USB_HIDv5::IOCtl(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
request.Log(GetDeviceName(), Common::Log::LogType::IOS_USB);
|
request.Log(GetDeviceName(), Common::Log::LogType::IOS_USB);
|
||||||
|
@ -50,7 +50,7 @@ std::optional<IPCReply> USB_HIDv5::IOCtl(const IOCtlRequest& request)
|
||||||
return HandleDeviceIOCtl(request,
|
return HandleDeviceIOCtl(request,
|
||||||
[&](USBV5Device& device) { return CancelEndpoint(device, request); });
|
[&](USBV5Device& device) { return CancelEndpoint(device, request); });
|
||||||
default:
|
default:
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_USB,
|
request.DumpUnknown(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_USB,
|
||||||
Common::Log::LogLevel::LERROR);
|
Common::Log::LogLevel::LERROR);
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,6 @@ std::optional<IPCReply> USB_HIDv5::IOCtl(const IOCtlRequest& request)
|
||||||
|
|
||||||
std::optional<IPCReply> USB_HIDv5::IOCtlV(const IOCtlVRequest& request)
|
std::optional<IPCReply> USB_HIDv5::IOCtlV(const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_USB);
|
|
||||||
switch (request.request)
|
switch (request.request)
|
||||||
{
|
{
|
||||||
// TODO: HIDv5 seems to be able to queue transfers depending on the transfer length (unlike VEN).
|
// TODO: HIDv5 seems to be able to queue transfers depending on the transfer length (unlike VEN).
|
||||||
|
@ -82,6 +81,7 @@ std::optional<IPCReply> USB_HIDv5::IOCtlV(const IOCtlVRequest& request)
|
||||||
[&, this]() { return SubmitTransfer(*device, *host_device, request); });
|
[&, this]() { return SubmitTransfer(*device, *host_device, request); });
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
request.DumpUnknown(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_USB);
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,12 +92,13 @@ s32 USB_HIDv5::SubmitTransfer(USBV5Device& device, USB::Device& host_device,
|
||||||
switch (ioctlv.request)
|
switch (ioctlv.request)
|
||||||
{
|
{
|
||||||
case USB::IOCTLV_USBV5_CTRLMSG:
|
case USB::IOCTLV_USBV5_CTRLMSG:
|
||||||
return host_device.SubmitTransfer(std::make_unique<USB::V5CtrlMessage>(m_ios, ioctlv));
|
return host_device.SubmitTransfer(
|
||||||
|
std::make_unique<USB::V5CtrlMessage>(GetEmulationKernel(), ioctlv));
|
||||||
case USB::IOCTLV_USBV5_INTRMSG:
|
case USB::IOCTLV_USBV5_INTRMSG:
|
||||||
{
|
{
|
||||||
auto message = std::make_unique<USB::V5IntrMessage>(m_ios, ioctlv);
|
auto message = std::make_unique<USB::V5IntrMessage>(GetEmulationKernel(), ioctlv);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
// Unlike VEN, the endpoint is determined by the value at 8-12.
|
// Unlike VEN, the endpoint is determined by the value at 8-12.
|
||||||
|
@ -118,7 +119,7 @@ s32 USB_HIDv5::SubmitTransfer(USBV5Device& device, USB::Device& host_device,
|
||||||
|
|
||||||
IPCReply USB_HIDv5::CancelEndpoint(USBV5Device& device, const IOCtlRequest& request)
|
IPCReply USB_HIDv5::CancelEndpoint(USBV5Device& device, const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u8 value = memory.Read_U8(request.buffer_in + 8);
|
const u8 value = memory.Read_U8(request.buffer_in + 8);
|
||||||
|
@ -148,7 +149,7 @@ IPCReply USB_HIDv5::GetDeviceInfo(USBV5Device& device, const IOCtlRequest& reque
|
||||||
if (request.buffer_out == 0 || request.buffer_out_size != 0x60)
|
if (request.buffer_out == 0 || request.buffer_out_size != 0x60)
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const std::shared_ptr<USB::Device> host_device = GetDeviceById(device.host_id);
|
const std::shared_ptr<USB::Device> host_device = GetDeviceById(device.host_id);
|
||||||
|
|
|
@ -184,7 +184,8 @@ USB_KBD::MessageData::MessageData(MessageType type, u8 modifiers_, PressedKeyDat
|
||||||
|
|
||||||
// TODO: support in netplay/movies.
|
// TODO: support in netplay/movies.
|
||||||
|
|
||||||
USB_KBD::USB_KBD(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
|
USB_KBD::USB_KBD(EmulationKernel& ios, const std::string& device_name)
|
||||||
|
: EmulationDevice(ios, device_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +215,7 @@ std::optional<IPCReply> USB_KBD::IOCtl(const IOCtlRequest& request)
|
||||||
if (Config::Get(Config::MAIN_WII_KEYBOARD) && !Core::WantsDeterminism() &&
|
if (Config::Get(Config::MAIN_WII_KEYBOARD) && !Core::WantsDeterminism() &&
|
||||||
ControlReference::GetInputGate() && !m_message_queue.empty())
|
ControlReference::GetInputGate() && !m_message_queue.empty())
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
memory.CopyToEmu(request.buffer_out, &m_message_queue.front(), sizeof(MessageData));
|
memory.CopyToEmu(request.buffer_out, &m_message_queue.front(), sizeof(MessageData));
|
||||||
m_message_queue.pop();
|
m_message_queue.pop();
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
class USB_KBD : public Device
|
class USB_KBD : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
USB_KBD(Kernel& ios, const std::string& device_name);
|
USB_KBD(EmulationKernel& ios, const std::string& device_name);
|
||||||
|
|
||||||
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
std::optional<IPCReply> Open(const OpenRequest& request) override;
|
||||||
std::optional<IPCReply> Write(const ReadWriteRequest& request) override;
|
std::optional<IPCReply> Write(const ReadWriteRequest& request) override;
|
||||||
|
|
|
@ -25,7 +25,7 @@ USB_VEN::~USB_VEN()
|
||||||
|
|
||||||
std::optional<IPCReply> USB_VEN::IOCtl(const IOCtlRequest& request)
|
std::optional<IPCReply> USB_VEN::IOCtl(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
request.Log(GetDeviceName(), Common::Log::LogType::IOS_USB);
|
request.Log(GetDeviceName(), Common::Log::LogType::IOS_USB);
|
||||||
|
@ -53,7 +53,7 @@ std::optional<IPCReply> USB_VEN::IOCtl(const IOCtlRequest& request)
|
||||||
return HandleDeviceIOCtl(request,
|
return HandleDeviceIOCtl(request,
|
||||||
[&](USBV5Device& device) { return CancelEndpoint(device, request); });
|
[&](USBV5Device& device) { return CancelEndpoint(device, request); });
|
||||||
default:
|
default:
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_USB,
|
request.DumpUnknown(GetSystem(), GetDeviceName(), Common::Log::LogType::IOS_USB,
|
||||||
Common::Log::LogLevel::LERROR);
|
Common::Log::LogLevel::LERROR);
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -100,13 +100,16 @@ s32 USB_VEN::SubmitTransfer(USB::Device& device, const IOCtlVRequest& ioctlv)
|
||||||
switch (ioctlv.request)
|
switch (ioctlv.request)
|
||||||
{
|
{
|
||||||
case USB::IOCTLV_USBV5_CTRLMSG:
|
case USB::IOCTLV_USBV5_CTRLMSG:
|
||||||
return device.SubmitTransfer(std::make_unique<USB::V5CtrlMessage>(m_ios, ioctlv));
|
return device.SubmitTransfer(
|
||||||
|
std::make_unique<USB::V5CtrlMessage>(GetEmulationKernel(), ioctlv));
|
||||||
case USB::IOCTLV_USBV5_INTRMSG:
|
case USB::IOCTLV_USBV5_INTRMSG:
|
||||||
return device.SubmitTransfer(std::make_unique<USB::V5IntrMessage>(m_ios, ioctlv));
|
return device.SubmitTransfer(
|
||||||
|
std::make_unique<USB::V5IntrMessage>(GetEmulationKernel(), ioctlv));
|
||||||
case USB::IOCTLV_USBV5_BULKMSG:
|
case USB::IOCTLV_USBV5_BULKMSG:
|
||||||
return device.SubmitTransfer(std::make_unique<USB::V5BulkMessage>(m_ios, ioctlv));
|
return device.SubmitTransfer(
|
||||||
|
std::make_unique<USB::V5BulkMessage>(GetEmulationKernel(), ioctlv));
|
||||||
case USB::IOCTLV_USBV5_ISOMSG:
|
case USB::IOCTLV_USBV5_ISOMSG:
|
||||||
return device.SubmitTransfer(std::make_unique<USB::V5IsoMessage>(m_ios, ioctlv));
|
return device.SubmitTransfer(std::make_unique<USB::V5IsoMessage>(GetEmulationKernel(), ioctlv));
|
||||||
default:
|
default:
|
||||||
return IPC_EINVAL;
|
return IPC_EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -114,7 +117,7 @@ s32 USB_VEN::SubmitTransfer(USB::Device& device, const IOCtlVRequest& ioctlv)
|
||||||
|
|
||||||
IPCReply USB_VEN::CancelEndpoint(USBV5Device& device, const IOCtlRequest& request)
|
IPCReply USB_VEN::CancelEndpoint(USBV5Device& device, const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const u8 endpoint = memory.Read_U8(request.buffer_in + 8);
|
const u8 endpoint = memory.Read_U8(request.buffer_in + 8);
|
||||||
|
@ -129,7 +132,7 @@ IPCReply USB_VEN::GetDeviceInfo(USBV5Device& device, const IOCtlRequest& request
|
||||||
if (request.buffer_out == 0 || request.buffer_out_size != 0xc0)
|
if (request.buffer_out == 0 || request.buffer_out_size != 0xc0)
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
const std::shared_ptr<USB::Device> host_device = GetDeviceById(device.host_id);
|
const std::shared_ptr<USB::Device> host_device = GetDeviceById(device.host_id);
|
||||||
|
|
|
@ -94,7 +94,8 @@ void ARCUnpacker::Extract(const WriteCallback& callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WFSIDevice::WFSIDevice(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
|
WFSIDevice::WFSIDevice(EmulationKernel& ios, const std::string& device_name)
|
||||||
|
: EmulationDevice(ios, device_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ std::optional<IPCReply> WFSIDevice::IOCtl(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
s32 return_error_code = IPC_SUCCESS;
|
s32 return_error_code = IPC_SUCCESS;
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
switch (request.request)
|
switch (request.request)
|
||||||
|
@ -351,7 +352,7 @@ std::optional<IPCReply> WFSIDevice::IOCtl(const IOCtlRequest& request)
|
||||||
return_error_code = -3;
|
return_error_code = -3;
|
||||||
if (homedir_path_len > 0x1FD)
|
if (homedir_path_len > 0x1FD)
|
||||||
break;
|
break;
|
||||||
auto device = GetIOS()->GetDeviceByName("/dev/usb/wfssrv");
|
auto device = GetEmulationKernel().GetDeviceByName("/dev/usb/wfssrv");
|
||||||
if (!device)
|
if (!device)
|
||||||
break;
|
break;
|
||||||
std::static_pointer_cast<WFSSRVDevice>(device)->SetHomeDir(homedir_path);
|
std::static_pointer_cast<WFSSRVDevice>(device)->SetHomeDir(homedir_path);
|
||||||
|
@ -384,14 +385,14 @@ std::optional<IPCReply> WFSIDevice::IOCtl(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(IOS_WFS, "IOCTL_WFSI_INIT");
|
INFO_LOG_FMT(IOS_WFS, "IOCTL_WFSI_INIT");
|
||||||
u64 tid;
|
u64 tid;
|
||||||
if (GetIOS()->GetES()->GetTitleId(&tid) < 0)
|
if (GetEmulationKernel().GetES()->GetTitleId(&tid) < 0)
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(IOS_WFS, "IOCTL_WFSI_INIT: Could not get title id.");
|
ERROR_LOG_FMT(IOS_WFS, "IOCTL_WFSI_INIT: Could not get title id.");
|
||||||
return_error_code = IPC_EINVAL;
|
return_error_code = IPC_EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ES::TMDReader tmd = GetIOS()->GetES()->FindInstalledTMD(tid);
|
const ES::TMDReader tmd = GetEmulationKernel().GetES()->FindInstalledTMD(tid);
|
||||||
SetCurrentTitleIdAndGroupId(tmd.GetTitleId(), tmd.GetGroupId());
|
SetCurrentTitleIdAndGroupId(tmd.GetTitleId(), tmd.GetGroupId());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -543,7 +544,7 @@ std::optional<IPCReply> WFSIDevice::IOCtl(const IOCtlRequest& request)
|
||||||
// TODO(wfs): Should be returning an error. However until we have
|
// TODO(wfs): Should be returning an error. However until we have
|
||||||
// everything properly stubbed it's easier to simulate the methods
|
// everything properly stubbed it's easier to simulate the methods
|
||||||
// succeeding.
|
// succeeding.
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_WFS,
|
request.DumpUnknown(system, GetDeviceName(), Common::Log::LogType::IOS_WFS,
|
||||||
Common::Log::LogLevel::LWARNING);
|
Common::Log::LogLevel::LWARNING);
|
||||||
memory.Memset(request.buffer_out, 0, request.buffer_out_size);
|
memory.Memset(request.buffer_out, 0, request.buffer_out_size);
|
||||||
break;
|
break;
|
||||||
|
@ -564,7 +565,7 @@ u32 WFSIDevice::GetTmd(u16 group_id, u32 title_id, u64 subtitle_id, u32 address,
|
||||||
}
|
}
|
||||||
if (address)
|
if (address)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
fp.ReadBytes(memory.GetPointer(address), fp.GetSize());
|
fp.ReadBytes(memory.GetPointer(address), fp.GetSize());
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,10 +31,10 @@ private:
|
||||||
std::vector<u8> m_whole_file;
|
std::vector<u8> m_whole_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WFSIDevice : public Device
|
class WFSIDevice : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WFSIDevice(Kernel& ios, const std::string& device_name);
|
WFSIDevice(EmulationKernel& ios, const std::string& device_name);
|
||||||
|
|
||||||
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,8 @@ std::string NativePath(const std::string& wfs_path)
|
||||||
}
|
}
|
||||||
} // namespace WFS
|
} // namespace WFS
|
||||||
|
|
||||||
WFSSRVDevice::WFSSRVDevice(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
|
WFSSRVDevice::WFSSRVDevice(EmulationKernel& ios, const std::string& device_name)
|
||||||
|
: EmulationDevice(ios, device_name)
|
||||||
{
|
{
|
||||||
m_device_name = "msc01";
|
m_device_name = "msc01";
|
||||||
}
|
}
|
||||||
|
@ -34,7 +35,7 @@ std::optional<IPCReply> WFSSRVDevice::IOCtl(const IOCtlRequest& request)
|
||||||
{
|
{
|
||||||
int return_error_code = IPC_SUCCESS;
|
int return_error_code = IPC_SUCCESS;
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = GetSystem();
|
||||||
auto& memory = system.GetMemory();
|
auto& memory = system.GetMemory();
|
||||||
|
|
||||||
switch (request.request)
|
switch (request.request)
|
||||||
|
@ -57,11 +58,11 @@ std::optional<IPCReply> WFSSRVDevice::IOCtl(const IOCtlRequest& request)
|
||||||
// Close all hanging attach/detach ioctls with an appropriate error code.
|
// Close all hanging attach/detach ioctls with an appropriate error code.
|
||||||
for (auto address : m_hanging)
|
for (auto address : m_hanging)
|
||||||
{
|
{
|
||||||
IOCtlRequest hanging_request{address};
|
IOCtlRequest hanging_request{system, address};
|
||||||
memory.Write_U32(0x80000000, hanging_request.buffer_out);
|
memory.Write_U32(0x80000000, hanging_request.buffer_out);
|
||||||
memory.Write_U32(0, hanging_request.buffer_out + 4);
|
memory.Write_U32(0, hanging_request.buffer_out + 4);
|
||||||
memory.Write_U32(0, hanging_request.buffer_out + 8);
|
memory.Write_U32(0, hanging_request.buffer_out + 8);
|
||||||
m_ios.EnqueueIPCReply(hanging_request, 0);
|
GetEmulationKernel().EnqueueIPCReply(hanging_request, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -355,7 +356,7 @@ std::optional<IPCReply> WFSSRVDevice::IOCtl(const IOCtlRequest& request)
|
||||||
default:
|
default:
|
||||||
// TODO(wfs): Should be returning -3. However until we have everything
|
// TODO(wfs): Should be returning -3. However until we have everything
|
||||||
// properly stubbed it's easier to simulate the methods succeeding.
|
// properly stubbed it's easier to simulate the methods succeeding.
|
||||||
request.DumpUnknown(GetDeviceName(), Common::Log::LogType::IOS_WFS,
|
request.DumpUnknown(system, GetDeviceName(), Common::Log::LogType::IOS_WFS,
|
||||||
Common::Log::LogLevel::LWARNING);
|
Common::Log::LogLevel::LWARNING);
|
||||||
memory.Memset(request.buffer_out, 0, request.buffer_out_size);
|
memory.Memset(request.buffer_out, 0, request.buffer_out_size);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -28,10 +28,10 @@ enum
|
||||||
WFS_FILE_IS_OPENED = -10032, // Cannot perform operation on an opened file.
|
WFS_FILE_IS_OPENED = -10032, // Cannot perform operation on an opened file.
|
||||||
};
|
};
|
||||||
|
|
||||||
class WFSSRVDevice : public Device
|
class WFSSRVDevice : public EmulationDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WFSSRVDevice(Kernel& ios, const std::string& device_name);
|
WFSSRVDevice(EmulationKernel& ios, const std::string& device_name);
|
||||||
|
|
||||||
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
std::optional<IPCReply> IOCtl(const IOCtlRequest& request) override;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue