Re: [edk2-devel] [PATCH 1/2] CloudHv/arm: add PeiMemInfoLib

2022-08-19 Thread Jianyong Wu
Thanks Sami. I will fix them all and send the v2 later.

From: Sami Mujawar 
Sent: Thursday, August 18, 2022 7:41 PM
To: Jianyong Wu ; devel@edk2.groups.io
Cc: Ard Biesheuvel ; Justin He ; 
nd 
Subject: Re: [edk2-devel] [PATCH 1/2] CloudHv/arm: add PeiMemInfoLib

Hi Jianyong,

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar

From: Jianyong Wu mailto:jianyong...@arm.com>>
Date: Thursday, 18 August 2022 at 06:22
To: "devel@edk2.groups.io<mailto:devel@edk2.groups.io>" 
mailto:devel@edk2.groups.io>>, Jianyong Wu 
mailto:jianyong...@arm.com>>, Sami Mujawar 
mailto:sami.muja...@arm.com>>
Cc: Ard Biesheuvel 
mailto:ardb+tianoc...@kernel.org>>, Justin He 
mailto:justin...@arm.com>>, nd 
mailto:n...@arm.com>>
Subject: RE: [edk2-devel] [PATCH 1/2] CloudHv/arm: add PeiMemInfoLib

Hi Sami,

Thanks for review. All the comments are Ok for me. Just one inline reply:


+

+struct CloudHvMemNodeInfo CloudHvMemNode[CLOUDHV_MAX_MEM_NODE_NUM];

+

+RETURN_STATUS

+EFIAPI

+CloudHvVirtMemInfoPeiLibConstructor (

+  VOID

+  )

