/* * This file is part of open_agb_firm * Copyright (C) 2021 derrek, profi200 * * 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, either version 3 of the License, or * (at your option) any later version. * * 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "drivers/mmc/sdmmc.h" #include "drivers/toshsd.h" #include "drivers/toshsd_config.h" #ifdef _3DS #ifdef ARM9 #include "arm9/drivers/timer.h" #include "util.h" // wait_cycles() #elif ARM11 #include "arm11/drivers/timer.h" #endif // #ifdef ARM9 #elif TWL // TODO #endif // #ifdef _3DS #include "drivers/mmc/sd_spec.h" #include "drivers/mmc/mmc_spec.h" // Note on INIT_CLOCK: // 400 kHz is allowed by the specs. 523 kHz has been proven to work reliably // for SD cards and eMMC but very early MMCs can fail at init. // We lose about 5 ms of time on init by using 261 kHz. #ifdef _3DS #ifdef ARM9 #define DELAY_MULT (1u) // Assumes ARM9 timer. Same speed as controller. #elif ARM11 #define DELAY_MULT (2u) // Assumes ARM11 timer. 2x controller speed. #endif // #ifdef ARM9 #define INIT_CLOCK (1u<<6) // 261 kHz #define INIT_DELAY (DELAY_MULT * 256 * 74) #define SDR12_CLOCK (1u) // 16.756991 MHz #define SDR25_CLOCK (0u) // 33.513982 MHz #elif TWL #define INIT_CLOCK (1u<<5) // 261 kHz #define INIT_DELAY (1u * 128 * 74) // Assumes ARM9 timers. Same speed as controller. #define SDR12_CLOCK (0u) // 16.756991 MHz #endif // #ifdef _3DS #define IF_COND_ARG (SD_CMD8_VHS_2_7_3_6V | SD_CMD8_CHK_PATT) #define SD_OP_COND_ARG (SD_ACMD41_XPC | SD_OCR_3_2_3_3V) // We support 150 mA and 3.3V. Without HCS bit. #define MMC_OP_COND_ARG (/*MMC_OCR_SECT_MODE |*/ MMC_OCR_3_2_3_3V) // We support s̶e̶c̶t̶o̶r̶ a̶d̶r̶e̶s̶s̶i̶n̶g̶ a̶n̶d̶ 3.3V. #define SD_OCR_VOLT_MASK (SD_OCR_3_2_3_3V) // We support 3.3V only. #define MMC_OCR_VOLT_MASK (MMC_OCR_3_2_3_3V) // We support 3.3V only. enum { // Card types. CTYPE_NONE = 0u, // Unitialized/no card. CTYPE_SDSC = 1u, // SDSC. CTYPE_SDHC = 2u, // SDHC, SDXC. CTYPE_SDUC = 3u, // SDUC. CTYPE_MMC = 4u, // (e)MMC. CTYPE_MMCHC = 5u // High capacity (e)MMC (>2 GB). }; typedef struct { ToshsdPort port; u8 cardType; u8 spec_vers; // (e)MMC only SPEC_VERS from CSD. 0 for SD. u16 rca; // Relative Card Address (RCA). u16 ccc; // SD/(e)MMC command class support from CSD. One per bit starting at 0. u32 sectors; // Size in 512 byte units. // Cached card infos. u32 cid[4]; // Raw CID with the CRC zeroed out. } SdmmcDev; SdmmcDev g_devs[2] = {0}; /*static u32 sendCardStatus(ToshsdPort *const port, u32 rca, u32 *const statusOut) { // Same CMD for SD/(e)MMC but the argument format differs slightly. const u32 res = TOSHSD_sendCommand(port, MMC_SEND_STATUS, rca); if(res == 0) *statusOut = port->resp[0]; return res; }*/ static u32 sdSendAppCmd(ToshsdPort *const port, u16 cmd, u32 arg, u32 rca) { u32 res = TOSHSD_sendCommand(port, SD_APP_CMD, rca); // TODO: How do we handle the R1 response? if(res == 0) { res = TOSHSD_sendCommand(port, cmd, arg); } return res; } static u32 goIdleState(ToshsdPort *const port) { // Enter idle state before we start the init procedure. // Works from all but inactive state. CMD is the same for SD/(e)MMC. // For (e)MMC there are optional init paths: // arg = 0x00000000 -> GO_IDLE_STATE. // arg = 0xF0F0F0F0 -> GO_PRE_IDLE_STATE. // arg = 0xFFFFFFFA -> BOOT_INITIATION. u32 res = TOSHSD_sendCommand(port, MMC_GO_IDLE_STATE, 0); if(res != 0) return SDMMC_ERR_GO_IDLE_STATE; return SDMMC_ERR_NONE; } static u32 initIdleState(ToshsdPort *const port, u8 *const cardTypeOut) { // Tell the card what interfaces and voltages we support. // Only SD v2 and up will respond. (e)MMC won't respond. u32 res = TOSHSD_sendCommand(port, SD_SEND_IF_COND, IF_COND_ARG); if(res == 0) { // If the card supports the interfaces and voltages // it should echo back the check pattern and set the // support bits. // Since we don't support anything but the // standard SD interface at 3.3V we can check // the whole response at once. if(port->resp[0] != IF_COND_ARG) return SDMMC_ERR_IF_COND_RESP; } else if(res != TSD_ERR_CMD_TMOUT) return SDMMC_ERR_SEND_IF_COND; // Card responded but an error occured. // Send the first app CMD. If this times out it's (e)MMC. // If SEND_IF_COND timed out tell the SD card we are a v1 host. const u32 opCondArg = SD_OP_COND_ARG | (res<<8 ^ SD_ACMD41_HCS); // Caution! Controller specific hack. u8 cardType = CTYPE_SDSC; res = sdSendAppCmd(port, SD_APP_SD_SEND_OP_COND, opCondArg, 0); if(res != 0) { if(res == TSD_ERR_CMD_TMOUT) cardType = CTYPE_MMC; // Continue with (e)MMC init. else return SDMMC_ERR_SEND_OP_COND; // Unknown error. } if(cardType == CTYPE_SDSC) // SD card. { // Loop until a timeout of 1 second or the card is ready. u32 tries = 199; // 200 tries minus the first one. u32 ocr; do { // Linux uses 10 ms but the card doesn't become ready faster // when polling with delay. Use 5 ms as compromise so not much // time is wasted when the card becomes ready in the middle of the delay. TIMER_sleepMs(5); res = sdSendAppCmd(port, SD_APP_SD_SEND_OP_COND, opCondArg, 0); if(res != 0) return SDMMC_ERR_SEND_OP_COND; ocr = port->resp[0]; } while(--tries && !(ocr & SD_OCR_NOT_BUSY)); // SD card didn't finish init within 1 second. if(tries == 0) return SDMMC_ERR_OP_COND_TMOUT; // TODO: From sd.c in Linux: // "Some SD cards claims an out of spec VDD voltage range. // Let's treat these bits as being in-valid and especially also bit7." if(!(ocr & SD_OCR_VOLT_MASK)) return SDMMC_ERR_VOLT_SUPPORT; if(ocr & SD_OCR_CCS) cardType = CTYPE_SDHC; } else // (e)MMC { // Loop until a timeout of 1 second or the card is ready. u32 tries = 200; u32 ocr; do { res = TOSHSD_sendCommand(port, MMC_SEND_OP_COND, MMC_OP_COND_ARG); if(res != 0) return SDMMC_ERR_SEND_OP_COND; ocr = port->resp[0]; if(!--tries || (ocr & MMC_OCR_NOT_BUSY)) break; // Linux uses 10 ms but the card doesn't become ready faster // when polling with delay. Use 5 ms as compromise so not much // time is wasted when the card becomes ready in the middle of the delay. TIMER_sleepMs(5); } while(1); // (e)MMC didn't finish init within 1 second. if(tries == 0) return SDMMC_ERR_OP_COND_TMOUT; // Check if the (e)MMC supports the voltage and if it's high capacity. if(!(ocr & MMC_OCR_VOLT_MASK)) return SDMMC_ERR_VOLT_SUPPORT; // Voltage not supported. // TODO: High capacity (e)MMC check. } *cardTypeOut = cardType; return SDMMC_ERR_NONE; } static u32 initReadyState(SdmmcDev *const dev) { ToshsdPort *const port = &dev->port; // SD card voltage switch sequence goes here if supported. // Get the CID. CMD is the same for SD/(e)MMC. u32 res = TOSHSD_sendCommand(port, MMC_ALL_SEND_CID, 0); if(res != 0) return SDMMC_ERR_ALL_SEND_CID; memcpy(dev->cid, port->resp, 16); return SDMMC_ERR_NONE; } static u32 initIdentState(SdmmcDev *const dev, const u8 cardType, u32 *const rcaOut) { ToshsdPort *const port = &dev->port; u32 rca; if(cardType < CTYPE_MMC) { // Ask the SD card to send its RCA. u32 res = TOSHSD_sendCommand(port, SD_SEND_RELATIVE_ADDR, 0); if(res != 0) return SDMMC_ERR_SET_SEND_RCA; rca = port->resp[0]>>16; // RCA in upper 16 bits. } else { // Set the RCA of the (e)MMC to 1. 0 is reserved. // A few extremely old, unbranded (but Nokia?) MMC's will time // out here for unknown reason. They won't work on DSi anyway (FAT12). // The RCA is in the upper 16 bits of the argument. u32 res = TOSHSD_sendCommand(port, MMC_SET_RELATIVE_ADDR, 1u<<16); // TODO: Should we check the R1 response? if(res != 0) return SDMMC_ERR_SET_SEND_RCA; rca = 1; } dev->rca = rca; *rcaOut = rca<<16; return SDMMC_ERR_NONE; } // Based on code from linux/drivers/mmc/core/sd.c. // Works only with u32[4] buffer. #define UNSTUFF_BITS(resp, start, size) \ ({ \ const u32 __size = size; \ const u32 __mask = (__size < 32 ? 1u<<__size : 0u) - 1; \ const u32 __off = 3 - ((start) / 32u); \ const u32 __shift = (start) & 31u; \ u32 __res; \ \ __res = resp[__off]>>__shift; \ if(__size + __shift > 32) \ __res |= resp[__off - 1]<<((32 - __shift) % 32u); \ __res & __mask; \ }) static void parseCsd(SdmmcDev *const dev, const u8 cardType) { // Note: The MSBs are in csd[0]. const u32 *const csd = dev->port.resp; // structure = 0 is CSD version 1.0. const u8 structure = UNSTUFF_BITS(csd, 126, 2); // [127:126] dev->spec_vers = UNSTUFF_BITS(csd, 122, 4); // [125:122] All 0 for SD cards. u32 sectors; if(structure == 0 || cardType == CTYPE_MMC) { // Same calculation for SDSC and (e)MMC <=2 GB. // TODO: https://github.com/torvalds/linux/blob/master/drivers/mmc/core/sd.c#L129 // This doesn't work? Always calculates half of the expected sectors. const u32 read_bl_len = UNSTUFF_BITS(csd, 80, 4); // [83:80] const u32 c_size = UNSTUFF_BITS(csd, 62, 12); // [73:62] const u32 c_size_mult = UNSTUFF_BITS(csd, 47, 3); // [49:47] // Note: READ_BL_LEN is at least 9. // Slightly modified to calculate sectors instead of bytes. sectors = (c_size + 1) * (1u<<(c_size_mult + 2)) * (1u<<(read_bl_len - 9)); } else { // SD CSD version 3.0 format. // For version 2.0 this is 22 bits however the uppe bits // are reserved and zero filled so this is fine. const u32 c_size = UNSTUFF_BITS(csd, 48, 28); // [75:48] sectors = (c_size + 1) * 1024u; } // TODO: High capacity (e)MMC encodes the size in the ext CSD. dev->sectors = sectors; dev->ccc = UNSTUFF_BITS(csd, 84, 12); // [95:84] } static u32 initStandbyState(SdmmcDev *const dev, const u8 cardType, const u32 rca) { ToshsdPort *const port = &dev->port; // Get the CSD. CMD is the same for SD/(e)MMC. u32 res = TOSHSD_sendCommand(port, MMC_SEND_CSD, rca); if(res != 0) return SDMMC_ERR_SEND_CSD; parseCsd(dev, cardType); // Select card and switch to transfer state. const u16 selCardCmd = (cardType < CTYPE_MMC ? SD_SELECT_CARD : MMC_SELECT_CARD); res = TOSHSD_sendCommand(port, selCardCmd, rca); // TODO: Should we check the R1 response? if(res != 0) return SDMMC_ERR_SELECT_CARD; // The SD card spec mentions that we should check the lock bit in the // response to CMD7 to identify cards requiring a password // to unlock which we don't support. Same seems to apply for (e)MMC. // Same bit for SD/(e)MMC R1 card status. if(port->resp[0] & MMC_R1_CARD_IS_LOCKED) return SDMMC_ERR_LOCKED; return SDMMC_ERR_NONE; } static u32 initTranState(SdmmcDev *const dev, const u8 cardType, const u32 rca) { ToshsdPort *const port = &dev->port; if(cardType < CTYPE_MMC) { // Remove DAT3 pull-up. u32 res = sdSendAppCmd(port, SD_APP_SET_CLR_CARD_DETECT, 0, rca); // arg = 0 removes the pull-up. if(res != 0) return SDMMC_ERR_SET_CLR_CD; // Switch to 4 bit bus mode. res = sdSendAppCmd(port, SD_APP_SET_BUS_WIDTH, 2, rca); // arg = 2 is 4 bit bus width. if(res != 0) return SDMMC_ERR_SET_BUS_WIDTH; TOSHSD_setBusWidth(port, 4); #ifndef TWL // TODO: Is it faster to double the clock earlier or to run this CMD with 4 bit bus width? if(dev->ccc & 1u<<10) // Class 10 command support. { TOSHSD_setBlockLen(port, 64); alignas(4) u8 switchStat[64]; // MSB first and big endian. TOSHSD_setBuffer(port, (u32*)switchStat, 1); const u32 arg = SD_SWITCH_FUNC_ARG(1, 0xF, 0xF, 0xF, 1); res = TOSHSD_sendCommand(port, SD_SWITCH_FUNC, arg); if(res != 0) return SDMMC_ERR_SWITCH_HS; TOSHSD_setBlockLen(port, 512); // [415:400] Support Bits of Functions in Function Group 1. if(switchStat[63 - 400 / 8] & 1u<<1) // Is group 1, function 1 "SDR25" supported? { // SDR25 (50 MHz) supported. Switch to highest supported clock. // Stop clock at idle. 33 MHz. TOSHSD_setClock(port, (1u<<9) | (1u<<8) | SDR25_CLOCK); } } #endif } else { // Very old 1 bit bus MMC will time out and set the SWITCH_ERROR bit // for these CMDs. Only try with (e)MMC spec >4.0. if(dev->spec_vers >= 4) // Version 4.1–4.2–4.3 or higher. { // Switch to 4 bit bus mode. u32 arg = MMC_SWITCH_ARG(MMC_SWITCH_ACC_WR_BYTE, 183, 1, 0); u32 res = TOSHSD_sendCommand(port, MMC_SWITCH, arg); if(res != 0) return SDMMC_ERR_SET_BUS_WIDTH; TOSHSD_setBusWidth(port, 4); #ifndef TWL // Switch to high speed timing (52 MHz). arg = MMC_SWITCH_ARG(MMC_SWITCH_ACC_WR_BYTE, 185, 1, 0); res = TOSHSD_sendCommand(port, MMC_SWITCH, arg); if(res != 0) return SDMMC_ERR_SWITCH_HS; // Stop clock at idle. 33 MHz. TOSHSD_setClock(port, (1u<<9) | (1u<<8) | SDR25_CLOCK); #endif // We also should check in the ext CSD the power budget for the card. // Nintendo seems to leave it on default (no change). } } // SD: The description for CMD SET_BLOCKLEN says 512 bytes is the default. // (e)MMC: The description for READ_BL_LEN (CSD) says 512 bytes is the default. // So it's not required to set the block length? //u32 res = TOSHSD_sendCommand(port, MMC_SET_BLOCKLEN, 512); //if(res != 0) return SDMMC_ERR_SET_BLOCKLEN; return SDMMC_ERR_NONE; } static inline u8 dev2portNum(u8 devNum) { return (devNum == SDMMC_DEV_eMMC ? TOSHSD_eMMC_PORT : TOSHSD_SLOT_PORT); } // TODO: In many places we also want to check the card's response. u32 SDMMC_init(u8 devNum) { if(devNum > SDMMC_DEV_eMMC) return SDMMC_ERR_INVAL_PARAM; SdmmcDev *const dev = &g_devs[devNum]; ToshsdPort *const port = &dev->port; if(dev->cardType != CTYPE_NONE) return SDMMC_ERR_INITIALIZED; // TODO: When does the card detection timer start? Does not restart on controller reset. TOSHSD_initPort(port, dev2portNum(devNum)); TOSHSD_setClock(port, (1u<<8) | INIT_CLOCK); // Continuous clock, 261/523 kHz. #ifdef _3DS #ifdef ARM9 // TODO: Use a timer instead? The delay is only a few hundred us though. wait_cycles(2 * INIT_DELAY); // CPU is 2x timer freqency. #elif ARM11 // TODO: Is it worth using a timer? The delay is only a few hundred us. TIMER_sleepTicks(INIT_DELAY); #endif // #ifdef ARM9 #elif TWL #error "SD/MMC necessary delay unimplemented." #endif // #ifdef _3DS u32 res = goIdleState(port); if(res != 0) return res; // SD/(e)MMC now in idle state (idle). u8 cardType; res = initIdleState(port, &cardType); if(res != 0) return res; // Stop clock at idle. 261/523 kHz. TOSHSD_setClock(port, (1u<<9) | (1u<<8) | INIT_CLOCK); // SD/(e)MMC now in ready state (ready). res = initReadyState(dev); if(res != 0) return res; // SD/(e)MMC now in identification state (ident). u32 rca; res = initIdentState(dev, cardType, &rca); if(res != 0) return res; // Maximum at this point would be 25 MHz for SD and 20 for (e)MMC. // SD: We can increase the clock after end of identification state. // TODO: eMMC spec section 7.6 // "Until the contents of the CSD register is known by the host, // the fPP clock rate must remain at fOD. (See Section 12.7 on page 176.)" // Since the absolute minimum clock rate is 20 MHz and we are in push-pull // mode already can we cheat and switch to 16 MHz before getting the CSD? // Note: This seems to be working just fine in all tests. // Stop clock at idle. 16 MHz. TOSHSD_setClock(port, (1u<<9) | (1u<<8) | SDR12_CLOCK); // SD/(e)MMC now in stand-by state (stby). res = initStandbyState(dev, cardType, rca); if(res != 0) return res; // SD/(e)MMC now in transfer state (tran). res = initTranState(dev, cardType, rca); if(res != 0) return res; dev->cardType = cardType; return SDMMC_ERR_NONE; } // TODO: Is there any "best practice" way of deinitializing cards? // Kick the card back into idle state maybe? // Linux seems to deselect cards on "suspend". u32 SDMMC_deinit(u8 devNum) { if(devNum > SDMMC_DEV_eMMC) return SDMMC_ERR_INVAL_PARAM; g_devs[devNum].cardType = CTYPE_NONE; return SDMMC_ERR_NONE; } void SDMMC_getCardInfo(u8 devNum, SdmmcInfo *const infoOut) { if(devNum > SDMMC_DEV_eMMC) return; const SdmmcDev *const dev = &g_devs[devNum]; const ToshsdPort *const port = &dev->port; infoOut->type = dev->cardType; infoOut->spec_vers = dev->spec_vers; infoOut->rca = dev->rca; infoOut->sectors = dev->sectors; const u32 clkSetting = port->sd_clk_ctrl & 0xFFu; infoOut->clock = TOSHSD_HCLK / (clkSetting ? clkSetting<<2 : 2u); memcpy(infoOut->cid, dev->cid, 16); infoOut->ccc = dev->ccc; infoOut->busWidth = (port->sd_option & 1u<<15 ? 1u : 4u); } u32 SDMMC_getCid(u8 devNum, u32 *const cidOut) { if(devNum > SDMMC_DEV_eMMC) return SDMMC_ERR_INVAL_PARAM; if(cidOut != NULL) memcpy(cidOut, g_devs[devNum].cid, 16); return SDMMC_ERR_NONE; } u32 SDMMC_getSectors(u8 devNum) { if(devNum > SDMMC_DEV_eMMC) return 0; return g_devs[devNum].sectors; } u32 SDMMC_readSectors(u8 devNum, u32 sect, u32 *const buf, u16 count) { if(devNum > SDMMC_DEV_eMMC || count == 0) return SDMMC_ERR_INVAL_PARAM; SdmmcDev *const dev = &g_devs[devNum]; const u8 cardType = dev->cardType; if(cardType == CTYPE_NONE) return SDMMC_ERR_NO_CARD; ToshsdPort *const port = &dev->port; TOSHSD_setBuffer(port, buf, count); if(cardType == CTYPE_SDSC || cardType == CTYPE_MMC) sect *= 512; // Read a single 512 bytes block. Same CMD for SD/(e)MMC. // Read multiple 512 byte blocks. Same CMD for SD/(e)MMC. const u16 cmd = (count == 1 ? MMC_READ_SINGLE_BLOCK : MMC_READ_MULTIPLE_BLOCK); const u32 res = TOSHSD_sendCommand(port, cmd, sect); if(res != 0) return SDMMC_ERR_SECT_RW; // TODO: In case of errors check the card status. return SDMMC_ERR_NONE; } u32 SDMMC_writeSectors(u8 devNum, u32 sect, const u32 *const buf, u16 count) { if(devNum > SDMMC_DEV_eMMC || count == 0) return SDMMC_ERR_INVAL_PARAM; SdmmcDev *const dev = &g_devs[devNum]; const u8 cardType = dev->cardType; if(cardType == CTYPE_NONE) return SDMMC_ERR_NO_CARD; ToshsdPort *const port = &dev->port; if(!TOSHSD_cardSliderUnlocked()) return SDMMC_ERR_WRITE_PROT; // TODO: Don't do this check for eMMC. TOSHSD_setBuffer(port, (u32*)buf, count); if(cardType == CTYPE_SDSC || cardType == CTYPE_MMC) sect *= 512; // Write a single 512 bytes block. Same CMD for SD/(e)MMC. // Write multiple 512 byte blocks. Same CMD for SD/(e)MMC. const u16 cmd = (count == 1 ? MMC_WRITE_BLOCK : MMC_WRITE_MULTIPLE_BLOCK); const u32 res = TOSHSD_sendCommand(port, cmd, sect); if(res != 0) return SDMMC_ERR_SECT_RW; // TODO: In case of errors check the card status. return SDMMC_ERR_NONE; }