IOS HLE: Deduplicate request code in STM

This commit is contained in:
Léo Lam
2017-01-15 02:07:09 +01:00
parent e2d072250f
commit d7b4e6ead5
2 changed files with 32 additions and 63 deletions

View File

@ -5,6 +5,7 @@
#include "Core/IPC_HLE/WII_IPC_HLE_Device_stm.h" #include "Core/IPC_HLE/WII_IPC_HLE_Device_stm.h"
#include <functional> #include <functional>
#include <memory>
#include "Common/Assert.h" #include "Common/Assert.h"
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
@ -16,22 +17,12 @@ void QueueHostJob(std::function<void()> job, bool run_during_stop);
void Stop(); void Stop();
} }
static u32 s_event_hook_address = 0; static std::unique_ptr<IOSIOCtlRequest> s_event_hook_request;
IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(u32 command_address) IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(const IOSIOCtlRequest& request)
{ {
u32 parameter = Memory::Read_U32(command_address + 0x0C); s32 return_value = IPC_SUCCESS;
u32 buffer_in = Memory::Read_U32(command_address + 0x10); switch (request.request)
u32 buffer_in_size = Memory::Read_U32(command_address + 0x14);
u32 buffer_out = Memory::Read_U32(command_address + 0x18);
u32 buffer_out_size = Memory::Read_U32(command_address + 0x1C);
// Prepare the out buffer(s) with zeroes as a safety precaution
// to avoid returning bad values
Memory::Memset(buffer_out, 0, buffer_out_size);
u32 return_value = 0;
switch (parameter)
{ {
case IOCTL_STM_IDLE: case IOCTL_STM_IDLE:
case IOCTL_STM_SHUTDOWN: case IOCTL_STM_SHUTDOWN:
@ -40,15 +31,15 @@ IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(u32 command_address)
break; break;
case IOCTL_STM_RELEASE_EH: case IOCTL_STM_RELEASE_EH:
if (s_event_hook_address == 0) if (!s_event_hook_request)
{ {
return_value = IPC_ENOENT; return_value = IPC_ENOENT;
break; break;
} }
Memory::Write_U32(0, Memory::Read_U32(s_event_hook_address + 0x18)); Memory::Write_U32(0, s_event_hook_request->buffer_out);
Memory::Write_U32(IPC_SUCCESS, s_event_hook_address + 4); s_event_hook_request->SetReturnValue(IPC_SUCCESS);
WII_IPC_HLE_Interface::EnqueueReply(s_event_hook_address); WII_IPC_HLE_Interface::EnqueueReply(*s_event_hook_request);
s_event_hook_address = 0; s_event_hook_request.reset();
break; break;
case IOCTL_STM_HOTRESET: case IOCTL_STM_HOTRESET:
@ -69,79 +60,59 @@ IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(u32 command_address)
break; break;
default: default:
{ request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_STM);
_dbg_assert_msg_(WII_IPC_STM, 0, "CWII_IPC_HLE_Device_stm_immediate: 0x%x", parameter);
INFO_LOG(WII_IPC_STM, "%s - IOCtl:", GetDeviceName().c_str());
DEBUG_LOG(WII_IPC_STM, " parameter: 0x%x", parameter);
DEBUG_LOG(WII_IPC_STM, " InBuffer: 0x%08x", buffer_in);
DEBUG_LOG(WII_IPC_STM, " InBufferSize: 0x%08x", buffer_in_size);
DEBUG_LOG(WII_IPC_STM, " OutBuffer: 0x%08x", buffer_out);
DEBUG_LOG(WII_IPC_STM, " OutBufferSize: 0x%08x", buffer_out_size);
}
break;
} }
// Write return value to the IPC call request.SetReturnValue(return_value);
Memory::Write_U32(return_value, command_address + 0x4);
return GetDefaultReply(); return GetDefaultReply();
} }
IPCCommandResult CWII_IPC_HLE_Device_stm_eventhook::Close(u32 command_address, bool force) void CWII_IPC_HLE_Device_stm_eventhook::Close()
{ {
s_event_hook_address = 0; s_event_hook_request.reset();
m_is_active = false; m_is_active = false;
return GetDefaultReply();
} }
IPCCommandResult CWII_IPC_HLE_Device_stm_eventhook::IOCtl(u32 command_address) IPCCommandResult CWII_IPC_HLE_Device_stm_eventhook::IOCtl(const IOSIOCtlRequest& request)
{ {
u32 parameter = Memory::Read_U32(command_address + 0x0C); if (request.request != IOCTL_STM_EVENTHOOK)
if (parameter != IOCTL_STM_EVENTHOOK)
{ {
ERROR_LOG(WII_IPC_STM, "Bad IOCtl in CWII_IPC_HLE_Device_stm_eventhook"); ERROR_LOG(WII_IPC_STM, "Bad IOCtl in CWII_IPC_HLE_Device_stm_eventhook");
Memory::Write_U32(IPC_EINVAL, command_address + 4); request.SetReturnValue(IPC_EINVAL);
return GetDefaultReply(); return GetDefaultReply();
} }
if (s_event_hook_address != 0) if (s_event_hook_request)
{ {
Memory::Write_U32(FS_EEXIST, command_address + 4); request.SetReturnValue(IPC_EEXIST);
return GetDefaultReply(); return GetDefaultReply();
} }
// IOCTL_STM_EVENTHOOK waits until the reset button or power button // IOCTL_STM_EVENTHOOK waits until the reset button or power button is pressed.
// is pressed. s_event_hook_request = std::make_unique<IOSIOCtlRequest>(request.address);
s_event_hook_address = command_address;
return GetNoReply(); return GetNoReply();
} }
bool CWII_IPC_HLE_Device_stm_eventhook::HasHookInstalled() const bool CWII_IPC_HLE_Device_stm_eventhook::HasHookInstalled() const
{ {
return s_event_hook_address != 0; return s_event_hook_request != nullptr;
} }
void CWII_IPC_HLE_Device_stm_eventhook::TriggerEvent(const u32 event) const void CWII_IPC_HLE_Device_stm_eventhook::TriggerEvent(const u32 event) const
{ {
if (!m_is_active || s_event_hook_address == 0)
{
// If the device isn't open, ignore the button press. // If the device isn't open, ignore the button press.
if (!m_is_active || !s_event_hook_request)
return; return;
}
// The reset button returns STM_EVENT_RESET. Memory::Write_U32(event, s_event_hook_request->buffer_out);
u32 buffer_out = Memory::Read_U32(s_event_hook_address + 0x18); s_event_hook_request->SetReturnValue(IPC_SUCCESS);
Memory::Write_U32(event, buffer_out); WII_IPC_HLE_Interface::EnqueueReply(*s_event_hook_request);
s_event_hook_request.reset();
Memory::Write_U32(IPC_SUCCESS, s_event_hook_address + 4);
WII_IPC_HLE_Interface::EnqueueReply(s_event_hook_address);
s_event_hook_address = 0;
} }
void CWII_IPC_HLE_Device_stm_eventhook::ResetButton() const void CWII_IPC_HLE_Device_stm_eventhook::ResetButton() const
{ {
// The reset button returns STM_EVENT_RESET. // The reset button triggers STM_EVENT_RESET.
TriggerEvent(STM_EVENT_RESET); TriggerEvent(STM_EVENT_RESET);
} }

View File

@ -43,8 +43,7 @@ public:
{ {
} }
~CWII_IPC_HLE_Device_stm_immediate() override = default; IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override;
IPCCommandResult IOCtl(u32 command_address) override;
}; };
// The /dev/stm/eventhook // The /dev/stm/eventhook
@ -56,9 +55,8 @@ public:
{ {
} }
~CWII_IPC_HLE_Device_stm_eventhook() override = default; void Close() override;
IPCCommandResult Close(u32 command_address, bool force) override; IPCCommandResult IOCtl(const IOSIOCtlRequest& request) override;
IPCCommandResult IOCtl(u32 command_address) override;
bool HasHookInstalled() const; bool HasHookInstalled() const;
void ResetButton() const; void ResetButton() const;