[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/1] hw/arm/aspeed: Automatically zero-extend flash images
From: |
Peter Delevoryas |
Subject: |
[PATCH 1/1] hw/arm/aspeed: Automatically zero-extend flash images |
Date: |
Mon, 14 Nov 2022 11:08:23 -0800 |
One thing that's really annoying about the Aspeed machines is that you
have to provide a flash image that is the same size as the SPI-NOR flash
device the board uses, or something larger. If you don't, you'll get
this obscure error message:
qemu-system-aarch64: failed to read the initial flash content
Which is just because the file isn't the right size. Zero-extending the
file to 128MB (the largest SPI-NOR flash size) fixes this.
This commit just performs the zero-extend automatically, so people don't
have to maintain bash scripts for it. And if your bash script does this
already, it will be a no-op. And, if your firmware image is larger than
the SPI-NOR device, then it will not truncate it.
Signed-off-by: Peter Delevoryas <peter@pjd.dev>
---
hw/arm/aspeed.c | 40 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 55f114ef72..26450d90db 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -260,6 +260,30 @@ static void write_boot_rom(DriveInfo *dinfo, hwaddr addr,
size_t rom_size,
rom_add_blob_fixed("aspeed.boot_rom", storage, rom_size, addr);
}
+static int zero_extend_block_device(BlockBackend *blk, uint64_t size,
+ Error **errp)
+{
+ uint64_t perm, shared_perm;
+
+ blk_get_perm(blk, &perm, &shared_perm);
+
+ if (blk_set_perm(blk, BLK_PERM_ALL, BLK_PERM_ALL, errp)) {
+ error_append_hint(errp, "Unable to change permissions on block
device");
+ return -1;
+ }
+ if (blk_truncate(blk, size, true, PREALLOC_MODE_OFF, BDRV_REQ_ZERO_WRITE,
+ errp)) {
+ error_append_hint(errp, "Unable to zero-extend block device");
+ return -1;
+ }
+ if (blk_set_perm(blk, perm, shared_perm, errp)) {
+ error_append_hint(errp,
+ "Unable to restore permissions on block device");
+ /* Ignore error since we successfully extended the device already */
+ }
+ return 0;
+}
+
void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
unsigned int count, int unit0)
{
@@ -273,10 +297,24 @@ void aspeed_board_init_flashes(AspeedSMCState *s, const
char *flashtype,
DriveInfo *dinfo = drive_get(IF_MTD, 0, unit0 + i);
qemu_irq cs_line;
DeviceState *dev;
+ AspeedSMCFlash *flash = &s->flashes[i];
+ uint64_t flash_size = memory_region_size(&flash->mmio);
dev = qdev_new(flashtype);
if (dinfo) {
- qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo));
+ BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
+ int64_t blk_size = blk_getlength(blk);
+
+ if (blk_size > 0 && blk_size < (int64_t)flash_size) {
+ Error *err = NULL;
+
+ zero_extend_block_device(blk, flash_size, &err);
+ if (err) {
+ warn_reportf_err(err, "Error zero-extending MTD drive[%d] "
+ "to flash size", i);
+ }
+ }
+ qdev_prop_set_drive(dev, "drive", blk);
}
qdev_realize_and_unref(dev, BUS(s->spi), &error_fatal);
--
2.38.1