aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/arm/virt-acpi-build.c17
-rw-r--r--hw/arm/virt.c66
-rw-r--r--include/hw/arm/virt-acpi-build.h1
-rw-r--r--include/hw/arm/virt.h1
4 files changed, 76 insertions, 9 deletions
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index f365140..9088248 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -159,7 +159,8 @@ static void acpi_dsdt_add_virtio(Aml *scope,
}
}
-static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, int irq)
+static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, int irq,
+ bool use_highmem)
{
Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf;
int i, bus_no;
@@ -234,6 +235,17 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, int irq)
AML_ENTIRE_RANGE, 0x0000, 0x0000, size_pio - 1, base_pio,
size_pio));
+ if (use_highmem) {
+ hwaddr base_mmio_high = memmap[VIRT_PCIE_MMIO_HIGH].base;
+ hwaddr size_mmio_high = memmap[VIRT_PCIE_MMIO_HIGH].size;
+
+ aml_append(rbuf,
+ aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
+ AML_NON_CACHEABLE, AML_READ_WRITE, 0x0000,
+ base_mmio_high, base_mmio_high, 0x0000,
+ size_mmio_high));
+ }
+
aml_append(method, aml_name_decl("RBUF", rbuf));
aml_append(method, aml_return(rbuf));
aml_append(dev, method);
@@ -510,7 +522,8 @@ build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
(irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
- acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE));
+ acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
+ guest_info->use_highmem);
aml_append(dsdt, scope);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index bbd061b..60736c2 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -80,6 +80,7 @@ typedef struct {
typedef struct {
MachineState parent;
bool secure;
+ bool highmem;
} VirtMachineState;
#define TYPE_VIRT_MACHINE "virt"
@@ -120,6 +121,8 @@ static const MemMapEntry a15memmap[] = {
[VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
[VIRT_MEM] = { 0x40000000, 30ULL * 1024 * 1024 * 1024 },
+ /* Second PCIe window, 512GB wide at the 512GB boundary */
+ [VIRT_PCIE_MMIO_HIGH] = { 0x8000000000ULL, 0x8000000000ULL },
};
static const int a15irqmap[] = {
@@ -667,10 +670,13 @@ static void create_pcie_irq_map(const VirtBoardInfo *vbi, uint32_t gic_phandle,
0x7 /* PCI irq */);
}
-static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic)
+static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
+ bool use_highmem)
{
hwaddr base_mmio = vbi->memmap[VIRT_PCIE_MMIO].base;
hwaddr size_mmio = vbi->memmap[VIRT_PCIE_MMIO].size;
+ hwaddr base_mmio_high = vbi->memmap[VIRT_PCIE_MMIO_HIGH].base;
+ hwaddr size_mmio_high = vbi->memmap[VIRT_PCIE_MMIO_HIGH].size;
hwaddr base_pio = vbi->memmap[VIRT_PCIE_PIO].base;
hwaddr size_pio = vbi->memmap[VIRT_PCIE_PIO].size;
hwaddr base_ecam = vbi->memmap[VIRT_PCIE_ECAM].base;
@@ -707,6 +713,16 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic)
mmio_reg, base_mmio, size_mmio);
memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias);
+ if (use_highmem) {
+ /* Map high MMIO space */
+ MemoryRegion *high_mmio_alias = g_new0(MemoryRegion, 1);
+
+ memory_region_init_alias(high_mmio_alias, OBJECT(dev), "pcie-mmio-high",
+ mmio_reg, base_mmio_high, size_mmio_high);
+ memory_region_add_subregion(get_system_memory(), base_mmio_high,
+ high_mmio_alias);
+ }
+
/* Map IO port space */
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
@@ -728,11 +744,23 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic)
qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg",
2, base_ecam, 2, size_ecam);
- qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "ranges",
- 1, FDT_PCI_RANGE_IOPORT, 2, 0,
- 2, base_pio, 2, size_pio,
- 1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
- 2, base_mmio, 2, size_mmio);
+
+ if (use_highmem) {
+ qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "ranges",
+ 1, FDT_PCI_RANGE_IOPORT, 2, 0,
+ 2, base_pio, 2, size_pio,
+ 1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
+ 2, base_mmio, 2, size_mmio,
+ 1, FDT_PCI_RANGE_MMIO_64BIT,
+ 2, base_mmio_high,
+ 2, base_mmio_high, 2, size_mmio_high);
+ } else {
+ qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "ranges",
+ 1, FDT_PCI_RANGE_IOPORT, 2, 0,
+ 2, base_pio, 2, size_pio,
+ 1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
+ 2, base_mmio, 2, size_mmio);
+ }
qemu_fdt_setprop_cell(vbi->fdt, nodename, "#interrupt-cells", 1);
create_pcie_irq_map(vbi, vbi->gic_phandle, irq, nodename);
@@ -915,7 +943,7 @@ static void machvirt_init(MachineState *machine)
create_rtc(vbi, pic);
- create_pcie(vbi, pic);
+ create_pcie(vbi, pic, vms->highmem);
/* Create mmio transports, so the user can create virtio backends
* (which will be automatically plugged in to the transports). If
@@ -930,6 +958,7 @@ static void machvirt_init(MachineState *machine)
guest_info->fw_cfg = fw_cfg_find();
guest_info->memmap = vbi->memmap;
guest_info->irqmap = vbi->irqmap;
+ guest_info->use_highmem = vms->highmem;
guest_info_state->machine_done.notify = virt_guest_info_machine_done;
qemu_add_machine_init_done_notifier(&guest_info_state->machine_done);
@@ -967,6 +996,20 @@ static void virt_set_secure(Object *obj, bool value, Error **errp)
vms->secure = value;
}
+static bool virt_get_highmem(Object *obj, Error **errp)
+{
+ VirtMachineState *vms = VIRT_MACHINE(obj);
+
+ return vms->highmem;
+}
+
+static void virt_set_highmem(Object *obj, bool value, Error **errp)
+{
+ VirtMachineState *vms = VIRT_MACHINE(obj);
+
+ vms->highmem = value;
+}
+
static void virt_instance_init(Object *obj)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -979,6 +1022,15 @@ static void virt_instance_init(Object *obj)
"Set on/off to enable/disable the ARM "
"Security Extensions (TrustZone)",
NULL);
+
+ /* High memory is enabled by default */
+ vms->highmem = true;
+ object_property_add_bool(obj, "highmem", virt_get_highmem,
+ virt_set_highmem, NULL);
+ object_property_set_description(obj, "highmem",
+ "Set on/off to enable/disable using "
+ "physical address space above 32 bits",
+ NULL);
}
static void virt_class_init(ObjectClass *oc, void *data)
diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
index 04f174d..19b68a4 100644
--- a/include/hw/arm/virt-acpi-build.h
+++ b/include/hw/arm/virt-acpi-build.h
@@ -31,6 +31,7 @@ typedef struct VirtGuestInfo {
FWCfgState *fw_cfg;
const MemMapEntry *memmap;
const int *irqmap;
+ bool use_highmem;
} VirtGuestInfo;
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index d22fd8e..808753f 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -56,6 +56,7 @@ enum {
VIRT_PCIE_ECAM,
VIRT_GIC_V2M,
VIRT_PLATFORM_BUS,
+ VIRT_PCIE_MMIO_HIGH,
};
typedef struct MemMapEntry {