As a part of removing DeviceTree from EDK2 I wrote code for CPU information.
TF-A reads data for upto 512 cpus and keep it in local memory.
Two SMC calls are provided for EDK2:
- GET_CPU_COUNT reports amount of cpus - GET_CPU_NODE returns MPIDR and NUMA node id values for selected cpu
I took some ideas from Xiong Yining's memory patches.
For EDK2 I removed FdtHelperLib as we no longer need it. Dropped FdtLib from all places where it is no longer needed - the only place is getting memory nodes but that is handled by Xiong Yining's patches.
There is SbsaQemuSmc helper library with functions to get MPIDR and NUMA node id for selected cpu.
Amount of cpus is read in SbsaQemuPlatformDxe and stored in PcdCoreCount variable. It is the first place where this data is used so I replaced all FdtHelperLib calls with PcdGet32 calls.
Generation of SRAT table needs to be rewritten.
Marcin Juszkiewicz (2): feat(qemu_sbsa): handle CPU information SbsaQemu: get cpu information from TF-A
We want to remove use of DeviceTree from EDK2. So we move functions to TF-A:
- counting cpu cores - checking NUMA node id - checking MPIDR
And then it gets passed to EDK2 via SMC calls.
Change-Id: I1c7fc234ba90ba32433b6e4aa2cf127f26da00fd Signed-off-by: Marcin Juszkiewicz marcin.juszkiewicz@linaro.org --- plat/qemu/qemu_sbsa/sbsa_sip_svc.c | 93 ++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+)
diff --git a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c index 05ebec472..cbbf7151c 100644 --- a/plat/qemu/qemu_sbsa/sbsa_sip_svc.c +++ b/plat/qemu/qemu_sbsa/sbsa_sip_svc.c @@ -28,13 +28,95 @@ static int platform_version_minor; #define SIP_SVC_VERSION SIP_FUNCTION_ID(1) #define SIP_SVC_GET_GIC SIP_FUNCTION_ID(100) #define SIP_SVC_GET_GIC_ITS SIP_FUNCTION_ID(101) +#define SIP_SVC_GET_CPU_COUNT SIP_FUNCTION_ID(200) +#define SIP_SVC_GET_CPU_NODE SIP_FUNCTION_ID(201) + +#define MAX_CPUS 512 /* QEMU supports upto 512 cpus for sbsa-ref */
static uint64_t gic_its_addr;
+typedef struct { + uint32_t nodeid; + uint32_t mpidr; +} cpu_node; + +typedef struct { + uint32_t num_cpunodes; + cpu_node cpunode[MAX_CPUS]; +} cpu_info; + +static cpu_info sbsa_cpu_info; + void sbsa_set_gic_bases(const uintptr_t gicd_base, const uintptr_t gicr_base); uintptr_t sbsa_get_gicd(void); uintptr_t sbsa_get_gicr(void);
+void read_cpuinfo_from_dt(void *dtb) +{ + int node; + int prev; + int cpunode = 0; + uint32_t nodeid = 0; + uintptr_t mpidr; + + /* + * QEMU gives us this DeviceTree node: + * numa-node-id entries are only when NUMA config is used + * + * cpus { + * #size-cells = <0x00>; + * #address-cells = <0x02>; + * + * cpu@0 { + * numa-node-id = <0x00>; + * reg = <0x00 0x00>; + * }; + * + * cpu@1 { + * numa-node-id = <0x03>; + * reg = <0x00 0x01>; + * }; + * }; + */ + node = fdt_path_offset(dtb, "/cpus"); + if (node < 0) { + /* Fake one cpu entry */ + sbsa_cpu_info.num_cpunodes = 1; + sbsa_cpu_info.cpunode[0].nodeid = 0; + sbsa_cpu_info.cpunode[0].mpidr = 0; + INFO("No /cpus nodes. Created node for 1 cpu.\n"); + return; + } + + node = fdt_first_subnode(dtb, node); + + while (1) { + if (fdt_getprop(dtb, node, "reg", NULL)) { + fdt_get_reg_props_by_index(dtb, node, 0, &mpidr, NULL); + } + + if (fdt_getprop(dtb, node, "numa-node-id", NULL)) { + fdt_read_uint32(dtb, node, "numa-node-id", &nodeid); + } + + sbsa_cpu_info.cpunode[cpunode].nodeid = nodeid; + sbsa_cpu_info.cpunode[cpunode].mpidr = mpidr; + + INFO("CPU %d: node-id: %d, mpidr: %ld\n", cpunode, nodeid, mpidr); + + cpunode++; + + prev = node; + node = fdt_next_subnode(dtb, prev); + if (node < 0) { + break; + } + } + + sbsa_cpu_info.num_cpunodes = cpunode; + INFO("Found %d cpus\n", sbsa_cpu_info.num_cpunodes); +} + void read_platform_config_from_dt(void *dtb) { int node; @@ -129,6 +211,7 @@ void sip_svc_init(void) INFO("Platform version: %d.%d\n", platform_version_major, platform_version_minor);
read_platform_config_from_dt(dtb); + read_cpuinfo_from_dt(dtb); }
/* @@ -144,6 +227,7 @@ uintptr_t sbsa_sip_smc_handler(uint32_t smc_fid, u_register_t flags) { uint32_t ns; + uint64_t index;
/* Determine which security state this SMC originated from */ ns = is_caller_non_secure(flags); @@ -163,6 +247,15 @@ uintptr_t sbsa_sip_smc_handler(uint32_t smc_fid, case SIP_SVC_GET_GIC_ITS: SMC_RET2(handle, NULL, gic_its_addr);
+ case SIP_SVC_GET_CPU_COUNT: + SMC_RET2(handle, NULL, sbsa_cpu_info.num_cpunodes); + + case SIP_SVC_GET_CPU_NODE: + index = x1; + SMC_RET3(handle, NULL, + sbsa_cpu_info.cpunode[index].nodeid, + sbsa_cpu_info.cpunode[index].mpidr); + default: ERROR("%s: unhandled SMC (0x%x) (function id: %d)\n", __func__, smc_fid, smc_fid - SIP_FUNCTION);
As part of removing DeviceTree use we moved cpu related parts to TF-A. On EDK2 side we get values via SMC calls during platform initialization.
Handled are: - get cpu cores count - get MPIDR - get NUMA node id
Signed-off-by: Marcin Juszkiewicz marcin.juszkiewicz@linaro.org --- Platform/Qemu/SbsaQemu/SbsaQemu.dsc | 4 +- .../Qemu/SbsaQemu/OemMiscLib/OemMiscLib.inf | 6 +- .../SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf | 4 +- .../SbsaQemuPlatformDxe.inf | 3 +- .../Library/FdtHelperLib/FdtHelperLib.inf | 33 ------- .../Library/SbsaQemuSmc/SbsaQemuSmc.inf | 28 ++++++ .../Include/IndustryStandard/SbsaQemuSmc.h | 2 + .../SbsaQemu/Include/Library/FdtHelperLib.h | 36 ------- .../SbsaQemu/Include/Library/QemuSbsaSmc.h | 36 +++++++ .../Qemu/SbsaQemu/OemMiscLib/OemMiscLib.c | 10 +- .../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c | 16 +-- .../SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c | 16 ++- .../Library/FdtHelperLib/FdtHelperLib.c | 98 ------------------- .../Library/SbsaQemuSmc/SbsaQemuSmc.c | 55 +++++++++++ 14 files changed, 150 insertions(+), 197 deletions(-) delete mode 100644 Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.inf create mode 100644 Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.inf delete mode 100644 Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h create mode 100644 Silicon/Qemu/SbsaQemu/Include/Library/QemuSbsaSmc.h delete mode 100644 Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c create mode 100644 Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c
diff --git a/Platform/Qemu/SbsaQemu/SbsaQemu.dsc b/Platform/Qemu/SbsaQemu/SbsaQemu.dsc index 378600050df9..231db11cb07b 100644 --- a/Platform/Qemu/SbsaQemu/SbsaQemu.dsc +++ b/Platform/Qemu/SbsaQemu/SbsaQemu.dsc @@ -1,6 +1,6 @@ # # Copyright (c) 2021, NUVIA Inc. All rights reserved. -# Copyright (c) 2019, Linaro Limited. All rights reserved. +# Copyright (c) 2023, Linaro Ltd. All rights reserved. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -126,7 +126,7 @@ [LibraryClasses.common] # ARM PL011 UART Driver PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
- FdtHelperLib|Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.inf + SbsaQemuSmc|Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.inf OemMiscLib|Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.inf
# Debug Support diff --git a/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.inf b/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.inf index a34f54d431d4..8e2bf8c512f1 100644 --- a/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.inf +++ b/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.inf @@ -3,7 +3,7 @@ # # Copyright (c) 2021, NUVIA Inc. All rights reserved. # Copyright (c) 2018, Hisilicon Limited. All rights reserved. -# Copyright (c) 2018, Linaro Limited. All rights reserved. +# Copyright (c) 2023, Linaro Ltd. All rights reserved. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -29,8 +29,6 @@ [Packages]
[LibraryClasses] BaseMemoryLib - FdtLib - FdtHelperLib IoLib PcdLib
@@ -40,7 +38,6 @@ [Guids] [Pcd] gArmTokenSpaceGuid.PcdEmbeddedControllerFirmwareRelease gArmTokenSpaceGuid.PcdSystemBiosRelease - gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdDeviceTreeBaseAddress
gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdSystemManufacturer gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdSystemSerialNumber @@ -56,3 +53,4 @@ [Pcd] gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdChassisManufacturer gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdChassisAssetTag gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdChassisSKU + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdCoreCount diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf index 291743b19115..d23b53586cd3 100644 --- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf @@ -1,7 +1,7 @@ ## @file # This driver modifies ACPI tables for the Qemu SBSA platform # -# Copyright (c) 2020, Linaro Ltd. All rights reserved. +# Copyright (c) Linaro Ltd. All rights reserved. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -35,9 +35,9 @@ [LibraryClasses] BaseLib DebugLib DxeServicesLib - FdtHelperLib PcdLib PrintLib + SbsaQemuSmc UefiDriverEntryPoint UefiLib UefiRuntimeServicesTableLib diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.inf b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.inf index 19534b7a274a..726cb4fb3754 100644 --- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.inf +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.inf @@ -1,7 +1,7 @@ ## @file # This driver effectuates SbsaQemu platform configuration settings # -# Copyright (c) 2019, Linaro Ltd. All rights reserved. +# Copyright (c) Linaro Ltd. All rights reserved. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -46,6 +46,7 @@ [Pcd] gArmTokenSpaceGuid.PcdGicDistributorBase gArmTokenSpaceGuid.PcdGicRedistributorsBase gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdGicItsBase + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdCoreCount
[Depex] diff --git a/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.inf b/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.inf deleted file mode 100644 index 9c059f3e5851..000000000000 --- a/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.inf +++ /dev/null @@ -1,33 +0,0 @@ -#/** @file -# -# Component description file for FdtHelperLib module -# -# Copyright (c) 2021, NUVIA Inc. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#**/ - -[Defines] - INF_VERSION = 1.29 - BASE_NAME = FdtHelperLib - FILE_GUID = 34e4396f-c2fc-4f9e-ad58-0f98e99e3875 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = FdtHelperLib - -[Sources.common] - FdtHelperLib.c - -[Packages] - EmbeddedPkg/EmbeddedPkg.dec - MdePkg/MdePkg.dec - Silicon/Qemu/SbsaQemu/SbsaQemu.dec - -[LibraryClasses] - DebugLib - FdtLib - PcdLib - -[FixedPcd] - gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdDeviceTreeBaseAddress diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.inf b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.inf new file mode 100644 index 000000000000..3eae73650eeb --- /dev/null +++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.inf @@ -0,0 +1,28 @@ +#/* @file +# +# Copyright (c) Linaro Ltd. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#*/ + +[Defines] + INF_VERSION = 0x0001001c + BASE_NAME = SbsaQemuSmc + FILE_GUID = 6454006f-6502-46e2-9be4-4bba8d4b29fb + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmPlatformLib + +[Sources] + SbsaQemuSmc.c + +[Packages] + ArmPkg/ArmPkg.dec + MdePkg/MdePkg.dec + Silicon/Qemu/SbsaQemu/SbsaQemu.dec + +[LibraryClasses] + ArmSmcLib + BaseMemoryLib + DebugLib diff --git a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h index 7934875e4aba..e33648ee1462 100644 --- a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h +++ b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h @@ -14,5 +14,7 @@ #define SIP_SVC_VERSION SMC_SIP_FUNCTION_ID(1) #define SIP_SVC_GET_GIC SMC_SIP_FUNCTION_ID(100) #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)
#endif /* SBSA_QEMU_SMC_H_ */ diff --git a/Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h b/Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h deleted file mode 100644 index ea9159857215..000000000000 --- a/Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h +++ /dev/null @@ -1,36 +0,0 @@ -/** @file -* FdtHelperLib.h -* -* Copyright (c) 2021, NUVIA Inc. All rights reserved. -* -* SPDX-License-Identifier: BSD-2-Clause-Patent -* -**/ - -#ifndef FDT_HELPER_LIB_ -#define FDT_HELPER_LIB_ - -/** - Get MPIDR for a given cpu from device tree passed by Qemu. - - @param [in] CpuId Index of cpu to retrieve MPIDR value for. - - @retval MPIDR value of CPU at index <CpuId> -**/ -UINT64 -FdtHelperGetMpidr ( - IN UINTN CpuId - ); - -/** Walks through the Device Tree created by Qemu and counts the number - of CPUs present in it. - - @return The number of CPUs present. -**/ -EFIAPI -UINT32 -FdtHelperCountCpus ( - VOID - ); - -#endif /* FDT_HELPER_LIB_ */ diff --git a/Silicon/Qemu/SbsaQemu/Include/Library/QemuSbsaSmc.h b/Silicon/Qemu/SbsaQemu/Include/Library/QemuSbsaSmc.h new file mode 100644 index 000000000000..e87e966d394a --- /dev/null +++ b/Silicon/Qemu/SbsaQemu/Include/Library/QemuSbsaSmc.h @@ -0,0 +1,36 @@ +/** @file +* +* Copyright (c) Linaro Ltd. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#ifndef QEMU_SBSA_SMC_ +#define QEMU_SBSA_SMC_ + +/** + Get MPIDR for a given cpu from device tree passed by Qemu. + + @param [in] CpuId Index of cpu to retrieve MPIDR value for. + + @retval MPIDR value of CPU at index <CpuId> +**/ +UINT64 +SbsaQemuGetMpidr ( + IN UINTN CpuId + ); + +/** + Get NUMA node id for a given cpu from device tree passed by Qemu. + + @param [in] CpuId Index of cpu to retrieve NUMA node id for. + + @retval NUMA node id for CPU at index <CpuId> +**/ +UINT64 +SbsaQemuGetCpuNumaNode ( + IN UINTN CpuId + ); + +#endif /* QEMU_SBSA_SMC_ */ diff --git a/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.c b/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.c index c38f2851904f..f8d47767d79e 100644 --- a/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.c +++ b/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.c @@ -2,7 +2,7 @@ * OemMiscLib.c * * Copyright (c) 2021, NUVIA Inc. All rights reserved. -* Copyright (c) 2020, Linaro Ltd. All rights reserved. +* Copyright (c) 2023, Linaro Ltd. All rights reserved. * * SPDX-License-Identifier: BSD-2-Clause-Patent * @@ -12,14 +12,12 @@ #include <Guid/ZeroGuid.h> #include <Library/BaseMemoryLib.h> #include <Library/DebugLib.h> -#include <Library/FdtHelperLib.h> #include <Library/HiiLib.h> #include <Library/IoLib.h> #include <Library/OemMiscLib.h> #include <Library/PcdLib.h> #include <Library/SerialPortLib.h> #include <Library/TimerLib.h> -#include <libfdt.h>
/** Returns whether the specified processor is present or not.
@@ -33,7 +31,7 @@ OemIsProcessorPresent ( UINTN ProcessorIndex ) { - if (ProcessorIndex < FdtHelperCountCpus ()) { + if (ProcessorIndex < PcdGet32 (PcdCoreCount)) { return TRUE; }
@@ -76,7 +74,7 @@ OemGetProcessorInformation ( { UINT16 ProcessorCount;
- ProcessorCount = FdtHelperCountCpus (); + ProcessorCount = PcdGet32 (PcdCoreCount);
if (ProcessorIndex < ProcessorCount) { ProcessorStatus->Bits.CpuStatus = 1; // CPU enabled @@ -121,7 +119,7 @@ OemGetMaxProcessors ( VOID ) { - return FdtHelperCountCpus (); + return PcdGet32 (PcdCoreCount); }
/** Gets information about the cache at the specified cache level. diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c index 9fb17151d7b8..89c4b797d2d1 100644 --- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c @@ -1,7 +1,7 @@ /** @file * This file is an ACPI driver for the Qemu SBSA platform. * -* Copyright (c) 2020, Linaro Ltd. All rights reserved. +* Copyright (c) Linaro Ltd. All rights reserved. * * SPDX-License-Identifier: BSD-2-Clause-Patent * @@ -15,7 +15,7 @@ #include <Library/ArmLib.h> #include <Library/BaseMemoryLib.h> #include <Library/DebugLib.h> -#include <Library/FdtHelperLib.h> +#include <Library/QemuSbsaSmc.h> #include <Library/MemoryAllocationLib.h> #include <Library/PcdLib.h> #include <Library/PrintLib.h> @@ -255,7 +255,7 @@ AddMadtTable ( // Initialize GIC Redistributor Structure EFI_ACPI_6_0_GICR_STRUCTURE Gicr = SBSAQEMU_MADT_GICR_INIT();
- // Get CoreCount which was determined eariler after parsing device tree + // Get CoreCount which was determined earlier from TF-A NumCores = PcdGet32 (PcdCoreCount);
// Calculate the new table size based on the number of cores @@ -291,13 +291,13 @@ AddMadtTable ( New += sizeof (EFI_ACPI_6_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
// Add new GICC structures for the Cores - for (CoreIndex = 0; CoreIndex < PcdGet32 (PcdCoreCount); CoreIndex++) { + for (CoreIndex = 0; CoreIndex < NumCores; CoreIndex++) { EFI_ACPI_6_0_GIC_STRUCTURE *GiccPtr;
CopyMem (New, &Gicc, sizeof (EFI_ACPI_6_0_GIC_STRUCTURE)); GiccPtr = (EFI_ACPI_6_0_GIC_STRUCTURE *) New; GiccPtr->AcpiProcessorUid = CoreIndex; - GiccPtr->MPIDR = FdtHelperGetMpidr (CoreIndex); + GiccPtr->MPIDR = SbsaQemuGetMpidr (CoreIndex); New += sizeof (EFI_ACPI_6_0_GIC_STRUCTURE); }
@@ -758,12 +758,6 @@ InitializeSbsaQemuAcpiDxe ( { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; - UINT32 NumCores; - - // Parse the device tree and get the number of CPUs - NumCores = FdtHelperCountCpus (); - Status = PcdSet32S (PcdCoreCount, NumCores); - ASSERT_RETURN_ERROR (Status);
// Check if ACPI Table Protocol has been installed Status = gBS->LocateProtocol ( diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c index 4ebbe7c93a19..d9f5ab452fb5 100644 --- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c @@ -1,7 +1,7 @@ /** @file -* FDT client protocol driver for qemu,mach-virt-ahci DT node +* SbsaQemu Platform Initialization * -* Copyright (c) 2019, Linaro Ltd. All rights reserved. +* Copyright (c) Linaro Ltd. All rights reserved. * * SPDX-License-Identifier: BSD-2-Clause-Patent * @@ -17,8 +17,6 @@ #include <IndustryStandard/SbsaQemuSmc.h> #include <IndustryStandard/SbsaQemuPlatformVersion.h>
-#include <Protocol/FdtClient.h> - EFI_STATUS EFIAPI InitializeSbsaQemuPlatformDxe ( @@ -123,5 +121,15 @@ InitializeSbsaQemuPlatformDxe ( } }
+ SmcResult = ArmCallSmc0 (SIP_SVC_GET_CPU_COUNT, &Arg0, NULL, NULL); + if (SmcResult == SMC_ARCH_CALL_SUCCESS) { + Result = PcdSet32S (PcdCoreCount, Arg0); + ASSERT_RETURN_ERROR (Result); + } + + Arg0 = PcdGet32 (PcdCoreCount); + + DEBUG ((DEBUG_INFO, "We have %d cpus.\n", Arg0)); + return EFI_SUCCESS; } diff --git a/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c b/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c deleted file mode 100644 index 7fdfb055db76..000000000000 --- a/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c +++ /dev/null @@ -1,98 +0,0 @@ -/** @file -* FdtHelperLib.c -* -* Copyright (c) 2021, NUVIA Inc. All rights reserved. -* Copyright (c) 2020, Linaro Ltd. All rights reserved. -* -* SPDX-License-Identifier: BSD-2-Clause-Patent -* -**/ - -#include <Uefi.h> -#include <Library/DebugLib.h> -#include <Library/FdtHelperLib.h> -#include <Library/PcdLib.h> -#include <libfdt.h> - -STATIC INT32 mFdtFirstCpuOffset; -STATIC INT32 mFdtCpuNodeSize; - -/** - Get MPIDR for a given cpu from device tree passed by Qemu. - - @param [in] CpuId Index of cpu to retrieve MPIDR value for. - - @retval MPIDR value of CPU at index <CpuId> -**/ -UINT64 -FdtHelperGetMpidr ( - IN UINTN CpuId - ) -{ - VOID *DeviceTreeBase; - CONST UINT64 *RegVal; - INT32 Len; - - DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); - ASSERT (DeviceTreeBase != NULL); - - RegVal = fdt_getprop (DeviceTreeBase, - mFdtFirstCpuOffset + (CpuId * mFdtCpuNodeSize), - "reg", - &Len); - if (!RegVal) { - DEBUG ((DEBUG_ERROR, "Couldn't find reg property for CPU:%d\n", CpuId)); - return 0; - } - - return (fdt64_to_cpu (ReadUnaligned64 (RegVal))); -} - -/** Walks through the Device Tree created by Qemu and counts the number - of CPUs present in it. - - @return The number of CPUs present. -**/ -EFIAPI -UINT32 -FdtHelperCountCpus ( - VOID - ) -{ - VOID *DeviceTreeBase; - INT32 Node; - INT32 Prev; - INT32 CpuNode; - UINT32 CpuCount; - - DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); - ASSERT (DeviceTreeBase != NULL); - - // Make sure we have a valid device tree blob - ASSERT (fdt_check_header (DeviceTreeBase) == 0); - - CpuNode = fdt_path_offset (DeviceTreeBase, "/cpus"); - if (CpuNode <= 0) { - DEBUG ((DEBUG_ERROR, "Unable to locate /cpus in device tree\n")); - return 0; - } - - CpuCount = 0; - - // Walk through /cpus node and count the number of subnodes. - // The count of these subnodes corresponds to the number of - // CPUs created by Qemu. - Prev = fdt_first_subnode (DeviceTreeBase, CpuNode); - mFdtFirstCpuOffset = Prev; - while (1) { - CpuCount++; - Node = fdt_next_subnode (DeviceTreeBase, Prev); - if (Node < 0) { - break; - } - mFdtCpuNodeSize = Node - Prev; - Prev = Node; - } - - return CpuCount; -} diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c new file mode 100644 index 000000000000..31a39f9a4e84 --- /dev/null +++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c @@ -0,0 +1,55 @@ +/** @file +* +* Copyright (c) Linaro Ltd. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#include <Library/ArmSmcLib.h> +#include <Library/DebugLib.h> +#include <IndustryStandard/SbsaQemuSmc.h> + +UINT64 +SbsaQemuGetMpidr ( + IN UINTN CpuId + ) +{ + UINTN SmcResult; + UINTN Arg0; + UINTN Arg1; + + Arg0 = CpuId; + + SmcResult = ArmCallSmc0 (SIP_SVC_GET_CPU_NODE, &Arg0, &Arg1, NULL); + if (SmcResult != SMC_ARCH_CALL_SUCCESS) { + DEBUG ((DEBUG_ERROR, "Couldn't find information for CPU:%d\n", CpuId)); + return 0; + } + + DEBUG ((DEBUG_ERROR, "MPIDR for CPU:%d = %d\n", CpuId, Arg1)); + + return Arg1; +} + +UINT64 +SbsaQemuGetCpuNumaNode ( + IN UINTN CpuId + ) +{ + UINTN SmcResult; + UINTN Arg0; + UINTN Arg1; + + Arg0 = CpuId; + + SmcResult = ArmCallSmc0 (SIP_SVC_GET_CPU_NODE, &Arg0, &Arg1, NULL); + if (SmcResult != SMC_ARCH_CALL_SUCCESS) { + DEBUG ((DEBUG_ERROR, "Couldn't find information for CPU:%d\n", CpuId)); + return 0; + } + + DEBUG ((DEBUG_ERROR, "NUMA node for CPU:%d = %d\n", CpuId, Arg0)); + + return Arg0; +}
W dniu 8.12.2023 o 13:41, Marcin Juszkiewicz pisze:
delete mode 100644 Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.inf create mode 100644 Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.inf delete mode 100644 Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h create mode 100644 Silicon/Qemu/SbsaQemu/Include/Library/QemuSbsaSmc.h delete mode 100644 Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c create mode 100644 Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c
After some thoughts I realized that there is one thing to do here...
I dropped DT parsing but it does make EDK2 not seeing more than one cpu if used with older TF-A. So will have to add parsing DT back as a backup option.
This will go into SbsaQemuSmc.c in a way that when EDK2 wants to do SMC call but it is not present then DT fallback will be called. So this could allow us to drop DT code without going through whole repo.
As part of removing DeviceTree use we moved cpu related parts to TF-A. On EDK2 side we get values via SMC calls during platform initialization.
Handled are: - get cpu cores count - get MPIDR - get NUMA node id
If too old TF-A is used then cpu count and MPIDR are read directly from DeviceTree.
Signed-off-by: Marcin Juszkiewicz marcin.juszkiewicz@linaro.org --- Platform/Qemu/SbsaQemu/SbsaQemu.dsc | 4 +- .../Qemu/SbsaQemu/OemMiscLib/OemMiscLib.inf | 6 +- .../SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf | 4 +- .../SbsaQemuPlatformDxe.inf | 4 +- .../Library/FdtHelperLib/FdtHelperLib.inf | 33 --- .../Library/SbsaQemuSmc/SbsaQemuSmc.inf | 34 +++ .../Include/IndustryStandard/SbsaQemuSmc.h | 2 + .../SbsaQemu/Include/Library/FdtHelperLib.h | 36 ---- .../SbsaQemu/Include/Library/SbsaQemuSmc.h | 45 ++++ .../Qemu/SbsaQemu/OemMiscLib/OemMiscLib.c | 10 +- .../Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c | 16 +- .../SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c | 9 +- .../Library/FdtHelperLib/FdtHelperLib.c | 98 --------- .../Library/SbsaQemuSmc/SbsaQemuSmc.c | 204 ++++++++++++++++++ 14 files changed, 308 insertions(+), 197 deletions(-) delete mode 100644 Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.inf create mode 100644 Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.inf delete mode 100644 Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h create mode 100644 Silicon/Qemu/SbsaQemu/Include/Library/SbsaQemuSmc.h delete mode 100644 Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c create mode 100644 Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c
diff --git a/Platform/Qemu/SbsaQemu/SbsaQemu.dsc b/Platform/Qemu/SbsaQemu/SbsaQemu.dsc index 378600050df9..231db11cb07b 100644 --- a/Platform/Qemu/SbsaQemu/SbsaQemu.dsc +++ b/Platform/Qemu/SbsaQemu/SbsaQemu.dsc @@ -1,6 +1,6 @@ # # Copyright (c) 2021, NUVIA Inc. All rights reserved. -# Copyright (c) 2019, Linaro Limited. All rights reserved. +# Copyright (c) 2023, Linaro Ltd. All rights reserved. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -126,7 +126,7 @@ [LibraryClasses.common] # ARM PL011 UART Driver PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
- FdtHelperLib|Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.inf + SbsaQemuSmc|Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.inf OemMiscLib|Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.inf
# Debug Support diff --git a/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.inf b/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.inf index a34f54d431d4..8e2bf8c512f1 100644 --- a/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.inf +++ b/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.inf @@ -3,7 +3,7 @@ # # Copyright (c) 2021, NUVIA Inc. All rights reserved. # Copyright (c) 2018, Hisilicon Limited. All rights reserved. -# Copyright (c) 2018, Linaro Limited. All rights reserved. +# Copyright (c) 2023, Linaro Ltd. All rights reserved. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -29,8 +29,6 @@ [Packages]
[LibraryClasses] BaseMemoryLib - FdtLib - FdtHelperLib IoLib PcdLib
@@ -40,7 +38,6 @@ [Guids] [Pcd] gArmTokenSpaceGuid.PcdEmbeddedControllerFirmwareRelease gArmTokenSpaceGuid.PcdSystemBiosRelease - gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdDeviceTreeBaseAddress
gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdSystemManufacturer gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdSystemSerialNumber @@ -56,3 +53,4 @@ [Pcd] gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdChassisManufacturer gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdChassisAssetTag gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdChassisSKU + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdCoreCount diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf index 291743b19115..d23b53586cd3 100644 --- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.inf @@ -1,7 +1,7 @@ ## @file # This driver modifies ACPI tables for the Qemu SBSA platform # -# Copyright (c) 2020, Linaro Ltd. All rights reserved. +# Copyright (c) Linaro Ltd. All rights reserved. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -35,9 +35,9 @@ [LibraryClasses] BaseLib DebugLib DxeServicesLib - FdtHelperLib PcdLib PrintLib + SbsaQemuSmc UefiDriverEntryPoint UefiLib UefiRuntimeServicesTableLib diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.inf b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.inf index 19534b7a274a..c8203a6ffc47 100644 --- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.inf +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.inf @@ -1,7 +1,7 @@ ## @file # This driver effectuates SbsaQemu platform configuration settings # -# Copyright (c) 2019, Linaro Ltd. All rights reserved. +# Copyright (c) Linaro Ltd. All rights reserved. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -32,6 +32,7 @@ [LibraryClasses] PcdLib DebugLib NonDiscoverableDeviceRegistrationLib + SbsaQemuSmc UefiDriverEntryPoint
[Pcd] @@ -46,6 +47,7 @@ [Pcd] gArmTokenSpaceGuid.PcdGicDistributorBase gArmTokenSpaceGuid.PcdGicRedistributorsBase gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdGicItsBase + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdCoreCount
[Depex] diff --git a/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.inf b/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.inf deleted file mode 100644 index 9c059f3e5851..000000000000 --- a/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.inf +++ /dev/null @@ -1,33 +0,0 @@ -#/** @file -# -# Component description file for FdtHelperLib module -# -# Copyright (c) 2021, NUVIA Inc. All rights reserved. -# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#**/ - -[Defines] - INF_VERSION = 1.29 - BASE_NAME = FdtHelperLib - FILE_GUID = 34e4396f-c2fc-4f9e-ad58-0f98e99e3875 - MODULE_TYPE = BASE - VERSION_STRING = 1.0 - LIBRARY_CLASS = FdtHelperLib - -[Sources.common] - FdtHelperLib.c - -[Packages] - EmbeddedPkg/EmbeddedPkg.dec - MdePkg/MdePkg.dec - Silicon/Qemu/SbsaQemu/SbsaQemu.dec - -[LibraryClasses] - DebugLib - FdtLib - PcdLib - -[FixedPcd] - gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdDeviceTreeBaseAddress diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.inf b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.inf new file mode 100644 index 000000000000..a9d51d8871b0 --- /dev/null +++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.inf @@ -0,0 +1,34 @@ +#/* @file +# +# Copyright (c) Linaro Ltd. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#*/ + +[Defines] + INF_VERSION = 0x0001001c + BASE_NAME = SbsaQemuSmc + FILE_GUID = 6454006f-6502-46e2-9be4-4bba8d4b29fb + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ArmPlatformLib + +[Sources] + SbsaQemuSmc.c + +[Packages] + ArmPkg/ArmPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + Silicon/Qemu/SbsaQemu/SbsaQemu.dec + +[LibraryClasses] + ArmSmcLib + BaseMemoryLib + DebugLib + FdtLib + + [Pcd] + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdDeviceTreeBaseAddress + gArmVirtSbsaQemuPlatformTokenSpaceGuid.PcdCoreCount diff --git a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h index 7934875e4aba..e33648ee1462 100644 --- a/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h +++ b/Silicon/Qemu/SbsaQemu/Include/IndustryStandard/SbsaQemuSmc.h @@ -14,5 +14,7 @@ #define SIP_SVC_VERSION SMC_SIP_FUNCTION_ID(1) #define SIP_SVC_GET_GIC SMC_SIP_FUNCTION_ID(100) #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)
#endif /* SBSA_QEMU_SMC_H_ */ diff --git a/Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h b/Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h deleted file mode 100644 index ea9159857215..000000000000 --- a/Silicon/Qemu/SbsaQemu/Include/Library/FdtHelperLib.h +++ /dev/null @@ -1,36 +0,0 @@ -/** @file -* FdtHelperLib.h -* -* Copyright (c) 2021, NUVIA Inc. All rights reserved. -* -* SPDX-License-Identifier: BSD-2-Clause-Patent -* -**/ - -#ifndef FDT_HELPER_LIB_ -#define FDT_HELPER_LIB_ - -/** - Get MPIDR for a given cpu from device tree passed by Qemu. - - @param [in] CpuId Index of cpu to retrieve MPIDR value for. - - @retval MPIDR value of CPU at index <CpuId> -**/ -UINT64 -FdtHelperGetMpidr ( - IN UINTN CpuId - ); - -/** Walks through the Device Tree created by Qemu and counts the number - of CPUs present in it. - - @return The number of CPUs present. -**/ -EFIAPI -UINT32 -FdtHelperCountCpus ( - VOID - ); - -#endif /* FDT_HELPER_LIB_ */ diff --git a/Silicon/Qemu/SbsaQemu/Include/Library/SbsaQemuSmc.h b/Silicon/Qemu/SbsaQemu/Include/Library/SbsaQemuSmc.h new file mode 100644 index 000000000000..883b8d0d0d17 --- /dev/null +++ b/Silicon/Qemu/SbsaQemu/Include/Library/SbsaQemuSmc.h @@ -0,0 +1,45 @@ +/** @file +* +* Copyright (c) Linaro Ltd. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#ifndef SBSA_QEMU_SMC_ +#define SBSA_QEMU_SMC_ + +/** + Get CPU count from information passed by Qemu. + +**/ +VOID +SbsaQemuGetCpuCount ( + VOID + ); + +/** + Get MPIDR for a given cpu from device tree passed by Qemu. + + @param [in] CpuId Index of cpu to retrieve MPIDR value for. + + @retval MPIDR value of CPU at index <CpuId> +**/ +UINT64 +SbsaQemuGetMpidr ( + IN UINTN CpuId + ); + +/** + Get NUMA node id for a given cpu from device tree passed by Qemu. + + @param [in] CpuId Index of cpu to retrieve NUMA node id for. + + @retval NUMA node id for CPU at index <CpuId> +**/ +UINT64 +SbsaQemuGetCpuNumaNode ( + IN UINTN CpuId + ); + +#endif /* SBSA_QEMU_SMC_ */ diff --git a/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.c b/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.c index c38f2851904f..ab97768b5ddc 100644 --- a/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.c +++ b/Platform/Qemu/SbsaQemu/OemMiscLib/OemMiscLib.c @@ -2,7 +2,7 @@ * OemMiscLib.c * * Copyright (c) 2021, NUVIA Inc. All rights reserved. -* Copyright (c) 2020, Linaro Ltd. All rights reserved. +* Copyright (c) Linaro Ltd. All rights reserved. * * SPDX-License-Identifier: BSD-2-Clause-Patent * @@ -12,14 +12,12 @@ #include <Guid/ZeroGuid.h> #include <Library/BaseMemoryLib.h> #include <Library/DebugLib.h> -#include <Library/FdtHelperLib.h> #include <Library/HiiLib.h> #include <Library/IoLib.h> #include <Library/OemMiscLib.h> #include <Library/PcdLib.h> #include <Library/SerialPortLib.h> #include <Library/TimerLib.h> -#include <libfdt.h>
/** Returns whether the specified processor is present or not.
@@ -33,7 +31,7 @@ OemIsProcessorPresent ( UINTN ProcessorIndex ) { - if (ProcessorIndex < FdtHelperCountCpus ()) { + if (ProcessorIndex < PcdGet32 (PcdCoreCount)) { return TRUE; }
@@ -76,7 +74,7 @@ OemGetProcessorInformation ( { UINT16 ProcessorCount;
- ProcessorCount = FdtHelperCountCpus (); + ProcessorCount = PcdGet32 (PcdCoreCount);
if (ProcessorIndex < ProcessorCount) { ProcessorStatus->Bits.CpuStatus = 1; // CPU enabled @@ -121,7 +119,7 @@ OemGetMaxProcessors ( VOID ) { - return FdtHelperCountCpus (); + return PcdGet32 (PcdCoreCount); }
/** Gets information about the cache at the specified cache level. diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c index 9fb17151d7b8..fa9102194e84 100644 --- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuAcpiDxe/SbsaQemuAcpiDxe.c @@ -1,7 +1,7 @@ /** @file * This file is an ACPI driver for the Qemu SBSA platform. * -* Copyright (c) 2020, Linaro Ltd. All rights reserved. +* Copyright (c) Linaro Ltd. All rights reserved. * * SPDX-License-Identifier: BSD-2-Clause-Patent * @@ -15,10 +15,10 @@ #include <Library/ArmLib.h> #include <Library/BaseMemoryLib.h> #include <Library/DebugLib.h> -#include <Library/FdtHelperLib.h> #include <Library/MemoryAllocationLib.h> #include <Library/PcdLib.h> #include <Library/PrintLib.h> +#include <Library/SbsaQemuSmc.h> #include <Library/UefiBootServicesTableLib.h> #include <Library/UefiDriverEntryPoint.h> #include <Library/UefiLib.h> @@ -255,7 +255,7 @@ AddMadtTable ( // Initialize GIC Redistributor Structure EFI_ACPI_6_0_GICR_STRUCTURE Gicr = SBSAQEMU_MADT_GICR_INIT();
- // Get CoreCount which was determined eariler after parsing device tree + // Get CoreCount which was determined earlier from TF-A NumCores = PcdGet32 (PcdCoreCount);
// Calculate the new table size based on the number of cores @@ -291,13 +291,13 @@ AddMadtTable ( New += sizeof (EFI_ACPI_6_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
// Add new GICC structures for the Cores - for (CoreIndex = 0; CoreIndex < PcdGet32 (PcdCoreCount); CoreIndex++) { + for (CoreIndex = 0; CoreIndex < NumCores; CoreIndex++) { EFI_ACPI_6_0_GIC_STRUCTURE *GiccPtr;
CopyMem (New, &Gicc, sizeof (EFI_ACPI_6_0_GIC_STRUCTURE)); GiccPtr = (EFI_ACPI_6_0_GIC_STRUCTURE *) New; GiccPtr->AcpiProcessorUid = CoreIndex; - GiccPtr->MPIDR = FdtHelperGetMpidr (CoreIndex); + GiccPtr->MPIDR = SbsaQemuGetMpidr (CoreIndex); New += sizeof (EFI_ACPI_6_0_GIC_STRUCTURE); }
@@ -758,12 +758,6 @@ InitializeSbsaQemuAcpiDxe ( { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTable; - UINT32 NumCores; - - // Parse the device tree and get the number of CPUs - NumCores = FdtHelperCountCpus (); - Status = PcdSet32S (PcdCoreCount, NumCores); - ASSERT_RETURN_ERROR (Status);
// Check if ACPI Table Protocol has been installed Status = gBS->LocateProtocol ( diff --git a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c index 4ebbe7c93a19..bc5545a272fe 100644 --- a/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c +++ b/Silicon/Qemu/SbsaQemu/Drivers/SbsaQemuPlatformDxe/SbsaQemuPlatformDxe.c @@ -1,7 +1,7 @@ /** @file -* FDT client protocol driver for qemu,mach-virt-ahci DT node +* SbsaQemu Platform Initialization * -* Copyright (c) 2019, Linaro Ltd. All rights reserved. +* Copyright (c) Linaro Ltd. All rights reserved. * * SPDX-License-Identifier: BSD-2-Clause-Patent * @@ -12,13 +12,12 @@ #include <Library/DebugLib.h> #include <Library/NonDiscoverableDeviceRegistrationLib.h> #include <Library/PcdLib.h> +#include <Library/SbsaQemuSmc.h> #include <Library/UefiBootServicesTableLib.h> #include <Library/UefiDriverEntryPoint.h> #include <IndustryStandard/SbsaQemuSmc.h> #include <IndustryStandard/SbsaQemuPlatformVersion.h>
-#include <Protocol/FdtClient.h> - EFI_STATUS EFIAPI InitializeSbsaQemuPlatformDxe ( @@ -123,5 +122,7 @@ InitializeSbsaQemuPlatformDxe ( } }
+ SbsaQemuGetCpuCount(); + return EFI_SUCCESS; } diff --git a/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c b/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c deleted file mode 100644 index 7fdfb055db76..000000000000 --- a/Silicon/Qemu/SbsaQemu/Library/FdtHelperLib/FdtHelperLib.c +++ /dev/null @@ -1,98 +0,0 @@ -/** @file -* FdtHelperLib.c -* -* Copyright (c) 2021, NUVIA Inc. All rights reserved. -* Copyright (c) 2020, Linaro Ltd. All rights reserved. -* -* SPDX-License-Identifier: BSD-2-Clause-Patent -* -**/ - -#include <Uefi.h> -#include <Library/DebugLib.h> -#include <Library/FdtHelperLib.h> -#include <Library/PcdLib.h> -#include <libfdt.h> - -STATIC INT32 mFdtFirstCpuOffset; -STATIC INT32 mFdtCpuNodeSize; - -/** - Get MPIDR for a given cpu from device tree passed by Qemu. - - @param [in] CpuId Index of cpu to retrieve MPIDR value for. - - @retval MPIDR value of CPU at index <CpuId> -**/ -UINT64 -FdtHelperGetMpidr ( - IN UINTN CpuId - ) -{ - VOID *DeviceTreeBase; - CONST UINT64 *RegVal; - INT32 Len; - - DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); - ASSERT (DeviceTreeBase != NULL); - - RegVal = fdt_getprop (DeviceTreeBase, - mFdtFirstCpuOffset + (CpuId * mFdtCpuNodeSize), - "reg", - &Len); - if (!RegVal) { - DEBUG ((DEBUG_ERROR, "Couldn't find reg property for CPU:%d\n", CpuId)); - return 0; - } - - return (fdt64_to_cpu (ReadUnaligned64 (RegVal))); -} - -/** Walks through the Device Tree created by Qemu and counts the number - of CPUs present in it. - - @return The number of CPUs present. -**/ -EFIAPI -UINT32 -FdtHelperCountCpus ( - VOID - ) -{ - VOID *DeviceTreeBase; - INT32 Node; - INT32 Prev; - INT32 CpuNode; - UINT32 CpuCount; - - DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); - ASSERT (DeviceTreeBase != NULL); - - // Make sure we have a valid device tree blob - ASSERT (fdt_check_header (DeviceTreeBase) == 0); - - CpuNode = fdt_path_offset (DeviceTreeBase, "/cpus"); - if (CpuNode <= 0) { - DEBUG ((DEBUG_ERROR, "Unable to locate /cpus in device tree\n")); - return 0; - } - - CpuCount = 0; - - // Walk through /cpus node and count the number of subnodes. - // The count of these subnodes corresponds to the number of - // CPUs created by Qemu. - Prev = fdt_first_subnode (DeviceTreeBase, CpuNode); - mFdtFirstCpuOffset = Prev; - while (1) { - CpuCount++; - Node = fdt_next_subnode (DeviceTreeBase, Prev); - if (Node < 0) { - break; - } - mFdtCpuNodeSize = Node - Prev; - Prev = Node; - } - - return CpuCount; -} diff --git a/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c new file mode 100644 index 000000000000..70bae6739fcb --- /dev/null +++ b/Silicon/Qemu/SbsaQemu/Library/SbsaQemuSmc/SbsaQemuSmc.c @@ -0,0 +1,204 @@ +/** @file +* +* Copyright (c) 2021, NUVIA Inc. All rights reserved. +* Copyright (c) Linaro Ltd. All rights reserved. +* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#include <Library/ArmSmcLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/SbsaQemuSmc.h> +#include <libfdt.h> +#include <IndustryStandard/SbsaQemuSmc.h> + +/** + Get MPIDR for a given cpu from device tree passed by Qemu. + + @param [in] CpuId Index of cpu to retrieve MPIDR value for. + + @retval MPIDR value of CPU at index <CpuId> +**/ +UINT64 +FdtHelperGetMpidr ( + IN UINTN CpuId + ) +{ + VOID *DeviceTreeBase; + INT32 Node; + INT32 Prev; + UINT32 CpuCount; + CONST UINT64 *RegVal; + + DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); + ASSERT (DeviceTreeBase != NULL); + + // Make sure we have a valid device tree blob + ASSERT (fdt_check_header (DeviceTreeBase) == 0); + + Node = fdt_path_offset (DeviceTreeBase, "/cpus"); + if (Node <= 0) { + DEBUG ((DEBUG_ERROR, "Unable to locate /cpus in device tree\n")); + return 0; + } + + CpuCount = 0; + + Prev = fdt_first_subnode (DeviceTreeBase, Node); + while (1) { + + if (CpuCount == CpuId) { + RegVal = fdt_getprop (DeviceTreeBase, Prev, "reg", NULL); + if (!RegVal) { + DEBUG ((DEBUG_ERROR, "Couldn't find reg property for CPU:%d\n", CpuId)); + return 0; + } + return (fdt64_to_cpu (ReadUnaligned64 (RegVal))); + } + + Node = fdt_next_subnode (DeviceTreeBase, Prev); + if (Node < 0) { + break; + } + Prev = Node; + CpuCount++; + } + + return 0; /* We did not found MPIDR */ + +} + +/** Walks through the Device Tree created by Qemu and counts the number + of CPUs present in it. + + @return The number of CPUs present. +**/ +EFIAPI +UINT32 +FdtHelperCountCpus ( + VOID + ) +{ + VOID *DeviceTreeBase; + INT32 Node; + INT32 Prev; + UINT32 CpuCount; + + DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeBaseAddress); + ASSERT (DeviceTreeBase != NULL); + + // Make sure we have a valid device tree blob + ASSERT (fdt_check_header (DeviceTreeBase) == 0); + + Node = fdt_path_offset (DeviceTreeBase, "/cpus"); + if (Node <= 0) { + DEBUG ((DEBUG_ERROR, "Unable to locate /cpus in device tree\n")); + return 0; + } + + CpuCount = 0; + + // Walk through /cpus node and count the number of subnodes. + // The count of these subnodes corresponds to the number of + // CPUs created by Qemu. + Prev = fdt_first_subnode (DeviceTreeBase, Node); + while (1) { + CpuCount++; + Node = fdt_next_subnode (DeviceTreeBase, Prev); + if (Node < 0) { + break; + } + Prev = Node; + } + + return CpuCount; +} + + +/** + Get CPU count from information passed by Qemu. + +**/ +VOID +SbsaQemuGetCpuCount ( + VOID + ) +{ + UINTN Arg0; + UINTN SmcResult; + RETURN_STATUS Result; + + SmcResult = ArmCallSmc0 (SIP_SVC_GET_CPU_COUNT, &Arg0, NULL, NULL); + if (SmcResult != SMC_ARCH_CALL_SUCCESS) { + DEBUG ((DEBUG_INFO, "Too old TF-A. We have to get cpu info from DT.\n")); + Arg0 = FdtHelperCountCpus(); + } + + Result = PcdSet32S (PcdCoreCount, Arg0); + ASSERT_RETURN_ERROR (Result); + + Arg0 = PcdGet32 (PcdCoreCount); + + DEBUG ((DEBUG_INFO, "We have %d cpus.\n", Arg0)); +} + +/** + Get MPIDR for a given cpu from device tree passed by Qemu. + + @param [in] CpuId Index of cpu to retrieve MPIDR value for. + + @retval MPIDR value of CPU at index <CpuId> +**/ +UINT64 +SbsaQemuGetMpidr ( + IN UINTN CpuId + ) +{ + UINTN SmcResult; + UINTN Arg0; + UINTN Arg1; + + Arg0 = CpuId; + + SmcResult = ArmCallSmc0 (SIP_SVC_GET_CPU_NODE, &Arg0, &Arg1, NULL); + if (SmcResult != SMC_ARCH_CALL_SUCCESS) { + DEBUG ((DEBUG_INFO, "Too old TF-A. We have to get cpu info from DT.\n")); + Arg1 = FdtHelperGetMpidr(CpuId); +} + + DEBUG ((DEBUG_ERROR, "MPIDR for CPU:%d = %d\n", CpuId, Arg1)); + + return Arg1; +} + +/** + Get NUMA node id for a given cpu from device tree passed by Qemu. + + @param [in] CpuId Index of cpu to retrieve NUMA node id for. + + @retval NUMA node id for CPU at index <CpuId> +**/ +UINT64 +SbsaQemuGetCpuNumaNode ( + IN UINTN CpuId + ) +{ + UINTN SmcResult; + UINTN Arg0; + UINTN Arg1; + + Arg0 = CpuId; + + SmcResult = ArmCallSmc0 (SIP_SVC_GET_CPU_NODE, &Arg0, &Arg1, NULL); + if (SmcResult != SMC_ARCH_CALL_SUCCESS) { + /* No fallback to DeviceTree as we did not had that info earlier. */ + DEBUG ((DEBUG_ERROR, "Couldn't find information for CPU:%d\n", CpuId)); + return 0; + } + + DEBUG ((DEBUG_ERROR, "NUMA node for CPU:%d = %d\n", CpuId, Arg0)); + + return Arg0; +}