From nobody Mon Feb 9 13:32:21 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+80878+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+80878+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1632152877; cv=none; d=zohomail.com; s=zohoarc; b=BbSeljcqbUuEUj4QJlgjKtaUo8WJz/sB5CJ3Nqf7VewxXODCszL66t2fqHdWDeJW3MmhdRYvl5qcG0bkgCp6WIyMtSr5OUXCCty3u/CDdNSKF38UAZgnzxjS17O+0NlPZ2NxsM+Y4W96fHV9QA5Sdm5V+pl4SaU8ZK54PBoZ3jM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1632152877; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=UeKpu30c0qBtyY9FsyiWBef8A79039aPILC/oLqjSVs=; b=FGkO9QPuQ+3LAyO4koTuojECkui9xAgu6h9xOZUuCOUVP3LYnDdvNrYv2DfdjNKH+6toJqn2XNtB3xdp9wtrzDMgS1xC7LkjWlm4bfSoBAoISk+vn/NXfylSXwBm9uVJ4OkFOz1FEvcSZhvFHuqoJMmBNYthq5WB7azLJi4Agdc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+80878+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1632152877931142.92294833721633; Mon, 20 Sep 2021 08:47:57 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id HOh8YY1788612xQXluLNcBIP; Mon, 20 Sep 2021 08:47:57 -0700 X-Received: from mail-pf1-f179.google.com (mail-pf1-f179.google.com [209.85.210.179]) by mx.groups.io with SMTP id smtpd.web09.542.1632152876737105359 for ; Mon, 20 Sep 2021 08:47:56 -0700 X-Received: by mail-pf1-f179.google.com with SMTP id q23so14537344pfs.9 for ; Mon, 20 Sep 2021 08:47:56 -0700 (PDT) X-Gm-Message-State: dx8Wdq1YvGSBJYUMKK0O0Sn7x1787277AA= X-Google-Smtp-Source: ABdhPJx5XNVNpgheDsh96so2s7NgirxXMa+o32tzEfPUMNfc6N85RLdtMSj90pUijOH+A8b5lHhPVg== X-Received: by 2002:a62:ee12:0:b0:412:444e:f5ff with SMTP id e18-20020a62ee12000000b00412444ef5ffmr26355092pfi.82.1632152875651; Mon, 20 Sep 2021 08:47:55 -0700 (PDT) X-Received: from linbox.int.bluestop.org.com (c-174-52-16-57.hsd1.ut.comcast.net. [174.52.16.57]) by smtp.gmail.com with ESMTPSA id x16sm15656182pgc.49.2021.09.20.08.47.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Sep 2021 08:47:55 -0700 (PDT) From: "Rebecca Cran" To: devel@edk2.groups.io, Jian J Wang , Liming Gao Cc: Rebecca Cran Subject: [edk2-devel] [PATCH v2 1/1] MdeModulePkg: Add MpServicesTest application to exercise MP Services Date: Mon, 20 Sep 2021 09:47:32 -0600 Message-Id: <20210920154732.10181-2-rebecca@nuviainc.com> In-Reply-To: <20210920154732.10181-1-rebecca@nuviainc.com> References: <20210920154732.10181-1-rebecca@nuviainc.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,rebecca@nuviainc.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1632152877; bh=O0r+vwXj7VGK9zR4r03L0DcflcEHkNANylot3zue5Sc=; h=Cc:Date:From:Reply-To:Subject:To; b=PtNnTOdGzqpmhC8r49cWJ7DqSwc9g/jjuwwWGiSKNvtTGDnIAryIHLkB6Q4QF/7M4jI l03ZOlyr5o/Ya9Vl/r3S3vIe9CFZ3D/Im/SJ0agNFCp859fBrll6i8yePU1njJxEKZSvY tqqejFVAJX9xdLLrfmiONGgotY2EF9u7BRE= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1632152880111100001 Content-Type: text/plain; charset="utf-8" Add a new MpServicesTest application under MdeModulePkg/Application that exercises the EFI_MP_SERVICES_PROTOCOL. Signed-off-by: Rebecca Cran --- 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/Mde= ModulePkg/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.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include +#include +#include + +#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 =3D 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 =3D 0; Index < NumCpu; Index++) { + Status =3D Mp->GetProcessorInfo (Mp, CPU_V2_EXTENDED_TOPOLOGY | Index,= &CpuInfo); + if (EFI_ERROR (Status)) { + Print (L"GetProcessorInfo for Processor %d failed: %r\n", Index, Sta= tus); + } 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"En= abled" : 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 =3D 0; + + Success =3D GetRandomNumber16 (&RandomNumber); + ASSERT (Success =3D=3D TRUE); + + Status =3D Mp->GetNumberOfProcessors (Mp, &NumCpus, &NumEnabledCpus); + ASSERT_EFI_ERROR (Status); + + if (NumEnabledCpus =3D=3D 1) { + Print (L"All APs are disabled\n"); + return EFI_NOT_FOUND; + } + + IndexOfEnabledCpuToUse =3D RandomNumber % NumEnabledCpus; + + for (Index =3D 0; Index < NumCpus; Index++) { + Status =3D Mp->GetProcessorInfo (Mp, Index, &CpuInfo); + ASSERT_EFI_ERROR (Status); + if ((CpuInfo.StatusFlag & PROCESSOR_ENABLED_BIT) && + !(CpuInfo.StatusFlag & PROCESSOR_AS_BSP_BIT)) { + if (IndexOfEnabledCpuToUse =3D=3D IndexOfEnabledCpu) { + *ProcessorIndex =3D Index; + Status =3D EFI_SUCCESS; + break; + } + + IndexOfEnabledCpu++; + } + } + + if (Index =3D=3D NumCpus) { + Status =3D 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 =3D 0; + + do { + Status =3D 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 =3D Mp->StartupThisAP ( + Mp, + ApFunction, + ProcessorIndex, + NULL, + INFINITE_TIMEOUT, + NULL, + NULL + ); + + RETURN_IF_EFI_ERROR (Status); + + Retries =3D 0; + + do { + Status =3D 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 =3D 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 =3D Mp->StartupAllAPs (Mp, ApFunction, FALSE, NULL, INFINITE_TIME= OUT, NULL, NULL); + RETURN_IF_EFI_ERROR (Status); + + Timeout =3D NumCpus * AP_STARTUP_TEST_TIMEOUT_US; + + Print (L"Running with SingleThread TRUE, %dms timeout...", Timeout / 100= 0); + Status =3D 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 =3D 0; + + for (Index =3D 1; Index < NumCpus; Index++) { + Print (L"Disabling Processor %d with HealthFlag faulted...", Index); + Status =3D Mp->EnableDisableAP (Mp, Index, FALSE, &HealthFlag); + RETURN_IF_EFI_ERROR (Status); + } + + HealthFlag =3D PROCESSOR_HEALTH_STATUS_BIT; + + for (Index =3D 1; Index < NumCpus; Index++) { + Print (L"Enabling Processor %d with HealthFlag healthy...", Index); + Status =3D 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 =3D 1; Index < NumCpus; Index++) { + Print (L"Switching BSP to Processor %d with EnableOldBSP FALSE...", In= dex); + Status =3D Mp->SwitchBSP (Mp, Index, FALSE); + RETURN_IF_EFI_ERROR (Status); + } + + for (Index =3D 0; Index < NumCpus; Index++) { + Print (L"Switching BSP to Processor %d with EnableOldBSP TRUE...", Ind= ex); + Status =3D Mp->SwitchBSP (Mp, Index, TRUE); + RETURN_IF_EFI_ERROR (Status); + } +} + +/** + The user Entry Point for Application. The user code starts with this fun= ction + as the real entry point for the application. + + @param[in] ImageHandle The firmware allocated handle for the EFI imag= e. + @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 po= int. + +**/ +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 =3D NULL; + HandleCount =3D 0; + BspId =3D 0; + + Status =3D 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 =3D 0; Index < HandleCount; Index++) { + Status =3D 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 =3D 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 =3D 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, N= ULL); + return EFI_SUCCESS; +} diff --git a/MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf b/M= deModulePkg/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.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 1.29 + BASE_NAME =3D MpServicesTest + FILE_GUID =3D 43e9defa-7209-4b0d-b136-cc4ca02cb469 + MODULE_TYPE =3D UEFI_APPLICATION + VERSION_STRING =3D 0.1 + ENTRY_POINT =3D UefiMain + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D 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/UefiMemoryAll= ocationLib.inf DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + RngLib|MdePkg/Library/DxeRngLib/DxeRngLib.inf =20 [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 =20 MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf MdeModulePkg/Logo/Logo.inf --=20 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#80878): https://edk2.groups.io/g/devel/message/80878 Mute This Topic: https://groups.io/mt/85744131/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-