IOS: Clean up the way IPC replies are constructed

Instead of constructing IPCCommandResult with static member functions
in the Device class, we can just add the relevant constructors to the
reply struct itself. Makes more sense than putting it in Device
when the struct is used in the kernel code and doesn't use any Device
specific members...

This commit also changes the IPC command handlers to return an optional
IPCCommandResult rather than an IPCCommandResult. This removes the need
for a separate boolean that indicates whether the "result" is actually
a reply, and also avoids the need to set dummy result values and ticks.

It also makes it really obvious which commands can result in no reply
being generated.

Finally, this commit renames IPCCommandResult to IPCReply since the
struct is now only used for actual replies. This new name is less
verbose in my opinion.

The diff is quite large since this touches every command handler, but
the only functional change is that I fixed EnqueueIPCReply to
take a s64 for cycles_in_future to match IPCReply.
This commit is contained in:
Léo Lam committed 2021-02-13 20:15:30 +01:00
1 parent f52aa3d041
commit d0136dd7c2
61 files changed
+872 -873

No files matched your search

+28 -30
View File
@@ -34,29 +34,29 @@ enum
};
IPCCommandResult GetSystemTime(const IOCtlVRequest& request)
IPCReply GetSystemTime(const IOCtlVRequest& request)
{
if (!request.HasNumberOfValidVectors(0, 1))
{
return DolphinDevice::GetDefaultReply(IPC_EINVAL);
return IPCReply(IPC_EINVAL);
}
if (request.io_vectors[0].size != 4)
{
return DolphinDevice::GetDefaultReply(IPC_EINVAL);
return IPCReply(IPC_EINVAL);
}
const u32 milliseconds = Common::Timer::GetTimeMs();
Memory::Write_U32(milliseconds, request.io_vectors[0].address);
return DolphinDevice::GetDefaultReply(IPC_SUCCESS);
return IPCReply(IPC_SUCCESS);
}
IPCCommandResult GetVersion(const IOCtlVRequest& request)
IPCReply GetVersion(const IOCtlVRequest& request)
{
if (!request.HasNumberOfValidVectors(0, 1))
{
return DolphinDevice::GetDefaultReply(IPC_EINVAL);
return IPCReply(IPC_EINVAL);
}
const auto length = std::min(size_t(request.io_vectors[0].size), std::strlen(SCM_DESC_STR));
@@ -64,19 +64,19 @@ IPCCommandResult GetVersion(const IOCtlVRequest& request)
Memory::Memset(request.io_vectors[0].address, 0, request.io_vectors[0].size);
Memory::CopyToEmu(request.io_vectors[0].address, SCM_DESC_STR, length);
return DolphinDevice::GetDefaultReply(IPC_SUCCESS);
return IPCReply(IPC_SUCCESS);
}
IPCCommandResult GetCPUSpeed(const IOCtlVRequest& request)
IPCReply GetCPUSpeed(const IOCtlVRequest& request)
{
if (!request.HasNumberOfValidVectors(0, 1))
{
return DolphinDevice::GetDefaultReply(IPC_EINVAL);
return IPCReply(IPC_EINVAL);
}
if (request.io_vectors[0].size != 4)
{
return DolphinDevice::GetDefaultReply(IPC_EINVAL);
return IPCReply(IPC_EINVAL);
}
const SConfig& config = SConfig::GetInstance();
@@ -86,66 +86,66 @@ IPCCommandResult GetCPUSpeed(const IOCtlVRequest& request)
Memory::Write_U32(core_clock, request.io_vectors[0].address);
return DolphinDevice::GetDefaultReply(IPC_SUCCESS);
return IPCReply(IPC_SUCCESS);
}
IPCCommandResult GetSpeedLimit(const IOCtlVRequest& request)
IPCReply GetSpeedLimit(const IOCtlVRequest& request)
{
// get current speed limit
if (!request.HasNumberOfValidVectors(0, 1))
{
return DolphinDevice::GetDefaultReply(IPC_EINVAL);
return IPCReply(IPC_EINVAL);
}
if (request.io_vectors[0].size != 4)
{
return DolphinDevice::GetDefaultReply(IPC_EINVAL);
return IPCReply(IPC_EINVAL);
}
const SConfig& config = SConfig::GetInstance();
const u32 speed_percent = config.m_EmulationSpeed * 100;
Memory::Write_U32(speed_percent, request.io_vectors[0].address);
return DolphinDevice::GetDefaultReply(IPC_SUCCESS);
return IPCReply(IPC_SUCCESS);
}
IPCCommandResult SetSpeedLimit(const IOCtlVRequest& request)
IPCReply SetSpeedLimit(const IOCtlVRequest& request)
{
// set current speed limit
if (!request.HasNumberOfValidVectors(1, 0))
{
return DolphinDevice::GetDefaultReply(IPC_EINVAL);
return IPCReply(IPC_EINVAL);
}
if (request.in_vectors[0].size != 4)
{
return DolphinDevice::GetDefaultReply(IPC_EINVAL);
return IPCReply(IPC_EINVAL);
}
const float speed = float(Memory::Read_U32(request.in_vectors[0].address)) / 100.0f;
SConfig::GetInstance().m_EmulationSpeed = speed;
BootManager::SetEmulationSpeedReset(true);
return DolphinDevice::GetDefaultReply(IPC_SUCCESS);
return IPCReply(IPC_SUCCESS);
}
IPCCommandResult GetRealProductCode(const IOCtlVRequest& request)
IPCReply GetRealProductCode(const IOCtlVRequest& request)
{
if (!request.HasNumberOfValidVectors(0, 1))
{
return DolphinDevice::GetDefaultReply(IPC_EINVAL);
return IPCReply(IPC_EINVAL);
}
const std::string backup_file_path = File::GetUserPath(D_BACKUP_IDX) + DIR_SEP + WII_SETTING;
File::IOFile file(backup_file_path, "rb");
if (!file)
return DolphinDevice::GetDefaultReply(IPC_ENOENT);
return IPCReply(IPC_ENOENT);
Common::SettingsHandler::Buffer data;
if (!file.ReadBytes(data.data(), data.size()))
return DolphinDevice::GetDefaultReply(IPC_ENOENT);
return IPCReply(IPC_ENOENT);
Common::SettingsHandler gen;
gen.SetBytes(std::move(data));
@@ -153,21 +153,19 @@ IPCCommandResult GetRealProductCode(const IOCtlVRequest& request)
const size_t length = std::min<size_t>(request.io_vectors[0].size, code.length());
if (length == 0)
return DolphinDevice::GetDefaultReply(IPC_ENOENT);
return IPCReply(IPC_ENOENT);
Memory::Memset(request.io_vectors[0].address, 0, request.io_vectors[0].size);
Memory::CopyToEmu(request.io_vectors[0].address, code.c_str(), length);
return DolphinDevice::GetDefaultReply(IPC_SUCCESS);
return IPCReply(IPC_SUCCESS);
}
} // namespace
IPCCommandResult DolphinDevice::IOCtlV(const IOCtlVRequest& request)
std::optional<IPCReply> DolphinDevice::IOCtlV(const IOCtlVRequest& request)
{
if (Core::WantsDeterminism())
{
return DolphinDevice::GetDefaultReply(IPC_EACCES);
}
return IPCReply(IPC_EACCES);
switch (request.request)
{
@@ -184,7 +182,7 @@ IPCCommandResult DolphinDevice::IOCtlV(const IOCtlVRequest& request)
case IOCTL_DOLPHIN_GET_REAL_PRODUCTCODE:
return GetRealProductCode(request);
default:
return GetDefaultReply(IPC_EINVAL);
return IPCReply(IPC_EINVAL);
}
}
} // namespace IOS::HLE