Some registers are read-only.
Since we allow instances to clear/set extra bits of capareg,
log when read-only bits normally set by hardware are cleared
at board level.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/hw/sd/sdhci.h | 7 +++++++
hw/sd/sdhci.c | 10 +++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
index 108bc1993c6..eb21b64f932 100644
--- a/include/hw/sd/sdhci.h
+++ b/include/hw/sd/sdhci.h
@@ -120,6 +120,13 @@ struct SDHCIClass {
const MemoryRegionOps *io_ops;
uint32_t quirks;
uint64_t iomem_size;
+
+ /* Read-only registers */
+ struct {
+ uint64_t capareg;
+ uint64_t maxcurr;
+ uint16_t version;
+ } ro;
};
/*
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 6868bf68285..eb6a0e0f939 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -73,6 +73,7 @@ static bool sdhci_check_capab_freq_range(SDHCIState *s, const char *desc,
static void sdhci_check_capareg(SDHCIState *s, Error **errp)
{
+ SDHCIClass *sc = s->sc;
uint64_t msk = s->capareg;
uint32_t val;
bool y;
@@ -208,6 +209,11 @@ static void sdhci_check_capareg(SDHCIState *s, Error **errp)
qemu_log_mask(LOG_UNIMP,
"SDHCI: unknown CAPAB mask: 0x%016" PRIx64 "\n", msk);
}
+ msk = sc->ro.capareg & ~s->capareg;
+ if (msk) {
+ qemu_log_mask(LOG_UNIMP,
+ "SDHCI: ignored CAPAB mask: 0x%016" PRIx64 "\n", msk);
+ }
}
static uint8_t sdhci_slotint(SDHCIState *s)
@@ -1407,7 +1413,9 @@ static void sdhci_init_readonly_registers(SDHCIState *s, Error **errp)
error_setg(errp, "Only Spec v2/v3 are supported");
return;
}
- s->version = (SDHC_HCVER_VENDOR << 8) | (s->sd_spec_version - 1);
+ s->version = s->sc->ro.version
+ ?: (SDHC_HCVER_VENDOR << 8) | (s->sd_spec_version - 1);
+ s->maxcurr = s->sc->ro.maxcurr;
sdhci_check_capareg(s, errp);
if (*errp) {
--
2.47.1