[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH 4/5] hw/arm: Flash image mapping follows image size
From: |
David Edmondson |
Subject: |
[RFC PATCH 4/5] hw/arm: Flash image mapping follows image size |
Date: |
Mon, 16 Nov 2020 10:42:15 +0000 |
When mapping flash images into the bottom 128MB, create mappings that
match the size of the underlying block device rather than 64MB.
Signed-off-by: David Edmondson <david.edmondson@oracle.com>
---
hw/arm/trace-events | 2 +
hw/arm/virt-acpi-build.c | 29 ++++++++-------
hw/arm/virt.c | 79 +++++++++++++++++++++-------------------
include/hw/arm/virt.h | 1 +
4 files changed, 60 insertions(+), 51 deletions(-)
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
index a335ee891d..a9174f8fba 100644
--- a/hw/arm/trace-events
+++ b/hw/arm/trace-events
@@ -53,3 +53,5 @@ smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier
node for iommu mr=%s
smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu
mr=%s"
smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint64_t iova,
uint8_t tg, uint64_t num_pages) "iommu mr=%s asid=%d iova=0x%"PRIx64" tg=%d
num_pages=0x%"PRIx64
+# virt.c
+virt_flash_map1(const char *name, uint64_t base, uint64_t size) "map %s at
0x%"PRIx64" + 0x%"PRIx64
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 9747a6458f..2c08d36624 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -102,28 +102,31 @@ static void acpi_dsdt_add_fw_cfg(Aml *scope, const
MemMapEntry *fw_cfg_memmap)
aml_append(scope, dev);
}
-static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap)
+static void acpi_dsdt_add_flash1(Aml *scope, int index,
+ hwaddr base, hwaddr size)
{
Aml *dev, *crs;
- hwaddr base = flash_memmap->base;
- hwaddr size = flash_memmap->size / 2;
- dev = aml_device("FLS0");
+ dev = aml_device("FLS%u", index);
aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015")));
- aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+ aml_append(dev, aml_name_decl("_UID", aml_int(index)));
crs = aml_resource_template();
aml_append(crs, aml_memory32_fixed(base, size, AML_READ_WRITE));
aml_append(dev, aml_name_decl("_CRS", crs));
aml_append(scope, dev);
+}
- dev = aml_device("FLS1");
- aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015")));
- aml_append(dev, aml_name_decl("_UID", aml_int(1)));
- crs = aml_resource_template();
- aml_append(crs, aml_memory32_fixed(base + size, size, AML_READ_WRITE));
- aml_append(dev, aml_name_decl("_CRS", crs));
- aml_append(scope, dev);
+static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap,
+ PFlashCFI01 *flash[2])
+{
+ acpi_dsdt_add_flash1(scope, 0,
+ flash_memmap->base,
+ virt_flash_size(flash[0]));
+
+ acpi_dsdt_add_flash1(scope, 1,
+ flash_memmap->base + flash_memmap->size / 2,
+ virt_flash_size(flash[1]));
}
static void acpi_dsdt_add_virtio(Aml *scope,
@@ -603,7 +606,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
VirtMachineState *vms)
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
if (vmc->acpi_expose_flash) {
- acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
+ acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH], vms->flash);
}
acpi_dsdt_add_fw_cfg(scope, &memmap[VIRT_FW_CFG]);
acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f9f10987dc..03ec844bf3 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -50,6 +50,7 @@
#include "sysemu/sysemu.h"
#include "sysemu/tpm.h"
#include "sysemu/kvm.h"
+#include "sysemu/block-backend.h"
#include "hw/loader.h"
#include "exec/address-spaces.h"
#include "qemu/bitops.h"
@@ -78,6 +79,7 @@
#include "hw/virtio/virtio-iommu.h"
#include "hw/char/pl011.h"
#include "qemu/guest-random.h"
+#include "trace.h"
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
@@ -931,6 +933,11 @@ static void create_virtio_devices(const VirtMachineState
*vms)
#define VIRT_FLASH_SECTOR_SIZE (256 * KiB)
+int64_t virt_flash_size(PFlashCFI01 *flash)
+{
+ return blk_getlength(pflash_cfi01_get_blk(flash));
+}
+
static PFlashCFI01 *virt_flash_create1(VirtMachineState *vms,
const char *name,
const char *alias_prop_name)
@@ -969,6 +976,8 @@ static void virt_flash_map1(PFlashCFI01 *flash,
DeviceState *dev = DEVICE(flash);
const char *name = blk_name(pflash_cfi01_get_blk(flash));
+ trace_virt_flash_map1(name, base, size);
+
if (size == 0 || !QEMU_IS_ALIGNED(size, VIRT_FLASH_SECTOR_SIZE)) {
error_report("system firmware block device %s has invalid size "
"%" PRId64, name, size);
@@ -995,63 +1004,57 @@ static void virt_flash_map(VirtMachineState *vms,
MemoryRegion *secure_sysmem)
{
/*
- * Map two flash devices to fill the VIRT_FLASH space in the memmap.
+ * Map two flash devices in the VIRT_FLASH space in the memmap.
* sysmem is the system memory space. secure_sysmem is the secure view
* of the system, and the first flash device should be made visible only
* there. The second flash device is visible to both secure and nonsecure.
* If sysmem == secure_sysmem this means there is no separate Secure
* address space and both flash devices are generally visible.
*/
- hwaddr flashsize = vms->memmap[VIRT_FLASH].size / 2;
- hwaddr flashbase = vms->memmap[VIRT_FLASH].base;
+ MemMapEntry *m = &vms->memmap[VIRT_FLASH];
- virt_flash_map1(vms->flash[0], flashbase, flashsize,
- secure_sysmem);
- virt_flash_map1(vms->flash[1], flashbase + flashsize, flashsize,
- sysmem);
+ virt_flash_map1(vms->flash[0], m->base,
+ virt_flash_size(vms->flash[0]), secure_sysmem);
+
+ virt_flash_map1(vms->flash[1], m->base + m->size / 2,
+ virt_flash_size(vms->flash[1]), sysmem);
}
static void virt_flash_fdt(VirtMachineState *vms,
MemoryRegion *sysmem,
MemoryRegion *secure_sysmem)
{
- hwaddr flashsize = vms->memmap[VIRT_FLASH].size / 2;
- hwaddr flashbase = vms->memmap[VIRT_FLASH].base;
+ bool secure = sysmem != secure_sysmem;
+ MemMapEntry *m = &vms->memmap[VIRT_FLASH];
+ hwaddr flashbase0 = m->base;
+ hwaddr flashbase1 = m->base + m->size / 2;
+ hwaddr flashsize0 = virt_flash_size(vms->flash[0]);
+ hwaddr flashsize1 = virt_flash_size(vms->flash[1]);
char *nodename;
- if (sysmem == secure_sysmem) {
- /* Report both flash devices as a single node in the DT */
- nodename = g_strdup_printf("/flash@%" PRIx64, flashbase);
- qemu_fdt_add_subnode(vms->fdt, nodename);
- qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", "cfi-flash");
- qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
- 2, flashbase, 2, flashsize,
- 2, flashbase + flashsize, 2, flashsize);
- qemu_fdt_setprop_cell(vms->fdt, nodename, "bank-width", 4);
- g_free(nodename);
+ if (secure) {
+ nodename = g_strdup_printf("/secflash@%" PRIx64, flashbase0);
} else {
- /*
- * Report the devices as separate nodes so we can mark one as
- * only visible to the secure world.
- */
- nodename = g_strdup_printf("/secflash@%" PRIx64, flashbase);
- qemu_fdt_add_subnode(vms->fdt, nodename);
- qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", "cfi-flash");
- qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
- 2, flashbase, 2, flashsize);
- qemu_fdt_setprop_cell(vms->fdt, nodename, "bank-width", 4);
+ nodename = g_strdup_printf("/flash@%" PRIx64, flashbase0);
+ }
+ qemu_fdt_add_subnode(vms->fdt, nodename);
+ qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", "cfi-flash");
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
+ 2, flashbase0, 2, flashsize0);
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "bank-width", 4);
+ if (secure) {
qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled");
qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay");
- g_free(nodename);
-
- nodename = g_strdup_printf("/flash@%" PRIx64, flashbase);
- qemu_fdt_add_subnode(vms->fdt, nodename);
- qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", "cfi-flash");
- qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
- 2, flashbase + flashsize, 2, flashsize);
- qemu_fdt_setprop_cell(vms->fdt, nodename, "bank-width", 4);
- g_free(nodename);
}
+ g_free(nodename);
+
+ nodename = g_strdup_printf("/flash@%" PRIx64, flashbase1);
+ qemu_fdt_add_subnode(vms->fdt, nodename);
+ qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", "cfi-flash");
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
+ 2, flashbase1, 2, flashsize1);
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "bank-width", 4);
+ g_free(nodename);
}
static bool virt_firmware_init(VirtMachineState *vms,
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index aad6d69841..ee21d691ea 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -172,6 +172,7 @@ OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass,
VIRT_MACHINE)
void virt_acpi_setup(VirtMachineState *vms);
bool virt_is_acpi_enabled(VirtMachineState *vms);
+int64_t virt_flash_size(PFlashCFI01 *flash);
/* Return the number of used redistributor regions */
static inline int virt_gicv3_redist_region_count(VirtMachineState *vms)
--
2.28.0
- [RFC PATCH 0/5] ARM: reduce the memory consumed when mapping UEFI flash images, David Edmondson, 2020/11/16
- [RFC PATCH 1/5] hw/block: blk_check_size_and_read_all should report backend name, David Edmondson, 2020/11/16
- [RFC PATCH 4/5] hw/arm: Flash image mapping follows image size,
David Edmondson <=
- [RFC PATCH 5/5] hw/arm: Only minimise flash size on older machines, David Edmondson, 2020/11/16
- [RFC PATCH 3/5] hw/arm: Convert assertions about flash image size to error_report, David Edmondson, 2020/11/16
- [RFC PATCH 2/5] hw/block: Flash images can be smaller than the device, David Edmondson, 2020/11/16
- Re: [RFC PATCH 0/5] ARM: reduce the memory consumed when mapping UEFI flash images, Philippe Mathieu-Daudé, 2020/11/16