[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 16/27] hw/arm/virt: Add high MMIO PCI region, 512G in
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 16/27] hw/arm/virt: Add high MMIO PCI region, 512G in size |
Date: |
Fri, 4 Sep 2015 16:05:45 +0100 |
From: Pavel Fedin <address@hidden>
This large region is necessary for some devices like ivshmem and video cards
32-bit kernels can be built without LPAE support. In this case such a kernel
will not be able to use PCI controller which has windows in high addresses.
In order to work around the problem, "highmem" option is introduced. It
defaults to on on, but can be manually set to off in order to be able to run
those old 32-bit guests.
Signed-off-by: Pavel Fedin <address@hidden>
Reviewed-by: Alexander Graf <address@hidden>
Reviewed-by: Igor Mammedov <address@hidden>
Reviewed-by: Shannon Zhao <address@hidden>
[PMM: Added missing ULL suffixes and a comment to the a15memmap[] entry]
Reviewed-by: Peter Maydell <address@hidden>
Signed-off-by: Peter Maydell <address@hidden>
---
hw/arm/virt-acpi-build.c | 17 +++++++++--
hw/arm/virt.c | 66 +++++++++++++++++++++++++++++++++++-----
include/hw/arm/virt-acpi-build.h | 1 +
include/hw/arm/virt.h | 1 +
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..808753f0 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 {
--
1.9.1
- [Qemu-devel] [PULL 19/27] i.MX: KZM: use standalone i.MX31 SOC support, (continued)
- [Qemu-devel] [PULL 19/27] i.MX: KZM: use standalone i.MX31 SOC support, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 15/27] target-arm: Fix AArch32:AArch64 general-purpose register mapping, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 17/27] target-arm: Fix arm_excp_unmasked() function, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 10/27] target-arm: Wire up HLT 0xf000 as the A64 semihosting instruction, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 25/27] i.MX: Add i2C devices to i.MX31 SOC, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 23/27] i.MX: Add the i.MX25 PDK platform, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 11/27] smbios: add smbios 3.0 support, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 08/27] target-arm/arm-semi.c: Implement A64 specific SyncCacheRange call, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 13/27] arm: cpu: assert() on no-EL2 virt IRQ error condition., Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 09/27] target-arm/arm-semi.c: SYS_EXIT on A64 takes a parameter block, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 16/27] hw/arm/virt: Add high MMIO PCI region, 512G in size,
Peter Maydell <=
- [Qemu-devel] [PULL 21/27] i.MX: Add FEC Ethernet Emulator, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 18/27] i.MX: Add SOC support for i.MX31, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 20/27] i.MX: Add I2C controller emulator, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 02/27] target-arm/arm-semi.c: Fix broken SYS_WRITE0 via gdb, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 12/27] smbios: implement smbios support for mach-virt, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 03/27] target-arm: Improve semihosting debug prints, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 27/27] arm/virt: Add full-sized CPU affinity handling, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 07/27] target-arm/arm-semi.c: Support widening APIs to 64 bits, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 26/27] target-arm: Refactor CPU affinity handling, Peter Maydell, 2015/09/04
- [Qemu-devel] [PULL 24/27] i.MX: Add qtest support for I2C device emulator., Peter Maydell, 2015/09/04