qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v5 1/1] xlnx-zynqmp: Add support for high DDR memory regions
@ 2016-01-12 22:39 Alistair Francis
  2016-01-15 14:36 ` Peter Maydell
  0 siblings, 1 reply; 3+ messages in thread
From: Alistair Francis @ 2016-01-12 22:39 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, crosthwaitepeter, alistair.francis

The Xilinx ZynqMP SoC and EP108 board supports three memory regions:
 - A 2GB region starting at 0
 - A 32GB region starting at 32GB
 - A 256GB region starting at 768GB

This patch adds support for the first two memory regions, which is
automatically created based on the size specified by the QEMU memory
command line argument.

On hardware the physical memory region is one continuous region, it is then
mapped into the three different regions by the DDRC. As we don't model the
DDRC this is done at startup by QEMU. The board creates the memory region and
then passes that memory region to the SoC. The SoC then maps the memory
regions.

Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
---
V5:
 - Fix compilation on 32-bit host issue
V4:
 - Small fixes
 - Localisation of ram_size
V3:
 - Assert on the RAM sizes
 - Remove ram_size property
 - General fixes
V2:
 - Create one continuous memory region and pass it to the SoC

Also, the Xilinx ZynqMP TRM is avaliable at:
http://www.xilinx.com/products/silicon-devices/soc/zynq-ultrascale-mpsoc.html?resultsTablePreSelect=documenttype:User%20Guides#documentation

 hw/arm/xlnx-ep108.c          | 40 +++++++++++++++++++++-------------------
 hw/arm/xlnx-zynqmp.c         | 37 +++++++++++++++++++++++++++++++++++++
 include/hw/arm/xlnx-zynqmp.h | 12 ++++++++++++
 3 files changed, 70 insertions(+), 19 deletions(-)

diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c
index 85b978f..93c1fb1 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("%s", error_get_pretty(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 87553bb..ccbdda5 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);
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
index d116092..1eba937 100644
--- a/include/hw/arm/xlnx-zynqmp.h
+++ b/include/hw/arm/xlnx-zynqmp.h
@@ -51,6 +51,14 @@
 #define XLNX_ZYNQMP_GIC_REGION_SIZE 0x1000
 #define XLNX_ZYNQMP_GIC_ALIASES     (0x10000 / XLNX_ZYNQMP_GIC_REGION_SIZE - 1)
 
+#define XLNX_ZYNQMP_MAX_LOW_RAM_SIZE    0x80000000ull
+
+#define XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE   0x800000000ull
+#define XLNX_ZYNQMP_HIGH_RAM_START      0x800000000ull
+
+#define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \
+                                  XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE)
+
 typedef struct XlnxZynqMPState {
     /*< private >*/
     DeviceState parent_obj;
@@ -60,8 +68,12 @@ typedef struct XlnxZynqMPState {
     ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS];
     GICState gic;
     MemoryRegion gic_mr[XLNX_ZYNQMP_GIC_REGIONS][XLNX_ZYNQMP_GIC_ALIASES];
+
     MemoryRegion ocm_ram[XLNX_ZYNQMP_NUM_OCM_BANKS];
 
+    MemoryRegion *ddr_ram;
+    MemoryRegion ddr_ram_low, ddr_ram_high;
+
     CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS];
     CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS];
     SysbusAHCIState sata;
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [PATCH v5 1/1] xlnx-zynqmp: Add support for high DDR memory regions
  2016-01-12 22:39 [Qemu-devel] [PATCH v5 1/1] xlnx-zynqmp: Add support for high DDR memory regions Alistair Francis
@ 2016-01-15 14:36 ` Peter Maydell
  2016-01-15 20:20   ` Alistair Francis
  0 siblings, 1 reply; 3+ messages in thread
From: Peter Maydell @ 2016-01-15 14:36 UTC (permalink / raw)
  To: Alistair Francis; +Cc: Peter Crosthwaite, QEMU Developers

On 12 January 2016 at 22:39, Alistair Francis
<alistair.francis@xilinx.com> wrote:
> The Xilinx ZynqMP SoC and EP108 board supports three memory regions:
>  - A 2GB region starting at 0
>  - A 32GB region starting at 32GB
>  - A 256GB region starting at 768GB
>
> This patch adds support for the first two memory regions, which is
> automatically created based on the size specified by the QEMU memory
> command line argument.
>
> On hardware the physical memory region is one continuous region, it is then
> mapped into the three different regions by the DDRC. As we don't model the
> DDRC this is done at startup by QEMU. The board creates the memory region and
> then passes that memory region to the SoC. The SoC then maps the memory
> regions.
>
> Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
> Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
> ---
> V5:
>  - Fix compilation on 32-bit host issue
> V4:
>  - Small fixes
>  - Localisation of ram_size
> V3:
>  - Assert on the RAM sizes
>  - Remove ram_size property
>  - General fixes
> V2:
>  - Create one continuous memory region and pass it to the SoC



Applied to target-arm.next, thanks.

-- PMM

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [PATCH v5 1/1] xlnx-zynqmp: Add support for high DDR memory regions
  2016-01-15 14:36 ` Peter Maydell
@ 2016-01-15 20:20   ` Alistair Francis
  0 siblings, 0 replies; 3+ messages in thread
From: Alistair Francis @ 2016-01-15 20:20 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Peter Crosthwaite, QEMU Developers, Alistair Francis

On Fri, Jan 15, 2016 at 6:36 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 12 January 2016 at 22:39, Alistair Francis
> <alistair.francis@xilinx.com> wrote:
>> The Xilinx ZynqMP SoC and EP108 board supports three memory regions:
>>  - A 2GB region starting at 0
>>  - A 32GB region starting at 32GB
>>  - A 256GB region starting at 768GB
>>
>> This patch adds support for the first two memory regions, which is
>> automatically created based on the size specified by the QEMU memory
>> command line argument.
>>
>> On hardware the physical memory region is one continuous region, it is then
>> mapped into the three different regions by the DDRC. As we don't model the
>> DDRC this is done at startup by QEMU. The board creates the memory region and
>> then passes that memory region to the SoC. The SoC then maps the memory
>> regions.
>>
>> Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
>> Reviewed-by: Peter Crosthwaite <crosthwaite.peter@gmail.com>
>> ---
>> V5:
>>  - Fix compilation on 32-bit host issue
>> V4:
>>  - Small fixes
>>  - Localisation of ram_size
>> V3:
>>  - Assert on the RAM sizes
>>  - Remove ram_size property
>>  - General fixes
>> V2:
>>  - Create one continuous memory region and pass it to the SoC
>
>
>
> Applied to target-arm.next, thanks.

Thanks!

Alistair

>
> -- PMM
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-01-15 20:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-12 22:39 [Qemu-devel] [PATCH v5 1/1] xlnx-zynqmp: Add support for high DDR memory regions Alistair Francis
2016-01-15 14:36 ` Peter Maydell
2016-01-15 20:20   ` Alistair Francis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).