Permalink
Browse files

Fix SDIO HLE writing garbage to memory.

When servicing a write-register request, it wrote the contents to the
register offset plus 0x8d070000, which corresponds to the actual
hardware registers, presumably in case the application wanted to read
them directly rather than with a read-register request.  WriteToHardware
doesn't handle cached writes to registers, so it decided the address was
RAM, applied RAM_MASK, and happily wrote the register contents to
0x81070000, causing random corruption.  Since the PPC does not normally
have access to those registers, there is no reason to be doing this in
the first place.  Use a member to store these values instead.

(Also add a proper DoState.)
  • Loading branch information...
comex committed Sep 10, 2013
1 parent a3ef35a commit 4add0f55e046c4fd2943e96da127b4940543ac84
@@ -22,6 +22,19 @@ CWII_IPC_HLE_Device_sdio_slot0::CWII_IPC_HLE_Device_sdio_slot0(u32 _DeviceID, co
, m_Card(NULL)
{}
+void CWII_IPC_HLE_Device_sdio_slot0::DoState(PointerWrap& p)
+{
+ DoStateShared(p);
+ if (p.GetMode() == PointerWrap::MODE_READ)
+ {
+ OpenInternal();
+ }
+ p.Do(m_Status);
+ p.Do(m_BlockLength);
+ p.Do(m_BusWidth);
+ p.Do(m_Registers);
+}
+
void CWII_IPC_HLE_Device_sdio_slot0::EventNotify()
{
if ((SConfig::GetInstance().m_WiiSDCard && m_event.type == EVENT_INSERT) ||
@@ -34,10 +47,8 @@ void CWII_IPC_HLE_Device_sdio_slot0::EventNotify()
}
}
-bool CWII_IPC_HLE_Device_sdio_slot0::Open(u32 _CommandAddress, u32 _Mode)
+void CWII_IPC_HLE_Device_sdio_slot0::OpenInternal()
{
- INFO_LOG(WII_IPC_SD, "Open");
-
const std::string filename = File::GetUserPath(D_WIIUSER_IDX) + "sd.raw";
m_Card.Open(filename, "r+b");
if (!m_Card)
@@ -53,8 +64,16 @@ bool CWII_IPC_HLE_Device_sdio_slot0::Open(u32 _CommandAddress, u32 _Mode)
ERROR_LOG(WII_IPC_SD, "Could not open SD Card image or create a new one, are you running from a read-only directory?");
}
}
+}
+
+bool CWII_IPC_HLE_Device_sdio_slot0::Open(u32 _CommandAddress, u32 _Mode)
+{
+ INFO_LOG(WII_IPC_SD, "Open");
+
+ OpenInternal();
Memory::Write_U32(GetDeviceID(), _CommandAddress + 0x4);
+ memset(m_Registers, 0, sizeof(m_Registers));
m_Active = true;
return true;
}
@@ -96,30 +115,43 @@ bool CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress)
DEBUG_LOG(WII_IPC_SD, "IOCTL_WRITEHCR 0x%08x - 0x%08x", reg, val);
+ if (reg >= 0x200)
+ {
+ DEBUG_LOG(WII_IPC_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
- Memory::Write_U32(val | 2, SDIO_BASE + reg);
+ m_Registers[reg] = val | 2;
}
else if ((reg == HCR_SOFTWARERESET) && val)
{
// When a reset is specified, the register gets cleared
- Memory::Write_U32(0, SDIO_BASE + reg);
+ m_Registers[reg] = 0;
}
else
{
// Default to just storing the new value
- Memory::Write_U32(val, SDIO_BASE + reg);
+ m_Registers[reg] = val;
}
}
break;
case IOCTL_READHCR:
{
u32 reg = Memory::Read_U32(BufferIn);
- u32 val = Memory::Read_U32(SDIO_BASE + reg);
+ if (reg >= 0x200)
+ {
+ DEBUG_LOG(WII_IPC_SD, "IOCTL_READHCR out of range");
+ break;
+ }
+
+ u32 val = m_Registers[reg];
DEBUG_LOG(WII_IPC_SD, "IOCTL_READHCR 0x%08x - 0x%08x", reg, val);
+
// Just reading the register
Memory::Write_U32(val, BufferOut);
}
@@ -15,6 +15,8 @@ class CWII_IPC_HLE_Device_sdio_slot0 : public IWII_IPC_HLE_Device
CWII_IPC_HLE_Device_sdio_slot0(u32 _DeviceID, const std::string& _rDeviceName);
+ virtual void DoState(PointerWrap& p);
+
bool Open(u32 _CommandAddress, u32 _Mode);
bool Close(u32 _CommandAddress, bool _bForce);
bool IOCtl(u32 _CommandAddress);
@@ -24,11 +26,6 @@ class CWII_IPC_HLE_Device_sdio_slot0 : public IWII_IPC_HLE_Device
private:
- enum
- {
- SDIO_BASE = 0x8d070000,
- };
-
// SD Host Controller Registers
enum
{
@@ -119,11 +116,14 @@ class CWII_IPC_HLE_Device_sdio_slot0 : public IWII_IPC_HLE_Device
u32 m_BlockLength;
u32 m_BusWidth;
+ u32 m_Registers[0x200/4];
+
File::IOFile m_Card;
u32 ExecuteCommand(u32 BufferIn, u32 BufferInSize,
u32 BufferIn2, u32 BufferInSize2,
u32 _BufferOut, u32 BufferOutSize);
+ void OpenInternal();
};
#endif

0 comments on commit 4add0f5

Please sign in to comment.