<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;
      charset=windows-1252">
  </head>
  <body>
    <p><font face="monospace">Sami,</font></p>
    <p><font face="monospace"><br>
      </font></p>
    <p><font face="monospace">I don't see your review. Did you review
        this, or just the separate patch to add EFI_MP_SERVICES_PROTOCOL
        for AArch64?</font></p>
    <p><font face="monospace"><br>
      </font></p>
    <p><font face="monospace">-- <br>
        Rebecca Cran<br>
      </font></p>
    <p><font face="monospace"></font><br>
    </p>
    <div class="moz-cite-prefix">On 10/16/21 12:54 AM, Sami Mujawar
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:AS8PR08MB680637AAF1C7296853DB68B584BA9@AS8PR08MB6806.eurprd08.prod.outlook.com">
      <meta http-equiv="Content-Type" content="text/html;
        charset=windows-1252">
      <div style="color: rgb(33, 33, 33); background-color: rgb(255,
        255, 255);" dir="auto">
        Hi Rebecca,</div>
      <div style="color: rgb(33, 33, 33); background-color: rgb(255,
        255, 255);" dir="auto">
        <br>
      </div>
      <div style="color: rgb(33, 33, 33); background-color: rgb(255,
        255, 255);" dir="auto">
        I will review this next week.</div>
      <div style="color: rgb(33, 33, 33); background-color: rgb(255,
        255, 255);" dir="auto">
        <br>
      </div>
      <div style="color: rgb(33, 33, 33); background-color: rgb(255,
        255, 255);" dir="auto">
        Regard</div>
      <div style="color: rgb(33, 33, 33); background-color: rgb(255,
        255, 255);" dir="auto">
        <br>
      </div>
      <div style="color: rgb(33, 33, 33); background-color: rgb(255,
        255, 255);" dir="auto">
        Sami Mujawar</div>
      <div id="ms-outlook-mobile-signature" dir="auto"><br>
      </div>
      <div id="id-063f6e36-37ac-47e6-a33c-db8ce61353cc"
        class="ms-outlook-mobile-reference-message">
        <hr style="display:inline-block;width:98%" tabindex="-1">
        <div id="divRplyFwdMsg"><strong>From:</strong> Rebecca Cran
          <a class="moz-txt-link-rfc2396E" href="mailto:rebecca@nuviainc.com"><rebecca@nuviainc.com></a><br>
          <strong>Sent:</strong> Saturday, 16 October 2021, 7:33 am<br>
          <strong>To:</strong> <a class="moz-txt-link-abbreviated" href="mailto:devel@edk2.groups.io">devel@edk2.groups.io</a>; Jian J Wang; Liming
          Gao<br>
          <strong>Cc:</strong> Ard Biesheuvel; Samer El-Haj-Mahmoud;
          Leif Lindholm; Sami Mujawar; Gerd Hoffmann<br>
          <strong>Subject:</strong> Re: [edk2-devel] [PATCH v2 1/1]
          MdeModulePkg: Add MpServicesTest application to exercise MP
          Services<br>
        </div>
        <br>
        <meta name="Generator" content="Microsoft Exchange Server">
        <!-- converted from text -->
        <style>.EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; }</style><font
          size="2"><span style="font-size:11pt;">
            <div class="PlainText">(cc Leif, Ard, Sami, Samer, Gerd)<br>
              <br>
              <br>
              Could someone review this please?<br>
              <br>
              <br>
              -- <br>
              Rebecca Cran<br>
              <br>
              <br>
              On 9/20/21 9:47 AM, Rebecca Cran via groups.io wrote:<br>
              > Add a new MpServicesTest application under
              MdeModulePkg/Application that<br>
              > exercises the EFI_MP_SERVICES_PROTOCOL.<br>
              ><br>
              > Signed-off-by: Rebecca Cran
              <a class="moz-txt-link-rfc2396E" href="mailto:rebecca@nuviainc.com"><rebecca@nuviainc.com></a><br>
              > ---<br>
              >  
              MdeModulePkg/Application/MpServicesTest/MpServicesTest.c  
              | 433 ++++++++++++++++++++<br>
              >  
              MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf
              |  38 ++<br>
              >  
              MdeModulePkg/MdeModulePkg.dsc                             
              |   2 +<br>
              >   3 files changed, 473 insertions(+)<br>
              ><br>
              > diff --git
              a/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c
              b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c<br>
              > new file mode 100644<br>
              > index 000000000000..4eb06e6b7cbd<br>
              > --- /dev/null<br>
              > +++
              b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c<br>
              > @@ -0,0 +1,433 @@<br>
              > +/** @file<br>
              > +<br>
              > +    Copyright (c) 2021, NUVIA Inc. All rights
              reserved.<BR><br>
              > +    SPDX-License-Identifier: BSD-2-Clause-Patent<br>
              > +**/<br>
              > +<br>
              > +#include <Uefi.h><br>
              > +#include <Library/DebugLib.h><br>
              > +#include <Library/RngLib.h><br>
              > +#include <Library/UefiBootServicesTableLib.h><br>
              > +#include <Library/UefiLib.h><br>
              > +#include <Pi/PiMultiPhase.h><br>
              > +#include <Protocol/MpService.h><br>
              > +<br>
              > +#define MAX_RANDOM_PROCESSOR_RETRIES 10<br>
              > +<br>
              > +#define AP_STARTUP_TEST_TIMEOUT_US  50000<br>
              > +#define INFINITE_TIMEOUT            0<br>
              > +<br>
              > +#define RETURN_IF_EFI_ERROR(x)   \<br>
              > +  if (EFI_ERROR (x)) {           \<br>
              > +    Print (L"failed: %r\n", x);  \<br>
              > +    return;                      \<br>
              > +  }                              \<br>
              > +  else {                         \<br>
              > +    Print (L"done.\n");          \<br>
              > +  }<br>
              > +<br>
              > +/** The procedure to run with the MP Services
              interface.<br>
              > +<br>
              > +  @param Buffer The procedure argument.<br>
              > +<br>
              > +**/<br>
              > +STATIC<br>
              > +VOID<br>
              > +EFIAPI<br>
              > +ApFunction (<br>
              > +  IN OUT VOID *Buffer<br>
              > +  )<br>
              > +{<br>
              > +}<br>
              > +<br>
              > +/** Displays information returned from MP Services
              Protocol.<br>
              > +<br>
              > +  @param Mp  The MP Services Protocol<br>
              > +<br>
              > +  @return The number of CPUs in the system.<br>
              > +<br>
              > +**/<br>
              > +STATIC<br>
              > +UINTN<br>
              > +PrintProcessorInformation (<br>
              > +  IN EFI_MP_SERVICES_PROTOCOL *Mp<br>
              > +  )<br>
              > +{<br>
              > +  EFI_STATUS                 Status;<br>
              > +  EFI_PROCESSOR_INFORMATION  CpuInfo;<br>
              > +  UINTN                      Index;<br>
              > +  UINTN                      NumCpu;<br>
              > +  UINTN                      NumEnabledCpu;<br>
              > +<br>
              > +  Status = Mp->GetNumberOfProcessors (Mp,
              &NumCpu, &NumEnabledCpu);<br>
              > +  if (EFI_ERROR (Status)) {<br>
              > +    Print (L"GetNumberOfProcessors failed: %r\n",
              Status);<br>
              > +  } else {<br>
              > +    Print (L"Number of CPUs: %ld, Enabled: %d\n",
              NumCpu, NumEnabledCpu);<br>
              > +  }<br>
              > +<br>
              > +  for (Index = 0; Index < NumCpu; Index++) {<br>
              > +    Status = Mp->GetProcessorInfo (Mp,
              CPU_V2_EXTENDED_TOPOLOGY | Index, &CpuInfo);<br>
              > +    if (EFI_ERROR (Status)) {<br>
              > +      Print (L"GetProcessorInfo for Processor %d
              failed: %r\n", Index, Status);<br>
              > +    } else {<br>
              > +      Print (<br>
              > +        L"Processor %d:\n"<br>
              > +        L"\tID: %016lx\n"<br>
              > +        L"\tStatus: %s | ",<br>
              > +        Index,<br>
              > +        CpuInfo.ProcessorId,<br>
              > +        (CpuInfo.StatusFlag &
              PROCESSOR_AS_BSP_BIT) ? L"BSP" : L"AP"<br>
              > +        );<br>
              > +<br>
              > +      Print (L"%s | ", (CpuInfo.StatusFlag &
              PROCESSOR_ENABLED_BIT) ? L"Enabled" : L"Disabled");<br>
              > +      Print (L"%s\n", (CpuInfo.StatusFlag &
              PROCESSOR_HEALTH_STATUS_BIT) ? L"Healthy" : L"Faulted");<br>
              > +<br>
              > +      Print (<br>
              > +        L"\tLocation: Package %d, Core %d, Thread
              %d\n"<br>
              > +        L"\tExtended Information: Package %d, Module
              %d, Tile %d, Die %d, Core %d, Thread %d\n\n",<br>
              > +        CpuInfo.Location.Package,<br>
              > +        CpuInfo.Location.Core,<br>
              > +        CpuInfo.Location.Thread,<br>
              > +       
              CpuInfo.ExtendedInformation.Location2.Package,<br>
              > +       
              CpuInfo.ExtendedInformation.Location2.Module,<br>
              > +        CpuInfo.ExtendedInformation.Location2.Tile,<br>
              > +        CpuInfo.ExtendedInformation.Location2.Die,<br>
              > +        CpuInfo.ExtendedInformation.Location2.Core,<br>
              > +        CpuInfo.ExtendedInformation.Location2.Thread<br>
              > +        );<br>
              > +    }<br>
              > +  }<br>
              > +<br>
              > +  return NumCpu;<br>
              > +}<br>
              > +<br>
              > +/** Returns the index of an enabled AP selected at
              random.<br>
              > +<br>
              > +  @param Mp             The MP Services Protocol.<br>
              > +  @param ProcessorIndex The index of a random
              enabled AP.<br>
              > +<br>
              > +  @retval EFI_SUCCESS   An enabled processor was
              found and returned.<br>
              > +  @retval EFI_NOT_FOUND A processor was unable to be
              selected.<br>
              > +<br>
              > +**/<br>
              > +STATIC<br>
              > +EFI_STATUS<br>
              > +GetRandomEnabledProcessorIndex (<br>
              > +  IN EFI_MP_SERVICES_PROTOCOL *Mp,<br>
              > +  OUT UINTN *ProcessorIndex<br>
              > +  )<br>
              > +{<br>
              > +  UINTN                      Index;<br>
              > +  UINTN                      IndexOfEnabledCpu;<br>
              > +  UINTN                      NumCpus;<br>
              > +  UINTN                      NumEnabledCpus;<br>
              > +  UINTN                      IndexOfEnabledCpuToUse;<br>
              > +  UINT16                     RandomNumber;<br>
              > +  BOOLEAN                    Success;<br>
              > +  EFI_STATUS                 Status;<br>
              > +  EFI_PROCESSOR_INFORMATION  CpuInfo;<br>
              > +<br>
              > +  IndexOfEnabledCpu = 0;<br>
              > +<br>
              > +  Success = GetRandomNumber16 (&RandomNumber);<br>
              > +  ASSERT (Success == TRUE);<br>
              > +<br>
              > +  Status = Mp->GetNumberOfProcessors (Mp,
              &NumCpus, &NumEnabledCpus);<br>
              > +  ASSERT_EFI_ERROR (Status);<br>
              > +<br>
              > +  if (NumEnabledCpus == 1) {<br>
              > +    Print (L"All APs are disabled\n");<br>
              > +    return EFI_NOT_FOUND;<br>
              > +  }<br>
              > +<br>
              > +  IndexOfEnabledCpuToUse = RandomNumber %
              NumEnabledCpus;<br>
              > +<br>
              > +  for (Index = 0; Index < NumCpus; Index++) {<br>
              > +    Status = Mp->GetProcessorInfo (Mp, Index,
              &CpuInfo);<br>
              > +    ASSERT_EFI_ERROR (Status);<br>
              > +    if ((CpuInfo.StatusFlag &
              PROCESSOR_ENABLED_BIT) &&<br>
              > +        !(CpuInfo.StatusFlag &
              PROCESSOR_AS_BSP_BIT)) {<br>
              > +      if (IndexOfEnabledCpuToUse ==
              IndexOfEnabledCpu) {<br>
              > +        *ProcessorIndex = Index;<br>
              > +        Status = EFI_SUCCESS;<br>
              > +        break;<br>
              > +      }<br>
              > +<br>
              > +      IndexOfEnabledCpu++;<br>
              > +    }<br>
              > +  }<br>
              > +<br>
              > +  if (Index == NumCpus) {<br>
              > +    Status = EFI_NOT_FOUND;<br>
              > +  }<br>
              > +<br>
              > +  return Status;<br>
              > +}<br>
              > +<br>
              > +/** Tests for the StartupThisAP function.<br>
              > +<br>
              > +  @param Mp The MP Services Protocol.<br>
              > +<br>
              > +**/<br>
              > +STATIC<br>
              > +VOID<br>
              > +StartupThisApTests (<br>
              > +  IN EFI_MP_SERVICES_PROTOCOL *Mp<br>
              > +  )<br>
              > +{<br>
              > +  EFI_STATUS  Status;<br>
              > +  UINTN       ProcessorIndex;<br>
              > +  UINT32      Retries;<br>
              > +<br>
              > +  Retries = 0;<br>
              > +<br>
              > +  do {<br>
              > +    Status = GetRandomEnabledProcessorIndex (Mp,
              &ProcessorIndex);<br>
              > +  } while (EFI_ERROR (Status) && Retries++
              < MAX_RANDOM_PROCESSOR_RETRIES);<br>
              > +<br>
              > +  if (EFI_ERROR (Status)) {<br>
              > +    return;<br>
              > +  }<br>
              > +<br>
              > +  Print (<br>
              > +    L"StartupThisAP on Processor %d with 0
              (infinite) timeout...",<br>
              > +    ProcessorIndex<br>
              > +    );<br>
              > +<br>
              > +  Status = Mp->StartupThisAP (<br>
              > +    Mp,<br>
              > +    ApFunction,<br>
              > +    ProcessorIndex,<br>
              > +    NULL,<br>
              > +    INFINITE_TIMEOUT,<br>
              > +    NULL,<br>
              > +    NULL<br>
              > +    );<br>
              > +<br>
              > +  RETURN_IF_EFI_ERROR (Status);<br>
              > +<br>
              > +  Retries = 0;<br>
              > +<br>
              > +  do {<br>
              > +    Status = GetRandomEnabledProcessorIndex (Mp,
              &ProcessorIndex);<br>
              > +  } while (EFI_ERROR (Status) && Retries++
              < MAX_RANDOM_PROCESSOR_RETRIES);<br>
              > +<br>
              > +  if (EFI_ERROR (Status)) {<br>
              > +    return;<br>
              > +  }<br>
              > +<br>
              > +  Print (<br>
              > +    L"StartupThisAP on Processor %d with %dms
              timeout...",<br>
              > +    ProcessorIndex,<br>
              > +    AP_STARTUP_TEST_TIMEOUT_US / 1000<br>
              > +    );<br>
              > +  Status = Mp->StartupThisAP (<br>
              > +                 Mp,<br>
              > +                 ApFunction,<br>
              > +                 ProcessorIndex,<br>
              > +                 NULL,<br>
              > +                 AP_STARTUP_TEST_TIMEOUT_US,<br>
              > +                 NULL,<br>
              > +                 NULL<br>
              > +                 );<br>
              > +  RETURN_IF_EFI_ERROR (Status);<br>
              > +}<br>
              > +<br>
              > +/** Tests for the StartupAllAPs function.<br>
              > +<br>
              > +  @param Mp      The MP Services Protocol.<br>
              > +  @param NumCpus The number of CPUs in the system.<br>
              > +<br>
              > +**/<br>
              > +STATIC<br>
              > +VOID<br>
              > +StartupAllAPsTests (<br>
              > +  IN EFI_MP_SERVICES_PROTOCOL *Mp,<br>
              > +  IN UINTN NumCpus<br>
              > +  )<br>
              > +{<br>
              > +  EFI_STATUS  Status;<br>
              > +  UINTN       Timeout;<br>
              > +<br>
              > +  Print (L"Running with SingleThread FALSE, 0
              (infinite) timeout...");<br>
              > +  Status = Mp->StartupAllAPs (Mp, ApFunction,
              FALSE, NULL, INFINITE_TIMEOUT, NULL, NULL);<br>
              > +  RETURN_IF_EFI_ERROR (Status);<br>
              > +<br>
              > +  Timeout = NumCpus * AP_STARTUP_TEST_TIMEOUT_US;<br>
              > +<br>
              > +  Print (L"Running with SingleThread TRUE, %dms
              timeout...", Timeout / 1000);<br>
              > +  Status = Mp->StartupAllAPs (<br>
              > +                 Mp,<br>
              > +                 ApFunction,<br>
              > +                 TRUE,<br>
              > +                 NULL,<br>
              > +                 Timeout,<br>
              > +                 NULL,<br>
              > +                 NULL<br>
              > +                 );<br>
              > +  RETURN_IF_EFI_ERROR (Status);<br>
              > +}<br>
              > +<br>
              > +/** Tests for the EnableDisableAP function.<br>
              > +<br>
              > +  @param Mp      The MP Services Protocol.<br>
              > +  @param NumCpus The number of CPUs in the system.<br>
              > +<br>
              > +**/<br>
              > +STATIC<br>
              > +VOID<br>
              > +EnableDisableAPTests (<br>
              > +  IN EFI_MP_SERVICES_PROTOCOL *Mp,<br>
              > +  IN UINTN                    NumCpus<br>
              > +  )<br>
              > +{<br>
              > +  EFI_STATUS  Status;<br>
              > +  UINTN       Index;<br>
              > +  UINT32      HealthFlag;<br>
              > +<br>
              > +  HealthFlag = 0;<br>
              > +<br>
              > +  for (Index = 1; Index < NumCpus; Index++) {<br>
              > +    Print (L"Disabling Processor %d with HealthFlag
              faulted...", Index);<br>
              > +    Status = Mp->EnableDisableAP (Mp, Index,
              FALSE, &HealthFlag);<br>
              > +    RETURN_IF_EFI_ERROR (Status);<br>
              > +  }<br>
              > +<br>
              > +  HealthFlag = PROCESSOR_HEALTH_STATUS_BIT;<br>
              > +<br>
              > +  for (Index = 1; Index < NumCpus; Index++) {<br>
              > +    Print (L"Enabling Processor %d with HealthFlag
              healthy...", Index);<br>
              > +    Status = Mp->EnableDisableAP (Mp, Index,
              TRUE, &HealthFlag);<br>
              > +    RETURN_IF_EFI_ERROR (Status);<br>
              > +  }<br>
              > +}<br>
              > +<br>
              > +/** Tests for the SwitchBSP function.<br>
              > +<br>
              > +  @param Mp      The MP Services Protocol.<br>
              > +  @param NumCpus The number of CPUs in the system.<br>
              > +<br>
              > +**/<br>
              > +STATIC<br>
              > +VOID<br>
              > +SwitchBSPTests (<br>
              > +  IN EFI_MP_SERVICES_PROTOCOL *Mp,<br>
              > +  IN UINTN                    NumCpus<br>
              > +  )<br>
              > +{<br>
              > +  EFI_STATUS  Status;<br>
              > +  UINTN       Index;<br>
              > +<br>
              > +  for (Index = 1; Index < NumCpus; Index++) {<br>
              > +    Print (L"Switching BSP to Processor %d with
              EnableOldBSP FALSE...", Index);<br>
              > +    Status = Mp->SwitchBSP (Mp, Index, FALSE);<br>
              > +    RETURN_IF_EFI_ERROR (Status);<br>
              > +  }<br>
              > +<br>
              > +  for (Index = 0; Index < NumCpus; Index++) {<br>
              > +    Print (L"Switching BSP to Processor %d with
              EnableOldBSP TRUE...", Index);<br>
              > +    Status = Mp->SwitchBSP (Mp, Index, TRUE);<br>
              > +    RETURN_IF_EFI_ERROR (Status);<br>
              > +  }<br>
              > +}<br>
              > +<br>
              > +/**<br>
              > +  The user Entry Point for Application. The user
              code starts with this function<br>
              > +  as the real entry point for the application.<br>
              > +<br>
              > +  @param[in] ImageHandle    The firmware allocated
              handle for the EFI image.<br>
              > +  @param[in] SystemTable    A pointer to the EFI
              System Table.<br>
              > +<br>
              > +  @retval EFI_SUCCESS       The entry point is
              executed successfully.<br>
              > +  @retval other             Some error occurs when
              executing this entry point.<br>
              > +<br>
              > +**/<br>
              > +EFI_STATUS<br>
              > +EFIAPI<br>
              > +UefiMain (<br>
              > +  IN EFI_HANDLE        ImageHandle,<br>
              > +  IN EFI_SYSTEM_TABLE  *SystemTable<br>
              > +  )<br>
              > +{<br>
              > +  EFI_STATUS                Status;<br>
              > +  EFI_MP_SERVICES_PROTOCOL  *Mp;<br>
              > +  EFI_HANDLE                *pHandle;<br>
              > +  UINTN                     HandleCount;<br>
              > +  UINTN                     BspId;<br>
              > +  UINTN                     NumCpus;<br>
              > +  UINTN                     Index;<br>
              > +<br>
              > +  pHandle     = NULL;<br>
              > +  HandleCount = 0;<br>
              > +  BspId = 0;<br>
              > +<br>
              > +  Status = gBS->LocateHandleBuffer (<br>
              > +                  ByProtocol,<br>
              > +                  &gEfiMpServiceProtocolGuid,<br>
              > +                  NULL,<br>
              > +                  &HandleCount,<br>
              > +                  &pHandle<br>
              > +                  );<br>
              > +<br>
              > +  if (EFI_ERROR (Status)) {<br>
              > +    Print (L"Failed to locate
              EFI_MP_SERVICES_PROTOCOL (%r). Not installed on
              platform?\n", Status);<br>
              > +    return EFI_NOT_FOUND;<br>
              > +  }<br>
              > +<br>
              > +  for (Index = 0; Index < HandleCount; Index++) {<br>
              > +    Status = gBS->OpenProtocol (<br>
              > +                    *pHandle,<br>
              > +                    &gEfiMpServiceProtocolGuid,<br>
              > +                    (VOID **)&Mp,<br>
              > +                    NULL,<br>
              > +                    gImageHandle,<br>
              > +                    EFI_OPEN_PROTOCOL_GET_PROTOCOL<br>
              > +                    );<br>
              > +<br>
              > +    if (EFI_ERROR (Status)) {<br>
              > +      return Status;<br>
              > +    }<br>
              > +<br>
              > +    pHandle++;<br>
              > +  }<br>
              > +<br>
              > +  Print (L"Exercising WhoAmI\n\n");<br>
              > +  Status = Mp->WhoAmI (Mp, &BspId);<br>
              > +  if (EFI_ERROR (Status)) {<br>
              > +    Print (L"WhoAmI failed: %r\n", Status);<br>
              > +    return Status;<br>
              > +  } else {<br>
              > +    Print (L"WhoAmI: %016lx\n", BspId);<br>
              > +  }<br>
              > +<br>
              > +  Print (L"\n");<br>
              > +  Print (<br>
              > +    L"Exercising GetNumberOfProcessors and
              GetProcessorInformation with "<br>
              > +    L"CPU_V2_EXTENDED_TOPOLOGY\n\n"<br>
              > +    );<br>
              > +  NumCpus = PrintProcessorInformation (Mp);<br>
              > +  if (NumCpus < 2) {<br>
              > +    Print (L"UP system found. Not running further
              tests.\n");<br>
              > +    return EFI_INVALID_PARAMETER;<br>
              > +  }<br>
              > +<br>
              > +  Print (L"\n");<br>
              > +  Print (L"Exercising StartupThisAP:\n\n");<br>
              > +  StartupThisApTests (Mp);<br>
              > +<br>
              > +  Print (L"\n");<br>
              > +  Print (L"Exercising StartupAllAPs:\n\n");<br>
              > +  StartupAllAPsTests (Mp, NumCpus);<br>
              > +<br>
              > +  Print (L"\n");<br>
              > +  Print (L"Exercising EnableDisableAP:\n\n");<br>
              > +  EnableDisableAPTests (Mp, NumCpus);<br>
              > +<br>
              > +  Print (L"\n");<br>
              > +  Print (L"Exercising SwitchBSP\n\n");<br>
              > +  SwitchBSPTests (Mp, NumCpus);<br>
              > +<br>
              > +  gBS->CloseProtocol (pHandle,
              &gEfiMpServiceProtocolGuid, gImageHandle, NULL);<br>
              > +  return EFI_SUCCESS;<br>
              > +}<br>
              > diff --git
              a/MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf
b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf<br>
              > new file mode 100644<br>
              > index 000000000000..8a21ca70d8fa<br>
              > --- /dev/null<br>
              > +++
              b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf<br>
              > @@ -0,0 +1,38 @@<br>
              > +## @file<br>
              > +#  UEFI Application to exercise
              EFI_MP_SERVICES_PROTOCOL.<br>
              > +#<br>
              > +#  Copyright (c) 2021, NUVIA Inc. All rights
              reserved.<BR><br>
              > +#<br>
              > +#  SPDX-License-Identifier: BSD-2-Clause-Patent<br>
              > +#<br>
              > +##<br>
              > +<br>
              > +[Defines]<br>
              > +  INF_VERSION                    = 1.29<br>
              > +  BASE_NAME                      = MpServicesTest<br>
              > +  FILE_GUID                      =
              43e9defa-7209-4b0d-b136-cc4ca02cb469<br>
              > +  MODULE_TYPE                    = UEFI_APPLICATION<br>
              > +  VERSION_STRING                 = 0.1<br>
              > +  ENTRY_POINT                    = UefiMain<br>
              > +<br>
              > +#<br>
              > +# The following information is for reference only
              and not required by the build tools.<br>
              > +#<br>
              > +#  VALID_ARCHITECTURES           = IA32 X64 AARCH64<br>
              > +#<br>
              > +<br>
              > +[Sources]<br>
              > +  MpServicesTest.c<br>
              > +<br>
              > +[Packages]<br>
              > +  MdePkg/MdePkg.dec<br>
              > +<br>
              > +[LibraryClasses]<br>
              > +  BaseLib<br>
              > +  RngLib<br>
              > +  UefiApplicationEntryPoint<br>
              > +  UefiLib<br>
              > +<br>
              > +[Protocols]<br>
              > +  gEfiMpServiceProtocolGuid    ## CONSUMES<br>
              > +<br>
              > diff --git a/MdeModulePkg/MdeModulePkg.dsc
              b/MdeModulePkg/MdeModulePkg.dsc<br>
              > index b1d83461865e..1cf5ccd30d40 100644<br>
              > --- a/MdeModulePkg/MdeModulePkg.dsc<br>
              > +++ b/MdeModulePkg/MdeModulePkg.dsc<br>
              > @@ -164,6 +164,7 @@<br>
              >    
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf<br>
              >    
              DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf<br>
              >    
              FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf<br>
              > +  RngLib|MdePkg/Library/DxeRngLib/DxeRngLib.inf<br>
              >   <br>
              >   [LibraryClasses.common.MM_STANDALONE]<br>
              >    
              HobLib|MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf<br>
              > @@ -215,6 +216,7 @@<br>
              >    
              MdeModulePkg/Application/HelloWorld/HelloWorld.inf<br>
              >    
              MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf<br>
              >    
              MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf<br>
              > + 
              MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf<br>
              >   <br>
              >     MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf<br>
              >     MdeModulePkg/Logo/Logo.inf<br>
            </div>
          </span></font><br>
      </div>
    </blockquote>
  </body>
</html>


 <div width="1" style="color:white;clear:both">_._,_._,_</div> <hr>   Groups.io Links:<p>   You receive all messages sent to this group.    <p> <a target="_blank" href="https://edk2.groups.io/g/devel/message/83202">View/Reply Online (#83202)</a> |    |  <a target="_blank" href="https://groups.io/mt/86366990/1813853">Mute This Topic</a>  | <a href="https://edk2.groups.io/g/devel/post">New Topic</a><br>    <a href="https://edk2.groups.io/g/devel/editsub/1813853">Your Subscription</a> | <a href="mailto:devel+owner@edk2.groups.io">Contact Group Owner</a> |  <a href="https://edk2.groups.io/g/devel/unsub">Unsubscribe</a>  [edk2-devel-archive@redhat.com]<br> <div width="1" style="color:white;clear:both">_._,_._,_</div>