[edk2-devel] [PATCH v2 1/1] MdeModulePkg: Add MpServicesTest application to exercise MP Services
Rebecca Cran
rebecca at nuviainc.com
Wed Nov 3 02:31:01 UTC 2021
Sami,
I don't see your review. Did you review this, or just the separate patch
to add EFI_MP_SERVICES_PROTOCOL for AArch64?
--
Rebecca Cran
On 10/16/21 12:54 AM, Sami Mujawar wrote:
> Hi Rebecca,
>
> I will review this next week.
>
> Regard
>
> Sami Mujawar
>
> ------------------------------------------------------------------------
> *From:* Rebecca Cran <rebecca at nuviainc.com>
> *Sent:* Saturday, 16 October 2021, 7:33 am
> *To:* devel at edk2.groups.io; Jian J Wang; Liming Gao
> *Cc:* Ard Biesheuvel; Samer El-Haj-Mahmoud; Leif Lindholm; Sami
> Mujawar; Gerd Hoffmann
> *Subject:* Re: [edk2-devel] [PATCH v2 1/1] MdeModulePkg: Add
> MpServicesTest application to exercise MP Services
>
> (cc Leif, Ard, Sami, Samer, Gerd)
>
>
> Could someone review this please?
>
>
> --
> Rebecca Cran
>
>
> On 9/20/21 9:47 AM, Rebecca Cran via groups.io wrote:
> > Add a new MpServicesTest application under MdeModulePkg/Application that
> > exercises the EFI_MP_SERVICES_PROTOCOL.
> >
> > Signed-off-by: Rebecca Cran <rebecca at nuviainc.com>
> > ---
> > MdeModulePkg/Application/MpServicesTest/MpServicesTest.c | 433
> ++++++++++++++++++++
> > MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf | 38 ++
> > MdeModulePkg/MdeModulePkg.dsc | 2 +
> > 3 files changed, 473 insertions(+)
> >
> > diff --git
> a/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c
> b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c
> > new file mode 100644
> > index 000000000000..4eb06e6b7cbd
> > --- /dev/null
> > +++ b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c
> > @@ -0,0 +1,433 @@
> > +/** @file
> > +
> > + Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/RngLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/UefiLib.h>
> > +#include <Pi/PiMultiPhase.h>
> > +#include <Protocol/MpService.h>
> > +
> > +#define MAX_RANDOM_PROCESSOR_RETRIES 10
> > +
> > +#define AP_STARTUP_TEST_TIMEOUT_US 50000
> > +#define INFINITE_TIMEOUT 0
> > +
> > +#define RETURN_IF_EFI_ERROR(x) \
> > + if (EFI_ERROR (x)) { \
> > + Print (L"failed: %r\n", x); \
> > + return; \
> > + } \
> > + else { \
> > + Print (L"done.\n"); \
> > + }
> > +
> > +/** The procedure to run with the MP Services interface.
> > +
> > + @param Buffer The procedure argument.
> > +
> > +**/
> > +STATIC
> > +VOID
> > +EFIAPI
> > +ApFunction (
> > + IN OUT VOID *Buffer
> > + )
> > +{
> > +}
> > +
> > +/** Displays information returned from MP Services Protocol.
> > +
> > + @param Mp The MP Services Protocol
> > +
> > + @return The number of CPUs in the system.
> > +
> > +**/
> > +STATIC
> > +UINTN
> > +PrintProcessorInformation (
> > + IN EFI_MP_SERVICES_PROTOCOL *Mp
> > + )
> > +{
> > + EFI_STATUS Status;
> > + EFI_PROCESSOR_INFORMATION CpuInfo;
> > + UINTN Index;
> > + UINTN NumCpu;
> > + UINTN NumEnabledCpu;
> > +
> > + Status = Mp->GetNumberOfProcessors (Mp, &NumCpu, &NumEnabledCpu);
> > + if (EFI_ERROR (Status)) {
> > + Print (L"GetNumberOfProcessors failed: %r\n", Status);
> > + } else {
> > + Print (L"Number of CPUs: %ld, Enabled: %d\n", NumCpu,
> NumEnabledCpu);
> > + }
> > +
> > + for (Index = 0; Index < NumCpu; Index++) {
> > + Status = Mp->GetProcessorInfo (Mp, CPU_V2_EXTENDED_TOPOLOGY |
> Index, &CpuInfo);
> > + if (EFI_ERROR (Status)) {
> > + Print (L"GetProcessorInfo for Processor %d failed: %r\n",
> Index, Status);
> > + } else {
> > + Print (
> > + L"Processor %d:\n"
> > + L"\tID: %016lx\n"
> > + L"\tStatus: %s | ",
> > + Index,
> > + CpuInfo.ProcessorId,
> > + (CpuInfo.StatusFlag & PROCESSOR_AS_BSP_BIT) ? L"BSP" : L"AP"
> > + );
> > +
> > + Print (L"%s | ", (CpuInfo.StatusFlag & PROCESSOR_ENABLED_BIT)
> ? L"Enabled" : L"Disabled");
> > + Print (L"%s\n", (CpuInfo.StatusFlag &
> PROCESSOR_HEALTH_STATUS_BIT) ? L"Healthy" : L"Faulted");
> > +
> > + Print (
> > + L"\tLocation: Package %d, Core %d, Thread %d\n"
> > + L"\tExtended Information: Package %d, Module %d, Tile %d,
> Die %d, Core %d, Thread %d\n\n",
> > + CpuInfo.Location.Package,
> > + CpuInfo.Location.Core,
> > + CpuInfo.Location.Thread,
> > + CpuInfo.ExtendedInformation.Location2.Package,
> > + CpuInfo.ExtendedInformation.Location2.Module,
> > + CpuInfo.ExtendedInformation.Location2.Tile,
> > + CpuInfo.ExtendedInformation.Location2.Die,
> > + CpuInfo.ExtendedInformation.Location2.Core,
> > + CpuInfo.ExtendedInformation.Location2.Thread
> > + );
> > + }
> > + }
> > +
> > + return NumCpu;
> > +}
> > +
> > +/** Returns the index of an enabled AP selected at random.
> > +
> > + @param Mp The MP Services Protocol.
> > + @param ProcessorIndex The index of a random enabled AP.
> > +
> > + @retval EFI_SUCCESS An enabled processor was found and returned.
> > + @retval EFI_NOT_FOUND A processor was unable to be selected.
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +GetRandomEnabledProcessorIndex (
> > + IN EFI_MP_SERVICES_PROTOCOL *Mp,
> > + OUT UINTN *ProcessorIndex
> > + )
> > +{
> > + UINTN Index;
> > + UINTN IndexOfEnabledCpu;
> > + UINTN NumCpus;
> > + UINTN NumEnabledCpus;
> > + UINTN IndexOfEnabledCpuToUse;
> > + UINT16 RandomNumber;
> > + BOOLEAN Success;
> > + EFI_STATUS Status;
> > + EFI_PROCESSOR_INFORMATION CpuInfo;
> > +
> > + IndexOfEnabledCpu = 0;
> > +
> > + Success = GetRandomNumber16 (&RandomNumber);
> > + ASSERT (Success == TRUE);
> > +
> > + Status = Mp->GetNumberOfProcessors (Mp, &NumCpus, &NumEnabledCpus);
> > + ASSERT_EFI_ERROR (Status);
> > +
> > + if (NumEnabledCpus == 1) {
> > + Print (L"All APs are disabled\n");
> > + return EFI_NOT_FOUND;
> > + }
> > +
> > + IndexOfEnabledCpuToUse = RandomNumber % NumEnabledCpus;
> > +
> > + for (Index = 0; Index < NumCpus; Index++) {
> > + Status = Mp->GetProcessorInfo (Mp, Index, &CpuInfo);
> > + ASSERT_EFI_ERROR (Status);
> > + if ((CpuInfo.StatusFlag & PROCESSOR_ENABLED_BIT) &&
> > + !(CpuInfo.StatusFlag & PROCESSOR_AS_BSP_BIT)) {
> > + if (IndexOfEnabledCpuToUse == IndexOfEnabledCpu) {
> > + *ProcessorIndex = Index;
> > + Status = EFI_SUCCESS;
> > + break;
> > + }
> > +
> > + IndexOfEnabledCpu++;
> > + }
> > + }
> > +
> > + if (Index == NumCpus) {
> > + Status = EFI_NOT_FOUND;
> > + }
> > +
> > + return Status;
> > +}
> > +
> > +/** Tests for the StartupThisAP function.
> > +
> > + @param Mp The MP Services Protocol.
> > +
> > +**/
> > +STATIC
> > +VOID
> > +StartupThisApTests (
> > + IN EFI_MP_SERVICES_PROTOCOL *Mp
> > + )
> > +{
> > + EFI_STATUS Status;
> > + UINTN ProcessorIndex;
> > + UINT32 Retries;
> > +
> > + Retries = 0;
> > +
> > + do {
> > + Status = GetRandomEnabledProcessorIndex (Mp, &ProcessorIndex);
> > + } while (EFI_ERROR (Status) && Retries++ <
> MAX_RANDOM_PROCESSOR_RETRIES);
> > +
> > + if (EFI_ERROR (Status)) {
> > + return;
> > + }
> > +
> > + Print (
> > + L"StartupThisAP on Processor %d with 0 (infinite) timeout...",
> > + ProcessorIndex
> > + );
> > +
> > + Status = Mp->StartupThisAP (
> > + Mp,
> > + ApFunction,
> > + ProcessorIndex,
> > + NULL,
> > + INFINITE_TIMEOUT,
> > + NULL,
> > + NULL
> > + );
> > +
> > + RETURN_IF_EFI_ERROR (Status);
> > +
> > + Retries = 0;
> > +
> > + do {
> > + Status = GetRandomEnabledProcessorIndex (Mp, &ProcessorIndex);
> > + } while (EFI_ERROR (Status) && Retries++ <
> MAX_RANDOM_PROCESSOR_RETRIES);
> > +
> > + if (EFI_ERROR (Status)) {
> > + return;
> > + }
> > +
> > + Print (
> > + L"StartupThisAP on Processor %d with %dms timeout...",
> > + ProcessorIndex,
> > + AP_STARTUP_TEST_TIMEOUT_US / 1000
> > + );
> > + Status = Mp->StartupThisAP (
> > + Mp,
> > + ApFunction,
> > + ProcessorIndex,
> > + NULL,
> > + AP_STARTUP_TEST_TIMEOUT_US,
> > + NULL,
> > + NULL
> > + );
> > + RETURN_IF_EFI_ERROR (Status);
> > +}
> > +
> > +/** Tests for the StartupAllAPs function.
> > +
> > + @param Mp The MP Services Protocol.
> > + @param NumCpus The number of CPUs in the system.
> > +
> > +**/
> > +STATIC
> > +VOID
> > +StartupAllAPsTests (
> > + IN EFI_MP_SERVICES_PROTOCOL *Mp,
> > + IN UINTN NumCpus
> > + )
> > +{
> > + EFI_STATUS Status;
> > + UINTN Timeout;
> > +
> > + Print (L"Running with SingleThread FALSE, 0 (infinite) timeout...");
> > + Status = Mp->StartupAllAPs (Mp, ApFunction, FALSE, NULL,
> INFINITE_TIMEOUT, NULL, NULL);
> > + RETURN_IF_EFI_ERROR (Status);
> > +
> > + Timeout = NumCpus * AP_STARTUP_TEST_TIMEOUT_US;
> > +
> > + Print (L"Running with SingleThread TRUE, %dms timeout...",
> Timeout / 1000);
> > + Status = Mp->StartupAllAPs (
> > + Mp,
> > + ApFunction,
> > + TRUE,
> > + NULL,
> > + Timeout,
> > + NULL,
> > + NULL
> > + );
> > + RETURN_IF_EFI_ERROR (Status);
> > +}
> > +
> > +/** Tests for the EnableDisableAP function.
> > +
> > + @param Mp The MP Services Protocol.
> > + @param NumCpus The number of CPUs in the system.
> > +
> > +**/
> > +STATIC
> > +VOID
> > +EnableDisableAPTests (
> > + IN EFI_MP_SERVICES_PROTOCOL *Mp,
> > + IN UINTN NumCpus
> > + )
> > +{
> > + EFI_STATUS Status;
> > + UINTN Index;
> > + UINT32 HealthFlag;
> > +
> > + HealthFlag = 0;
> > +
> > + for (Index = 1; Index < NumCpus; Index++) {
> > + Print (L"Disabling Processor %d with HealthFlag faulted...",
> Index);
> > + Status = Mp->EnableDisableAP (Mp, Index, FALSE, &HealthFlag);
> > + RETURN_IF_EFI_ERROR (Status);
> > + }
> > +
> > + HealthFlag = PROCESSOR_HEALTH_STATUS_BIT;
> > +
> > + for (Index = 1; Index < NumCpus; Index++) {
> > + Print (L"Enabling Processor %d with HealthFlag healthy...", Index);
> > + Status = Mp->EnableDisableAP (Mp, Index, TRUE, &HealthFlag);
> > + RETURN_IF_EFI_ERROR (Status);
> > + }
> > +}
> > +
> > +/** Tests for the SwitchBSP function.
> > +
> > + @param Mp The MP Services Protocol.
> > + @param NumCpus The number of CPUs in the system.
> > +
> > +**/
> > +STATIC
> > +VOID
> > +SwitchBSPTests (
> > + IN EFI_MP_SERVICES_PROTOCOL *Mp,
> > + IN UINTN NumCpus
> > + )
> > +{
> > + EFI_STATUS Status;
> > + UINTN Index;
> > +
> > + for (Index = 1; Index < NumCpus; Index++) {
> > + Print (L"Switching BSP to Processor %d with EnableOldBSP
> FALSE...", Index);
> > + Status = Mp->SwitchBSP (Mp, Index, FALSE);
> > + RETURN_IF_EFI_ERROR (Status);
> > + }
> > +
> > + for (Index = 0; Index < NumCpus; Index++) {
> > + Print (L"Switching BSP to Processor %d with EnableOldBSP
> TRUE...", Index);
> > + Status = Mp->SwitchBSP (Mp, Index, TRUE);
> > + RETURN_IF_EFI_ERROR (Status);
> > + }
> > +}
> > +
> > +/**
> > + The user Entry Point for Application. The user code starts with
> this function
> > + as the real entry point for the application.
> > +
> > + @param[in] ImageHandle The firmware allocated handle for the
> EFI image.
> > + @param[in] SystemTable A pointer to the EFI System Table.
> > +
> > + @retval EFI_SUCCESS The entry point is executed successfully.
> > + @retval other Some error occurs when executing this
> entry point.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UefiMain (
> > + IN EFI_HANDLE ImageHandle,
> > + IN EFI_SYSTEM_TABLE *SystemTable
> > + )
> > +{
> > + EFI_STATUS Status;
> > + EFI_MP_SERVICES_PROTOCOL *Mp;
> > + EFI_HANDLE *pHandle;
> > + UINTN HandleCount;
> > + UINTN BspId;
> > + UINTN NumCpus;
> > + UINTN Index;
> > +
> > + pHandle = NULL;
> > + HandleCount = 0;
> > + BspId = 0;
> > +
> > + Status = gBS->LocateHandleBuffer (
> > + ByProtocol,
> > + &gEfiMpServiceProtocolGuid,
> > + NULL,
> > + &HandleCount,
> > + &pHandle
> > + );
> > +
> > + if (EFI_ERROR (Status)) {
> > + Print (L"Failed to locate EFI_MP_SERVICES_PROTOCOL (%r). Not
> installed on platform?\n", Status);
> > + return EFI_NOT_FOUND;
> > + }
> > +
> > + for (Index = 0; Index < HandleCount; Index++) {
> > + Status = gBS->OpenProtocol (
> > + *pHandle,
> > + &gEfiMpServiceProtocolGuid,
> > + (VOID **)&Mp,
> > + NULL,
> > + gImageHandle,
> > + EFI_OPEN_PROTOCOL_GET_PROTOCOL
> > + );
> > +
> > + if (EFI_ERROR (Status)) {
> > + return Status;
> > + }
> > +
> > + pHandle++;
> > + }
> > +
> > + Print (L"Exercising WhoAmI\n\n");
> > + Status = Mp->WhoAmI (Mp, &BspId);
> > + if (EFI_ERROR (Status)) {
> > + Print (L"WhoAmI failed: %r\n", Status);
> > + return Status;
> > + } else {
> > + Print (L"WhoAmI: %016lx\n", BspId);
> > + }
> > +
> > + Print (L"\n");
> > + Print (
> > + L"Exercising GetNumberOfProcessors and GetProcessorInformation
> with "
> > + L"CPU_V2_EXTENDED_TOPOLOGY\n\n"
> > + );
> > + NumCpus = PrintProcessorInformation (Mp);
> > + if (NumCpus < 2) {
> > + Print (L"UP system found. Not running further tests.\n");
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + Print (L"\n");
> > + Print (L"Exercising StartupThisAP:\n\n");
> > + StartupThisApTests (Mp);
> > +
> > + Print (L"\n");
> > + Print (L"Exercising StartupAllAPs:\n\n");
> > + StartupAllAPsTests (Mp, NumCpus);
> > +
> > + Print (L"\n");
> > + Print (L"Exercising EnableDisableAP:\n\n");
> > + EnableDisableAPTests (Mp, NumCpus);
> > +
> > + Print (L"\n");
> > + Print (L"Exercising SwitchBSP\n\n");
> > + SwitchBSPTests (Mp, NumCpus);
> > +
> > + gBS->CloseProtocol (pHandle, &gEfiMpServiceProtocolGuid,
> gImageHandle, NULL);
> > + return EFI_SUCCESS;
> > +}
> > diff --git
> a/MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf
> b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf
> > new file mode 100644
> > index 000000000000..8a21ca70d8fa
> > --- /dev/null
> > +++ b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf
> > @@ -0,0 +1,38 @@
> > +## @file
> > +# UEFI Application to exercise EFI_MP_SERVICES_PROTOCOL.
> > +#
> > +# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > + INF_VERSION = 1.29
> > + BASE_NAME = MpServicesTest
> > + FILE_GUID = 43e9defa-7209-4b0d-b136-cc4ca02cb469
> > + MODULE_TYPE = UEFI_APPLICATION
> > + VERSION_STRING = 0.1
> > + ENTRY_POINT = UefiMain
> > +
> > +#
> > +# The following information is for reference only and not required
> by the build tools.
> > +#
> > +# VALID_ARCHITECTURES = IA32 X64 AARCH64
> > +#
> > +
> > +[Sources]
> > + MpServicesTest.c
> > +
> > +[Packages]
> > + MdePkg/MdePkg.dec
> > +
> > +[LibraryClasses]
> > + BaseLib
> > + RngLib
> > + UefiApplicationEntryPoint
> > + UefiLib
> > +
> > +[Protocols]
> > + gEfiMpServiceProtocolGuid ## CONSUMES
> > +
> > diff --git a/MdeModulePkg/MdeModulePkg.dsc
> b/MdeModulePkg/MdeModulePkg.dsc
> > index b1d83461865e..1cf5ccd30d40 100644
> > --- a/MdeModulePkg/MdeModulePkg.dsc
> > +++ b/MdeModulePkg/MdeModulePkg.dsc
> > @@ -164,6 +164,7 @@
> >
> MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> > DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
> > FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
> > + RngLib|MdePkg/Library/DxeRngLib/DxeRngLib.inf
> >
> > [LibraryClasses.common.MM_STANDALONE]
> > HobLib|MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf
> > @@ -215,6 +216,7 @@
> > MdeModulePkg/Application/HelloWorld/HelloWorld.inf
> > MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf
> > MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf
> > + MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf
> >
> > MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
> > MdeModulePkg/Logo/Logo.inf
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#83202): https://edk2.groups.io/g/devel/message/83202
Mute This Topic: https://groups.io/mt/86366990/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/edk2-devel-archive/attachments/20211102/9befd606/attachment.htm>
More information about the edk2-devel-archive
mailing list