IPC_HLE: Deduplicate syscall reply enqueue function

This is something that was copy-pasted across the IPC_HLE code
(because it's often used). Since all of the duplicated pieces of code
do the same thing as the previous EnqueueReply, except that they also
write to command_address + 0 and + 8 (to write the correct reply type),
this commit changes EnqueueReply to do that instead of having it
duplicated all over IPC HLE.
This commit is contained in:
Léo Lam 2016-10-21 17:47:02 +02:00
parent 9bfea4a0f2
commit b0377f02f0
11 changed files with 25 additions and 108 deletions

View File

@ -553,14 +553,7 @@ void ExecuteCommand(u32 address)
s_last_reply_time = CoreTiming::GetTicks() + result.reply_delay_ticks;
if (result.send_reply)
{
// The original hardware overwrites the command type with the async reply type.
Memory::Write_U32(IPC_REP_ASYNC, address);
// IOS also seems to write back the command that was responded to in the FD field.
Memory::Write_U32(Command, address + 8);
// Generate a reply to the IPC command
EnqueueReply(address, (int)result.reply_delay_ticks);
}
EnqueueReply(address, static_cast<int>(result.reply_delay_ticks));
}
// Happens AS SOON AS IPC gets a new pointer!
@ -569,12 +562,13 @@ void EnqueueRequest(u32 address)
CoreTiming::ScheduleEvent(1000, s_event_enqueue, address | ENQUEUE_REQUEST_FLAG);
}
// Called when IOS module has some reply
// NOTE: Only call this if you have correctly handled
// CommandAddress+0 and CommandAddress+8.
// Please search for examples of this being called elsewhere.
// Called to send a reply to an IOS syscall
void EnqueueReply(u32 address, int cycles_in_future, CoreTiming::FromThread from)
{
// IOS writes back the command that was responded to in the FD field.
Memory::Write_U32(Memory::Read_U32(address), address + 8);
// IOS also overwrites the command type with the async reply type.
Memory::Write_U32(IPC_REP_ASYNC, address);
CoreTiming::ScheduleEvent(cycles_in_future, s_event_enqueue, address, from);
}

View File

