提交 b3141c06 编写于 作者: P Philippe Mathieu-Daudé 提交者: Peter Maydell

sdcard: Use the ldst API

The load/store API will ease further code movement.

Per the Physical Layer Simplified Spec. "3.6 Bus Protocol":

  "In the CMD line the Most Significant Bit (MSB) is transmitted
   first, the Least Significant Bit (LSB) is the last."
Signed-off-by: NPhilippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: NPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
上级 13606b99
...@@ -118,8 +118,6 @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s) ...@@ -118,8 +118,6 @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s)
goto error; goto error;
} }
if (!(s->cmd & SDCMD_NO_RESPONSE)) { if (!(s->cmd & SDCMD_NO_RESPONSE)) {
#define RWORD(n) (((uint32_t)rsp[n] << 24) | (rsp[n + 1] << 16) \
| (rsp[n + 2] << 8) | rsp[n + 3])
if (rlen == 0 || (rlen == 4 && (s->cmd & SDCMD_LONG_RESPONSE))) { if (rlen == 0 || (rlen == 4 && (s->cmd & SDCMD_LONG_RESPONSE))) {
goto error; goto error;
} }
...@@ -127,15 +125,14 @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s) ...@@ -127,15 +125,14 @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s)
goto error; goto error;
} }
if (rlen == 4) { if (rlen == 4) {
s->rsp[0] = RWORD(0); s->rsp[0] = ldl_be_p(&rsp[0]);
s->rsp[1] = s->rsp[2] = s->rsp[3] = 0; s->rsp[1] = s->rsp[2] = s->rsp[3] = 0;
} else { } else {
s->rsp[0] = RWORD(12); s->rsp[0] = ldl_be_p(&rsp[12]);
s->rsp[1] = RWORD(8); s->rsp[1] = ldl_be_p(&rsp[8]);
s->rsp[2] = RWORD(4); s->rsp[2] = ldl_be_p(&rsp[4]);
s->rsp[3] = RWORD(0); s->rsp[3] = ldl_be_p(&rsp[0]);
} }
#undef RWORD
} }
/* We never really delay commands, so if this was a 'busywait' command /* We never really delay commands, so if this was a 'busywait' command
* then we've completed it now and can raise the interrupt. * then we've completed it now and can raise the interrupt.
......
...@@ -100,8 +100,7 @@ static void memcard_sd_command(MilkymistMemcardState *s) ...@@ -100,8 +100,7 @@ static void memcard_sd_command(MilkymistMemcardState *s)
SDRequest req; SDRequest req;
req.cmd = s->command[0] & 0x3f; req.cmd = s->command[0] & 0x3f;
req.arg = (s->command[1] << 24) | (s->command[2] << 16) req.arg = ldl_be_p(s->command + 1);
| (s->command[3] << 8) | s->command[4];
req.crc = s->command[5]; req.crc = s->command[5];
s->response[0] = req.cmd; s->response[0] = req.cmd;
......
...@@ -163,8 +163,7 @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir, ...@@ -163,8 +163,7 @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
CID_CSD_OVERWRITE; CID_CSD_OVERWRITE;
if (host->sdio & (1 << 13)) if (host->sdio & (1 << 13))
mask |= AKE_SEQ_ERROR; mask |= AKE_SEQ_ERROR;
rspstatus = (response[0] << 24) | (response[1] << 16) | rspstatus = ldl_be_p(response);
(response[2] << 8) | (response[3] << 0);
break; break;
case sd_r2: case sd_r2:
...@@ -182,8 +181,7 @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir, ...@@ -182,8 +181,7 @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
} }
rsplen = 4; rsplen = 4;
rspstatus = (response[0] << 24) | (response[1] << 16) | rspstatus = ldl_be_p(response);
(response[2] << 8) | (response[3] << 0);
if (rspstatus & 0x80000000) if (rspstatus & 0x80000000)
host->status &= 0xe000; host->status &= 0xe000;
else else
......
...@@ -182,23 +182,20 @@ static void pl181_send_command(PL181State *s) ...@@ -182,23 +182,20 @@ static void pl181_send_command(PL181State *s)
if (rlen < 0) if (rlen < 0)
goto error; goto error;
if (s->cmd & PL181_CMD_RESPONSE) { if (s->cmd & PL181_CMD_RESPONSE) {
#define RWORD(n) (((uint32_t)response[n] << 24) | (response[n + 1] << 16) \
| (response[n + 2] << 8) | response[n + 3])
if (rlen == 0 || (rlen == 4 && (s->cmd & PL181_CMD_LONGRESP))) if (rlen == 0 || (rlen == 4 && (s->cmd & PL181_CMD_LONGRESP)))
goto error; goto error;
if (rlen != 4 && rlen != 16) if (rlen != 4 && rlen != 16)
goto error; goto error;
s->response[0] = RWORD(0); s->response[0] = ldl_be_p(&response[0]);
if (rlen == 4) { if (rlen == 4) {
s->response[1] = s->response[2] = s->response[3] = 0; s->response[1] = s->response[2] = s->response[3] = 0;
} else { } else {
s->response[1] = RWORD(4); s->response[1] = ldl_be_p(&response[4]);
s->response[2] = RWORD(8); s->response[2] = ldl_be_p(&response[8]);
s->response[3] = RWORD(12) & ~1; s->response[3] = ldl_be_p(&response[12]) & ~1;
} }
DPRINTF("Response received\n"); DPRINTF("Response received\n");
s->status |= PL181_STATUS_CMDRESPEND; s->status |= PL181_STATUS_CMDRESPEND;
#undef RWORD
} else { } else {
DPRINTF("Command sent\n"); DPRINTF("Command sent\n");
s->status |= PL181_STATUS_CMDSENT; s->status |= PL181_STATUS_CMDSENT;
......
...@@ -342,17 +342,13 @@ static void sdhci_send_command(SDHCIState *s) ...@@ -342,17 +342,13 @@ static void sdhci_send_command(SDHCIState *s)
if (s->cmdreg & SDHC_CMD_RESPONSE) { if (s->cmdreg & SDHC_CMD_RESPONSE) {
if (rlen == 4) { if (rlen == 4) {
s->rspreg[0] = (response[0] << 24) | (response[1] << 16) | s->rspreg[0] = ldl_be_p(response);
(response[2] << 8) | response[3];
s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0; s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0;
trace_sdhci_response4(s->rspreg[0]); trace_sdhci_response4(s->rspreg[0]);
} else if (rlen == 16) { } else if (rlen == 16) {
s->rspreg[0] = (response[11] << 24) | (response[12] << 16) | s->rspreg[0] = ldl_be_p(&response[11]);
(response[13] << 8) | response[14]; s->rspreg[1] = ldl_be_p(&response[7]);
s->rspreg[1] = (response[7] << 24) | (response[8] << 16) | s->rspreg[2] = ldl_be_p(&response[3]);
(response[9] << 8) | response[10];
s->rspreg[2] = (response[3] << 24) | (response[4] << 16) |
(response[5] << 8) | response[6];
s->rspreg[3] = (response[0] << 16) | (response[1] << 8) | s->rspreg[3] = (response[0] << 16) | (response[1] << 8) |
response[2]; response[2];
trace_sdhci_response16(s->rspreg[3], s->rspreg[2], trace_sdhci_response16(s->rspreg[3], s->rspreg[2],
...@@ -396,8 +392,7 @@ static void sdhci_end_transfer(SDHCIState *s) ...@@ -396,8 +392,7 @@ static void sdhci_end_transfer(SDHCIState *s)
trace_sdhci_end_transfer(request.cmd, request.arg); trace_sdhci_end_transfer(request.cmd, request.arg);
sdbus_do_command(&s->sdbus, &request, response); sdbus_do_command(&s->sdbus, &request, response);
/* Auto CMD12 response goes to the upper Response register */ /* Auto CMD12 response goes to the upper Response register */
s->rspreg[3] = (response[0] << 24) | (response[1] << 16) | s->rspreg[3] = ldl_be_p(response);
(response[2] << 8) | response[3];
} }
s->prnsts &= ~(SDHC_DOING_READ | SDHC_DOING_WRITE | s->prnsts &= ~(SDHC_DOING_READ | SDHC_DOING_WRITE |
......
...@@ -96,8 +96,7 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val) ...@@ -96,8 +96,7 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
uint8_t longresp[16]; uint8_t longresp[16];
/* FIXME: Check CRC. */ /* FIXME: Check CRC. */
request.cmd = s->cmd; request.cmd = s->cmd;
request.arg = (s->cmdarg[0] << 24) | (s->cmdarg[1] << 16) request.arg = ldl_be_p(s->cmdarg);
| (s->cmdarg[2] << 8) | s->cmdarg[3];
DPRINTF("CMD%d arg 0x%08x\n", s->cmd, request.arg); DPRINTF("CMD%d arg 0x%08x\n", s->cmd, request.arg);
s->arglen = sdbus_do_command(&s->sdbus, &request, longresp); s->arglen = sdbus_do_command(&s->sdbus, &request, longresp);
if (s->arglen <= 0) { if (s->arglen <= 0) {
...@@ -122,8 +121,7 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val) ...@@ -122,8 +121,7 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
/* CMD13 returns a 2-byte statuse work. Other commands /* CMD13 returns a 2-byte statuse work. Other commands
only return the first byte. */ only return the first byte. */
s->arglen = (s->cmd == 13) ? 2 : 1; s->arglen = (s->cmd == 13) ? 2 : 1;
cardstatus = (longresp[0] << 24) | (longresp[1] << 16) cardstatus = ldl_be_p(longresp);
| (longresp[2] << 8) | longresp[3];
status = 0; status = 0;
if (((cardstatus >> 9) & 0xf) < 4) if (((cardstatus >> 9) & 0xf) < 4)
status |= SSI_SDR_IDLE; status |= SSI_SDR_IDLE;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册