moar SD/MMC commands
This commit is contained in:
parent
bedc0220fc
commit
6c75275593
13
src/DSi.cpp
13
src/DSi.cpp
|
@ -60,6 +60,9 @@ u32 NWRAMMask[2][3];
|
||||||
DSi_SDHost* SDMMC;
|
DSi_SDHost* SDMMC;
|
||||||
DSi_SDHost* SDIO;
|
DSi_SDHost* SDIO;
|
||||||
|
|
||||||
|
u64 ConsoleID;
|
||||||
|
u8 eMMC_CID[16];
|
||||||
|
|
||||||
|
|
||||||
bool Init()
|
bool Init()
|
||||||
{
|
{
|
||||||
|
@ -262,14 +265,12 @@ bool LoadNAND()
|
||||||
#define printhex(str, size) { for (int z = 0; z < (size); z++) printf("%02X", (str)[z]); printf("\n"); }
|
#define printhex(str, size) { for (int z = 0; z < (size); z++) printf("%02X", (str)[z]); printf("\n"); }
|
||||||
#define printhex_rev(str, size) { for (int z = (size)-1; z >= 0; z--) printf("%02X", (str)[z]); printf("\n"); }
|
#define printhex_rev(str, size) { for (int z = (size)-1; z >= 0; z--) printf("%02X", (str)[z]); printf("\n"); }
|
||||||
|
|
||||||
u8 emmc_cid[16];
|
|
||||||
u8 consoleid[8];
|
|
||||||
fseek(f, 0xF000010, SEEK_SET);
|
fseek(f, 0xF000010, SEEK_SET);
|
||||||
fread(emmc_cid, 1, 16, f);
|
fread(eMMC_CID, 1, 16, f);
|
||||||
fread(consoleid, 1, 8, f);
|
fread(&ConsoleID, 1, 8, f);
|
||||||
|
|
||||||
printf("eMMC CID: "); printhex(emmc_cid, 16);
|
printf("eMMC CID: "); printhex(eMMC_CID, 16);
|
||||||
printf("Console ID: "); printhex_rev(consoleid, 8);
|
printf("Console ID: %llx\n", ConsoleID);
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
namespace DSi
|
namespace DSi
|
||||||
{
|
{
|
||||||
|
|
||||||
|
extern u8 eMMC_CID[16];
|
||||||
|
|
||||||
bool Init();
|
bool Init();
|
||||||
void DeInit();
|
void DeInit();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
|
@ -52,6 +52,7 @@ void DSi_SDHost::Reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
SoftReset = 0x0007; // CHECKME
|
SoftReset = 0x0007; // CHECKME
|
||||||
|
SDClock = 0;
|
||||||
|
|
||||||
Command = 0;
|
Command = 0;
|
||||||
Param = 0;
|
Param = 0;
|
||||||
|
@ -67,8 +68,11 @@ void DSi_SDHost::Reset()
|
||||||
|
|
||||||
if (Num == 0)
|
if (Num == 0)
|
||||||
{
|
{
|
||||||
|
DSi_MMCStorage* mmc = new DSi_MMCStorage(this, true, "nand.bin");
|
||||||
|
mmc->SetCID(DSi::eMMC_CID);
|
||||||
|
|
||||||
// TODO: port 0 (SD)
|
// TODO: port 0 (SD)
|
||||||
Ports[1] = new DSi_MMCStorage(this, true, "nand.bin");
|
Ports[1] = mmc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -129,6 +133,8 @@ u16 DSi_SDHost::Read(u32 addr)
|
||||||
case 0x020: return IRQMask & 0x031D;
|
case 0x020: return IRQMask & 0x031D;
|
||||||
case 0x022: return (IRQMask >> 16) & 0x8B7F;
|
case 0x022: return (IRQMask >> 16) & 0x8B7F;
|
||||||
|
|
||||||
|
case 0x024: return SDClock;
|
||||||
|
|
||||||
case 0x0E0: return SoftReset;
|
case 0x0E0: return SoftReset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,10 +156,13 @@ void DSi_SDHost::Write(u32 addr, u16 val)
|
||||||
DSi_SDDevice* dev = Ports[PortSelect & 0x1];
|
DSi_SDDevice* dev = Ports[PortSelect & 0x1];
|
||||||
if (dev)
|
if (dev)
|
||||||
{
|
{
|
||||||
|
// CHECKME
|
||||||
|
// "Setting Command Type to "ACMD" is automatically sending an APP_CMD prefix prior to the command number"
|
||||||
|
// except DSi boot2 manually sends an APP_CMD prefix AND sets the next command to be ACMD
|
||||||
switch ((Command >> 6) & 0x3)
|
switch ((Command >> 6) & 0x3)
|
||||||
{
|
{
|
||||||
case 0: dev->SendCMD(cmd, Param); break;
|
case 0: dev->SendCMD(cmd, Param); break;
|
||||||
case 1: dev->SendACMD(cmd, Param); break;
|
case 1: /*dev->SendCMD(55, 0);*/ dev->SendCMD(cmd, Param); break;
|
||||||
default:
|
default:
|
||||||
printf("%s: unknown command type %d, %02X %08X\n", SD_DESC, (Command>>6)&0x3, cmd, Param);
|
printf("%s: unknown command type %d, %02X %08X\n", SD_DESC, (Command>>6)&0x3, cmd, Param);
|
||||||
break;
|
break;
|
||||||
|
@ -171,6 +180,8 @@ void DSi_SDHost::Write(u32 addr, u16 val)
|
||||||
case 0x020: IRQMask = (IRQMask & 0x8B7F0000) | (val & 0x031D); return;
|
case 0x020: IRQMask = (IRQMask & 0x8B7F0000) | (val & 0x031D); return;
|
||||||
case 0x022: IRQMask = (IRQMask & 0x0000031D) | ((val & 0x8B7F) << 16); return;
|
case 0x022: IRQMask = (IRQMask & 0x0000031D) | ((val & 0x8B7F) << 16); return;
|
||||||
|
|
||||||
|
case 0x024: SDClock = val & 0x03FF; return;
|
||||||
|
|
||||||
case 0x0E0:
|
case 0x0E0:
|
||||||
if ((SoftReset & 0x0001) && !(val & 0x0001))
|
if ((SoftReset & 0x0001) && !(val & 0x0001))
|
||||||
{
|
{
|
||||||
|
@ -200,6 +211,14 @@ DSi_MMCStorage::DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path
|
||||||
File = Platform::OpenLocalFile(path, "r+b");
|
File = Platform::OpenLocalFile(path, "r+b");
|
||||||
|
|
||||||
CSR = 0x00; // checkme
|
CSR = 0x00; // checkme
|
||||||
|
|
||||||
|
// TODO: busy bit
|
||||||
|
// TODO: SDHC/SDXC bit
|
||||||
|
OCR = 0x80FF8000;
|
||||||
|
|
||||||
|
// TODO: customize based on card size etc
|
||||||
|
u8 csd_template[16] = {0x40, 0x40, 0x96, 0xE9, 0x7F, 0xDB, 0xF6, 0xDF, 0x01, 0x59, 0x0F, 0x2A, 0x01, 0x26, 0x90, 0x00};
|
||||||
|
memcpy(CSD, csd_template, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
DSi_MMCStorage::~DSi_MMCStorage()
|
DSi_MMCStorage::~DSi_MMCStorage()
|
||||||
|
@ -209,21 +228,76 @@ DSi_MMCStorage::~DSi_MMCStorage()
|
||||||
|
|
||||||
void DSi_MMCStorage::SendCMD(u8 cmd, u32 param)
|
void DSi_MMCStorage::SendCMD(u8 cmd, u32 param)
|
||||||
{
|
{
|
||||||
|
if (CSR & (1<<5))
|
||||||
|
{
|
||||||
|
CSR &= ~(1<<5);
|
||||||
|
return SendACMD(cmd, param);
|
||||||
|
}
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case 0x00: // reset/etc
|
case 0: // reset/etc
|
||||||
Host->SendResponse(CSR, true);
|
Host->SendResponse(CSR, true);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x08: // set voltage
|
case 2:
|
||||||
|
case 10: // get CID
|
||||||
|
Host->SendResponse(*(u32*)&CID[0], false);
|
||||||
|
Host->SendResponse(*(u32*)&CID[1], false);
|
||||||
|
Host->SendResponse(*(u32*)&CID[2], false);
|
||||||
|
Host->SendResponse(*(u32*)&CID[3], true);
|
||||||
|
//if (cmd == 2) SetState(0x02);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 3: // get/set RCA
|
||||||
|
if (Internal)
|
||||||
|
{
|
||||||
|
RCA = param >> 16;
|
||||||
|
Host->SendResponse(CSR|0x10000, true); // huh??
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
printf("CMD3 on SD card: TODO\n");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 7: // select card (by RCA)
|
||||||
|
Host->SendResponse(CSR, true);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 8: // set voltage
|
||||||
Host->SendResponse(param, true);
|
Host->SendResponse(param, true);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case 9: // get CSD
|
||||||
|
Host->SendResponse(*(u32*)&CSD[0], false);
|
||||||
|
Host->SendResponse(*(u32*)&CSD[1], false);
|
||||||
|
Host->SendResponse(*(u32*)&CSD[2], false);
|
||||||
|
Host->SendResponse(*(u32*)&CSD[3], true);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 55: // ??
|
||||||
|
printf("CMD55 %08X\n", param);
|
||||||
|
CSR |= (1<<5);
|
||||||
|
Host->SendResponse(CSR, true);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("MMC: unknown CMD %02X %08X\n", cmd, param);
|
printf("MMC: unknown CMD %d %08X\n", cmd, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSi_MMCStorage::SendACMD(u8 cmd, u32 param)
|
void DSi_MMCStorage::SendACMD(u8 cmd, u32 param)
|
||||||
{
|
{
|
||||||
printf("MMC: ACMD %02X %08X\n", cmd, param);
|
switch (cmd)
|
||||||
|
{
|
||||||
|
case 41: // set operating conditions
|
||||||
|
OCR &= 0xBF000000;
|
||||||
|
OCR |= (param & 0x40FFFFFF);
|
||||||
|
Host->SendResponse(OCR, true);
|
||||||
|
SetState(0x01);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("MMC: unknown ACMD %d %08X\n", cmd, param);
|
||||||
}
|
}
|
||||||
|
|
13
src/DSi_SD.h
13
src/DSi_SD.h
|
@ -42,6 +42,7 @@ private:
|
||||||
|
|
||||||
u16 PortSelect;
|
u16 PortSelect;
|
||||||
u16 SoftReset;
|
u16 SoftReset;
|
||||||
|
u16 SDClock;
|
||||||
|
|
||||||
u32 IRQStatus; // IF
|
u32 IRQStatus; // IF
|
||||||
u32 IRQMask; // ~IE
|
u32 IRQMask; // ~IE
|
||||||
|
@ -63,7 +64,6 @@ public:
|
||||||
~DSi_SDDevice() {}
|
~DSi_SDDevice() {}
|
||||||
|
|
||||||
virtual void SendCMD(u8 cmd, u32 param) = 0;
|
virtual void SendCMD(u8 cmd, u32 param) = 0;
|
||||||
virtual void SendACMD(u8 cmd, u32 param) = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DSi_SDHost* Host;
|
DSi_SDHost* Host;
|
||||||
|
@ -76,6 +76,8 @@ public:
|
||||||
DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path);
|
DSi_MMCStorage(DSi_SDHost* host, bool internal, const char* path);
|
||||||
~DSi_MMCStorage();
|
~DSi_MMCStorage();
|
||||||
|
|
||||||
|
void SetCID(u8* cid) { memcpy(CID, cid, 16); }
|
||||||
|
|
||||||
void SendCMD(u8 cmd, u32 param);
|
void SendCMD(u8 cmd, u32 param);
|
||||||
void SendACMD(u8 cmd, u32 param);
|
void SendACMD(u8 cmd, u32 param);
|
||||||
|
|
||||||
|
@ -84,7 +86,14 @@ private:
|
||||||
char FilePath[1024];
|
char FilePath[1024];
|
||||||
FILE* File;
|
FILE* File;
|
||||||
|
|
||||||
u8 CSR;
|
u8 CID[16];
|
||||||
|
u8 CSD[16];
|
||||||
|
|
||||||
|
u32 CSR;
|
||||||
|
u32 OCR;
|
||||||
|
u32 RCA;
|
||||||
|
|
||||||
|
void SetState(u32 state) { CSR &= ~(0xF << 9); CSR |= (state << 9); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DSI_SD_H
|
#endif // DSI_SD_H
|
||||||
|
|
Loading…
Reference in New Issue