@ -107,12 +107,6 @@ void CWII_IPC_HLE_Device_di::FinishIOCtl(DVDInterface::DIInterruptType interrupt
// The DI interrupt type is used as a return value
Memory::Write_U32(interrupt_type, command_address + 4);
// The original hardware overwrites the command type with the async reply type.
Memory::Write_U32(IPC_REP_ASYNC, command_address);
// IOS also seems to write back the command that was responded to in the FD field.
Memory::Write_U32(Memory::Read_U32(command_address), command_address + 8);
// Generate a reply to the IPC command
WII_IPC_HLE_Interface::EnqueueReply(command_address);
// DVDInterface is now ready to execute another command,

View File

@ -33,14 +33,8 @@ void CWII_IPC_HLE_Device_hid::checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid)
hid->FillOutDevices(Memory::Read_U32(hid->deviceCommandAddress + 0x18),
Memory::Read_U32(hid->deviceCommandAddress + 0x1C));
// The original hardware overwrites the command type with the async reply type.
Memory::Write_U32(IPC_REP_ASYNC, hid->deviceCommandAddress);
// IOS also seems to write back the command that was responded to in the FD field.
Memory::Write_U32(IPC_CMD_IOCTL, hid->deviceCommandAddress + 8);
// Return value
Memory::Write_U32(0, hid->deviceCommandAddress + 4);
WII_IPC_HLE_Interface::EnqueueReply(hid->deviceCommandAddress, 0,
CoreTiming::FromThread::NON_CPU);
hid->deviceCommandAddress = 0;
@ -62,17 +56,9 @@ void CWII_IPC_HLE_Device_hid::handleUsbUpdates(struct libusb_transfer* transfer)
ret = transfer->length;
}
// The original hardware overwrites the command type with the async reply type.
Memory::Write_U32(IPC_REP_ASYNC, replyAddress);
// IOS also seems to write back the command that was responded to in the FD field.
Memory::Write_U32(IPC_CMD_IOCTL, replyAddress + 8);
// Return value
Memory::Write_U32(ret, replyAddress + 4);
WII_IPC_HLE_Interface::EnqueueReply(replyAddress, 0, CoreTiming::FromThread::NON_CPU);
// DEBUG_LOG(WII_IPC_HID, "OMG OMG OMG I GOT A CALLBACK, IMMA BE FAMOUS %d %d %d",
// transfer->actual_length, transfer->length, transfer->status);
}
CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName)
@ -259,11 +245,6 @@ IPCCommandResult CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress)
{
Memory::Write_U32(0xFFFFFFFF, Memory::Read_U32(deviceCommandAddress + 0x18));
// The original hardware overwrites the command type with the async reply type.
Memory::Write_U32(IPC_REP_ASYNC, deviceCommandAddress);
// IOS also seems to write back the command that was responded to in the FD field.
Memory::Write_U32(IPC_CMD_IOCTL, deviceCommandAddress + 8);
// Return value
Memory::Write_U32(-1, deviceCommandAddress + 4);
WII_IPC_HLE_Interface::EnqueueReply(deviceCommandAddress);

View File

@ -14,19 +14,6 @@
#include "Core/IPC_HLE/WII_IPC_HLE.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h"
void CWII_IPC_HLE_Device_sdio_slot0::EnqueueReply(u32 CommandAddress, u32 ReturnValue)
{
// IOS seems to write back the command that was responded to, this class does not
// overwrite the command so it is safe to read.
Memory::Write_U32(Memory::Read_U32(CommandAddress), CommandAddress + 8);
// The original hardware overwrites the command type with the async reply type.
Memory::Write_U32(IPC_REP_ASYNC, CommandAddress);
Memory::Write_U32(ReturnValue, CommandAddress + 4);
WII_IPC_HLE_Interface::EnqueueReply(CommandAddress);
}
CWII_IPC_HLE_Device_sdio_slot0::CWII_IPC_HLE_Device_sdio_slot0(u32 _DeviceID,
const std::string& _rDeviceName)
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName), m_Status(CARD_NOT_EXIST), m_BlockLength(0),
@ -54,7 +41,8 @@ void CWII_IPC_HLE_Device_sdio_slot0::EventNotify()
if ((SConfig::GetInstance().m_WiiSDCard && m_event.type == EVENT_INSERT) ||
(!SConfig::GetInstance().m_WiiSDCard && m_event.type == EVENT_REMOVE))
{
EnqueueReply(m_event.addr, m_event.type);
Memory::Write_U32(m_event.type, m_event.addr + 4);
WII_IPC_HLE_Interface::EnqueueReply(m_event.addr);
m_event.addr = 0;
m_event.type = EVENT_NONE;
}
@ -236,7 +224,8 @@ IPCCommandResult CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress)
// release returns 0
// unknown sd int
// technically we do it out of order, oh well
EnqueueReply(m_event.addr, EVENT_INVALID);
Memory::Write_U32(EVENT_INVALID, m_event.addr + 4);
WII_IPC_HLE_Interface::EnqueueReply(m_event.addr);
m_event.addr = 0;
m_event.type = EVENT_NONE;
Memory::Write_U32(0, _CommandAddress + 0x4);

View File

@ -29,7 +29,6 @@ public:
IPCCommandResult IOCtl(u32 _CommandAddress) override;
IPCCommandResult IOCtlV(u32 _CommandAddress) override;
static void EnqueueReply(u32 CommandAddress, u32 ReturnValue);
void EventNotify();
private:

View File

@ -58,8 +58,6 @@ IPCCommandResult CWII_IPC_HLE_Device_stm_immediate::IOCtl(u32 command_address)
}
Memory::Write_U32(0, Memory::Read_U32(s_event_hook_address + 0x18));
Memory::Write_U32(FS_SUCCESS, s_event_hook_address + 4);
Memory::Write_U32(IPC_REP_ASYNC, s_event_hook_address);
Memory::Write_U32(IPC_CMD_IOCTL, s_event_hook_address + 8);
WII_IPC_HLE_Interface::EnqueueReply(s_event_hook_address);
s_event_hook_address = 0;
break;
@ -152,12 +150,7 @@ void CWII_IPC_HLE_Device_stm_eventhook::TriggerEvent(const u32 event) const
u32 buffer_out = Memory::Read_U32(s_event_hook_address + 0x18);
Memory::Write_U32(event, buffer_out);
// Fill in command buffer.
Memory::Write_U32(FS_SUCCESS, s_event_hook_address + 4);
Memory::Write_U32(IPC_REP_ASYNC, s_event_hook_address);
Memory::Write_U32(IPC_CMD_IOCTL, s_event_hook_address + 8);
// Generate a reply to the IPC command.
WII_IPC_HLE_Interface::EnqueueReply(s_event_hook_address);
s_event_hook_address = 0;
}