+{

+  VOID   *DeviceTreeBase;

+  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttributes;

+  INT32  Node, Prev;

+  UINT64 CurBase, MemBase;

+  UINT64 CurSize;

+  CONST CHAR8*Type;

+  INT32  Len;

+  CONST UINT64   *RegProp;

+  RETURN_STATUS  PcdStatus;

+  UINT8  Index;

+

+  ZeroMem (CloudHvMemNode, sizeof(CloudHvMemNode[0]) * 
CLOUDHV_MAX_MEM_NODE_NUM);
[SAMI] Will sizeof (CloudHvMemNode) should be sufficient above? Also, can you 
run uncrustify on your patches, please?

[Jong] The local uncrustify test environment is not ready. But I think “sizeof” 
here is OK, as this struct contains only two u64 variables, thus no padding 
here. If sizeof is not preference here, is there any suggestion from you?
[SAMI] I think you could just use

+  ZeroMem (CloudHvMemNode, sizeof(CloudHvMemNode));

Also, let me know if you need any help to get uncrustify working locally. I 
will dig out the relevant information for you.

[/SAMI]


Thanks
Jianyong




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#92569): https://edk2.groups.io/g/devel/message/92569
Mute This Topic: https://groups.io/mt/92686349/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH 1/2] CloudHv/arm: add PeiMemInfoLib

2022-08-18 Thread Sami Mujawar
Hi Jianyong,

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar

From: Jianyong Wu 
Date: Thursday, 18 August 2022 at 06:22
To: "devel@edk2.groups.io" , Jianyong Wu 
, Sami Mujawar 
Cc: Ard Biesheuvel , Justin He , 
nd 
Subject: RE: [edk2-devel] [PATCH 1/2] CloudHv/arm: add PeiMemInfoLib

Hi Sami,

Thanks for review. All the comments are Ok for me. Just one inline reply:


+

+struct CloudHvMemNodeInfo CloudHvMemNode[CLOUDHV_MAX_MEM_NODE_NUM];

+

+RETURN_STATUS

+EFIAPI

+CloudHvVirtMemInfoPeiLibConstructor (

+  VOID

+  )

+{

+  VOID   *DeviceTreeBase;

+  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttributes;

+  INT32  Node, Prev;

+  UINT64 CurBase, MemBase;

+  UINT64 CurSize;

+  CONST CHAR8*Type;

+  INT32  Len;

+  CONST UINT64   *RegProp;

+  RETURN_STATUS  PcdStatus;

+  UINT8  Index;

+

+  ZeroMem (CloudHvMemNode, sizeof(CloudHvMemNode[0]) * 
CLOUDHV_MAX_MEM_NODE_NUM);
[SAMI] Will sizeof (CloudHvMemNode) should be sufficient above? Also, can you 
run uncrustify on your patches, please?

[Jong] The local uncrustify test environment is not ready. But I think “sizeof” 
here is OK, as this struct contains only two u64 variables, thus no padding 
here. If sizeof is not preference here, is there any suggestion from you?
[SAMI] I think you could just use

+  ZeroMem (CloudHvMemNode, sizeof(CloudHvMemNode));

Also, let me know if you need any help to get uncrustify working locally. I 
will dig out the relevant information for you.

[/SAMI]


Thanks
Jianyong




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#92549): https://edk2.groups.io/g/devel/message/92549
Mute This Topic: https://groups.io/mt/92686349/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH 1/2] CloudHv/arm: add PeiMemInfoLib

2022-08-17 Thread Jianyong Wu
Hi Sami,

Thanks for review. All the comments are Ok for me. Just one inline reply:


+

+struct CloudHvMemNodeInfo CloudHvMemNode[CLOUDHV_MAX_MEM_NODE_NUM];

+

+RETURN_STATUS

+EFIAPI

+CloudHvVirtMemInfoPeiLibConstructor (

+  VOID

+  )

+{

+  VOID   *DeviceTreeBase;

+  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttributes;

+  INT32  Node, Prev;

+  UINT64 CurBase, MemBase;

+  UINT64 CurSize;

+  CONST CHAR8*Type;

+  INT32  Len;

+  CONST UINT64   *RegProp;

+  RETURN_STATUS  PcdStatus;

+  UINT8  Index;

+

+  ZeroMem (CloudHvMemNode, sizeof(CloudHvMemNode[0]) * 
CLOUDHV_MAX_MEM_NODE_NUM);
[SAMI] Will sizeof (CloudHvMemNode) should be sufficient above? Also, can you 
run uncrustify on your patches, please?

[Jong] The local uncrustify test environment is not ready. But I think “sizeof” 
here is OK, as this struct contains only two u64 variables, thus no padding 
here. If sizeof is not preference here, is there any suggestion from you?

Thanks
Jianyong




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#92540): https://edk2.groups.io/g/devel/message/92540
Mute This Topic: https://groups.io/mt/92686349/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH 1/2] CloudHv/arm: add PeiMemInfoLib

2022-08-09 Thread Jianyong Wu
Hi Sami,

Thanks for review. All the comments are Ok for me. Just one inline reply:

+

+struct CloudHvMemNodeInfo CloudHvMemNode[CLOUDHV_MAX_MEM_NODE_NUM];

+

+RETURN_STATUS

+EFIAPI

+CloudHvVirtMemInfoPeiLibConstructor (

+  VOID

+  )

+{

+  VOID   *DeviceTreeBase;

+  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttributes;

+  INT32  Node, Prev;

+  UINT64 CurBase, MemBase;

+  UINT64 CurSize;

+  CONST CHAR8*Type;

+  INT32  Len;

+  CONST UINT64   *RegProp;

+  RETURN_STATUS  PcdStatus;

+  UINT8  Index;

+

+  ZeroMem (CloudHvMemNode, sizeof(CloudHvMemNode[0]) * 
CLOUDHV_MAX_MEM_NODE_NUM);
[SAMI] Will sizeof (CloudHvMemNode) should be sufficient above? Also, can you 
run uncrustify on your patches, please?

[Jong] The local uncrustify test environment is not ready. But I think “sizeof” 
here is OK, as this struct contains only two u64 variables, thus no padding 
here.

Thanks
Jianyong



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#92241): https://edk2.groups.io/g/devel/message/92241
Mute This Topic: https://groups.io/mt/92686349/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-




Re: [edk2-devel] [PATCH 1/2] CloudHv/arm: add PeiMemInfoLib

2022-08-08 Thread Sami Mujawar

Hi Jianyong,

Thank you for this patch.

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar

On 29/07/2022 08:21 am, Jianyong Wu wrote:

Memory layout in CLoud Hypervisor for arm is changed and is different
with Qemu, thus we should build its own PeiMemInfoLib.
The main change in the memory layout is that normal ram may not contiguous
under 4G. The top 64M under 4G is reserved for 32bit device.

What this patch does:
1. get all of the memory node from DT;
2. Init page table for each memory node;
3. Add all of the memory nodes to Hob;

Signed-off-by: Jianyong Wu
---
  .../CloudHvVirtMemInfoLib.c   | 251 ++
  .../CloudHvVirtMemInfoPeiLib.inf  |  46 
  2 files changed, 297 insertions(+)
  create mode 100755 
ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c
  create mode 100755 
ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoPeiLib.inf

diff --git a/ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c 
b/ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c
new file mode 100755
index 00..7ae24641d3
--- /dev/null
+++ b/ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c
@@ -0,0 +1,251 @@
+/** @file
+
+  Copyright (c) 2022, Arm Limited. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include
+
+// The first memnory node is the one whose base address is the lowest.
+UINT64 FirMemNodeBase = 0, FirMemNodeSize = 0;
[SAMI] Is it possible to move the above variables within the scope of 
CloudHvVirtMemInfoPeiLibConstructor() ?

+//
+// Cloud Hypervisor may have more than one memory nodes. Even there is no 
limit for that,
+// I think 10 is enough in general.
+//
+#define CLOUDHV_MAX_MEM_NODE_NUM 10
+
+// Record memory node info (base address and size)
+struct CloudHvMemNodeInfo {
+  UINT64 Base;
+  UINT64 Size;
+};


[SAMI] The edk2 coding guidelines require definition of a typedef for 
structures, see section 5.6.3.[1,2,3] at 
https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/5_source_files/56_declarations_and_types#5.6.3.1-structures-shall-not-be-directly-declared.



+
+struct CloudHvMemNodeInfo CloudHvMemNode[CLOUDHV_MAX_MEM_NODE_NUM];
+
+RETURN_STATUS
+EFIAPI
+CloudHvVirtMemInfoPeiLibConstructor (
+  VOID
+  )
+{
+  VOID   *DeviceTreeBase;
+  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttributes;
+  INT32  Node, Prev;
+  UINT64 CurBase, MemBase;
+  UINT64 CurSize;
+  CONST CHAR8*Type;
+  INT32  Len;
+  CONST UINT64   *RegProp;
+  RETURN_STATUS  PcdStatus;
+  UINT8  Index;
+
+  ZeroMem (CloudHvMemNode, sizeof(CloudHvMemNode[0]) * 
CLOUDHV_MAX_MEM_NODE_NUM);
[SAMI] Will sizeof (CloudHvMemNode) should be sufficient above? Also can 
you run uncrustify on your patches, please?

+
+  Index = 0;
+  MemBase = FixedPcdGet64 (PcdSystemMemoryBase);
+  ResourceAttributes = (
+EFI_RESOURCE_ATTRIBUTE_PRESENT |
+EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+EFI_RESOURCE_ATTRIBUTE_TESTED
+);
+  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
+  ASSERT (DeviceTreeBase != NULL);
+
+  //
+  // Make sure we have a valid device tree blob
+  //
+  ASSERT (fdt_check_header (DeviceTreeBase) == 0);
[SAMI] I think the two ASSERTs above must return an error, otherwise 
they would result in a crash in release builds.

+
+  //
+  // Look for the lowest memory node
+  //
+  for (Prev = 0; ; Prev = Node) {
+Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
+if (Node < 0) {
+  break;
+}
+
+//
+// Check for memory node
+//
+Type = fdt_getprop (DeviceTreeBase, Node, "device_type", );
+if (Type && (AsciiStrnCmp (Type, "memory", Len) == 0)) {
+  //
+  // Get the 'reg' property of this node. For now, we will assume
+  // two 8 byte quantities for base and size, respectively.
+  //
+  RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", );
+  if ((RegProp != 0) && (Len == (2 * sizeof (UINT64 {
+CurBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
+CurSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
+
+DEBUG ((
+  DEBUG_INFO,
+  "%a: System RAM @ 0x%lx - 0x%lx\n",
+  __FUNCTION__,
+  CurBase,
+  CurBase + CurSize - 1
+  ));
+
+if (CurBase == MemBase) {
+FirMemNodeBase = CurBase;
+FirMemNodeSize = CurSize;
+}
+
+CloudHvMemNode[Index].Base = CurBase;
+CloudHvMemNode[Index].Size = CurSize;
+Index++;
+// We should build Hob seperately for the memory node except the first 
one
+if (CurBase != MemBase) {
[SAMI] Can this be made an 

Re: [edk2-devel] [PATCH 1/2] CloudHv/arm: add PeiMemInfoLib

2022-08-08 Thread Jianyong Wu
+cc: Ard Biesheuvel, Leif Lindholm, Gerd Hoffmann

> -Original Message-
> From: devel@edk2.groups.io  On Behalf Of Jianyong
> Wu via groups.io
> Sent: Friday, July 29, 2022 3:22 PM
> To: devel@edk2.groups.io; Sami Mujawar 
> Cc: ard.biesheu...@linaro.org; Justin He ; Jianyong
> Wu 
> Subject: [edk2-devel] [PATCH 1/2] CloudHv/arm: add PeiMemInfoLib
>
> Memory layout in CLoud Hypervisor for arm is changed and is different with
> Qemu, thus we should build its own PeiMemInfoLib.
> The main change in the memory layout is that normal ram may not
> contiguous under 4G. The top 64M under 4G is reserved for 32bit device.
>
> What this patch does:
> 1. get all of the memory node from DT;
> 2. Init page table for each memory node; 3. Add all of the memory nodes to
> Hob;
>
> Signed-off-by: Jianyong Wu 
> ---
>  .../CloudHvVirtMemInfoLib.c   | 251 ++
>  .../CloudHvVirtMemInfoPeiLib.inf  |  46 
>  2 files changed, 297 insertions(+)
>  create mode 100755
> ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c
>  create mode 100755
> ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoPeiLib.inf
>
> diff --git
> a/ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c
> b/ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c
> new file mode 100755
> index 00..7ae24641d3
> --- /dev/null
> +++
> b/ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c
> @@ -0,0 +1,251 @@
> +/** @file
> +
> +  Copyright (c) 2022, Arm Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include  #include 
> +
> +#include
> +
> +// The first memnory node is the one whose base address is the lowest.
> +UINT64 FirMemNodeBase = 0, FirMemNodeSize = 0; // // Cloud Hypervisor
> +may have more than one memory nodes. Even there is no limit for that,
> +// I think 10 is enough in general.
> +//
> +#define CLOUDHV_MAX_MEM_NODE_NUM 10
> +
> +// Record memory node info (base address and size) struct
> +CloudHvMemNodeInfo {
> +  UINT64 Base;
> +  UINT64 Size;
> +};
> +
> +struct CloudHvMemNodeInfo
> CloudHvMemNode[CLOUDHV_MAX_MEM_NODE_NUM];
> +
> +RETURN_STATUS
> +EFIAPI
> +CloudHvVirtMemInfoPeiLibConstructor (
> +  VOID
> +  )
> +{
> +  VOID   *DeviceTreeBase;
> +  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttributes;
> +  INT32  Node, Prev;
> +  UINT64 CurBase, MemBase;
> +  UINT64 CurSize;
> +  CONST CHAR8*Type;
> +  INT32  Len;
> +  CONST UINT64   *RegProp;
> +  RETURN_STATUS  PcdStatus;
> +  UINT8  Index;
> +
> +  ZeroMem (CloudHvMemNode, sizeof(CloudHvMemNode[0]) *
> + CLOUDHV_MAX_MEM_NODE_NUM);
> +
> +  Index = 0;
> +  MemBase = FixedPcdGet64 (PcdSystemMemoryBase);  ResourceAttributes
> =
> + (
> +EFI_RESOURCE_ATTRIBUTE_PRESENT |
> +EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
> +EFI_RESOURCE_ATTRIBUTE_TESTED
> +);
> +  DeviceTreeBase = (VOID *)(UINTN)PcdGet64
> + (PcdDeviceTreeInitialBaseAddress);
> +  ASSERT (DeviceTreeBase != NULL);
> +
> +  //
> +  // Make sure we have a valid device tree blob  //  ASSERT
> + (fdt_check_header (DeviceTreeBase) == 0);
> +
> +  //
> +  // Look for the lowest memory node
> +  //
> +  for (Prev = 0; ; Prev = Node) {
> +Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
> +if (Node < 0) {
> +  break;
> +}
> +
> +//
> +// Check for memory node
> +//
> +Type = fdt_getprop (DeviceTreeBase, Node, "device_type", );
> +if (Type && (AsciiStrnCmp (Type, "memory", Len) == 0)) {
> +  //
> +  // Get the 'reg' property of this node. For now, we will assume
> +  // two 8 byte quantities for base and size, respectively.
> +  //
> +  RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", );
> +  if ((RegProp != 0) && (Len == (2 * sizeof (UINT64 {
> +CurBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
> +CurSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
> +
> +DEBUG ((
> +  DEBUG_INFO,
> +  "%a: System RAM @ 0x%lx - 0x%lx\n",
> +  __FUNCTION__,
> +  CurBase,
> +  CurBase + CurSize - 1
> +  ));
> +
> +if (CurBase == MemBase) {
> +FirMe

[edk2-devel] [PATCH 1/2] CloudHv/arm: add PeiMemInfoLib

2022-07-29 Thread Jianyong Wu
Memory layout in CLoud Hypervisor for arm is changed and is different
with Qemu, thus we should build its own PeiMemInfoLib.
The main change in the memory layout is that normal ram may not contiguous
under 4G. The top 64M under 4G is reserved for 32bit device.

What this patch does:
1. get all of the memory node from DT;
2. Init page table for each memory node;
3. Add all of the memory nodes to Hob;

Signed-off-by: Jianyong Wu 
---
 .../CloudHvVirtMemInfoLib.c   | 251 ++
 .../CloudHvVirtMemInfoPeiLib.inf  |  46 
 2 files changed, 297 insertions(+)
 create mode 100755 
ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c
 create mode 100755 
ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoPeiLib.inf

diff --git a/ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c 
b/ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c
new file mode 100755
index 00..7ae24641d3
--- /dev/null
+++ b/ArmVirtPkg/Library/CloudHvVirtMemInfoLib/CloudHvVirtMemInfoLib.c
@@ -0,0 +1,251 @@
+/** @file
+
+  Copyright (c) 2022, Arm Limited. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include
+
+// The first memnory node is the one whose base address is the lowest.
+UINT64 FirMemNodeBase = 0, FirMemNodeSize = 0;
+//
+// Cloud Hypervisor may have more than one memory nodes. Even there is no 
limit for that,
+// I think 10 is enough in general.
+//
+#define CLOUDHV_MAX_MEM_NODE_NUM 10
+
+// Record memory node info (base address and size)
+struct CloudHvMemNodeInfo {
+  UINT64 Base;
+  UINT64 Size;
+};
+
+struct CloudHvMemNodeInfo CloudHvMemNode[CLOUDHV_MAX_MEM_NODE_NUM];
+
+RETURN_STATUS
+EFIAPI
+CloudHvVirtMemInfoPeiLibConstructor (
+  VOID
+  )
+{
+  VOID   *DeviceTreeBase;
+  EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttributes;
+  INT32  Node, Prev;
+  UINT64 CurBase, MemBase;
+  UINT64 CurSize;
+  CONST CHAR8*Type;
+  INT32  Len;
+  CONST UINT64   *RegProp;
+  RETURN_STATUS  PcdStatus;
+  UINT8  Index;
+
+  ZeroMem (CloudHvMemNode, sizeof(CloudHvMemNode[0]) * 
CLOUDHV_MAX_MEM_NODE_NUM);
+
+  Index = 0;
+  MemBase = FixedPcdGet64 (PcdSystemMemoryBase);
+  ResourceAttributes = (
+EFI_RESOURCE_ATTRIBUTE_PRESENT |
+EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+EFI_RESOURCE_ATTRIBUTE_TESTED
+);
+  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);
+  ASSERT (DeviceTreeBase != NULL);
+
+  //
+  // Make sure we have a valid device tree blob
+  //
+  ASSERT (fdt_check_header (DeviceTreeBase) == 0);
+
+  //
+  // Look for the lowest memory node
+  //
+  for (Prev = 0; ; Prev = Node) {
+Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
+if (Node < 0) {
+  break;
+}
+
+//
+// Check for memory node
+//
+Type = fdt_getprop (DeviceTreeBase, Node, "device_type", );
+if (Type && (AsciiStrnCmp (Type, "memory", Len) == 0)) {
+  //
+  // Get the 'reg' property of this node. For now, we will assume
+  // two 8 byte quantities for base and size, respectively.
+  //
+  RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", );
+  if ((RegProp != 0) && (Len == (2 * sizeof (UINT64 {
+CurBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
+CurSize = fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
+
+DEBUG ((
+  DEBUG_INFO,
+  "%a: System RAM @ 0x%lx - 0x%lx\n",
+  __FUNCTION__,
+  CurBase,
+  CurBase + CurSize - 1
+  ));
+
+if (CurBase == MemBase) {
+FirMemNodeBase = CurBase;
+FirMemNodeSize = CurSize;
+}
+
+CloudHvMemNode[Index].Base = CurBase;
+CloudHvMemNode[Index].Size = CurSize;
+Index++;
+// We should build Hob seperately for the memory node except the first 
one
+if (CurBase != MemBase) {
+  BuildResourceDescriptorHob (
+EFI_RESOURCE_SYSTEM_MEMORY,
+ResourceAttributes,
+CurBase,
+CurSize
+);
+}
+if (Index >= CLOUDHV_MAX_MEM_NODE_NUM) {
+  DEBUG ((
+DEBUG_WARN,
+"%a: memory node larger than %d will not be included into Memory 
System\n",
+__FUNCTION__,
+CLOUDHV_MAX_MEM_NODE_NUM
+));
+  break;
+}
+  } else {
+DEBUG ((
+  DEBUG_ERROR,
+  "%a: Failed to parse FDT memory node\n",
+  __FUNCTION__
+  ));
+  }
+}
+  }
+
+  //
+  // Make sure the start of DRAM matches our expectation
+  //
+  ASSERT (FixedPcdGet64 (PcdSystemMemoryBase) == FirMemNodeBase);
+  PcdStatus = PcdSet64S