From 225ac37f21f6013382c9260e4c55fcb0037eb41d Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 13 Mar 2017 16:22:41 -0400 Subject: [PATCH] SDIOSlot0: Separate IOCtl/IOCtlV behavior into individual functions Keeps the individual behaviors separate from one another. --- Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp | 243 ++++++++++++++---------- Source/Core/Core/IOS/SDIO/SDIOSlot0.h | 22 ++- 2 files changed, 157 insertions(+), 108 deletions(-) diff --git a/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp b/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp index 2d43c1fd14..96a2d48219 100644 --- a/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp +++ b/Source/Core/Core/IOS/SDIO/SDIOSlot0.cpp @@ -92,137 +92,46 @@ void SDIOSlot0::Close() m_is_active = false; } -// The front SD slot IPCCommandResult SDIOSlot0::IOCtl(const IOCtlRequest& request) { Memory::Memset(request.buffer_out, 0, request.buffer_out_size); - s32 return_value = IPC_SUCCESS; + switch (request.request) { case IOCTL_WRITEHCR: - { - u32 reg = Memory::Read_U32(request.buffer_in); - u32 val = Memory::Read_U32(request.buffer_in + 16); - - INFO_LOG(IOS_SD, "IOCTL_WRITEHCR 0x%08x - 0x%08x", reg, val); - - if (reg >= m_registers.size()) - { - WARN_LOG(IOS_SD, "IOCTL_WRITEHCR out of range"); - break; - } - - if ((reg == HCR_CLOCKCONTROL) && (val & 1)) - { - // Clock is set to oscillate, enable bit 1 to say it's stable - m_registers[reg] = val | 2; - } - else if ((reg == HCR_SOFTWARERESET) && val) - { - // When a reset is specified, the register gets cleared - m_registers[reg] = 0; - } - else - { - // Default to just storing the new value - m_registers[reg] = val; - } - } - break; - + return WriteHCRegister(request); case IOCTL_READHCR: - { - u32 reg = Memory::Read_U32(request.buffer_in); - - if (reg >= m_registers.size()) - { - WARN_LOG(IOS_SD, "IOCTL_READHCR out of range"); - break; - } - - u32 val = m_registers[reg]; - INFO_LOG(IOS_SD, "IOCTL_READHCR 0x%08x - 0x%08x", reg, val); - - // Just reading the register - Memory::Write_U32(val, request.buffer_out); - } - break; - + return ReadHCRegister(request); case IOCTL_RESETCARD: - INFO_LOG(IOS_SD, "IOCTL_RESETCARD"); - if (m_Card) - m_Status |= CARD_INITIALIZED; - // Returns 16bit RCA and 16bit 0s (meaning success) - Memory::Write_U32(0x9f620000, request.buffer_out); - break; - + return ResetCard(request); case IOCTL_SETCLK: - { - INFO_LOG(IOS_SD, "IOCTL_SETCLK"); - // libogc only sets it to 1 and makes sure the return isn't negative... - // one half of the sdclk divisor: a power of two or zero. - u32 clock = Memory::Read_U32(request.buffer_in); - if (clock != 1) - INFO_LOG(IOS_SD, "Setting to %i, interesting", clock); - } - break; - + return SetClk(request); case IOCTL_SENDCMD: - INFO_LOG(IOS_SD, "IOCTL_SENDCMD %x IPC:%08x", Memory::Read_U32(request.buffer_in), - request.address); - return_value = ExecuteCommand(request, request.buffer_in, request.buffer_in_size, 0, 0, - request.buffer_out, request.buffer_out_size); - break; - + return SendCommand(request); case IOCTL_GETSTATUS: - if (SConfig::GetInstance().m_WiiSDCard) - m_Status |= CARD_INSERTED; - else - m_Status = CARD_NOT_EXIST; - INFO_LOG(IOS_SD, "IOCTL_GETSTATUS. Replying that SD card is %s%s", - (m_Status & CARD_INSERTED) ? "inserted" : "not present", - (m_Status & CARD_INITIALIZED) ? " and initialized" : ""); - Memory::Write_U32(m_Status, request.buffer_out); - break; - + return GetStatus(request); case IOCTL_GETOCR: - INFO_LOG(IOS_SD, "IOCTL_GETOCR"); - Memory::Write_U32(0x80ff8000, request.buffer_out); - break; - + return GetOCRegister(request); default: ERROR_LOG(IOS_SD, "Unknown SD IOCtl command (0x%08x)", request.request); break; } - if (return_value == RET_EVENT_REGISTER) - { - // Check if the condition is already true - EventNotify(); - return GetNoReply(); - } - return GetDefaultReply(return_value); + return GetDefaultReply(IPC_SUCCESS); } IPCCommandResult SDIOSlot0::IOCtlV(const IOCtlVRequest& request) { - s32 return_value = IPC_SUCCESS; switch (request.request) { case IOCTLV_SENDCMD: - DEBUG_LOG(IOS_SD, "IOCTLV_SENDCMD 0x%08x", Memory::Read_U32(request.in_vectors[0].address)); - Memory::Memset(request.io_vectors[0].address, 0, request.io_vectors[0].size); - return_value = - ExecuteCommand(request, request.in_vectors[0].address, request.in_vectors[0].size, - request.in_vectors[1].address, request.in_vectors[1].size, - request.io_vectors[0].address, request.io_vectors[0].size); - break; - + return SendCommand(request); default: ERROR_LOG(IOS_SD, "Unknown SD IOCtlV command 0x%08x", request.request); + break; } - return GetDefaultReply(return_value); + return GetDefaultReply(IPC_SUCCESS); } u32 SDIOSlot0::ExecuteCommand(const Request& request, u32 _BufferIn, u32 _BufferInSize, @@ -405,6 +314,134 @@ u32 SDIOSlot0::ExecuteCommand(const Request& request, u32 _BufferIn, u32 _Buffer return ret; } + +IPCCommandResult SDIOSlot0::WriteHCRegister(const IOCtlRequest& request) +{ + u32 reg = Memory::Read_U32(request.buffer_in); + u32 val = Memory::Read_U32(request.buffer_in + 16); + + INFO_LOG(IOS_SD, "IOCTL_WRITEHCR 0x%08x - 0x%08x", reg, val); + + if (reg >= m_registers.size()) + { + WARN_LOG(IOS_SD, "IOCTL_WRITEHCR out of range"); + return GetDefaultReply(IPC_SUCCESS); + } + + if ((reg == HCR_CLOCKCONTROL) && (val & 1)) + { + // Clock is set to oscillate, enable bit 1 to say it's stable + m_registers[reg] = val | 2; + } + else if ((reg == HCR_SOFTWARERESET) && val) + { + // When a reset is specified, the register gets cleared + m_registers[reg] = 0; + } + else + { + // Default to just storing the new value + m_registers[reg] = val; + } + + return GetDefaultReply(IPC_SUCCESS); +} + +IPCCommandResult SDIOSlot0::ReadHCRegister(const IOCtlRequest& request) +{ + u32 reg = Memory::Read_U32(request.buffer_in); + + if (reg >= m_registers.size()) + { + WARN_LOG(IOS_SD, "IOCTL_READHCR out of range"); + return GetDefaultReply(IPC_SUCCESS); + } + + u32 val = m_registers[reg]; + INFO_LOG(IOS_SD, "IOCTL_READHCR 0x%08x - 0x%08x", reg, val); + + // Just reading the register + Memory::Write_U32(val, request.buffer_out); + return GetDefaultReply(IPC_SUCCESS); +} + +IPCCommandResult SDIOSlot0::ResetCard(const IOCtlRequest& request) +{ + INFO_LOG(IOS_SD, "IOCTL_RESETCARD"); + + if (m_Card) + m_Status |= CARD_INITIALIZED; + + // Returns 16bit RCA and 16bit 0s (meaning success) + Memory::Write_U32(0x9f620000, request.buffer_out); + return GetDefaultReply(IPC_SUCCESS); +} + +IPCCommandResult SDIOSlot0::SetClk(const IOCtlRequest& request) +{ + INFO_LOG(IOS_SD, "IOCTL_SETCLK"); + + // libogc only sets it to 1 and makes sure the return isn't negative... + // one half of the sdclk divisor: a power of two or zero. + u32 clock = Memory::Read_U32(request.buffer_in); + if (clock != 1) + INFO_LOG(IOS_SD, "Setting to %i, interesting", clock); + + return GetDefaultReply(IPC_SUCCESS); +} + +IPCCommandResult SDIOSlot0::SendCommand(const IOCtlRequest& request) +{ + INFO_LOG(IOS_SD, "IOCTL_SENDCMD %x IPC:%08x", Memory::Read_U32(request.buffer_in), + request.address); + + const s32 return_value = ExecuteCommand(request, request.buffer_in, request.buffer_in_size, 0, 0, + request.buffer_out, request.buffer_out_size); + + if (return_value == RET_EVENT_REGISTER) + { + // Check if the condition is already true + EventNotify(); + return GetNoReply(); + } + + return GetDefaultReply(IPC_SUCCESS); +} + +IPCCommandResult SDIOSlot0::GetStatus(const IOCtlRequest& request) +{ + if (SConfig::GetInstance().m_WiiSDCard) + m_Status |= CARD_INSERTED; + else + m_Status = CARD_NOT_EXIST; + + INFO_LOG(IOS_SD, "IOCTL_GETSTATUS. Replying that SD card is %s%s", + (m_Status & CARD_INSERTED) ? "inserted" : "not present", + (m_Status & CARD_INITIALIZED) ? " and initialized" : ""); + + Memory::Write_U32(m_Status, request.buffer_out); + return GetDefaultReply(IPC_SUCCESS); +} + +IPCCommandResult SDIOSlot0::GetOCRegister(const IOCtlRequest& request) +{ + INFO_LOG(IOS_SD, "IOCTL_GETOCR"); + Memory::Write_U32(0x80ff8000, request.buffer_out); + return GetDefaultReply(IPC_SUCCESS); +} + +IPCCommandResult SDIOSlot0::SendCommand(const IOCtlVRequest& request) +{ + DEBUG_LOG(IOS_SD, "IOCTLV_SENDCMD 0x%08x", Memory::Read_U32(request.in_vectors[0].address)); + Memory::Memset(request.io_vectors[0].address, 0, request.io_vectors[0].size); + + const s32 return_value = + ExecuteCommand(request, request.in_vectors[0].address, request.in_vectors[0].size, + request.in_vectors[1].address, request.in_vectors[1].size, + request.io_vectors[0].address, request.io_vectors[0].size); + + return GetDefaultReply(return_value); +} } // namespace Device } // namespace HLE } // namespace IOS diff --git a/Source/Core/Core/IOS/SDIO/SDIOSlot0.h b/Source/Core/Core/IOS/SDIO/SDIOSlot0.h index 1beb504669..6fd08a9b16 100644 --- a/Source/Core/Core/IOS/SDIO/SDIOSlot0.h +++ b/Source/Core/Core/IOS/SDIO/SDIOSlot0.h @@ -22,6 +22,7 @@ namespace HLE { namespace Device { +// The front SD slot class SDIOSlot0 : public Device { public: @@ -110,13 +111,28 @@ private: EVENT_INVALID = 0xc210000 }; - // TODO do we need more than one? struct Event { Event(EventType type_, Request request_) : type(type_), request(request_) {} EventType type; Request request; }; + + IPCCommandResult WriteHCRegister(const IOCtlRequest& request); + IPCCommandResult ReadHCRegister(const IOCtlRequest& request); + IPCCommandResult ResetCard(const IOCtlRequest& request); + IPCCommandResult SetClk(const IOCtlRequest& request); + IPCCommandResult SendCommand(const IOCtlRequest& request); + IPCCommandResult GetStatus(const IOCtlRequest& request); + IPCCommandResult GetOCRegister(const IOCtlRequest& request); + + IPCCommandResult SendCommand(const IOCtlVRequest& request); + + u32 ExecuteCommand(const Request& request, u32 BufferIn, u32 BufferInSize, u32 BufferIn2, + u32 BufferInSize2, u32 _BufferOut, u32 BufferOutSize); + void OpenInternal(); + + // TODO: do we need more than one? std::unique_ptr m_event; u32 m_Status = CARD_NOT_EXIST; @@ -126,10 +142,6 @@ private: std::array m_registers; File::IOFile m_Card; - - u32 ExecuteCommand(const Request& request, u32 BufferIn, u32 BufferInSize, u32 BufferIn2, - u32 BufferInSize2, u32 _BufferOut, u32 BufferOutSize); - void OpenInternal(); }; } // namespace Device } // namespace HLE