View File

@ -18,17 +18,6 @@
#include "Core/Movie.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::EnqueueReply(u32 CommandAddress)
{
// IOS seems to write back the command that was responded to in the FD field, this
// class does not overwrite the command so it is safe to read back.
Memory::Write_U32(Memory::Read_U32(CommandAddress), CommandAddress + 8);
// The original hardware overwrites the command type with the async reply type.
Memory::Write_U32(IPC_REP_ASYNC, CommandAddress);
WII_IPC_HLE_Interface::EnqueueReply(CommandAddress);
}
// The device class
CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::CWII_IPC_HLE_Device_usb_oh1_57e_305_emu(
u32 _DeviceID, const std::string& _rDeviceName)
@ -368,7 +357,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendACLPacket(u16 connection_handl
memcpy(reinterpret_cast<u8*>(header) + sizeof(hci_acldata_hdr_t), data, header->length);
m_ACLEndpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + size);
EnqueueReply(m_ACLEndpoint.m_cmd_address);
WII_IPC_HLE_Interface::EnqueueReply(m_ACLEndpoint.m_cmd_address);
m_ACLEndpoint.Invalidate();
}
else
@ -397,7 +386,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent
m_HCIEndpoint.FillBuffer(_event.m_buffer, _event.m_size);
m_HCIEndpoint.SetRetVal(_event.m_size);
// Send a reply to indicate HCI buffer is filled
EnqueueReply(m_HCIEndpoint.m_cmd_address);
WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address);
m_HCIEndpoint.Invalidate();
}
else // push new one, pop oldest
@ -413,7 +402,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent
m_HCIEndpoint.FillBuffer(event.m_buffer, event.m_size);
m_HCIEndpoint.SetRetVal(event.m_size);
// Send a reply to indicate HCI buffer is filled
EnqueueReply(m_HCIEndpoint.m_cmd_address);
WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address);
m_HCIEndpoint.Invalidate();
m_EventQueue.pop_front();
}
@ -441,7 +430,7 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update()
m_HCIEndpoint.FillBuffer(event.m_buffer, event.m_size);
m_HCIEndpoint.SetRetVal(event.m_size);
// Send a reply to indicate HCI buffer is filled
EnqueueReply(m_HCIEndpoint.m_cmd_address);
WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address);
m_HCIEndpoint.Invalidate();
m_EventQueue.pop_front();
packet_transferred = true;
@ -542,7 +531,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ACLPool::WriteToEndpoint(CtrlBuffe
m_queue.pop_front();
EnqueueReply(endpoint.m_cmd_address);
WII_IPC_HLE_Interface::EnqueueReply(endpoint.m_cmd_address);
endpoint.Invalidate();
}
@ -1264,7 +1253,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage(
}
// HCI command is finished, send a reply to command
EnqueueReply(_rHCICommandMessage.m_Address);
WII_IPC_HLE_Interface::EnqueueReply(_rHCICommandMessage.m_Address);
}
//

View File

@ -56,8 +56,6 @@ public:
u32 Update() override;
static void EnqueueReply(u32 CommandAddress);
// Send ACL data back to Bluetooth stack
void SendACLPacket(u16 connection_handle, const u8* data, u32 size);

View File

