We submit a patch in TF-A which is armed at reporting the information of through SMC. Cooperating with that patch, we can get thecinformation of memory in EDK2 via SMC calls.
Changes in v2: - Align with the latest version. - modify language and formatting errors.
Changes in v3: - read the information of memory in SbsaQemuSmc.c.
Xiong Yining (1): SbsaQemu: get the information of memory form TF-A
.../SbsaQemuPlatformVersion.h | 1 + .../Include/IndustryStandard/SbsaQemuSmc.h | 2 + .../SbsaQemu/Include/Library/QemuSbsaSmc.h | 28 ++++++++++ .../Library/SbsaQemuLib/SbsaQemuLib.inf | 2 +- .../Library/SbsaQemuLib/SbsaQemuMem.c | 52 +++++-------------- .../Library/SbsaQemuSmc/SbsaQemuSmc.c | 45 ++++++++++++++++ 6 files changed, 89 insertions(+), 41 deletions(-)
we can get the information of memory via SMC calls during platform initialization.
Handled are: - get the number of memory node - get the memory infomation(base, size and NUMA node id) of given memory node
Signed-off-by: Xiong Yining xiongyining1480@phytium.com.cn Signed-off-by: Chen Baozi chenbaozi@phytium.com.cn --- .../SbsaQemuPlatformVersion.h | 1 + .../Include/IndustryStandard/SbsaQemuSmc.h | 2 + .../SbsaQemu/Include/Library/QemuSbsaSmc.h | 28 ++++++++++ .../Library/SbsaQemuLib/SbsaQemuLib.inf | 2 +- .../Library/SbsaQemuLib/SbsaQemuMem.c | 52 +++++-------------- .../Library/SbsaQemuSmc/SbsaQemuSmc.c | 45 ++++++++++++++++ 6 files changed, 89 insertions(+), 41 deletions(-)
diff --git a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuPlatformVersion.h b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuPlatformVersion.h index d342f8f363..de3b153caf 100644 --- a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuPlatformVersion.h +++ b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuPlatformVersion.h @@ -22,4 +22,5 @@ ) \ ) \ ) + #endif diff --git a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h index e33648ee14..31dd699b0b 100644 --- a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h +++ b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h @@ -16,5 +16,7 @@ #define SIP_SVC_GET_GIC_ITS SMC_SIP_FUNCTION_ID(101) #define SIP_SVC_GET_CPU_COUNT SMC_SIP_FUNCTION_ID(200) #define SIP_SVC_GET_CPU_NODE SMC_SIP_FUNCTION_ID(201) +#define SIP_SVC_GET_MEMORYNODE_COUNT SMC_SIP_FUNCTION_ID(300) +#define SIP_SVC_GET_MEMORY SMC_SIP_FUNCTION_ID(301)
#endif /* SBSA_QEMU_SMC_H_ */ diff --git a/Silicon/Qemu/SbsaQemu/Include/Library/QemuSbsaSmc.h b/Silicon/Qemu/SbsaQemu/Include/Library/QemuSbsaSmc.h index e87e966d39..4d9b8b95e7 100644 --- a/Silicon/Qemu/SbsaQemu/Include/Library/QemuSbsaSmc.h +++ b/Silicon/Qemu/SbsaQemu/Include/Library/QemuSbsaSmc.h @@ -33,4 +33,32 @@ SbsaQemuGetCpuNumaNode ( IN UINTN CpuId );
+/** + Get the number of memory node from device tree passed by Qemu. + + @retval the number of memory node +**/ +UINT64 +SbsaQemuGetMemNode ( + VOID + ); + +typedef struct{ + UINT32 NodeId; + UINT64 AddressBase; + UINT64 AddressSize; +} MemoryInfo; + +/** + Get memory infomation(node-id, addressbase, addresssize) for a given memory node from device tree passed by Qemu. + + @param [in] MemNode Index of memory to retrieve memory information. + + @retval memory infomation for given memory node. +**/ +MemoryInfo +SbsaQemuGetMemInfo ( + IN UINTN MemNode + ); + #endif /* QEMU_SBSA_SMC_ */ diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf index c067a80cc7..3a4fff7bc7 100644 --- a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf +++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf @@ -32,9 +32,9 @@ ArmLib BaseMemoryLib DebugLib - FdtLib MemoryAllocationLib PcdLib + SbsaQemuSmc
[Pcd] gArmTokenSpaceGuid.PcdSystemMemoryBase diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c index 8c2eb0b6a0..fe2df2d60f 100644 --- a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c +++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c @@ -12,7 +12,7 @@ #include <Library/DebugLib.h> #include <Library/MemoryAllocationLib.h> #include <Library/PcdLib.h> -#include <libfdt.h> +#include <Library/QemuSbsaSmc.h>
// Number of Virtual Memory Map Descriptors #define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 4 @@ -23,53 +23,25 @@ SbsaQemuLibConstructor ( VOID ) { - VOID *DeviceTreeBase; - INT32 Node, Prev; UINT64 NewBase, CurBase; UINT64 NewSize, CurSize; - CONST CHAR8 *Type; - INT32 Len; - CONST UINT64 *RegProp; + UINT64 NumMemNode; + UINT64 Index; + MemoryInfo MemInfo; RETURN_STATUS PcdStatus;
NewBase = 0; NewSize = 0;
- DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); - ASSERT (DeviceTreeBase != NULL); + NumMemNode = SbsaQemuGetMemNode(); + for(Index = 0; Index < NumMemNode; Index++){ + MemInfo = SbsaQemuGetMemInfo(Index); + CurBase = MemInfo.AddressBase; + CurSize = MemInfo.AddressSize;
- // 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", &Len); - 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", &Len); - 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 (NewBase > CurBase || NewBase == 0) { - NewBase = CurBase; - NewSize = CurSize; - } - } else { - DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT memory node\n", - __FUNCTION__)); - } + if (NewBase > CurBase || NewBase == 0) { + NewBase = CurBase; + NewSize = CurSize; } }
diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c index 41df610f52..f7c5308a63 100644 --- a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c +++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c @@ -8,6 +8,7 @@
#include <Library/ArmSmcLib.h> #include <Library/DebugLib.h> +#include <Library/QemuSbsaSmc.h> #include <IndustryStandard/SbsaQemuSmc.h>
UINT64 @@ -53,3 +54,47 @@ SbsaQemuGetCpuNumaNode (
return Arg0; } + +UINT64 +SbsaQemuGetMemNode ( + VOID + ) +{ + UINTN SmcResult; + UINTN Arg0; + + SmcResult = ArmCallSmc0 (SIP_SVC_GET_MEMORYNODE_COUNT, &Arg0, NULL, NULL); + if (SmcResult != SMC_ARCH_CALL_SUCCESS) { + DEBUG ((DEBUG_ERROR, "Couldn't find information for memory\n")); + return 0; + } + + return Arg0; +} + +MemoryInfo +SbsaQemuGetMemInfo ( + IN UINTN MemNode + ) +{ + UINTN SmcResult; + UINTN Arg0; + UINTN Arg1; + UINTN Arg2; + MemoryInfo MemInfo; + + Arg0 = MemNode; + + SmcResult = ArmCallSmc1 (SIP_SVC_GET_MEMORY, &Arg0, &Arg1, &Arg2); + if (SmcResult == SMC_ARCH_CALL_SUCCESS) { + MemInfo.NodeId = Arg0; + MemInfo.AddressBase = Arg1; + MemInfo.AddressSize = Arg2; + DEBUG(( DEBUG_INFO, "System RAM@%d: 0x%lx - 0x%lx\n", + MemInfo.NodeId, + MemInfo.AddressBase, + MemInfo.AddressBase + MemInfo.AddressSize -1 )); + } + + return MemInfo; +} \ No newline at end of file
W dniu 13.12.2023 o 10:19, Xiong Yining pisze:
we can get the information of memory via SMC calls during platform initialization.
Handled are:
- get the number of memory node
- get the memory infomation(base, size and NUMA node id) of given memory node
Signed-off-by: Xiong Yining xiongyining1480@phytium.com.cn Signed-off-by: Chen Baozi chenbaozi@phytium.com.cn
.../SbsaQemuPlatformVersion.h | 1 + .../Include/IndustryStandard/SbsaQemuSmc.h | 2 + .../SbsaQemu/Include/Library/QemuSbsaSmc.h | 28 ++++++++++ .../Library/SbsaQemuLib/SbsaQemuLib.inf | 2 +- .../Library/SbsaQemuLib/SbsaQemuMem.c | 52 +++++-------------- .../Library/SbsaQemuSmc/SbsaQemuSmc.c | 45 ++++++++++++++++ 6 files changed, 89 insertions(+), 41 deletions(-)
diff --git a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuPlatformVersion.h b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuPlatformVersion.h index d342f8f363..de3b153caf 100644 --- a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuPlatformVersion.h +++ b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuPlatformVersion.h @@ -22,4 +22,5 @@ ) \ ) \ )
- #endif
drop
diff --git a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h index e33648ee14..31dd699b0b 100644 --- a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h +++ b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h @@ -16,5 +16,7 @@ #define SIP_SVC_GET_GIC_ITS SMC_SIP_FUNCTION_ID(101) #define SIP_SVC_GET_CPU_COUNT SMC_SIP_FUNCTION_ID(200) #define SIP_SVC_GET_CPU_NODE SMC_SIP_FUNCTION_ID(201) +#define SIP_SVC_GET_MEMORYNODE_COUNT SMC_SIP_FUNCTION_ID(300) +#define SIP_SVC_GET_MEMORY SMC_SIP_FUNCTION_ID(301) #endif /* SBSA_QEMU_SMC_H_ */ diff --git a/Silicon/Qemu/SbsaQemu/Include/Library/QemuSbsaSmc.h b/Silicon/Qemu/SbsaQemu/Include/Library/QemuSbsaSmc.h index e87e966d39..4d9b8b95e7 100644 --- a/Silicon/Qemu/SbsaQemu/Include/Library/QemuSbsaSmc.h +++ b/Silicon/Qemu/SbsaQemu/Include/Library/QemuSbsaSmc.h @@ -33,4 +33,32 @@ SbsaQemuGetCpuNumaNode ( IN UINTN CpuId ); +/**
- Get the number of memory node from device tree passed by Qemu.
- @retval the number of memory node
+**/ +UINT64 +SbsaQemuGetMemNode (
SbsaQemuGetMemNodeCount() so it will be more readable.
- VOID
- );
+typedef struct{
- UINT32 NodeId;
- UINT64 AddressBase;
- UINT64 AddressSize;
+} MemoryInfo;
+/**
- Get memory infomation(node-id, addressbase, addresssize) for a given memory node from device tree passed by Qemu.
- @param [in] MemNode Index of memory to retrieve memory information.
- @retval memory infomation for given memory node.
+**/ +MemoryInfo +SbsaQemuGetMemInfo (
- IN UINTN MemNode
- );
- #endif /* QEMU_SBSA_SMC_ */
diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf index c067a80cc7..3a4fff7bc7 100644 --- a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf +++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuLib.inf @@ -32,9 +32,9 @@ ArmLib BaseMemoryLib DebugLib
- FdtLib MemoryAllocationLib PcdLib
- SbsaQemuSmc
[Pcd] gArmTokenSpaceGuid.PcdSystemMemoryBase diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c index 8c2eb0b6a0..fe2df2d60f 100644 --- a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c +++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuLib/SbsaQemuMem.c @@ -12,7 +12,7 @@ #include <Library/DebugLib.h> #include <Library/MemoryAllocationLib.h> #include <Library/PcdLib.h> -#include <libfdt.h> +#include <Library/QemuSbsaSmc.h> // Number of Virtual Memory Map Descriptors #define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 4 @@ -23,53 +23,25 @@ SbsaQemuLibConstructor ( VOID ) {
- VOID *DeviceTreeBase;
- INT32 Node, Prev; UINT64 NewBase, CurBase; UINT64 NewSize, CurSize;
- CONST CHAR8 *Type;
- INT32 Len;
- CONST UINT64 *RegProp;
- UINT64 NumMemNode;
NumMemNodeCount and UINT32 is enough - there are 128 nodes max.
- UINT64 Index;
- MemoryInfo MemInfo; RETURN_STATUS PcdStatus;
NewBase = 0; NewSize = 0;
- DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress);
- ASSERT (DeviceTreeBase != NULL);
- NumMemNode = SbsaQemuGetMemNode();
- for(Index = 0; Index < NumMemNode; Index++){
- MemInfo = SbsaQemuGetMemInfo(Index);
- CurBase = MemInfo.AddressBase;
- CurSize = MemInfo.AddressSize;
- // 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", &Len);
- 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", &Len);
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 (NewBase > CurBase || NewBase == 0) {
NewBase = CurBase;
NewSize = CurSize;
}
} else {
DEBUG ((DEBUG_ERROR, "%a: Failed to parse FDT memory node\n",
__FUNCTION__));
}
- if (NewBase > CurBase || NewBase == 0) {
NewBase = CurBase;
}NewSize = CurSize; }
diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c index 41df610f52..f7c5308a63 100644 --- a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c +++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c @@ -8,6 +8,7 @@ #include <Library/ArmSmcLib.h> #include <Library/DebugLib.h> +#include <Library/QemuSbsaSmc.h> #include <IndustryStandard/SbsaQemuSmc.h> UINT64 @@ -53,3 +54,47 @@ SbsaQemuGetCpuNumaNode ( return Arg0; }
+UINT64 +SbsaQemuGetMemNode (
- VOID
- )
+{
- UINTN SmcResult;
- UINTN Arg0;
- SmcResult = ArmCallSmc0 (SIP_SVC_GET_MEMORYNODE_COUNT, &Arg0, NULL, NULL);
- if (SmcResult != SMC_ARCH_CALL_SUCCESS) {
- DEBUG ((DEBUG_ERROR, "Couldn't find information for memory\n"));
Here should be DT fallback. In case of older TF-A.
- return 0;
- }
- return Arg0;
+}
+MemoryInfo +SbsaQemuGetMemInfo (
- IN UINTN MemNode
- )
+{
- UINTN SmcResult;
- UINTN Arg0;
- UINTN Arg1;
- UINTN Arg2;
- MemoryInfo MemInfo;
- Arg0 = MemNode;
- SmcResult = ArmCallSmc1 (SIP_SVC_GET_MEMORY, &Arg0, &Arg1, &Arg2);
- if (SmcResult == SMC_ARCH_CALL_SUCCESS) {
- MemInfo.NodeId = Arg0;
- MemInfo.AddressBase = Arg1;
- MemInfo.AddressSize = Arg2;
- DEBUG(( DEBUG_INFO, "System RAM@%d: 0x%lx - 0x%lx\n",
MemInfo.NodeId,
MemInfo.AddressBase,
MemInfo.AddressBase + MemInfo.AddressSize -1 ));
- }
else { // DT fallback }
- return MemInfo;
+} \ No newline at end of file