summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-01-15 15:49:43 +0000
committerPeter Maydell <peter.maydell@linaro.org>2016-01-15 15:49:43 +0000
commit5a57acb66f19ee52723aa05b8afbbc41c3e9ec99 (patch)
tree8401eae5b86ae112ee3504e0dbb35d3951217868 /hw
parentf02ccf53693758b65843264e077f90cf295e7d98 (diff)
parent67736a25f86595c8ae174a21d965af5a027884c9 (diff)
downloadqemu-5a57acb66f19ee52723aa05b8afbbc41c3e9ec99.tar.gz
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20160115' into staging
target-arm queue: * use the right MMU index when handling unaligned accesses * xlnx-zynqmp: Add support for high DDR memory regions * target-arm: support QMP dump-guest-memory * ARM: virt: Don't generate RTC ACPI device when using UEFI # gpg: Signature made Fri 15 Jan 2016 15:16:19 GMT using RSA key ID 14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" * remotes/pmaydell/tags/pull-target-arm-20160115: ARM: virt: Don't generate RTC ACPI device when using UEFI target-arm: dump-guest-memory: add vfp notes for arm elf: add arm note types target-arm: dump-guest-memory: add prfpreg notes for aarch64 target-arm: support QMP dump-guest-memory dump: allow target to set the physical base dump: allow target to set the page size dump: qemunotes aren't commonly needed qapi-schema: dump-guest-memory: Improve text xlnx-zynqmp: Add support for high DDR memory regions target-arm: Use the right MMU index in arm_regime_using_lpae_format Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/virt-acpi-build.c24
-rw-r--r--hw/arm/xlnx-ep108.c40
-rw-r--r--hw/arm/xlnx-zynqmp.c37
3 files changed, 63 insertions, 38 deletions
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 0caf5ced69..0d5c635cc8 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -94,23 +94,6 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
aml_append(scope, dev);
}
-static void acpi_dsdt_add_rtc(Aml *scope, const MemMapEntry *rtc_memmap,
- uint32_t rtc_irq)
-{
- Aml *dev = aml_device("RTC0");
- aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0013")));
- aml_append(dev, aml_name_decl("_UID", aml_int(0)));
-
- Aml *crs = aml_resource_template();
- aml_append(crs, aml_memory32_fixed(rtc_memmap->base,
- rtc_memmap->size, AML_READ_WRITE));
- aml_append(crs,
- aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
- AML_EXCLUSIVE, &rtc_irq, 1));
- aml_append(dev, aml_name_decl("_CRS", crs));
- aml_append(scope, dev);
-}
-
static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap)
{
Aml *dev, *crs;
@@ -571,12 +554,15 @@ build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
/* Reserve space for header */
acpi_data_push(dsdt->buf, sizeof(AcpiTableHeader));
+ /* When booting the VM with UEFI, UEFI takes ownership of the RTC hardware.
+ * While UEFI can use libfdt to disable the RTC device node in the DTB that
+ * it passes to the OS, it cannot modify AML. Therefore, we won't generate
+ * the RTC ACPI device at all when using UEFI.
+ */
scope = aml_scope("\\_SB");
acpi_dsdt_add_cpus(scope, guest_info->smp_cpus);
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
- acpi_dsdt_add_rtc(scope, &memmap[VIRT_RTC],
- (irqmap[VIRT_RTC] + ARM_SPI_BASE));
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);
diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c
index 73e60876e8..9099025a79 100644
--- a/hw/arm/xlnx-ep108.c
+++ b/hw/arm/xlnx-ep108.c
@@ -25,42 +25,44 @@ typedef struct XlnxEP108 {
MemoryRegion ddr_ram;
} XlnxEP108;
-/* Max 2GB RAM */
-#define EP108_MAX_RAM_SIZE 0x80000000ull
-
static struct arm_boot_info xlnx_ep108_binfo;
static void xlnx_ep108_init(MachineState *machine)
{
XlnxEP108 *s = g_new0(XlnxEP108, 1);
Error *err = NULL;
+ uint64_t ram_size = machine->ram_size;
+
+ /* Create the memory region to pass to the SoC */
+ if (ram_size > XLNX_ZYNQMP_MAX_RAM_SIZE) {
+ error_report("ERROR: RAM size 0x%" PRIx64 " above max supported of "
+ "0x%llx", ram_size,
+ XLNX_ZYNQMP_MAX_RAM_SIZE);
+ exit(1);
+ }
+
+ if (ram_size < 0x08000000) {
+ qemu_log("WARNING: RAM size 0x%" PRIx64 " is small for EP108",
+ ram_size);
+ }
+
+ memory_region_allocate_system_memory(&s->ddr_ram, NULL, "ddr-ram",
+ ram_size);
object_initialize(&s->soc, sizeof(s->soc), TYPE_XLNX_ZYNQMP);
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
&error_abort);
+ object_property_set_link(OBJECT(&s->soc), OBJECT(&s->ddr_ram),
+ "ddr-ram", &error_abort);
+
object_property_set_bool(OBJECT(&s->soc), true, "realized", &err);
if (err) {
error_report_err(err);
exit(1);
}
- if (machine->ram_size > EP108_MAX_RAM_SIZE) {
- error_report("WARNING: RAM size " RAM_ADDR_FMT " above max supported, "
- "reduced to %llx", machine->ram_size, EP108_MAX_RAM_SIZE);
- machine->ram_size = EP108_MAX_RAM_SIZE;
- }
-
- if (machine->ram_size < 0x08000000) {
- qemu_log("WARNING: RAM size " RAM_ADDR_FMT " is small for EP108",
- machine->ram_size);
- }
-
- memory_region_allocate_system_memory(&s->ddr_ram, NULL, "ddr-ram",
- machine->ram_size);
- memory_region_add_subregion(get_system_memory(), 0, &s->ddr_ram);
-
- xlnx_ep108_binfo.ram_size = machine->ram_size;
+ xlnx_ep108_binfo.ram_size = ram_size;
xlnx_ep108_binfo.kernel_filename = machine->kernel_filename;
xlnx_ep108_binfo.kernel_cmdline = machine->kernel_cmdline;
xlnx_ep108_binfo.initrd_filename = machine->initrd_filename;
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 20a3b2b093..f26efd802a 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -90,6 +90,11 @@ static void xlnx_zynqmp_init(Object *obj)
&error_abort);
}
+ object_property_add_link(obj, "ddr-ram", TYPE_MEMORY_REGION,
+ (Object **)&s->ddr_ram,
+ qdev_prop_allow_set_link_before_realize,
+ OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
+
object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
@@ -119,10 +124,42 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
XlnxZynqMPState *s = XLNX_ZYNQMP(dev);
MemoryRegion *system_memory = get_system_memory();
uint8_t i;
+ uint64_t ram_size;
const char *boot_cpu = s->boot_cpu ? s->boot_cpu : "apu-cpu[0]";
+ ram_addr_t ddr_low_size, ddr_high_size;
qemu_irq gic_spi[GIC_NUM_SPI_INTR];
Error *err = NULL;
+ ram_size = memory_region_size(s->ddr_ram);
+
+ /* Create the DDR Memory Regions. User friendly checks should happen at
+ * the board level
+ */
+ if (ram_size > XLNX_ZYNQMP_MAX_LOW_RAM_SIZE) {
+ /* The RAM size is above the maximum available for the low DDR.
+ * Create the high DDR memory region as well.
+ */
+ assert(ram_size <= XLNX_ZYNQMP_MAX_RAM_SIZE);
+ ddr_low_size = XLNX_ZYNQMP_MAX_LOW_RAM_SIZE;
+ ddr_high_size = ram_size - XLNX_ZYNQMP_MAX_LOW_RAM_SIZE;
+
+ memory_region_init_alias(&s->ddr_ram_high, NULL,
+ "ddr-ram-high", s->ddr_ram,
+ ddr_low_size, ddr_high_size);
+ memory_region_add_subregion(get_system_memory(),
+ XLNX_ZYNQMP_HIGH_RAM_START,
+ &s->ddr_ram_high);
+ } else {
+ /* RAM must be non-zero */
+ assert(ram_size);
+ ddr_low_size = ram_size;
+ }
+
+ memory_region_init_alias(&s->ddr_ram_low, NULL,
+ "ddr-ram-low", s->ddr_ram,
+ 0, ddr_low_size);
+ memory_region_add_subregion(get_system_memory(), 0, &s->ddr_ram_low);
+
/* Create the four OCM banks */
for (i = 0; i < XLNX_ZYNQMP_NUM_OCM_BANKS; i++) {
char *ocm_name = g_strdup_printf("zynqmp.ocm_ram_bank_%d", i);