[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 1/3] hw/sd: implement CMD23 (SET_BLOCK_COUNT) for
From: |
Andrew Baumann |
Subject: |
[Qemu-devel] [PATCH v2 1/3] hw/sd: implement CMD23 (SET_BLOCK_COUNT) for MMC compatibility |
Date: |
Wed, 16 Dec 2015 11:02:46 -0800 |
CMD23 is optional for SD but required for MMC, and the UEFI bootloader
used for Windows on Raspberry Pi 2 issues it.
Signed-off-by: Andrew Baumann <address@hidden>
---
hw/sd/sd.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 1a9935c..1a24933 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -92,6 +92,7 @@ struct SDState {
int32_t wpgrps_size;
uint64_t size;
uint32_t blk_len;
+ uint32_t multi_blk_cnt;
uint32_t erase_start;
uint32_t erase_end;
uint8_t pwd[16];
@@ -423,6 +424,7 @@ static void sd_reset(SDState *sd)
sd->blk_len = 0x200;
sd->pwd_len = 0;
sd->expecting_acmd = false;
+ sd->multi_blk_cnt = 0;
}
static void sd_cardchange(void *opaque, bool load)
@@ -455,6 +457,7 @@ static const VMStateDescription sd_vmstate = {
VMSTATE_UINT32(vhs, SDState),
VMSTATE_BITMAP(wp_groups, SDState, 0, wpgrps_size),
VMSTATE_UINT32(blk_len, SDState),
+ VMSTATE_UINT32(multi_blk_cnt, SDState),
VMSTATE_UINT32(erase_start, SDState),
VMSTATE_UINT32(erase_end, SDState),
VMSTATE_UINT8_ARRAY(pwd, SDState, 16),
@@ -671,6 +674,12 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
if (sd_cmd_type[req.cmd] == sd_ac || sd_cmd_type[req.cmd] == sd_adtc)
rca = req.arg >> 16;
+ /* CMD23 (set block count) must be immediately followed by CMD18 or CMD25
+ * if not, its effects are cancelled */
+ if (sd->multi_blk_cnt != 0 && !(req.cmd == 18 || req.cmd == 25)) {
+ sd->multi_blk_cnt = 0;
+ }
+
DPRINTF("CMD%d 0x%08x state %d\n", req.cmd, req.arg, sd->state);
switch (req.cmd) {
/* Basic commands (Class 0 and Class 1) */
@@ -966,6 +975,17 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
}
break;
+ case 23: /* CMD23: SET_BLOCK_COUNT */
+ switch (sd->state) {
+ case sd_transfer_state:
+ sd->multi_blk_cnt = req.arg;
+ return sd_r1;
+
+ default:
+ break;
+ }
+ break;
+
/* Block write commands (Class 4) */
case 24: /* CMD24: WRITE_SINGLE_BLOCK */
if (sd->spi)
@@ -1564,6 +1584,14 @@ void sd_write_data(SDState *sd, uint8_t value)
sd->data_offset = 0;
sd->csd[14] |= 0x40;
+ if (sd->multi_blk_cnt != 0) {
+ if (--sd->multi_blk_cnt == 0) {
+ /* Stop! */
+ sd->state = sd_transfer_state;
+ break;
+ }
+ }
+
/* Bzzzzzzztt .... Operation complete. */
sd->state = sd_receivingdata_state;
}
@@ -1711,6 +1739,15 @@ uint8_t sd_read_data(SDState *sd)
if (sd->data_offset >= io_len) {
sd->data_start += io_len;
sd->data_offset = 0;
+
+ if (sd->multi_blk_cnt != 0) {
+ if (--sd->multi_blk_cnt == 0) {
+ /* Stop! */
+ sd->state = sd_transfer_state;
+ break;
+ }
+ }
+
if (sd->data_start + io_len > sd->size) {
sd->card_status |= ADDRESS_ERROR;
break;
--
2.5.3
- [Qemu-devel] [PATCH v2 0/3] SD emulation fixes for Pi2 Tianocore EDK2 UEFI, Andrew Baumann, 2015/12/16
- [Qemu-devel] [PATCH v2 3/3] hw/sd: use guest error logging rather than fprintf to stderr, Andrew Baumann, 2015/12/16
- [Qemu-devel] [PATCH v2 1/3] hw/sd: implement CMD23 (SET_BLOCK_COUNT) for MMC compatibility,
Andrew Baumann <=
- [Qemu-devel] [PATCH v2 2/3] hw/sd: model a power-up delay, as a workaround for an EDK2 bug, Andrew Baumann, 2015/12/16
- Re: [Qemu-devel] [PATCH v2 2/3] hw/sd: model a power-up delay, as a workaround for an EDK2 bug, Peter Crosthwaite, 2015/12/21
- Re: [Qemu-devel] [PATCH v2 2/3] hw/sd: model a power-up delay, as a workaround for an EDK2 bug, Peter Maydell, 2015/12/23
- Re: [Qemu-devel] [PATCH v2 2/3] hw/sd: model a power-up delay, as a workaround for an EDK2 bug, Andrew Baumann, 2015/12/23