storage: 64-bit sector offsets

* Create new 'sector_t' type alias:
    * uint64_t for all targets with HAVE_LBA48 or HAVE_SDUC
    * unsigned long for the everything else
 * Alter all storage APIs to use sector_t instead of 'unsigned long'
 * Alter Volume/Partition/storage info structures to use sector_t
 * Disk cache converted to sector_t
 * ATA Core:
    * convert to using sector_t for sector addresses and drive sizes
    * Always fill out upper 16 bits of LBA48 addresses
    * IDENTIFY INFO is fixed at 512 bytes, not SECTOR_SIZE
 * USB mass storage:
    * convert to using sector_t for sector addesses and drive sizes
    * Implement READ_16/WRITE_16 for LBA48 addresses
 * Convert FAT code to use sector_t for all sector references
 * output_dyn_value() now accepts int64_t instead of 'int'
 * Corrected "rockbox info" to work for (MULTIVOLUME & !MULTIDRIVE)
 * Better reporting of disk and (logical+physical) sector sizes in debug info
 * Detect SDUC cards and report on storage debug_info screen

To-do: SDUC

 * Refactor SD core to remove duplicate code in every driver
   * Card probe and init state machine
 * Implement core SDUC support
   * SD2.0 needs to be 2.0+ (fixed for jz47xx and x1000)
   * Host and Card ID (ACMD41)
   * 32-bit addressing for all read/write/erase operations (CMD22)
 * ADD SDUC to target device drivers, defining HAVE_SDUC as appropriate

Change-Id: Ib0138781a0081664d11511037685503df1b93608
This commit is contained in:
Solomon Peachy 2024-07-05 16:00:30 -04:00
parent 9ff308a589
commit 15e5237469
49 changed files with 629 additions and 435 deletions

View file

