From f787bcfc9c07ecf97716481b8f669162be982b47 Mon Sep 17 00:00:00 2001
From: David Edmondson <david.edmondson@oracle.com>
Date: Tue, 16 Feb 2021 16:48:35 +0000
Subject: [PATCH 4/4] hw/pflash_cfi01: Allow devices to have a smaller backing
device
Allow the backing device to be smaller than the extent of the flash
device by mapping it as a subregion of the flash device region.
Return zeroes for all reads of the flash device beyond the extent of
the backing device.
For writes beyond the extent of the underlying device, fail on
read-only devices and discard them for writable devices.
Signed-off-by: David Edmondson <david.edmondson@oracle.com>
hw/block/pflash_cfi01.c | 39 ++++++++++++++++-----------------------
1 file changed, 16 insertions(+), 23 deletions(-)
static MemTxResult pflash_outer_write_with_attrs(void *opaque, hwaddr addr,
PFlashCFI01 *pfl = opaque;
trace_pflash_outer_write(pfl->name, addr, len);
- assert(pfl->ro);
- return MEMTX_ERROR;
+ if (pfl->ro) {
+ return MEMTX_ERROR;
+ } else {
+ /* Discard writes. */
+ warn_report_once("%s: attempt to write outside of the backing block device "
+ "(offset " TARGET_FMT_plx ") ignored", pfl->name, addr);
+ return MEMTX_OK;
+ }
}
static const MemoryRegionOps pflash_cfi01_outer_ops = {
static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
return;
}
- if (pfl->ro) {
- /*
- * A read-only flash device can utilise an underlying
- * block device that is smaller than the flash device, but
- * not one that is larger.
- */
- inner_len = blk_getlength(pfl->blk);
-
- if (inner_len > outer_len) {
- error_setg(errp,
- "block backend provides %" HWADDR_PRIu " bytes, "
- "device limited to %" PRIu64 " bytes",
- inner_len, outer_len);
- return;
- }
- } else {
- /*
- * If the flash device is to be writable, the underlying
- * block device must be large enough to accommodate it.
- */
- inner_len = outer_len;
+ inner_len = blk_getlength(pfl->blk);
+
+ if (inner_len > outer_len) {
+ error_setg(errp,
+ "block backend provides %" HWADDR_PRIu " bytes, "
+ "device limited to %" PRIu64 " bytes",
+ inner_len, outer_len);
+ return;
}
} else {
pfl->ro = false;
--
2.30.0