From: Xiong Yining <xiongyining1...@phytium.com.cn>

Add the DeviceTree fallbacks to parsing the information about memory
if the related SMC calls Failed.

Signed-off-by: Xiong Yining <xiongyining1...@phytium.com.cn>
Signed-off-by: Chen Baozi <chenba...@phytium.com.cn>
---
 .../SbsaQemuHardwareInfoLib.c                       | 106 +++++++++++++++++++-
 1 file changed, 104 insertions(+), 2 deletions(-)

diff --git 
a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuHardwareInfoLib/SbsaQemuHardwareInfoLib.c
 
b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuHardwareInfoLib/SbsaQemuHardwareInfoLib.c
index 88b50e46c072..d63cfbf7d5ef 100644
--- 
a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuHardwareInfoLib/SbsaQemuHardwareInfoLib.c
+++ 
b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuHardwareInfoLib/SbsaQemuHardwareInfoLib.c
@@ -118,6 +118,106 @@ FdtHelperCountCpus (
   return CpuCount;
 }
 
+/**
+  Walks through the Device Tree created by Qemu and counts the number of 
Memory node present in it.
+
+  @retval                   the number of memory nodes.
+**/
+UINT32
+FdtHelperMemNodeCount (
+  VOID
+  )
+{
+  VOID          *DeviceTreeBase;
+  CONST CHAR8   *Type;
+  UINT32        MemNodeCount;
+  INT32         Node;
+  INT32         Prev;
+  INT32         Len;
+
+  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress);
+  ASSERT (DeviceTreeBase != NULL);
+
+  // Make sure we have a valid device tree blob
+  ASSERT (fdt_check_header (DeviceTreeBase) == 0);
+
+  MemNodeCount = 0;
+  for (Prev = 0;; Prev = Node) {
+    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
+    if (Node < 0){
+      break;
+    }
+
+    Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
+    if (Type && AsciiStrnCmp (Type, "memory", Len) == 0) {
+      MemNodeCount++;
+    }
+  }
+
+  return MemNodeCount;
+}
+
+/** Walks through the Device Tree created by Qemu and counts the adress、size 
and node-id of the Memory node present in it.
+
+  @param [in]   MemoryId    Index of memory to retrieve memory information.
+
+  @retval                   memory infomation for given memory node.
+**/
+MemoryInfo
+FdtHelperGetMemInfo (
+  IN UINTN   MemoryId
+)
+{
+  VOID          *DeviceTreeBase;
+  CONST UINT64  *RegProp;
+  CONST UINT32  *NodeProp;
+  CONST CHAR8   *Type;
+  INT64         MemNodeCount;
+  INT32         Len;
+  INT32         Node;
+  INT32         Prev;
+  MemoryInfo    MemInfo = {0};
+
+  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress);
+  ASSERT (DeviceTreeBase != NULL);
+
+  // Make sure we have a valid device tree blob
+  ASSERT (fdt_check_header (DeviceTreeBase) == 0);
+
+  MemNodeCount = 0;
+
+  for (Prev = 0;; Prev = Node){
+    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
+    if (Node < 0){
+      break;
+    }
+
+    Type = fdt_getprop (DeviceTreeBase, Node, "device_type", &Len);
+    if (Type && AsciiStrnCmp (Type, "memory", Len) == 0){
+      if (MemoryId == MemNodeCount){
+        RegProp = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
+        if (RegProp != 0 && Len == (2 * sizeof (UINT64))) {
+            MemInfo.AddressBase = fdt64_to_cpu (ReadUnaligned64 (RegProp));
+            MemInfo.AddressSize= fdt64_to_cpu (ReadUnaligned64 (RegProp + 1));
+        } else {
+          DEBUG ((DEBUG_ERROR, "Failed to find the address and size of the 
memory"));
+        }
+
+        NodeProp= fdt_getprop (DeviceTreeBase, Node, "numa-node-id", &Len);
+        if (NodeProp){
+          MemInfo.NodeId= fdt32_to_cpu (ReadUnaligned32 (NodeProp));
+        } else {
+          DEBUG ((DEBUG_ERROR, "Failed to find the node-id of the memory"));
+        }
+      }
+
+      MemNodeCount ++;
+    }
+  }
+
+  return MemInfo;
+}
+
 /**
   Get CPU count from information passed by Qemu.
 
@@ -212,7 +312,8 @@ SbsaQemuGetMemNodeCount (
 
   SmcResult = ArmCallSmc0 (SIP_SVC_GET_MEMORY_NODE_COUNT, &Arg0, NULL, NULL);
   if (SmcResult != SMC_SIP_CALL_SUCCESS) {
-    DEBUG ((DEBUG_ERROR, "SIP_SVC_GET_MEMORY_NODE_COUNT call failed.\n"));
+    DEBUG ((DEBUG_ERROR, "SIP_SVC_GET_MEMORY_NODE_COUNT call failed. We have 
to get the number of memory nodes from DT.\n"));
+    Arg0 = FdtHelperMemNodeCount();
   }
 
   DEBUG(( DEBUG_INFO, "The number of the memory nodes is %ld\n", Arg0));
@@ -234,7 +335,8 @@ SbsaQemuGetMemInfo (
 
   SmcResult = ArmCallSmc1 (SIP_SVC_GET_MEMORY_NODE, &Arg0, &Arg1, &Arg2);
   if (SmcResult != SMC_SIP_CALL_SUCCESS) {
-    DEBUG ((DEBUG_ERROR, "SIP_SVC_GET_MEMORY_NODE call failed.\n"));
+    DEBUG ((DEBUG_ERROR, "SIP_SVC_GET_MEMORY_NODE call failed. We have to get 
memory info from DT.\n"));
+    MemInfo = FdtHelperGetMemInfo(MemoryId);
   } else {
     MemInfo.NodeId = Arg0;
     MemInfo.AddressBase = Arg1;

-- 
2.44.0



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


Reply via email to