mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
IOS HLE: Deduplicate request code in STM
This commit is contained in:
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user