From nobody Thu May 2 16:59:33 2024 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+84662+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+84662+1787277+3901457@groups.io ARC-Seal: i=1; a=rsa-sha256; t=1639332540; cv=none; d=zohomail.com; s=zohoarc; b=KEVN0Kqb/5TIIrGJtdwS4NBtnVLEVnfDq6/XHvy0Jjo+RGIwc1jXWPr+Dk4UwT86VguXUb+u06e/ntpWP03RPUxI2TgS++ehLKNp0/M8XwBW5jKx0JhqUIvqX00BIP7aov89Dfbikv5xOnXrGWXHYyxb5eJ0PnLI1TxtirzirlE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1639332540; 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=PyuxaCNIt6l8sjKOJgXcNEtQruVszga0IIjlZm2gZXg=; b=kyqFRKMFZsLUc/JSltCtUschsWeRw8vpVNayYBe2XTP5UW416FsYTaf7JrTBKZfK9KaBJojVCZ24SKNHASaGq2bmqVGu00kWbWh8LqVLt06a0iEszLYwfAQb0NrylEuzQ/i0AuMxyBeVOk2rcrSfxNKTJ4GZA7sjaumh0PJqmJs= 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+84662+1787277+3901457@groups.io Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1639332540425961.0884730639948; Sun, 12 Dec 2021 10:09:00 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id ElepYY1788612xLFEfJ9RYhR; Sun, 12 Dec 2021 10:09:00 -0800 X-Received: from mail-pf1-f172.google.com (mail-pf1-f172.google.com [209.85.210.172]) by mx.groups.io with SMTP id smtpd.web09.1084.1639332539317998534 for ; Sun, 12 Dec 2021 10:08:59 -0800 X-Received: by mail-pf1-f172.google.com with SMTP id 8so13054908pfo.4 for ; Sun, 12 Dec 2021 10:08:59 -0800 (PST) X-Gm-Message-State: UmsP276ln7KxDqv1zjsL5LeLx1787277AA= X-Google-Smtp-Source: ABdhPJwQeCuYyX4JDgwXkvPd2cPuO9rwSKfklwl05szC0dwk2VuVw4MCFTcJnNB7MGyB1WOT2G5/bw== X-Received: by 2002:a63:5651:: with SMTP id g17mr48476080pgm.275.1639332538010; Sun, 12 Dec 2021 10:08:58 -0800 (PST) X-Received: from linbox.ba.nuviainc.com ([2601:681:4300:69e:9e7b:efff:fe2b:884c]) by smtp.gmail.com with ESMTPSA id a23sm7820989pgh.35.2021.12.12.10.08.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 12 Dec 2021 10:08:57 -0800 (PST) From: "Rebecca Cran" To: devel@edk2.groups.io, Ard Biesheuvel , Gerd Hoffmann , Samer El-Haj-Mahmoud , Leif Lindholm , Jian J Wang , Liming Gao , nd , Sami Mujawar Cc: Rebecca Cran Subject: [edk2-devel] [PATCH v4 1/1] MdeModulePkg: Add MpServicesTest application to exercise MP Services Date: Sun, 12 Dec 2021 11:08:46 -0700 Message-Id: <20211212180846.6563-2-rebecca@nuviainc.com> In-Reply-To: <20211212180846.6563-1-rebecca@nuviainc.com> References: <20211212180846.6563-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=1639332540; bh=9shuQPtbozlN1XOiJyJ0GxwNWy7IA+JEi1mKerWEX9k=; h=Cc:Date:From:Reply-To:Subject:To; b=G/FUZoaLtHQVfVzjRTCAgTl3uqaciT5MYkhgdhWUtO8XSKxUGig8uxXwzbu/63O15rH xts1I+jkanRJGl5v4zD1BI07VSX+nmfCl5ksz8Yxl1e9uLNzFtdeFTDj/agPZJmUj/BjY iIjSzjgb9hXfqNKWyzKG5gAZU/7BcTHN4NU= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1639332541802100001 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 Reviewed-by: Sami Mujawar --- MdeModulePkg/Application/MpServicesTest/MpServicesTest.c | 422 +++++++++= +++++++++++ MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf | 38 ++ MdeModulePkg/MdeModulePkg.dsc | 2 + 3 files changed, 462 insertions(+) diff --git a/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c b/Mde= ModulePkg/Application/MpServicesTest/MpServicesTest.c new file mode 100644 index 000000000000..933813e19e05 --- /dev/null +++ b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c @@ -0,0 +1,422 @@ +/** @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 + +/** 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 + ); + + if (EFI_ERROR (Status)) { + Print (L"failed: %r\n", Status); + return; + } else { + Print (L"done.\n"); + } + + 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 + ); + if (EFI_ERROR (Status)) { + Print (L"failed: %r\n", Status); + return; + } else { + Print (L"done.\n"); + } +} + +/** 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); + if (EFI_ERROR (Status)) { + Print (L"failed: %r\n", Status); + return; + } else { + Print (L"done.\n"); + } + + 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 + ); + if (EFI_ERROR (Status)) { + Print (L"failed: %r\n", Status); + return; + } else { + Print (L"done.\n"); + } +} + +/** 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); + if (EFI_ERROR (Status)) { + Print (L"failed: %r\n", Status); + return; + } else { + Print (L"done.\n"); + } + } + + 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); + if (EFI_ERROR (Status)) { + Print (L"failed: %r\n", Status); + return; + } else { + Print (L"done.\n"); + } + } +} + +/** + 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); + + 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 (#84662): https://edk2.groups.io/g/devel/message/84662 Mute This Topic: https://groups.io/mt/87681342/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-