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] -=-=-=-=-=-=-=-=-=-=-=-