@ -104,19 +104,19 @@ static bool sd_poll_status(unsigned int trigger, long timeout)
return true;
}
static int sd_command(unsigned int cmd, unsigned int arg,
static int sd_command(unsigned int cmd, unsigned int arg,
unsigned long* response, unsigned int resp_type)
{
int sdi_cmd = cmd;
sdi_cmd |= (127<<12) | (1<<11); /* max wait time | enable */
if (resp_type)
{
/* response type & response required flag */
sdi_cmd |= (resp_type<<7) | (1<<6);
}
if (cmd == SD_READ_SINGLE_BLOCK ||
cmd == SD_READ_MULTIPLE_BLOCK ||
cmd == SD_WRITE_BLOCK ||
@ -124,18 +124,18 @@ static int sd_command(unsigned int cmd, unsigned int arg,
{
sdi_cmd |= (1<<10); /* request data transfer */
}
if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000))
return -EC_COMMAND;
SDIARGU = arg;
SDICMD = sdi_cmd;
udelay(10);
if (response == NULL)
return 0;
if (!sd_poll_status(SDISTATUS_RESP_RCVD, 100000))
return -EC_COMMAND;
@ -150,7 +150,7 @@ static int sd_command(unsigned int cmd, unsigned int arg,
{
response[0] = SDIRSPARGU0;
}
return 0;
}
@ -220,7 +220,7 @@ static int sd1_oneshot_callback(struct timeout *tmo)
void EXT0(void)
{
static struct timeout sd1_oneshot;
timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0);
}
@ -248,7 +248,7 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
const int card_no = 0;
#endif
(void)card_no;
return false;
}
@ -259,7 +259,7 @@ static void sd_init_device(int card_no)
{
int ret;
unsigned long response;
/* Initialise card data as blank */
memset(currcard, 0, sizeof(*currcard));
@ -282,7 +282,7 @@ static void sd_init_device(int card_no)
#endif
ret = sd_command(SD_GO_IDLE_STATE, 0, NULL, SDICMD_RES_TYPE1);
if (ret < 0)
goto card_init_error;
@ -290,30 +290,30 @@ static void sd_init_device(int card_no)
SDICLK = (1<<12) | 59;
sd_command(SD_SEND_IF_COND, 0x1aa, &response, SDICMD_RES_TYPE3);
if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000))
goto card_init_error;
currcard->ocr = 0;
long start_tick = current_tick;
while ((currcard->ocr & (1<<31)) == 0
&& TIME_BEFORE(current_tick, start_tick + HZ))
{
udelay(100);
sd_command(SD_APP_CMD, 0, NULL, SDICMD_RES_TYPE1);
int arg = 0x100000 | ((response == 0x1aa) ? (1<<30):0);
sd_command(SD_APP_OP_COND, arg, &currcard->ocr, SDICMD_RES_TYPE3);
}
if ((currcard->ocr & (1<<31)) == 0)
{
ret = -EC_POWER_UP;
goto card_init_error;
}
ret = sd_command
(SD_ALL_SEND_CID, 0, currcard->cid, SDICMD_RES_TYPE2);
@ -322,39 +322,39 @@ static void sd_init_device(int card_no)
ret = sd_command
(SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, SDICMD_RES_TYPE1);
if (ret < 0)
goto card_init_error;
ret = sd_command
(SD_SEND_CSD, currcard->rca, currcard->csd, SDICMD_RES_TYPE2);
if (ret < 0)
goto card_init_error;
sd_parse_csd(currcard);
ret = sd_command
(SD_SELECT_CARD, currcard->rca, NULL, SDICMD_RES_TYPE1);
if (ret < 0)
goto card_init_error;
ret = sd_command
(SD_APP_CMD, currcard->rca, NULL, SDICMD_RES_TYPE1);
if (ret < 0)
goto card_init_error;
ret = sd_command /* 4 bit */
(SD_SET_BUS_WIDTH, currcard->rca | 2, NULL, SDICMD_RES_TYPE1);
if (ret < 0)
goto card_init_error;
ret = sd_command
(SD_SET_BLOCKLEN, currcard->blocksize, NULL, SDICMD_RES_TYPE1);
if (ret < 0)
goto card_init_error;
@ -386,7 +386,7 @@ static void sd_select_device(int card_no)
}
}
int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount,
int sd_read_sectors(IF_MD(int card_no,) sector_t start, int incount,
void* inbuf)
{
#ifndef HAVE_MULTIDRIVE
@ -416,23 +416,24 @@ sd_read_retry:
ret = currcard->initialized;
goto sd_read_error;
}
last_disk_activity = current_tick;
ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_ENTRY);
if (ret < 0)
goto sd_read_error;
/* Use full SD clock for data transfer (PCK_SDMMC) */
SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */
/* Block count | FIFO count | Block size (2^9) | 4-bit bus */
SDIDCTRL = (incount << 13) | (4<<8) | (9<<4) | (1<<2);
SDIDCTRL |= (1<<12); /* nReset */
SDIDCTRL2 = (1<<2); /* multi block, read */
// XXX 64-bit
if (currcard->ocr & (1<<30))
ret = sd_command(SD_READ_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1);
else
@ -500,7 +501,7 @@ sd_read_error:
}
}
int sd_write_sectors(IF_MD(int card_no,) unsigned long start, int count,
int sd_write_sectors(IF_MD(int card_no,) sector_t start, int count,
const void* outbuf)
{
/* Write support is not finished yet */
@ -538,21 +539,22 @@ sd_write_retry:
ret = currcard->initialized;
goto sd_write_error;
}
ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_ENTRY);
if (ret < 0)
goto sd_write_error;
/* Use full SD clock for data transfer (PCK_SDMMC) */
SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */
/* Block count | FIFO count | Block size (2^9) | 4-bit bus */
SDIDCTRL = (count<<13) | (4<<8) | (9<<4) | (1<<2);
SDIDCTRL |= (1<<12); /* nReset */
SDIDCTRL2 = (1<<2) | (1<<1); /* multi block, write */
// XXX 64-bit
if (currcard->ocr & (1<<30))
ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1);
else
@ -578,7 +580,7 @@ sd_write_retry:
else
{
int tmp_buf[4];
memcpy(tmp_buf, outbuf, 16);
SDIWDATA = tmp_buf[0];
@ -646,12 +648,12 @@ void sd_enable(bool on)
PCLK_SDMMC &= ~PCK_EN;
}
}
int sd_init(void)
{
static bool initialized = false;
int ret = 0;
if (!initialized)
mutex_init(&sd_mtx);
@ -678,7 +680,7 @@ int sd_init(void)
GPIOC_DIR |= (1<<24);
sleep(HZ/10);
#ifdef HAVE_HOTSWAP
/* Configure interrupts for the card slot */
TMODE &= ~EXT0_IRQ_MASK; /* edge-triggered */
@ -696,7 +698,7 @@ long sd_last_disk_activity(void)
}
tCardInfo *card_get_info_target(int card_no)
{
{
return &card_info[card_no];
}
@ -706,7 +708,7 @@ int sd_num_drives(int first_drive)
{
/* Store which logical drive number(s) we have been assigned */
sd_first_drive = first_drive;
#if defined(HAVE_INTERNAL_SD) && defined(HAVE_HOTSWAP)
return 2;
#else