From efd9bae44958e01984824058f3194b4697b1a4a2 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Thu, 2 Sep 2010 04:17:23 +0000 Subject: [PATCH] improve ios hle error handling. remove stubbed devices. they now fall back to the base device class, which reports the device as not available. fixes issue 3137. start ios fd counting at 0 instead of 0x13370000. I know it's sad, but it fixes homebrew booting and such. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6164 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 79 +++++++++++++------ Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h | 4 +- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device.h | 62 ++++++++++----- .../Src/IPC_HLE/WII_IPC_HLE_Device_Error.h | 52 ------------ 4 files changed, 99 insertions(+), 98 deletions(-) delete mode 100644 Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Error.h 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 c9d19f71c0..ee3d635097 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -41,7 +41,6 @@ They will also generate a true or false return for UpdateInterrupts() in WII_IPC #include "CommonPaths.h" #include "WII_IPC_HLE.h" #include "WII_IPC_HLE_Device.h" -#include "WII_IPC_HLE_Device_Error.h" #include "WII_IPC_HLE_Device_DI.h" #include "WII_IPC_HLE_Device_FileIO.h" #include "WII_IPC_HLE_Device_stm.h" @@ -76,7 +75,6 @@ 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() { _dbg_assert_msg_(WII_IPC_HLE, g_DeviceMap.empty(), "DeviceMap isnt empty on init"); @@ -93,11 +91,9 @@ void Init() g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_kd_time(i, std::string("/dev/net/kd/time")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_ncd_manage(i, std::string("/dev/net/ncd/manage")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_net_ip_top(i, std::string("/dev/net/ip/top")); i++; - g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_oh0(i, std::string("/dev/usb/oh0")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_kbd(i, std::string("/dev/usb/kbd")); i++; - g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_hid(i, std::string("/dev/usb/hid")); i++; g_DeviceMap[i] = new CWII_IPC_HLE_Device_sdio_slot0(i, std::string("/dev/sdio/slot0")); i++; - g_DeviceMap[i] = new CWII_IPC_HLE_Device_Error(i, std::string("_Unknown_Device_")); i++; + g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, std::string("_Unimplemented_Device_")); g_LastDeviceID = IPC_FIRST_FILEIO_ID; } @@ -151,7 +147,7 @@ u32 GetDeviceIDByName(const std::string& _rDeviceName) ++itr; } - return 0; + return -1; } IWII_IPC_HLE_Device* AccessDeviceByID(u32 _ID) @@ -284,22 +280,29 @@ void ExecuteCommand(u32 _Address) DeviceID = GetDeviceIDByName(DeviceName); // check if a device with this name has been created already - if (DeviceID == 0) + if (DeviceID == -1) { if (DeviceName.find("/dev/") != std::string::npos) { - ERROR_LOG(WII_IPC_FILEIO, "Unknown device: %s", DeviceName.c_str()); + WARN_LOG(WII_IPC_HLE, "Unimplemented device: %s", DeviceName.c_str()); + + pDevice = AccessDeviceByID(GetDeviceIDByName(std::string("_Unimplemented_Device_"))); + CmdSuccess = pDevice->Open(_Address, Mode); } - u32 CurrentDeviceID = g_LastDeviceID; - pDevice = CreateFileIO(CurrentDeviceID, DeviceName); - g_DeviceMap[CurrentDeviceID] = pDevice; - g_FileNameMap[CurrentDeviceID] = DeviceName; - g_LastDeviceID++; + else + { + // create new file handle + u32 CurrentDeviceID = g_LastDeviceID; + pDevice = CreateFileIO(CurrentDeviceID, DeviceName); + g_DeviceMap[CurrentDeviceID] = pDevice; + g_FileNameMap[CurrentDeviceID] = DeviceName; + g_LastDeviceID++; + + CmdSuccess = pDevice->Open(_Address, Mode); - CmdSuccess = pDevice->Open(_Address, Mode); - - INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, ID=%08x, Mode=%i)", - pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode); + INFO_LOG(WII_IPC_FILEIO, "IOP: Open File (Device=%s, ID=%08x, Mode=%i)", + pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode); + } } else { @@ -356,31 +359,50 @@ void ExecuteCommand(u32 _Address) case COMMAND_CLOSE_DEVICE: if (pDevice) { - pDevice->Close(_Address); + CmdSuccess = pDevice->Close(_Address); // Don't delete hardware if (!pDevice->IsHardware()) DeleteDeviceByID(DeviceID); - CmdSuccess = true; + } + else + { + Memory::Write_U32(FS_EINVAL, _Address + 4); + CmdSuccess = true; } break; case COMMAND_READ: - if (pDevice != NULL) + if (pDevice) CmdSuccess = pDevice->Read(_Address); + else + { + Memory::Write_U32(FS_EINVAL, _Address + 4); + CmdSuccess = true; + } break; case COMMAND_WRITE: - if (pDevice != NULL) + if (pDevice) CmdSuccess = pDevice->Write(_Address); + else + { + Memory::Write_U32(FS_EINVAL, _Address + 4); + CmdSuccess = true; + } break; case COMMAND_SEEK: - if (pDevice != NULL) + if (pDevice) CmdSuccess = pDevice->Seek(_Address); + else + { + Memory::Write_U32(FS_EINVAL, _Address + 4); + CmdSuccess = true; + } break; case COMMAND_IOCTL: - if (pDevice != NULL) + if (pDevice) CmdSuccess = pDevice->IOCtl(_Address); break; @@ -395,7 +417,7 @@ void ExecuteCommand(u32 _Address) } // It seems that the original hardware overwrites the command after it has been - // executed. We write 8 which is not any valid command, and what IOS does + // 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); @@ -407,7 +429,14 @@ void ExecuteCommand(u32 _Address) } else { - //DEBUG_LOG(WII_IPC_HLE, "<<-- Failed or Not Ready to Reply to IPC Request @ 0x%08x ", _Address); + if (pDevice) + { + INFO_LOG(WII_IPC_HLE, "<<-- Reply Failed to %s IPC Request %i @ 0x%08x ", pDevice->GetDeviceName().c_str(), Command, _Address); + } + else + { + INFO_LOG(WII_IPC_HLE, "<<-- Reply Failed to Unknown (%08x) IPC Request %i @ 0x%08x ", DeviceID, Command, _Address); + } } } 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 959c7c0e05..177a3f02ce 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h @@ -25,8 +25,8 @@ class IWII_IPC_HLE_Device; namespace WII_IPC_HLE_Interface { -#define IPC_FIRST_HARDWARE_ID 0x13370000 // first IPC device ID -#define IPC_FIRST_FILEIO_ID 0x13380000 // first IPC file ID +#define IPC_FIRST_HARDWARE_ID 0 // first IPC device ID +#define IPC_FIRST_FILEIO_ID 33 // first IPC file ID // Init void Init(); 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 b413f2aff1..c41c64fb12 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 @@ -23,6 +23,31 @@ class PointerWrap; + +#define FS_SUCCESS (u32)0 // Success +#define FS_EACCES (u32)-1 // Permission denied +#define FS_EEXIST (u32)-2 // File exists +#define FS_EINVAL (u32)-4 // Invalid argument Invalid FD +#define FS_ENOENT (u32)-6 // File not found +#define FS_EBUSY (u32)-8 // Resource busy +#define FS_EIO (u32)-12 // returned on ECC error +#define FS_ENOMEM (u32)-22 // Alloc failed during request +#define FS_EFATAL (u32)-101 // Fatal error +#define FS_EACCESS (u32)-102 // Permission denied +#define FS_ECORRUPT (u32)-103 // returned for "corrupted" NAND +#define FS_EEXIST2 (u32)-105 // File exists +#define FS_ENOENT2 (u32)-106 // File not found +#define FS_ENFILE (u32)-107 // Too many fds open +#define FS_EFBIG (u32)-108 // max block count reached? +#define FS_ENFILE2 (u32)-109 // Too many fds open +#define FS_ENAMELEN (u32)-110 // pathname is too long +#define FS_EFDOPEN (u32)-111 // FD is already open +#define FS_EIO2 (u32)-114 // returned on ECC error +#define FS_ENOTEMPTY (u32)-115 // Directory not empty +#define FS_EDIRDEPTH (u32)-116 // max directory depth exceeded +#define FS_EBUSY2 (u32)-118 // Resource busy +//#define FS_EFATAL (u32)-119 // fatal error not used by IOS as fatal ERROR + class IWII_IPC_HLE_Device { public: @@ -42,19 +67,21 @@ public: u32 GetDeviceID() const { return m_DeviceID; } virtual bool Open(u32 _CommandAddress, u32 _Mode) { - (void)_CommandAddress; (void)_Mode; - _dbg_assert_msg_(WII_IPC_HLE, 0, "%s does not support Open()", m_Name.c_str()); + (void)_Mode; + WARN_LOG(WII_IPC_HLE, "%s does not support Open()", m_Name.c_str()); + Memory::Write_U32(FS_ENOENT, _CommandAddress + 4); m_Active = true; return true; } virtual bool Close(u32 _CommandAddress, bool _bForce = false) { - (void)_CommandAddress; (void)_bForce; - _dbg_assert_msg_(WII_IPC_HLE, 0, "%s does not support Close()", m_Name.c_str()); + WARN_LOG(WII_IPC_HLE, "%s does not support Close()", m_Name.c_str()); + if (!_bForce) + Memory::Write_U32(FS_EINVAL, _CommandAddress + 4); m_Active = false; return true; } -#define UNIMPLEMENTED_CMD(cmd) _dbg_assert_msg_(WII_IPC_HLE, 0, "%s does not support "#cmd"()", m_Name.c_str()); return true; +#define UNIMPLEMENTED_CMD(cmd) WARN_LOG(WII_IPC_HLE, "%s does not support "#cmd"()", m_Name.c_str()); return true; virtual bool Seek (u32) { UNIMPLEMENTED_CMD(Seek) } virtual bool Read (u32) { UNIMPLEMENTED_CMD(Read) } virtual bool Write (u32) { UNIMPLEMENTED_CMD(Write) } @@ -80,46 +107,43 @@ protected: // A struct for IOS ioctlv calls struct SIOCtlVBuffer { - SIOCtlVBuffer(u32 _Address) - : m_Address(_Address) + 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. - 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 - BufferVector = Memory::Read_U32(m_Address + 0x18); // 6, arg3 + 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 + BufferVector = Memory::Read_U32(m_Address + 0x18); // 6, arg3 // The start of the out buffer u32 BufferVectorOffset = BufferVector; - //if(Parameter = 0x1d) PanicAlert("%i: %i", Parameter, NumberInBuffer); - // Write the address and size for all in messages for (u32 i = 0; i < NumberInBuffer; i++) { SBuffer Buffer; - Buffer.m_Address = Memory::Read_U32(BufferVectorOffset); + Buffer.m_Address = Memory::Read_U32(BufferVectorOffset); BufferVectorOffset += 4; - Buffer.m_Size = Memory::Read_U32(BufferVectorOffset); + Buffer.m_Size = Memory::Read_U32(BufferVectorOffset); BufferVectorOffset += 4; + InBuffer.push_back(Buffer); DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer in%i: 0x%08x, 0x%x", i, Buffer.m_Address, Buffer.m_Size); - InBuffer.push_back(Buffer); } // Write the address and size for all out or in-out messages for (u32 i = 0; i < NumberPayloadBuffer; i++) { SBuffer Buffer; - Buffer.m_Address = Memory::Read_U32(BufferVectorOffset); + Buffer.m_Address = Memory::Read_U32(BufferVectorOffset); BufferVectorOffset += 4; - Buffer.m_Size = Memory::Read_U32(BufferVectorOffset); + Buffer.m_Size = Memory::Read_U32(BufferVectorOffset); BufferVectorOffset += 4; + PayloadBuffer.push_back(Buffer); DEBUG_LOG(WII_IPC_HLE, "SIOCtlVBuffer io%i: 0x%08x, 0x%x", i, Buffer.m_Address, Buffer.m_Size); - PayloadBuffer.push_back(Buffer); } } diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Error.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Error.h deleted file mode 100644 index 9bdf1f4e88..0000000000 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Error.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#ifndef _WII_IPC_HLE_DEVICE_ERROR_H_ -#define _WII_IPC_HLE_DEVICE_ERROR_H_ - -#include "WII_IPC_HLE_Device.h" - -class CWII_IPC_HLE_Device_Error : public IWII_IPC_HLE_Device -{ -public: - - CWII_IPC_HLE_Device_Error(u32 _DeviceID, const std::string& _rDeviceName ) : - IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) - {} - - virtual ~CWII_IPC_HLE_Device_Error() - {} - - virtual bool Open(u32 _CommandAddress, u32 _Mode) - { - //PanicAlert("CWII_IPC_HLE_Device_Error"); - Memory::Write_U32(GetDeviceID(), _CommandAddress + 4); - m_Active = true; - return true; - } - - virtual bool Close(u32 _CommandAddress, bool _bForce) - { - if (!_bForce) - Memory::Write_U32(0, _CommandAddress + 4); - m_Active = false; - return true; - } -}; - -#endif -