@ -29,13 +29,6 @@ static Common::Flag s_need_reset_keys;
// and we showed an OSD message about it.
static Common::Flag s_showed_failed_transfer;
static void EnqueueReply(const u32 command_address)
{
Memory::Write_U32(Memory::Read_U32(command_address), command_address + 8);
Memory::Write_U32(IPC_REP_ASYNC, command_address);
WII_IPC_HLE_Interface::EnqueueReply(command_address, 0, CoreTiming::FromThread::ANY);
}
static bool IsWantedDevice(const libusb_device_descriptor& descriptor)
{
const int vid = SConfig::GetInstance().m_bt_passthrough_vid;
@ -394,7 +387,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(const Ctrl
hci_event->PacketIndicator = 0x01;
hci_event->Opcode = m_fake_vendor_command_reply_opcode;
ctrl.SetRetVal(sizeof(SHCIEventCommand));
EnqueueReply(ctrl.m_cmd_address);
WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address);
}
// Due to how the widcomm stack which Nintendo uses is coded, we must never
@ -420,7 +413,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(const Ctr
memcpy(packet + sizeof(SHCIEventCommand), &reply, sizeof(hci_read_buffer_size_rp));
ctrl.SetRetVal(sizeof(SHCIEventCommand) + sizeof(hci_read_buffer_size_rp));
EnqueueReply(ctrl.m_cmd_address);
WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address);
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(const CtrlBuffer& ctrl,
@ -432,7 +425,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(const CtrlBuf
hci_event->length = size;
memcpy(packet + sizeof(hci_event_hdr_t), payload, size);
ctrl.SetRetVal(sizeof(hci_event_hdr_t) + size);
EnqueueReply(ctrl.m_cmd_address);
WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address);
}
// When the red sync button is pressed, a HCI event is generated:
@ -578,7 +571,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::CommandCallback(libusb_transfer*
s_showed_failed_transfer.Clear();
}
EnqueueReply(cmd->address);
WII_IPC_HLE_Interface::EnqueueReply(cmd->address, 0, CoreTiming::FromThread::NON_CPU);
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::TransferCallback(libusb_transfer* tr)
@ -623,5 +616,5 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::TransferCallback(libusb_transfer*
}
ctrl->SetRetVal(tr->actual_length);
EnqueueReply(ctrl->m_cmd_address);
WII_IPC_HLE_Interface::EnqueueReply(ctrl->m_cmd_address, 0, CoreTiming::FromThread::NON_CPU);
}

View File

@ -576,7 +576,8 @@ void WiiSocket::Update(bool read, bool write, bool except)
"IOCTL(V) Sock: %08x ioctl/v: %d returned: %d nonBlock: %d forceNonBlock: %d", fd,
it->is_ssl ? (int)it->ssl_type : (int)it->net_type, ReturnValue, nonBlock,
forceNonBlock);
WiiSockMan::EnqueueReply(it->_CommandAddress, ReturnValue, ct);
Memory::Write_U32(ReturnValue, it->_CommandAddress + 4);
WII_IPC_HLE_Interface::EnqueueReply(it->_CommandAddress);
it = pending_sockops.erase(it);
}
else
@ -674,19 +675,6 @@ void WiiSockMan::Update()
}
}
void WiiSockMan::EnqueueReply(u32 CommandAddress, s32 ReturnValue, IPCCommandType CommandType)
{
// The original hardware overwrites the command type with the async reply type.
Memory::Write_U32(IPC_REP_ASYNC, CommandAddress);
// IOS also seems to write back the command that was responded to in the FD field.
Memory::Write_U32(CommandType, CommandAddress + 8);
// Return value
Memory::Write_U32(ReturnValue, CommandAddress + 4);
WII_IPC_HLE_Interface::EnqueueReply(CommandAddress);
}
void WiiSockMan::Convert(WiiSockAddrIn const& from, sockaddr_in& to)
{
to.sin_addr.s_addr = from.addr.addr;

View File

@ -209,7 +209,6 @@ public:
return instance; // Instantiated on first use.
}
void Update();
static void EnqueueReply(u32 CommandAddress, s32 ReturnValue, IPCCommandType CommandType);
static void Convert(WiiSockAddrIn const& from, sockaddr_in& to);
static void Convert(sockaddr_in const& from, WiiSockAddrIn& to, s32 addrlen = -1);
// NON-BLOCKING FUNCTIONS
@ -225,10 +224,10 @@ public:
auto socket_entry = WiiSockets.find(sock);
if (socket_entry == WiiSockets.end())
{
IPCCommandType ct = static_cast<IPCCommandType>(Memory::Read_U32(CommandAddress));
ERROR_LOG(WII_IPC_NET, "DoSock: Error, fd not found (%08x, %08X, %08X)", sock, CommandAddress,
type);
EnqueueReply(CommandAddress, -SO_EBADF, ct);
Memory::Write_U32(-SO_EBADF, CommandAddress + 4);
WII_IPC_HLE_Interface::EnqueueReply(CommandAddress);
}
else
{