SDIO: the CID/CSD are sent a bit differently
This commit is contained in:
parent
ed0d33953d
commit
a755969ca8
|
@ -237,18 +237,23 @@ s32 SDIOSlot0Device::ExecuteCommand(const Request& request, u32 buffer_in, u32 b
|
||||||
case SEND_CSD:
|
case SEND_CSD:
|
||||||
{
|
{
|
||||||
const std::array<u32, 4> csd = m_protocol == SDProtocol::V1 ? GetCSDv1() : GetCSDv2();
|
const std::array<u32, 4> csd = m_protocol == SDProtocol::V1 ? GetCSDv1() : GetCSDv2();
|
||||||
memory.CopyToEmuSwapped(buffer_out, csd.data(), csd.size() * sizeof(u32));
|
memory.Write_U32(csd[0], buffer_out + 12);
|
||||||
|
memory.Write_U32(csd[1], buffer_out + 8);
|
||||||
|
memory.Write_U32(csd[2], buffer_out + 4);
|
||||||
|
memory.Write_U32(csd[3], buffer_out + 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ALL_SEND_CID:
|
case ALL_SEND_CID:
|
||||||
case SEND_CID:
|
case SEND_CID:
|
||||||
|
{
|
||||||
INFO_LOG_FMT(IOS_SD, "(ALL_)SEND_CID");
|
INFO_LOG_FMT(IOS_SD, "(ALL_)SEND_CID");
|
||||||
memory.Write_U32(0x00D0444F, buffer_out + 12);
|
memory.Write_U32(0x00D0444F, buffer_out + 12);
|
||||||
memory.Write_U32(0x4C504849, buffer_out + 8);
|
memory.Write_U32(0x4C504849, buffer_out + 8);
|
||||||
memory.Write_U32(0x4E430403, buffer_out + 4);
|
memory.Write_U32(0x4E430403, buffer_out + 4);
|
||||||
memory.Write_U32(0xAC68006B, buffer_out + 0);
|
memory.Write_U32(0xAC68006B, buffer_out + 0);
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case SET_BLOCKLEN:
|
case SET_BLOCKLEN:
|
||||||
m_block_length = req.arg;
|
m_block_length = req.arg;
|
||||||
|
@ -554,9 +559,8 @@ std::array<u32, 4> SDIOSlot0Device::GetCSDv1() const
|
||||||
{
|
{
|
||||||
u64 size = m_card.GetSize();
|
u64 size = m_card.GetSize();
|
||||||
|
|
||||||
// 2048 bytes/sector
|
// 512 bytes/sector. A 2GB card should only ever have to bump this up to 10
|
||||||
// We could make this dynamic to support a wider range of file sizes
|
u32 read_bl_len = 9;
|
||||||
constexpr u32 read_bl_len = 11;
|
|
||||||
|
|
||||||
// size = (c_size + 1) * (1 << (2 + c_size_mult + read_bl_len))
|
// size = (c_size + 1) * (1 << (2 + c_size_mult + read_bl_len))
|
||||||
u32 c_size_mult = 0;
|
u32 c_size_mult = 0;
|
||||||
|
@ -565,7 +569,7 @@ std::array<u32, 4> SDIOSlot0Device::GetCSDv1() const
|
||||||
{
|
{
|
||||||
invalid_size |= size & 1;
|
invalid_size |= size & 1;
|
||||||
size >>= 1;
|
size >>= 1;
|
||||||
if (++c_size_mult >= 8 + 2 + read_bl_len)
|
if (++c_size_mult > 7 + 2 + read_bl_len && ++read_bl_len > 15)
|
||||||
{
|
{
|
||||||
ERROR_LOG_FMT(IOS_SD, "SD Card is too big!");
|
ERROR_LOG_FMT(IOS_SD, "SD Card is too big!");
|
||||||
// Set max values
|
// Set max values
|
||||||
|
@ -580,7 +584,8 @@ std::array<u32, 4> SDIOSlot0Device::GetCSDv1() const
|
||||||
if (invalid_size)
|
if (invalid_size)
|
||||||
WARN_LOG_FMT(IOS_SD, "SD Card size is invalid");
|
WARN_LOG_FMT(IOS_SD, "SD Card size is invalid");
|
||||||
else
|
else
|
||||||
INFO_LOG_FMT(IOS_SD, "SD C_SIZE = {}, C_SIZE_MULT = {}", c_size, c_size_mult);
|
INFO_LOG_FMT(IOS_SD, "SD C_SIZE = {}, C_SIZE_MULT = {}, READ_BL_LEN = {}", c_size, c_size_mult,
|
||||||
|
read_bl_len);
|
||||||
|
|
||||||
// 0b00 CSD_STRUCTURE (SDv1)
|
// 0b00 CSD_STRUCTURE (SDv1)
|
||||||
// 0b000000 reserved
|
// 0b000000 reserved
|
||||||
|
@ -589,7 +594,7 @@ std::array<u32, 4> SDIOSlot0Device::GetCSDv1() const
|
||||||
// 0b00110010 TRAN_SPEED (2.5 * 10 Mbit/s, max operating frequency)
|
// 0b00110010 TRAN_SPEED (2.5 * 10 Mbit/s, max operating frequency)
|
||||||
|
|
||||||
// 0b010110110101 CCC
|
// 0b010110110101 CCC
|
||||||
// 0b1111 READ_BL_LEN (2048 bytes)
|
// 0b???? READ_BL_LEN
|
||||||
// 0b1 READ_BL_PARTIAL
|
// 0b1 READ_BL_PARTIAL
|
||||||
// 0b0 WRITE_BL_MISALIGN
|
// 0b0 WRITE_BL_MISALIGN
|
||||||
// 0b0 READ_BLK_MISALIGN
|
// 0b0 READ_BLK_MISALIGN
|
||||||
|
@ -610,7 +615,7 @@ std::array<u32, 4> SDIOSlot0Device::GetCSDv1() const
|
||||||
// 0b0 WP_GRP_ENABLE (no write protection)
|
// 0b0 WP_GRP_ENABLE (no write protection)
|
||||||
// 0b00 reserved
|
// 0b00 reserved
|
||||||
// 0b001 R2W_FACTOR (write half as fast as read)
|
// 0b001 R2W_FACTOR (write half as fast as read)
|
||||||
// 0b1111 WRITE_BL_LEN (= READ_BL_LEN)
|
// 0b???? WRITE_BL_LEN (= READ_BL_LEN)
|
||||||
// 0b0 WRITE_BL_PARTIAL (no partial block writes)
|
// 0b0 WRITE_BL_PARTIAL (no partial block writes)
|
||||||
// 0b00000 reserved
|
// 0b00000 reserved
|
||||||
// 0b0 FILE_FORMAT_GRP (default)
|
// 0b0 FILE_FORMAT_GRP (default)
|
||||||
|
@ -623,14 +628,16 @@ std::array<u32, 4> SDIOSlot0Device::GetCSDv1() const
|
||||||
// 0b1 reserved
|
// 0b1 reserved
|
||||||
|
|
||||||
// TODO: CRC7 (but so far it looks like nobody is actually verifying this)
|
// TODO: CRC7 (but so far it looks like nobody is actually verifying this)
|
||||||
constexpr u32 crc = 0;
|
// constexpr u32 crc = 0; // The CRC doesn't seem to be sent any at all.
|
||||||
|
// Additionally, the entire response seems to be shifted to the right by 8 bits. Or the entire CSD
|
||||||
|
// was sent in reverse and IOS is only flipping the endianness of the four words.... It's weird.
|
||||||
|
|
||||||
// Form the csd using the description above
|
// Form the csd using the description above
|
||||||
return {{
|
return {{
|
||||||
0x007f003,
|
0x000007f0,
|
||||||
0x5b5f8000 | (c_size >> 2),
|
0x035b5080 | (read_bl_len << 8) | (c_size >> 10),
|
||||||
0x3ffc7f80 | (c_size << 30) | (c_size_mult << 15),
|
0x003ffc7f | (c_size << 22) | (c_size_mult << 7),
|
||||||
0x07c04001 | (crc << 1),
|
0x80040040 | (read_bl_len << 18),
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,16 +686,12 @@ std::array<u32, 4> SDIOSlot0Device::GetCSDv2() const
|
||||||
// 0b0000000 CRC
|
// 0b0000000 CRC
|
||||||
// 0b1 reserved
|
// 0b1 reserved
|
||||||
|
|
||||||
// TODO: CRC7 (but so far it looks like nobody is actually verifying this)
|
// TODO: CRC7 (but so far it looks like nobody is actually verifying this) // See GetCSDv1 notes
|
||||||
constexpr u32 crc = 0;
|
// on this
|
||||||
|
// constexpr u32 crc = 0;
|
||||||
|
|
||||||
// Form the csd using the description above
|
// Form the csd using the description above
|
||||||
return {{
|
return {{0x00400e00, 0x5a5f5900, 0x0000007f | (c_size << 8), 0x800a4000}};
|
||||||
0x400e005a,
|
|
||||||
0x5f590000 | (c_size >> 16),
|
|
||||||
0x00007f80 | (c_size << 16),
|
|
||||||
0x0a400001 | (crc << 1),
|
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 SDIOSlot0Device::GetAddressFromRequest(u32 arg) const
|
u64 SDIOSlot0Device::GetAddressFromRequest(u32 arg) const
|
||||||
|
|
Loading…
Reference in New Issue