From: "Rebecca Cran" <rebecca@nuviainc.com>
To: devel@edk2.groups.io, Sami Mujawar <sami.mujawar@arm.com>,
Ard Biesheuvel <ardb+tianocore@kernel.org>,
Gerd Hoffmann <kraxel@redhat.com>,
Samer El-Haj-Mahmoud <samer.el-haj-mahmoud@arm.com>,
Leif Lindholm <leif@nuviainc.com>,
Jian J Wang <jian.j.wang@intel.com>,
Liming Gao <gaoliming@byosoft.com.cn>, nd <nd@arm.com>
Subject: Re: [edk2-devel] [PATCH v3 1/1] MdeModulePkg: Add MpServicesTest application to exercise MP Services
Date: Sun, 12 Dec 2021 11:09:43 -0700 [thread overview]
Message-ID: <146df9c7-602f-71b0-ba58-548ae34ffbfd@nuviainc.com> (raw)
In-Reply-To: <16BF3806DE6E3547.21850@groups.io>
I've fixed issues Uncrustify noted, and have submitted a v4 patch.
--
Rebecca Cran
On 12/9/21 3:53 PM, Rebecca Cran via groups.io wrote:
> Now that the edk2 tree is unfrozen, I'd like to get this committed.
>
> Could anyone else review it please, or if it's ready commit it?
>
>
> Thanks.
>
> Rebecca Cran
>
>
> On 11/10/21 11:06 AM, Sami Mujawar wrote:
>> Hi Rebecca,
>>
>> Thank you for the updated patch. These changes look good to me.
>>
>> The INF file mentions support for IA32 and X64 so it would be got to get
>> feedback for other architectures and from the MdeModulePkg maintainers.
>>
>> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
>>
>> Regards,
>>
>> Sami Mujawar
>>
>> On 05/11/2021 08:31 PM, Rebecca Cran wrote:
>>> Add a new MpServicesTest application under MdeModulePkg/Application
>>> that
>>> exercises the EFI_MP_SERVICES_PROTOCOL.
>>>
>>> Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
>>> ---
>>> MdeModulePkg/Application/MpServicesTest/MpServicesTest.c | 428
>>> ++++++++++++++++++++
>>> MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf | 38 ++
>>> MdeModulePkg/MdeModulePkg.dsc | 2 +
>>> 3 files changed, 468 insertions(+)
>>>
>>> diff --git
>>> a/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c
>>> b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c
>>> new file mode 100644
>>> index 000000000000..d066bdd530d5
>>> --- /dev/null
>>> +++ b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c
>>> @@ -0,0 +1,428 @@
>>> +/** @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
>>> +
>>> +
>>> +/** 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
>>> + );
>>> +
>>> + if (EFI_ERROR (Status)) {
>>> + Print (L"failed: %r\n", Status);
>>> + return;
>>> + }
>>> + else {
>>> + Print (L"done.\n");
>>> + }
>>> +
>>> + 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
>>> + );
>>> + 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 = Mp->StartupAllAPs (Mp, ApFunction, FALSE, NULL,
>>> INFINITE_TIMEOUT, NULL, NULL);
>>> + if (EFI_ERROR (Status)) {
>>> + Print (L"failed: %r\n", Status);
>>> + return;
>>> + }
>>> + else {
>>> + Print (L"done.\n");
>>> + }
>>> +
>>> + 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
>>> + );
>>> + 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 = 0;
>>> +
>>> + for (Index = 1; Index < NumCpus; Index++) {
>>> + Print (L"Disabling Processor %d with HealthFlag faulted...",
>>> Index);
>>> + Status = Mp->EnableDisableAP (Mp, Index, FALSE, &HealthFlag);
>>> + if (EFI_ERROR (Status)) {
>>> + Print (L"failed: %r\n", Status);
>>> + return;
>>> + }
>>> + else {
>>> + Print (L"done.\n");
>>> + }
>>> + }
>>> +
>>> + 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);
>>> + 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 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);
>>> +
>>> + 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
>>
>> IMPORTANT NOTICE: The contents of this email and any attachments are
>> confidential and may also be privileged. If you are not the intended
>> recipient, please notify the sender immediately and do not disclose
>> the contents to any other person, use it for any purpose, or store or
>> copy the information in any medium. Thank you.
>
>
>
>
>
prev parent reply other threads:[~2021-12-12 18:09 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-05 20:31 [PATCH v3 1/1] MdeModulePkg: Add MpServicesTest application to exercise MP Services Rebecca Cran
2021-11-10 18:06 ` Sami Mujawar
2021-11-10 18:16 ` Rebecca Cran
2021-12-09 22:53 ` Rebecca Cran
[not found] ` <16BF3806DE6E3547.21850@groups.io>
2021-12-12 18:09 ` Rebecca Cran [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=146df9c7-602f-71b0-ba58-548ae34ffbfd@nuviainc.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox