From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f169.google.com (mail-pl1-f169.google.com [209.85.214.169]) by mx.groups.io with SMTP id smtpd.web12.1097.1639332586712612457 for ; Sun, 12 Dec 2021 10:09:46 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@nuviainc-com.20210112.gappssmtp.com header.s=20210112 header.b=KpYkbUFv; spf=pass (domain: nuviainc.com, ip: 209.85.214.169, mailfrom: rebecca@nuviainc.com) Received: by mail-pl1-f169.google.com with SMTP id m24so9653929pls.10 for ; Sun, 12 Dec 2021 10:09:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuviainc-com.20210112.gappssmtp.com; s=20210112; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding:content-language; bh=XOQvh9QpUuLG/1VK85ARiGypa4d9qQg92HpnLWOUIxI=; b=KpYkbUFvyTTLWnrxZvXvSpPmA19M/GDs9AWaar5ggtKar6dr/z+2Rb7iy0DOurY1FV jIuZy9wnBiVZKPfX+Jx963EbLHOoanIdCHBx16VgrIaaJtdRlUfeawfzBXE3HiJ0SGp6 kxVVwGOROekM4nPvrDn1xntVaMgOHL9y+LrYQE7TYvEr6gxU67R8J/YPgdUoopt2Z0qZ zBeJjGaMOgLbe4Rrp3+2HFRMVdUGeiPuwFjeYpd67OzRTzdRyLM556OKiygIe/CeBo09 aeWju894ielwsyJJYiXnmGtDy7BjQHBwnJY8DQ/NJDQbNp6faDv0K6T6LErQ/+NdZWfx lU1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=XOQvh9QpUuLG/1VK85ARiGypa4d9qQg92HpnLWOUIxI=; b=Qq984eIU42+XYRq4G+59xFamM1xOULBS08HRQAY8fH3AQn4aQjulhTW2PoNKXbUTyb g4pdyKOcVC1unJ6QrC0wtP+b/rIL+h8ZK5q0K1od/eU0cONGhTpjt/AUzIx3U88sPl9s bh/R3JWZ8JNi+qp3mxeT2u4lxICnGW9/1cYXkpi0kR0O3HbMIX6RPIk6/7KdZTMzuimN KFhWp9O4N5bhW3EGyKyEkgml2R4zQI5tKFi2MOp4WbS9hByitn/tYcZ5MvUsJJtcUpFA GeJJD+To1j58fFRUJkZwKve+53H+r24tbg5HSBRFqJUc45L8syeobuWhUQPHg/xqryxW z8uA== X-Gm-Message-State: AOAM531k1e5ONHaI4g15CrTYxEcCS0Uf1y/Pi/CuR6c/UsIV979om6QI nz5CFpnFgTcPvRb5SZl+0b+qwA== X-Google-Smtp-Source: ABdhPJzNG4Hp7MjJdhtTJu3QgWDMsUwDhjmlh3eq0R5rqzIAQrlERSq+a+QCSl9X3aQgCjIi+RLhOA== X-Received: by 2002:a17:90b:3b8e:: with SMTP id pc14mr37977931pjb.129.1639332586066; Sun, 12 Dec 2021 10:09:46 -0800 (PST) Return-Path: Received: from ?IPv6:2601:681:4300:69e:9e7b:efff:fe2b:884c? ([2601:681:4300:69e:9e7b:efff:fe2b:884c]) by smtp.gmail.com with ESMTPSA id t66sm9780115pfd.150.2021.12.12.10.09.44 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 12 Dec 2021 10:09:45 -0800 (PST) Subject: Re: [edk2-devel] [PATCH v3 1/1] MdeModulePkg: Add MpServicesTest application to exercise MP Services To: devel@edk2.groups.io, Sami Mujawar , Ard Biesheuvel , Gerd Hoffmann , Samer El-Haj-Mahmoud , Leif Lindholm , Jian J Wang , Liming Gao , nd References: <20211105203112.24313-1-rebecca@nuviainc.com> <16BF3806DE6E3547.21850@groups.io> From: "Rebecca Cran" Message-ID: <146df9c7-602f-71b0-ba58-548ae34ffbfd@nuviainc.com> Date: Sun, 12 Dec 2021 11:09:43 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0 MIME-Version: 1.0 In-Reply-To: <16BF3806DE6E3547.21850@groups.io> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US 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 >> >> 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 >>> --- >>>   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.
>>> +    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 = 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.
>>> +# >>> +#  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. > > > > >