From: Christian Speich <[email protected]> Currently, erased blocks are filled with 0xFF. However SCR Bit 55 (DATA_STAT_AFTER_ERASE) indicates that an erase produces zeros. One of them is wrong.
This patch does two things. First it fixes the reporting of DATA_STAT_AFTER_ERASE in SCR to correctly reflect the content of erased blocks. We also increase the Product Revision (REV in CID) to indicate to the guest that DATA_STAT_AFTER_ERASE is now reliable. Secondly, we introduce a erase-blocks-as-zero option, which allows the user to choose if erased blocks should contain 0xFF or 0x00. The default is still 0xFF to remain compatible with current users. Signed-off-by: Christian Speich <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Move global compat property `{ "sdmmc-common", "erase-blocks-as-zero", "false" }` to 11.1 section. Signed-off-by: Bernhard Beschow <[email protected]> --- hw/core/machine.c | 1 + hw/sd/sd.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/hw/core/machine.c b/hw/core/machine.c index d9ac4b419a..7b0be16444 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -41,6 +41,7 @@ #include "hw/arm/smmuv3.h" GlobalProperty hw_compat_11_1[] = { + { "sdmmc-common", "erase-blocks-as-zero", "false" }, { "sysbus-ehci-usb", "x-migrate-fetch-addr-64bit", "off" }, { "pci-ehci-usb", "x-migrate-fetch-addr-64bit", "off" }, }; diff --git a/hw/sd/sd.c b/hw/sd/sd.c index 6e2bb8ff2d..c40097924c 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -162,6 +162,7 @@ struct SDState { /* Static properties */ uint8_t spec_version; + bool erase_blocks_as_zero; uint64_t boot_part_size; uint64_t rpmb_part_size; BlockBackend *blk; @@ -440,6 +441,9 @@ static void sd_set_scr(SDState *sd) sd->scr[0] |= 2; /* Spec Version 2.00 or Version 3.0X */ sd->scr[1] = (2 << 4) /* SDSC Card (Security Version 1.01) */ | 0b0101; /* 1-bit or 4-bit width bus modes */ + if (!sd->erase_blocks_as_zero) { + sd->scr[1] |= (1 << 7); /* DATA_STAT_AFTER_ERASE: Erase produces 0xFF */ + } sd->scr[2] = 0x00; /* Extended Security is not supported. */ if (sd->spec_version >= SD_PHY_SPECv3_01_VERS) { sd->scr[2] |= 1 << 7; /* Spec Version 3.0X */ @@ -457,7 +461,7 @@ static void sd_set_scr(SDState *sd) #define MID 0xaa #define OID "XY" #define PNM "QEMU!" -#define PRV 0x01 +#define PRV 0x02 #define MDT_YR 2006 #define MDT_MON 2 @@ -1354,7 +1358,12 @@ static void sd_erase(SDState *sd) sd->erase_end = INVALID_ADDRESS; sd->csd[14] |= 0x40; - memset(sd->data, 0xff, erase_len); + if (sd->erase_blocks_as_zero) { + memset(sd->data, 0x0, erase_len); + } else { + memset(sd->data, 0xFF, erase_len); + } + for (erase_addr = erase_start; erase_addr <= erase_end; erase_addr += erase_len) { if (sdsc) { @@ -3281,6 +3290,8 @@ static void emmc_realize(DeviceState *dev, Error **errp) static const Property sdmmc_common_properties[] = { DEFINE_PROP_DRIVE("drive", SDState, blk), + DEFINE_PROP_BOOL("erase-blocks-as-zero", SDState, erase_blocks_as_zero, + true), }; static const Property sd_properties[] = { -- 2.56.0
