From f6db5b7d8d31b7bbcceb7a36bef696af0b84f70f Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Tue, 23 Mar 2010 03:32:19 +0000 Subject: [PATCH] make WII_IPC_HLEInterface manage the IPC message queue instead of the "lle" portion. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5224 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/HW/WII_IPC.cpp | 110 +++-------- Source/Core/Core/Src/HW/WII_IPC.h | 13 +- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 177 ++++++++---------- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h | 3 + .../Core/Src/IPC_HLE/WII_IPC_HLE_Device.h | 30 ++- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h | 65 +++---- .../Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp | 48 ++--- 7 files changed, 165 insertions(+), 281 deletions(-) diff --git a/Source/Core/Core/Src/HW/WII_IPC.cpp b/Source/Core/Core/Src/HW/WII_IPC.cpp index 0c31fd350e..74af1ecdea 100644 --- a/Source/Core/Core/Src/HW/WII_IPC.cpp +++ b/Source/Core/Core/Src/HW/WII_IPC.cpp @@ -16,6 +16,8 @@ // http://code.google.com/p/dolphin-emu/ #include +#include +#include #include "Common.h" #include "ChunkFile.h" @@ -91,23 +93,16 @@ struct CtrlRegister }; // STATE_TO_SAVE -u32 ppc_msg; -u32 arm_msg; -CtrlRegister ctrl; +static u32 ppc_msg; +static u32 arm_msg; +static CtrlRegister ctrl; -u32 ppc_irq_flags; -u32 ppc_irq_masks; -u32 arm_irq_flags; -u32 arm_irq_masks; +static u32 ppc_irq_flags; +static u32 ppc_irq_masks; +static u32 arm_irq_flags; +static u32 arm_irq_masks; -u32 sensorbar_power; // do we need to care about this? - -// not actual registers: -bool cmd_active; -u32 g_ReplyHead; -u32 g_ReplyTail; -u32 g_ReplyNum; -u32 g_ReplyFifo[REPLY_FIFO_DEPTH]; +static u32 sensorbar_power; // do we need to care about this? void DoState(PointerWrap &p) { @@ -119,17 +114,10 @@ void DoState(PointerWrap &p) p.Do(arm_irq_flags); p.Do(arm_irq_masks); p.Do(sensorbar_power); - p.Do(cmd_active); - p.Do(g_ReplyHead); - p.Do(g_ReplyTail); - p.Do(g_ReplyNum); - p.DoArray(g_ReplyFifo, REPLY_FIFO_DEPTH); } -// Init void Init() { - cmd_active = false; ctrl = CtrlRegister(); ppc_msg = arm_msg = @@ -139,12 +127,7 @@ void Init() arm_irq_flags = arm_irq_masks = - sensorbar_power = - - g_ReplyHead = - g_ReplyTail = - g_ReplyNum = 0; - memset(g_ReplyFifo, 0, REPLY_FIFO_DEPTH); + sensorbar_power = 0; ppc_irq_masks |= INT_CAUSE_IPC_BROADWAY; } @@ -166,7 +149,7 @@ void Read32(u32& _rReturnValue, const u32 _Address) { case IPC_PPCCTRL: _rReturnValue = ctrl.ppc(); - INFO_LOG(WII_IPC, "r32 IPC_PPCCTRL %03x [R:%i A:%i E:%i]", + DEBUG_LOG(WII_IPC, "r32 IPC_PPCCTRL %03x [R:%i A:%i E:%i]", ctrl.ppc(), ctrl.Y1, ctrl.Y2, ctrl.X1); // if ((REASON_REG & 0x14) == 0x14) CALL IPCReplayHandler @@ -175,7 +158,7 @@ void Read32(u32& _rReturnValue, const u32 _Address) case IPC_ARMMSG: // looks a little bit like a callback function _rReturnValue = arm_msg; - INFO_LOG(WII_IPC, "r32 IPC_ARMMSG %08x ", _rReturnValue); + DEBUG_LOG(WII_IPC, "r32 IPC_ARMMSG %08x ", _rReturnValue); break; case GPIOB_OUT: @@ -195,24 +178,28 @@ void Write32(const u32 _Value, const u32 _Address) case IPC_PPCMSG: // __ios_Ipc2 ... a value from __responses is loaded { ppc_msg = _Value; - INFO_LOG(WII_IPC, "IPC_PPCMSG = %08x", ppc_msg); + DEBUG_LOG(WII_IPC, "IPC_PPCMSG = %08x", ppc_msg); } break; case IPC_PPCCTRL: { ctrl.ppc(_Value); - INFO_LOG(WII_IPC, "w32 %08x IPC_PPCCTRL = %03x [R:%i A:%i E:%i]", + DEBUG_LOG(WII_IPC, "w32 %08x IPC_PPCCTRL = %03x [R:%i A:%i E:%i]", _Value, ctrl.ppc(), ctrl.Y1, ctrl.Y2, ctrl.X1); - if (ctrl.X1) // seems like we should just be able to use X1 directly, but it doesn't work...why?! - cmd_active = true; + if (ctrl.X1) + { + INFO_LOG(WII_IPC, "new pointer available: %08x", ppc_msg); + // Let the HLE handle the request on it's own time + WII_IPC_HLE_Interface::EnqRequest(ppc_msg); + } } break; case PPC_IRQFLAG: // ACR REGISTER IT IS CALLED IN DEBUG { ppc_irq_flags &= ~_Value; - INFO_LOG(WII_IPC, "w32 PPC_IRQFLAG %08x (%08x)", _Value, ppc_irq_flags); + DEBUG_LOG(WII_IPC, "w32 PPC_IRQFLAG %08x (%08x)", _Value, ppc_irq_flags); } break; @@ -221,7 +208,7 @@ void Write32(const u32 _Value, const u32 _Address) ppc_irq_masks = _Value; if (ppc_irq_masks & INT_CAUSE_IPC_BROADWAY) // wtf? Reset(); - INFO_LOG(WII_IPC, "w32 PPC_IRQMASK %08x", ppc_irq_masks); + DEBUG_LOG(WII_IPC, "w32 PPC_IRQMASK %08x", ppc_irq_masks); } break; @@ -253,21 +240,12 @@ void UpdateInterrupts() ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_WII_IPC, !!(ppc_irq_flags & ppc_irq_masks)); } -// The rest is for IOS HLE -bool IsReady() +void GenerateAck(u32 _Address) { - return ((ctrl.Y1 == 0) && (ctrl.Y2 == 0) && ((ppc_irq_flags & INT_CAUSE_IPC_BROADWAY) == 0)); -} - -u32 GetAddress() -{ - return (cmd_active ? ppc_msg : 0); -} - -void GenerateAck() -{ - cmd_active = false; + arm_msg = _Address; // dunno if it's really set here, but HLE needs to stay in context ctrl.Y2 = 1; + INFO_LOG(WII_IPC, "GenerateAck: %08x | %08x [R:%i A:%i E:%i]", + ppc_msg,_Address, ctrl.Y1, ctrl.Y2, ctrl.X1); UpdateInterrupts(); } @@ -275,40 +253,14 @@ void GenerateReply(u32 _Address) { arm_msg = _Address; ctrl.Y1 = 1; + INFO_LOG(WII_IPC, "GenerateReply: %08x | %08x [R:%i A:%i E:%i]", + ppc_msg,_Address, ctrl.Y1, ctrl.Y2, ctrl.X1); UpdateInterrupts(); } -void EnqReply(u32 _Address) +bool IsReady() { - if (g_ReplyNum < REPLY_FIFO_DEPTH) - { - g_ReplyFifo[g_ReplyTail++] = _Address; - g_ReplyTail &= REPLY_FIFO_MASK; - g_ReplyNum++; - } - else - { - ERROR_LOG(WII_IPC, "Reply FIFO is full, something must be wrong!"); - PanicAlert("WII_IPC: Reply FIFO is full, something must be wrong!"); - } -} - -u32 DeqReply() -{ - u32 _Address; - - if (g_ReplyNum) - { - _Address = g_ReplyFifo[g_ReplyHead++]; - g_ReplyHead &= REPLY_FIFO_MASK; - g_ReplyNum--; - } - else - { - _Address = NULL; - } - - return _Address; + return ((ctrl.Y1 == 0) && (ctrl.Y2 == 0) && ((ppc_irq_flags & INT_CAUSE_IPC_BROADWAY) == 0)); } } diff --git a/Source/Core/Core/Src/HW/WII_IPC.h b/Source/Core/Core/Src/HW/WII_IPC.h index 9cf4394c27..cb79a4f700 100644 --- a/Source/Core/Core/Src/HW/WII_IPC.h +++ b/Source/Core/Core/Src/HW/WII_IPC.h @@ -44,9 +44,6 @@ enum StarletInterruptCause INT_CAUSE_IPC_STARLET = 0x80000000 }; -#define REPLY_FIFO_DEPTH (unsigned)8 -#define REPLY_FIFO_MASK (REPLY_FIFO_DEPTH - 1) - void Init(); void Reset(); void Shutdown(); @@ -55,14 +52,10 @@ void DoState(PointerWrap &p); void Read32(u32& _rReturnValue, const u32 _Address); void Write32(const u32 _Value, const u32 _Address); -u32 GetAddress(); -void GenerateAck(); -void GenerateReply(u32 _Address); -void InsertReply(u32 _Address); -void EnqReply(u32 _Address); -u32 DeqReply(); - void UpdateInterrupts(); +void GenerateAck(u32 _Address); +void GenerateReply(u32 _Address); + bool IsReady(); } diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index 7190e41960..a4cf758a23 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -15,30 +15,23 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +/* +This is the main Wii IPC file that handles all incoming IPC calls and directs them +to the right function. +IPC basics (IOS' usage): -// ======================================================= -// File description -// ------------- -/* This is the main Wii IPC file that handles all incoming IPC calls and directs them - to the right function. - - IPC basics: - - Return values for file handles: All IPC calls will generate a return value to 0x04, - in case of success they are - Open: DeviceID - Close: 0 - Read: Bytes read - Write: Bytes written - Seek: Seek position - Ioctl: 0 (in addition to that there may be messages to the out buffers) - Ioctlv: 0 (in addition to that there may be messages to the out buffers) - They will also generate a true or false return for UpdateInterrupts() in WII_IPC.cpp. */ -// ============= - - - +Return values for file handles: All IPC calls will generate a return value to 0x04, +in case of success they are + Open: DeviceID + Close: 0 + Read: Bytes read + Write: Bytes written + Seek: Seek position + Ioctl: 0 (in addition to that there may be messages to the out buffers) + Ioctlv: 0 (in addition to that there may be messages to the out buffers) +They will also generate a true or false return for UpdateInterrupts() in WII_IPC.cpp. +*/ #include #include @@ -78,6 +71,10 @@ typedef std::map TFileNameMap; TFileNameMap g_FileNameMap; u32 g_LastDeviceID; +typedef std::queue ipc_msg_queue; +static ipc_msg_queue request_queue; // ppc -> arm +static ipc_msg_queue reply_queue; // arm -> ppc + // General IPC functions void Init() { @@ -125,6 +122,9 @@ void Reset(bool _bHard) g_DeviceMap.erase(itr, g_DeviceMap.end()); g_FileNameMap.clear(); + request_queue = std::queue(); + reply_queue = std::queue(); + g_LastDeviceID = IPC_FIRST_FILEIO_ID; } @@ -133,7 +133,6 @@ void Shutdown() Reset(true); } -// Set default content file void SetDefaultContentFile(const std::string& _rFilename) { CWII_IPC_HLE_Device_es* pDevice = (CWII_IPC_HLE_Device_es*)AccessDeviceByID(GetDeviceIDByName(std::string("/dev/es"))); @@ -172,7 +171,7 @@ void DeleteDeviceByID(u32 ID) g_FileNameMap.erase(ID); } -// This is called from COMMAND_OPEN_DEVICE. Here we either create a new file handle +// This is called from ExecuteCommand() COMMAND_OPEN_DEVICE IWII_IPC_HLE_Device* CreateFileIO(u32 _DeviceID, const std::string& _rDeviceName) { // scan device name and create the right one @@ -184,7 +183,7 @@ IWII_IPC_HLE_Device* CreateFileIO(u32 _DeviceID, const std::string& _rDeviceName return pDevice; } -// Let the game read the setting.txt file +// Try to make sure the game is always reading the setting.txt file we provide void CopySettingsFile(std::string& DeviceName) { std::string Source = File::GetSysDirectory() + WII_SYS_DIR + DIR_SEP; @@ -197,7 +196,8 @@ void CopySettingsFile(std::string& DeviceName) // Check if the target dir exists, otherwise create it std::string TargetDir = Target.substr(0, Target.find_last_of(DIR_SEP)); - if(!File::IsDirectory(TargetDir.c_str())) File::CreateFullPath(Target.c_str()); + if (!File::IsDirectory(TargetDir.c_str())) + File::CreateFullPath(Target.c_str()); if (File::Copy(Source.c_str(), Target.c_str())) { @@ -256,14 +256,6 @@ void DoState(PointerWrap &p) } } -// =================================================== -/* This generates an acknowledgment to IPC calls. This function is called from - IPC_CONTROL_REGISTER requests in WII_IPC.cpp. The acknowledgment _Address will - start with 0x033e...., it will be for the _CommandAddress 0x133e...., from - debugging I also noticed that the Ioctl arguments are stored temporarily in - 0x933e.... with the same .... as in the _CommandAddress. */ -// ---------------- - void ExecuteCommand(u32 _Address) { bool CmdSuccess = false; @@ -284,7 +276,8 @@ void ExecuteCommand(u32 _Address) Memory::GetString(DeviceName, Memory::Read_U32(_Address + 0xC)); // The game may try to read setting.txt here, in that case copy it so it can read it - if(DeviceName.find("setting.txt") != std::string::npos) CopySettingsFile(DeviceName); + if (DeviceName.find("setting.txt") != std::string::npos) + CopySettingsFile(DeviceName); u32 Mode = Memory::Read_U32(_Address + 0x10); DeviceID = GetDeviceIDByName(DeviceName); @@ -332,9 +325,9 @@ void ExecuteCommand(u32 _Address) INFO_LOG(WII_IPC_FILEIO, "IOP: ReOpen (Device=%s, DeviceID=%08x, Mode=%i)", pDevice->GetDeviceName().c_str(), DeviceID, Mode); - if(pDevice->IsHardware()) + if (pDevice->IsHardware()) { - if(pDevice->IsOpened()) + if (pDevice->IsOpened()) { if (pDevice->GetDeviceName().find("/dev/net/kd/request") != std::string::npos) // AyuanX: /dev/net/kd/request is more like event which doesn't need close so it can be reopened @@ -358,7 +351,7 @@ void ExecuteCommand(u32 _Address) // Open > Failed > ... other stuff > ReOpen call sequence, in that case // we have no file and no file handle, so we call Open again to basically // get a -106 error so that the game call CreateFile and then ReOpen again. - if(pDevice->ReturnFileHandle()) + if (pDevice->ReturnFileHandle()) Memory::Write_U32(DeviceID, _Address + 4); else pDevice->Open(_Address, Mode); @@ -368,110 +361,102 @@ void ExecuteCommand(u32 _Address) break; case COMMAND_CLOSE_DEVICE: - { - if (pDevice) - { - pDevice->Close(_Address); - // Don't delete hardware - if (!pDevice->IsHardware()) - DeleteDeviceByID(DeviceID); - CmdSuccess = true; - } - } + if (pDevice) + { + pDevice->Close(_Address); + // Don't delete hardware + if (!pDevice->IsHardware()) + DeleteDeviceByID(DeviceID); + CmdSuccess = true; + } break; case COMMAND_READ: - { - if (pDevice != NULL) - CmdSuccess = pDevice->Read(_Address); - } + if (pDevice != NULL) + CmdSuccess = pDevice->Read(_Address); break; case COMMAND_WRITE: - { - if (pDevice != NULL) - CmdSuccess = pDevice->Write(_Address); - } + if (pDevice != NULL) + CmdSuccess = pDevice->Write(_Address); break; case COMMAND_SEEK: - { - if (pDevice != NULL) - CmdSuccess = pDevice->Seek(_Address); - } + if (pDevice != NULL) + CmdSuccess = pDevice->Seek(_Address); break; case COMMAND_IOCTL: - { - if (pDevice != NULL) - CmdSuccess = pDevice->IOCtl(_Address); - } + if (pDevice != NULL) + CmdSuccess = pDevice->IOCtl(_Address); break; case COMMAND_IOCTLV: - { - if (pDevice) - CmdSuccess = pDevice->IOCtlV(_Address); - } + if (pDevice) + CmdSuccess = pDevice->IOCtlV(_Address); break; default: _dbg_assert_msg_(WII_IPC_HLE, 0, "Unknown IPC Command %i (0x%08x)", Command, _Address); - // Break on the same terms as the _dbg_assert_msg_, if LOGGING was defined break; } - // It seems that the original hardware overwrites the command after it has been - // executed. We write 8 which is not any valid command. - // - // AyuanX: Is this really necessary? - // My experiment says no, so I'm just commenting this out - // - //Memory::Write_U32(8, _Address); + // executed. We write 8 which is not any valid command, and what IOS does + Memory::Write_U32(8, _Address); + // IOS seems to write back the command that was responded to + Memory::Write_U32(Command, _Address + 8); if (CmdSuccess) { // Generate a reply to the IPC command - WII_IPCInterface::EnqReply(_Address); + EnqReply(_Address); } else { - //INFO_LOG(WII_IPC_HLE, "<<-- Failed or Not Ready to Reply to Command Address: 0x%08x ", _Address); + ERROR_LOG(WII_IPC_HLE, "<<-- Failed or Not Ready to Reply to IPC Request @ 0x%08x ", _Address); } } +// Happens AS SOON AS IPC gets a new pointer! +void EnqRequest(u32 _Address) +{ + request_queue.push(_Address); +} -// =================================================== -// This is called continuously from SystemTimers.cpp -// --------------------------------------------------- +// Called when IOS module has some reply +void EnqReply(u32 _Address) +{ + reply_queue.push(_Address); +} + +// This is called every IPC_HLE_PERIOD from SystemTimers.cpp +// Takes care of routing ipc <-> ipc HLE void Update() { - if (WII_IPCInterface::IsReady() == false) + if (!WII_IPCInterface::IsReady()) return; UpdateDevices(); - // if we have a reply to send - u32 _Reply = WII_IPCInterface::DeqReply(); - if (_Reply) + if (reply_queue.size()) { - WII_IPCInterface::GenerateReply(_Reply); - INFO_LOG(WII_IPC_HLE, "<<-- Reply to Command Address: 0x%08x", _Reply); + WII_IPCInterface::GenerateReply(reply_queue.front()); + INFO_LOG(WII_IPC_HLE, "<<-- Reply to IPC Request @ 0x%08x", reply_queue.front()); + reply_queue.pop(); return; } - // If there is a a new command - u32 _Address = WII_IPCInterface::GetAddress(); - if (_Address) + if (request_queue.size()) { - WII_IPCInterface::GenerateAck(); - INFO_LOG(WII_IPC_HLE, "||-- Acknowledge Command Address: 0x%08x", _Address); + WII_IPCInterface::GenerateAck(request_queue.front()); + INFO_LOG(WII_IPC_HLE, "||-- Acknowledge IPC Request @ 0x%08x", request_queue.front()); - ExecuteCommand(_Address); + ExecuteCommand(request_queue.front()); + request_queue.pop(); - #if MAX_LOG_LEVEL >= DEBUG_LEVEL - Debugger::PrintCallstack(LogTypes::WII_IPC_HLE, LogTypes::LDEBUG); + #if MAX_LOGLEVEL >= DEBUG_LEVEL + Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HLE, LogTypes::LDEBUG); #endif } } @@ -488,4 +473,4 @@ void UpdateDevices() } -} // end of namespace IPC +} // end of namespace WII_IPC_HLE_Interface diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h index c874e55c6a..959c7c0e05 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h @@ -61,6 +61,9 @@ void UpdateDevices(); void ExecuteCommand(u32 _Address); +void EnqRequest(u32 _Address); +void EnqReply(u32 _Address); + enum ECommandType { COMMAND_OPEN_DEVICE = 1, diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h index 41845483d8..b609cf54ef 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h @@ -77,17 +77,15 @@ protected: bool m_Hardware; bool m_Active; - // =================================================== - /* A struct for IOS ioctlv calls */ - // ---------------- + // A struct for IOS ioctlv calls struct SIOCtlVBuffer { SIOCtlVBuffer(u32 _Address) : m_Address(_Address) { - /* These are the Ioctlv parameters in the IOS communication. The BufferVector - is a memory address offset at where the in and out buffer addresses are - stored. */ + // These are the Ioctlv parameters in the IOS communication. The BufferVector + // is a memory address offset at where the in and out buffer addresses are + // stored. Parameter = Memory::Read_U32(m_Address + 0x0C); // command 3, arg0 NumberInBuffer = Memory::Read_U32(m_Address + 0x10); // 4, arg1 NumberPayloadBuffer = Memory::Read_U32(m_Address + 0x14); // 5, arg2 @@ -144,11 +142,8 @@ protected: std::vector PayloadBuffer; }; - - // =================================================== - /* Write out the IPC struct from _CommandAddress to _NumberOfCommands numbers - of 4 byte commands. */ - // ---------------- + // Write out the IPC struct from _CommandAddress to _NumberOfCommands numbers + // of 4 byte commands. void DumpCommands(u32 _CommandAddress, size_t _NumberOfCommands = 8, LogTypes::LOG_TYPE LogType = LogTypes::WII_IPC_HLE, LogTypes::LOG_LEVELS Verbosity = LogTypes::LDEBUG) @@ -161,7 +156,6 @@ protected: Memory::Read_U32(_CommandAddress + i*4)); } } - void DumpAsync(u32 BufferVector, u32 NumberInBuffer, u32 NumberOutBuffer, LogTypes::LOG_TYPE LogType = LogTypes::WII_IPC_HLE, @@ -175,7 +169,8 @@ protected: u32 InBuffer = Memory::Read_U32(BufferOffset); BufferOffset += 4; u32 InBufferSize = Memory::Read_U32(BufferOffset); BufferOffset += 4; - GENERIC_LOG(LogType, LogTypes::LINFO, "%s - IOCtlV InBuffer[%i]:", GetDeviceName().c_str(), i); + GENERIC_LOG(LogType, LogTypes::LINFO, "%s - IOCtlV InBuffer[%i]:", + GetDeviceName().c_str(), i); std::string Temp; for (u32 j = 0; j < InBufferSize; j++) @@ -188,22 +183,21 @@ protected: GENERIC_LOG(LogType, LogTypes::LDEBUG, " Buffer: %s", Temp.c_str()); } - for (u32 i = 0; i < NumberOutBuffer; i++) { u32 OutBuffer = Memory::Read_U32(BufferOffset); BufferOffset += 4; u32 OutBufferSize = Memory::Read_U32(BufferOffset); BufferOffset += 4; - GENERIC_LOG(LogType, LogTypes::LINFO, "%s - IOCtlV OutBuffer[%i]:", GetDeviceName().c_str(), i); - GENERIC_LOG(LogType, LogTypes::LINFO, " OutBuffer: 0x%08x (0x%x):", OutBuffer, OutBufferSize); + GENERIC_LOG(LogType, LogTypes::LINFO, "%s - IOCtlV OutBuffer[%i]:", + GetDeviceName().c_str(), i); + GENERIC_LOG(LogType, LogTypes::LINFO, " OutBuffer: 0x%08x (0x%x):", + OutBuffer, OutBufferSize); #if defined(MAX_LOGLEVEL) && MAX_LOGLEVEL >= INFO_LEVEL DumpCommands(OutBuffer, OutBufferSize, LogType, Verbosity); #endif } } - }; #endif - diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h index 4cb8773057..4d0a2d7983 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h @@ -37,10 +37,7 @@ enum IOCTL_STM_READDDRREG2 = 0x4002, }; - -// ======================================================= -// The /device/stm/immediate class -// ------------- +// The /dev/stm/immediate class CWII_IPC_HLE_Device_stm_immediate : public IWII_IPC_HLE_Device { public: @@ -71,11 +68,11 @@ public: virtual bool IOCtl(u32 _CommandAddress) { - u32 Parameter = Memory::Read_U32(_CommandAddress +0x0C); - u32 BufferIn = Memory::Read_U32(_CommandAddress +0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress +0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress +0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress +0x1C); + u32 Parameter = Memory::Read_U32(_CommandAddress + 0x0C); + u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); + u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); + u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); + u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); // Prepare the out buffer(s) with zeroes as a safety precaution // to avoid returning bad values @@ -123,16 +120,11 @@ public: // Write return value to the IPC call Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - - // Generate true or false reply for the main UpdateInterrupts() function return true; } }; - -// ======================================================= -// The /device/stm/eventhook class -// ------------- +// The /dev/stm/eventhook class CWII_IPC_HLE_Device_stm_eventhook : public IWII_IPC_HLE_Device { public: @@ -165,13 +157,13 @@ public: virtual bool IOCtl(u32 _CommandAddress) { - u32 Parameter = Memory::Read_U32(_CommandAddress +0x0C); - u32 BufferIn = Memory::Read_U32(_CommandAddress +0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress +0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress +0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress +0x1C); + u32 Parameter = Memory::Read_U32(_CommandAddress + 0x0C); + u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); + u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); + u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); + u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - // Prepare the out buffer(s) with zeroes as a safety precaution + // Prepare the out buffer(s) with zeros as a safety precaution // to avoid returning bad values Memory::Memset(BufferOut, 0, BufferOutSize); u32 ReturnValue = 0; @@ -184,42 +176,29 @@ public: m_EventHookAddress = _CommandAddress; INFO_LOG(WII_IPC_STM, "%s registers event hook:", GetDeviceName().c_str()); - DEBUG_LOG(WII_IPC_STM, " 0x1000 - IOCTL_STM_EVENTHOOK", Parameter); - DEBUG_LOG(WII_IPC_STM, " BufferIn: 0x%08x", BufferIn); - DEBUG_LOG(WII_IPC_STM, " BufferInSize: 0x%08x", BufferInSize); - DEBUG_LOG(WII_IPC_STM, " BufferOut: 0x%08x", BufferOut); - DEBUG_LOG(WII_IPC_STM, " BufferOutSize: 0x%08x", BufferOutSize); + DEBUG_LOG(WII_IPC_STM, "0x1000 - IOCTL_STM_EVENTHOOK", Parameter); + DEBUG_LOG(WII_IPC_STM, "BufferIn: 0x%08x", BufferIn); + DEBUG_LOG(WII_IPC_STM, "BufferInSize: 0x%08x", BufferInSize); + DEBUG_LOG(WII_IPC_STM, "BufferOut: 0x%08x", BufferOut); + DEBUG_LOG(WII_IPC_STM, "BufferOutSize: 0x%08x", BufferOutSize); DumpCommands(BufferIn, BufferInSize/4, LogTypes::WII_IPC_STM); - - return false; } break; default: - { - _dbg_assert_msg_(WII_IPC_STM, 0, "CWII_IPC_HLE_Device_stm_eventhook: 0x%x", Parameter); - INFO_LOG(WII_IPC_STM, "%s registers event hook:", GetDeviceName().c_str()); - DEBUG_LOG(WII_IPC_STM, " Parameter: 0x%x", Parameter); - DEBUG_LOG(WII_IPC_STM, " BufferIn: 0x%08x", BufferIn); - DEBUG_LOG(WII_IPC_STM, " BufferInSize: 0x%08x", BufferInSize); - DEBUG_LOG(WII_IPC_STM, " BufferOut: 0x%08x", BufferOut); - DEBUG_LOG(WII_IPC_STM, " BufferOutSize: 0x%08x", BufferOutSize); - } + _dbg_assert_msg_(WII_IPC_STM, 0, "unknown %s ioctl %x", + GetDeviceName().c_str(), Parameter); break; } // Write return value to the IPC call, 0 means success - Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - - // Generate true or false reply for the main UpdateInterrupts() function - return false; + Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); + return true; } // STATE_TO_SAVE u32 m_EventHookAddress; }; - #endif - diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp index 291a990b92..00206bc4b7 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp @@ -316,16 +316,11 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress) // write return value Memory::Write_U32(0, _CommandAddress + 0x4); - return (_SendReply); + return _SendReply; } -// ================ - -// =================================================== -/* Here we handle the USB_IOCTL_BLKMSG Ioctlv */ -// ---------------- - +// Here we handle the USB_IOCTL_BLKMSG Ioctlv void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendToDevice(u16 _ConnectionHandle, u8* _pData, u32 _Size) { CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(_ConnectionHandle); @@ -337,18 +332,12 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendToDevice(u16 _ConnectionHandle, u8 pWiiMote->ExecuteL2capCmd(_pData, _Size); } -// ================ - - -// =================================================== // Here we send ACL pakcets to CPU. They will consist of header + data. // The header is for example 07 00 41 00 which means size 0x0007 and channel 0x0041. // --------------------------------------------------- - // AyuanX: Basically, our WII_IPC_HLE is efficient enough to send the packet immediately // rather than enqueue it to some other memory // But...the only exception comes from the Wiimote_Plugin -// void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLPacket(u16 _ConnectionHandle, u8* _pData, u32 _Size) { if(m_ACLBuffer.m_address != 0) @@ -368,7 +357,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLPacket(u16 _ConnectionHandle, u Memory::Write_U32(sizeof(UACLHeader) + _Size, m_ACLBuffer.m_address + 0x4); // Send a reply to indicate ACL buffer is sent - WII_IPCInterface::EnqReply(m_ACLBuffer.m_address); + WII_IPC_HLE_Interface::EnqReply(m_ACLBuffer.m_address); // Invalidate ACL buffer m_ACLBuffer.m_address = 0; @@ -403,7 +392,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLPacket(u16 _ConnectionHandle, u // but current implementation of WiiMote_Plugin doesn't comply with this rule // It acts like sending all the 3 packets in one cycle and idling around in the other two cycles // that's why we need this contingent ACL pool -// void CWII_IPC_HLE_Device_usb_oh1_57e_305::PurgeACLPool() { if(m_ACLBuffer.m_address == 0) @@ -420,16 +408,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::PurgeACLPool() // Write the packet size as return value Memory::Write_U32(sizeof(UACLHeader) + ((UACLHeader*)_Address)->Size, m_ACLBuffer.m_address + 0x4); // Send a reply to indicate ACL buffer is sent - WII_IPCInterface::EnqReply(m_ACLBuffer.m_address); + WII_IPC_HLE_Interface::EnqReply(m_ACLBuffer.m_address); // Invalidate ACL buffer m_ACLBuffer.m_address = 0; m_ACLBuffer.m_buffer = NULL; } } -// =================================================== -/* See IPC_HLE_PERIOD in SystemTimers.cpp for a documentation of this update. */ -// ---------------- +// See IPC_HLE_PERIOD in SystemTimers.cpp for a documentation of this update. u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() { // Check if HCI Pool is not purged @@ -437,7 +423,7 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() { PurgeHCIPool(); if (m_HCIPool.m_number == 0) - WII_IPCInterface::EnqReply(m_CtrlSetup.m_Address); + WII_IPC_HLE_Interface::EnqReply(m_CtrlSetup.m_Address); return true; } @@ -453,23 +439,22 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() { PurgeACLPool(); if (m_ACLPool.m_number == 0) - WII_IPCInterface::EnqReply(m_ACLSetup); + WII_IPC_HLE_Interface::EnqReply(m_ACLSetup); return true; } - // -------------------------------------------------------------------- /* We wait for ScanEnable to be sent from the game through HCI_CMD_WRITE_SCAN_ENABLE before we initiate the connection. FiRES: TODO find a good solution to do this - /* Why do we need this? 0 worked with the emulated wiimote in all games I tried. Do we have to + Why do we need this? 0 worked with the emulated wiimote in all games I tried. Do we have to wait for wiiuse_init() and wiiuse_find() for a real Wiimote here? I'm testing this new method of not waiting at all if there are no real Wiimotes. Please let me know if it doesn't work. */ // AyuanX: I don't know the Real Wiimote behavior, so I'll leave it here untouched - // + // Initiate ACL connection static int counter = (Core::GetRealWiimote() ? 1000 : 0); if (m_HCIBuffer.m_address && (m_ScanEnable & 0x2)) @@ -537,17 +522,13 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update() return false; } - - // Events // ----------------- // These messages are sent from the Wiimote to the game, for example RequestConnection() // or ConnectionComplete(). // - // Our WII_IPC_HLE is so efficient that we could fill the buffer immediately // rather than enqueue it to some other memory and this will do good for StateSave -// void CWII_IPC_HLE_Device_usb_oh1_57e_305::AddEventToQueue(const SQueuedEvent& _event) { if (m_HCIBuffer.m_address != 0) @@ -560,7 +541,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::AddEventToQueue(const SQueuedEvent& _e Memory::Write_U32((u32)_event.m_size, m_HCIBuffer.m_address + 0x4); // Send a reply to indicate HCI buffer is filled - WII_IPCInterface::EnqReply(m_HCIBuffer.m_address); + WII_IPC_HLE_Interface::EnqReply(m_HCIBuffer.m_address); // Invalidate HCI buffer m_HCIBuffer.m_address = 0; @@ -590,7 +571,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::AddEventToQueue(const SQueuedEvent& _e // so when IPC is running too fast that CPU can't catch up // then CPU(actually it is the usb driver) sometimes throws out a command before sending us a HCI buffer // So I put this contingent HCI Pool here until we figure out the true reason -// void CWII_IPC_HLE_Device_usb_oh1_57e_305::PurgeHCIPool() { if(m_HCIBuffer.m_address == 0) @@ -607,7 +587,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::PurgeHCIPool() // Write the packet size as return value Memory::Write_U32(m_HCIPool.m_size[m_HCIPool.m_number], m_HCIBuffer.m_address + 0x4); // Send a reply to indicate ACL buffer is sent - WII_IPCInterface::EnqReply(m_HCIBuffer.m_address); + WII_IPC_HLE_Interface::EnqReply(m_HCIBuffer.m_address); // Invalidate ACL buffer m_HCIBuffer.m_address = 0; m_HCIBuffer.m_buffer = NULL; @@ -714,7 +694,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventConnectionComplete(const bdad return true; } -/* This is called from Update() after ScanEnable has been enabled. */ +// This is called from Update() after ScanEnable has been enabled. bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRequestConnection(CWII_IPC_HLE_WiiMote& _rWiiMote) { SQueuedEvent Event(sizeof(SHCIEventRequestConnection), 0); @@ -1137,8 +1117,6 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventConPacketTypeChange(u16 _conn // Command dispatcher // ----------------- // This is called from the USB_IOCTL_HCI_COMMAND_MESSAGE Ioctlv -// -// void CWII_IPC_HLE_Device_usb_oh1_57e_305::ExecuteHCICommandMessage(const SHCICommandMessage& _rHCICommandMessage) { u8* pInput = Memory::GetPointer(_rHCICommandMessage.m_PayLoadAddr + 3); @@ -1329,7 +1307,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::ExecuteHCICommandMessage(const SHCICom if ((m_LastCmd == 0) && (m_HCIPool.m_number == 0)) { // If HCI command is finished and HCI pool is empty, send a reply to command - WII_IPCInterface::EnqReply(_rHCICommandMessage.m_Address); + WII_IPC_HLE_Interface::EnqReply(_rHCICommandMessage.m_Address); } }