diff mbox

[v4,1/1] xlnx-zynqmp: Add support for high DDR memory regions

Message ID 629c613cae9234bed1e7d362209a2ea1d6f92a21.1452031236.git.alistair.francis@xilinx.com
State New
Headers show

Commit Message

Alistair Francis Jan. 5, 2016, 10:05 p.m. UTC
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>
---
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          | 35 ++++++++++++++++++-----------------
 hw/arm/xlnx-zynqmp.c         | 37 +++++++++++++++++++++++++++++++++++++
 include/hw/arm/xlnx-zynqmp.h | 12 ++++++++++++
 3 files changed, 67 insertions(+), 17 deletions(-)

Comments

Peter Maydell Jan. 7, 2016, 11:41 a.m. UTC | #1
On 5 January 2016 at 22:05, 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>



Applied to target-arm.next, thanks.

-- PMM
Peter Maydell Jan. 11, 2016, 4:04 p.m. UTC | #2
On 5 January 2016 at 22:05, 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>
> ---
> 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

> @@ -35,20 +32,12 @@ static void xlnx_ep108_init(MachineState *machine)
>      XlnxEP108 *s = g_new0(XlnxEP108, 1);
>      Error *err = NULL;
>
> -    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_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) {
> +    /* Create the memory region to pass to the SoC */
> +    if (machine->ram_size > XLNX_ZYNQMP_MAX_RAM_SIZE) {

Unfortunately this doesn't build on 32-bit hosts:

/home/petmay01/qemu/hw/arm/xlnx-ep108.c: In function 'xlnx_ep108_init':
/home/petmay01/qemu/hw/arm/xlnx-ep108.c:36:16: error: comparison is
always false due to limited range of data type [-Werror=type-limits]
     if (machine->ram_size > XLNX_ZYNQMP_MAX_RAM_SIZE) {
                ^
/home/petmay01/qemu/hw/arm/xlnx-ep108.c:40:9: error: large integer
implicitly truncated to unsigned type [-Werror=overflow]
         machine->ram_size = XLNX_ZYNQMP_MAX_RAM_SIZE;
         ^
cc1: all warnings being treated as errors

so I'm going to drop it from the target-arm pullreq. Please could
you fix the compile issue and resend?

There are a couple of problems you're running into:

(1) machine->ram_size is a ram_addr_t so might be 32 bit; you
can do what virt.c does to avoid the warning and use a local
uin64_t variable for the comparison

(2) complaint about reassigning back to ram_size. this is spurious
but you can avoid it by making this board behave the same way as
virt.c, vexpress.c etc do if presented with an unsupported
ram_size -- you should fail, rather than truncating and continuing.

(3) %llx is not the correct format string for a ram_addr_t:
use RAM_ADDR_FMT. (This isn't making the compiler complain,
but I noticed it looking at the code.)

thanks
-- PMM
Alistair Francis Jan. 12, 2016, 12:24 a.m. UTC | #3
On Mon, Jan 11, 2016 at 8:04 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 5 January 2016 at 22:05, 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>
>> ---
>> 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
>
>> @@ -35,20 +32,12 @@ static void xlnx_ep108_init(MachineState *machine)
>>      XlnxEP108 *s = g_new0(XlnxEP108, 1);
>>      Error *err = NULL;
>>
>> -    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_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) {
>> +    /* Create the memory region to pass to the SoC */
>> +    if (machine->ram_size > XLNX_ZYNQMP_MAX_RAM_SIZE) {
>
> Unfortunately this doesn't build on 32-bit hosts:
>
> /home/petmay01/qemu/hw/arm/xlnx-ep108.c: In function 'xlnx_ep108_init':
> /home/petmay01/qemu/hw/arm/xlnx-ep108.c:36:16: error: comparison is
> always false due to limited range of data type [-Werror=type-limits]
>      if (machine->ram_size > XLNX_ZYNQMP_MAX_RAM_SIZE) {
>                 ^
> /home/petmay01/qemu/hw/arm/xlnx-ep108.c:40:9: error: large integer
> implicitly truncated to unsigned type [-Werror=overflow]
>          machine->ram_size = XLNX_ZYNQMP_MAX_RAM_SIZE;
>          ^
> cc1: all warnings being treated as errors
>
> so I'm going to drop it from the target-arm pullreq. Please could
> you fix the compile issue and resend?

I think I have fixed them. Unfortunately I don't have access to a
32-bit machine to test.

>
> There are a couple of problems you're running into:
>
> (1) machine->ram_size is a ram_addr_t so might be 32 bit; you
> can do what virt.c does to avoid the warning and use a local
> uin64_t variable for the comparison

Ok, I now create a uint64_t variable to store the value.

>
> (2) complaint about reassigning back to ram_size. this is spurious
> but you can avoid it by making this board behave the same way as
> virt.c, vexpress.c etc do if presented with an unsupported
> ram_size -- you should fail, rather than truncating and continuing.

If I'm using a 64-bit variable to store the value won't this no longer
be a problem?

>
> (3) %llx is not the correct format string for a ram_addr_t:
> use RAM_ADDR_FMT. (This isn't making the compiler complain,
> but I noticed it looking at the code.)

Again, isn't this fixed by changing to a variable?

Thanks,

Alistair

>
> thanks
> -- PMM
>
Peter Maydell Jan. 12, 2016, 9:01 a.m. UTC | #4
On 12 January 2016 at 00:24, Alistair Francis
<alistair.francis@xilinx.com> wrote:
> On Mon, Jan 11, 2016 at 8:04 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> There are a couple of problems you're running into:
>>
>> (1) machine->ram_size is a ram_addr_t so might be 32 bit; you
>> can do what virt.c does to avoid the warning and use a local
>> uin64_t variable for the comparison
>
> Ok, I now create a uint64_t variable to store the value.
>
>>
>> (2) complaint about reassigning back to ram_size. this is spurious
>> but you can avoid it by making this board behave the same way as
>> virt.c, vexpress.c etc do if presented with an unsupported
>> ram_size -- you should fail, rather than truncating and continuing.
>
> If I'm using a 64-bit variable to store the value won't this no longer
> be a problem?

I think you should do the same thing the other boards do anyway.

>> (3) %llx is not the correct format string for a ram_addr_t:
>> use RAM_ADDR_FMT. (This isn't making the compiler complain,
>> but I noticed it looking at the code.)
>
> Again, isn't this fixed by changing to a variable?

%llx isn't right for uint64_t either :-)

thanks
-- PMM
Alistair Francis Jan. 12, 2016, 9:59 p.m. UTC | #5
On Tue, Jan 12, 2016 at 1:01 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 12 January 2016 at 00:24, Alistair Francis
> <alistair.francis@xilinx.com> wrote:
>> On Mon, Jan 11, 2016 at 8:04 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> There are a couple of problems you're running into:
>>>
>>> (1) machine->ram_size is a ram_addr_t so might be 32 bit; you
>>> can do what virt.c does to avoid the warning and use a local
>>> uin64_t variable for the comparison
>>
>> Ok, I now create a uint64_t variable to store the value.
>>
>>>
>>> (2) complaint about reassigning back to ram_size. this is spurious
>>> but you can avoid it by making this board behave the same way as
>>> virt.c, vexpress.c etc do if presented with an unsupported
>>> ram_size -- you should fail, rather than truncating and continuing.
>>
>> If I'm using a 64-bit variable to store the value won't this no longer
>> be a problem?
>
> I think you should do the same thing the other boards do anyway.

Ok, I have changed it to exit instead of resize.

>
>>> (3) %llx is not the correct format string for a ram_addr_t:
>>> use RAM_ADDR_FMT. (This isn't making the compiler complain,
>>> but I noticed it looking at the code.)
>>
>> Again, isn't this fixed by changing to a variable?
>
> %llx isn't right for uint64_t either :-)

I still have a %llx for the macro as it isn't a ram_addr_t.

Re sending now.

Thanks,

Alistair

>
> thanks
> -- PMM
>
Peter Crosthwaite Jan. 12, 2016, 10 p.m. UTC | #6
On Tue, Jan 12, 2016 at 1:59 PM, Alistair Francis
<alistair.francis@xilinx.com> wrote:
> On Tue, Jan 12, 2016 at 1:01 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> On 12 January 2016 at 00:24, Alistair Francis
>> <alistair.francis@xilinx.com> wrote:
>>> On Mon, Jan 11, 2016 at 8:04 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>>> There are a couple of problems you're running into:
>>>>
>>>> (1) machine->ram_size is a ram_addr_t so might be 32 bit; you
>>>> can do what virt.c does to avoid the warning and use a local
>>>> uin64_t variable for the comparison
>>>
>>> Ok, I now create a uint64_t variable to store the value.
>>>
>>>>
>>>> (2) complaint about reassigning back to ram_size. this is spurious
>>>> but you can avoid it by making this board behave the same way as
>>>> virt.c, vexpress.c etc do if presented with an unsupported
>>>> ram_size -- you should fail, rather than truncating and continuing.
>>>
>>> If I'm using a 64-bit variable to store the value won't this no longer
>>> be a problem?
>>
>> I think you should do the same thing the other boards do anyway.
>
> Ok, I have changed it to exit instead of resize.
>
>>
>>>> (3) %llx is not the correct format string for a ram_addr_t:
>>>> use RAM_ADDR_FMT. (This isn't making the compiler complain,
>>>> but I noticed it looking at the code.)
>>>
>>> Again, isn't this fixed by changing to a variable?
>>
>> %llx isn't right for uint64_t either :-)
>
> I still have a %llx for the macro as it isn't a ram_addr_t.
>

Should be PRIx64 though.

Regards,
Peter

> Re sending now.
>
> Thanks,
>
> Alistair
>
>>
>> thanks
>> -- PMM
>>
Alistair Francis Jan. 12, 2016, 10:07 p.m. UTC | #7
On Tue, Jan 12, 2016 at 2:00 PM, Peter Crosthwaite
<crosthwaitepeter@gmail.com> wrote:
> On Tue, Jan 12, 2016 at 1:59 PM, Alistair Francis
> <alistair.francis@xilinx.com> wrote:
>> On Tue, Jan 12, 2016 at 1:01 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> On 12 January 2016 at 00:24, Alistair Francis
>>> <alistair.francis@xilinx.com> wrote:
>>>> On Mon, Jan 11, 2016 at 8:04 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>>>> There are a couple of problems you're running into:
>>>>>
>>>>> (1) machine->ram_size is a ram_addr_t so might be 32 bit; you
>>>>> can do what virt.c does to avoid the warning and use a local
>>>>> uin64_t variable for the comparison
>>>>
>>>> Ok, I now create a uint64_t variable to store the value.
>>>>
>>>>>
>>>>> (2) complaint about reassigning back to ram_size. this is spurious
>>>>> but you can avoid it by making this board behave the same way as
>>>>> virt.c, vexpress.c etc do if presented with an unsupported
>>>>> ram_size -- you should fail, rather than truncating and continuing.
>>>>
>>>> If I'm using a 64-bit variable to store the value won't this no longer
>>>> be a problem?
>>>
>>> I think you should do the same thing the other boards do anyway.
>>
>> Ok, I have changed it to exit instead of resize.
>>
>>>
>>>>> (3) %llx is not the correct format string for a ram_addr_t:
>>>>> use RAM_ADDR_FMT. (This isn't making the compiler complain,
>>>>> but I noticed it looking at the code.)
>>>>
>>>> Again, isn't this fixed by changing to a variable?
>>>
>>> %llx isn't right for uint64_t either :-)
>>
>> I still have a %llx for the macro as it isn't a ram_addr_t.
>>
>
> Should be PRIx64 though.

Then I get a compiler warning as the macro is a long long unsigned int.

Thanks,

Alistair

>
> Regards,
> Peter
>
>> Re sending now.
>>
>> Thanks,
>>
>> Alistair
>>
>>>
>>> thanks
>>> -- PMM
>>>
>
Peter Crosthwaite Jan. 12, 2016, 10:15 p.m. UTC | #8
On Tue, Jan 12, 2016 at 2:07 PM, Alistair Francis
<alistair.francis@xilinx.com> wrote:
> On Tue, Jan 12, 2016 at 2:00 PM, Peter Crosthwaite
> <crosthwaitepeter@gmail.com> wrote:
>> On Tue, Jan 12, 2016 at 1:59 PM, Alistair Francis
>> <alistair.francis@xilinx.com> wrote:
>>> On Tue, Jan 12, 2016 at 1:01 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>>> On 12 January 2016 at 00:24, Alistair Francis
>>>> <alistair.francis@xilinx.com> wrote:
>>>>> On Mon, Jan 11, 2016 at 8:04 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>>>>> There are a couple of problems you're running into:
>>>>>>
>>>>>> (1) machine->ram_size is a ram_addr_t so might be 32 bit; you
>>>>>> can do what virt.c does to avoid the warning and use a local
>>>>>> uin64_t variable for the comparison
>>>>>
>>>>> Ok, I now create a uint64_t variable to store the value.
>>>>>
>>>>>>
>>>>>> (2) complaint about reassigning back to ram_size. this is spurious
>>>>>> but you can avoid it by making this board behave the same way as
>>>>>> virt.c, vexpress.c etc do if presented with an unsupported
>>>>>> ram_size -- you should fail, rather than truncating and continuing.
>>>>>
>>>>> If I'm using a 64-bit variable to store the value won't this no longer
>>>>> be a problem?
>>>>
>>>> I think you should do the same thing the other boards do anyway.
>>>
>>> Ok, I have changed it to exit instead of resize.
>>>
>>>>
>>>>>> (3) %llx is not the correct format string for a ram_addr_t:
>>>>>> use RAM_ADDR_FMT. (This isn't making the compiler complain,
>>>>>> but I noticed it looking at the code.)
>>>>>
>>>>> Again, isn't this fixed by changing to a variable?
>>>>
>>>> %llx isn't right for uint64_t either :-)
>>>
>>> I still have a %llx for the macro as it isn't a ram_addr_t.
>>>
>>
>> Should be PRIx64 though.
>
> Then I get a compiler warning as the macro is a long long unsigned int.
>

Ahh, the llx is for printing the constant, which hasn't really changed
from original code anyway (other than a rename). I think the
RAM_ADDR_FMT  goes to uint64_t and the llx stays?

Regards,
Peter

> Thanks,
>
> Alistair
>
>>
>> Regards,
>> Peter
>>
>>> Re sending now.
>>>
>>> Thanks,
>>>
>>> Alistair
>>>
>>>>
>>>> thanks
>>>> -- PMM
>>>>
>>
Alistair Francis Jan. 12, 2016, 10:18 p.m. UTC | #9
On Tue, Jan 12, 2016 at 2:15 PM, Peter Crosthwaite
<crosthwaitepeter@gmail.com> wrote:
> On Tue, Jan 12, 2016 at 2:07 PM, Alistair Francis
> <alistair.francis@xilinx.com> wrote:
>> On Tue, Jan 12, 2016 at 2:00 PM, Peter Crosthwaite
>> <crosthwaitepeter@gmail.com> wrote:
>>> On Tue, Jan 12, 2016 at 1:59 PM, Alistair Francis
>>> <alistair.francis@xilinx.com> wrote:
>>>> On Tue, Jan 12, 2016 at 1:01 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>>>> On 12 January 2016 at 00:24, Alistair Francis
>>>>> <alistair.francis@xilinx.com> wrote:
>>>>>> On Mon, Jan 11, 2016 at 8:04 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
>>>>>>> There are a couple of problems you're running into:
>>>>>>>
>>>>>>> (1) machine->ram_size is a ram_addr_t so might be 32 bit; you
>>>>>>> can do what virt.c does to avoid the warning and use a local
>>>>>>> uin64_t variable for the comparison
>>>>>>
>>>>>> Ok, I now create a uint64_t variable to store the value.
>>>>>>
>>>>>>>
>>>>>>> (2) complaint about reassigning back to ram_size. this is spurious
>>>>>>> but you can avoid it by making this board behave the same way as
>>>>>>> virt.c, vexpress.c etc do if presented with an unsupported
>>>>>>> ram_size -- you should fail, rather than truncating and continuing.
>>>>>>
>>>>>> If I'm using a 64-bit variable to store the value won't this no longer
>>>>>> be a problem?
>>>>>
>>>>> I think you should do the same thing the other boards do anyway.
>>>>
>>>> Ok, I have changed it to exit instead of resize.
>>>>
>>>>>
>>>>>>> (3) %llx is not the correct format string for a ram_addr_t:
>>>>>>> use RAM_ADDR_FMT. (This isn't making the compiler complain,
>>>>>>> but I noticed it looking at the code.)
>>>>>>
>>>>>> Again, isn't this fixed by changing to a variable?
>>>>>
>>>>> %llx isn't right for uint64_t either :-)
>>>>
>>>> I still have a %llx for the macro as it isn't a ram_addr_t.
>>>>
>>>
>>> Should be PRIx64 though.
>>
>> Then I get a compiler warning as the macro is a long long unsigned int.
>>
>
> Ahh, the llx is for printing the constant, which hasn't really changed
> from original code anyway (other than a rename). I think the
> RAM_ADDR_FMT  goes to uint64_t and the llx stays?

Yep, that sounds good to me.

Thanks,

Alistair

>
> Regards,
> Peter
>
>> Thanks,
>>
>> Alistair
>>
>>>
>>> Regards,
>>> Peter
>>>
>>>> Re sending now.
>>>>
>>>> Thanks,
>>>>
>>>> Alistair
>>>>
>>>>>
>>>>> thanks
>>>>> -- PMM
>>>>>
>>>
>
diff mbox

Patch

diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c
index 85b978f..1c34774 100644
--- a/hw/arm/xlnx-ep108.c
+++ b/hw/arm/xlnx-ep108.c
@@ -25,9 +25,6 @@  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)
@@ -35,20 +32,12 @@  static void xlnx_ep108_init(MachineState *machine)
     XlnxEP108 *s = g_new0(XlnxEP108, 1);
     Error *err = NULL;
 
-    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_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) {
+    /* Create the memory region to pass to the SoC */
+    if (machine->ram_size > XLNX_ZYNQMP_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;
+                     "reduced to %llx", machine->ram_size,
+                     XLNX_ZYNQMP_MAX_RAM_SIZE);
+        machine->ram_size = XLNX_ZYNQMP_MAX_RAM_SIZE;
     }
 
     if (machine->ram_size < 0x08000000) {
@@ -58,7 +47,19 @@  static void xlnx_ep108_init(MachineState *machine)
 
     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);
+
+    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);
+    }
 
     xlnx_ep108_binfo.ram_size = machine->ram_size;
     xlnx_ep108_binfo.kernel_filename = machine->kernel_filename;
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 87553bb..b9b8bee 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 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;