<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p><font face="monospace">No, I expect there to only ever be a
        single MP services instance.</font></p>
    <p><font face="monospace">I agree that the AP function should do
        something, but I'm hoping to get this initial implementation
        committed first.</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 12/29/21 20:21, Jeff Fan wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:2021123011214518968235@byosoft.com.cn">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <style>body { line-height: 1.5; }blockquote { margin-top: 0px; margin-bottom: 0px; margin-left: 0.5em; }body { font-size: 14px; font-family: "Microsoft YaHei UI"; color: rgb(0, 0, 0); line-height: 1.5; }</style>
      <div><span></span>Hi,Rebecca</div>
      <div><br>
      </div>
      <div>I'd like to give two comments on this patch.</div>
      <div><br>
      </div>
      <div>1,  <span style="background-color: transparent;">I don't
          think there are more than one MP services instances installed
          reuirement on one system.  X86 platform installed one MP
          service instance even on mutiple-sockets system. </span></div>
      <div><span style="background-color: transparent;">    For ARM
          platform, is there any requirement to handle multple MP
          services instance?</span></div>
      <div><span style="background-color: transparent;"><br>
        </span></div>
      <div><span style="background-color: transparent;">2,  AP function
          is </span><span style="background-color: transparent;">NULL
          implementation that could not make sure BSP recongized if APs
          run indeed.  You could simply update AP function to
          use one global variable seamphoere wrapped by lock
          protections.</span></div>
      <div>
        <div><span style="background-color: transparent;">    I think</span><span
            style="background-color: transparent;"> this patch is very
            good start to add MP test app in open source world.  This
            comment is only sugestion for your next plan. :-)</span></div>
      </div>
      <div><span style="background-color: transparent;"><br>
        </span></div>
      <div><span style="background-color: transparent;">Best Regards,</span></div>
      <div><span style="background-color: transparent;">Jeff</span></div>
      <blockquote style="margin-Top: 0px; margin-Bottom: 0px;
        margin-Left: 0.5em; margin-Right: inherit">
        <div> </div>
        <div style="border:none;border-top:solid #B5C4DF
          1.0pt;padding:3.0pt 0cm 0cm 0cm">
          <div style="PADDING-RIGHT: 8px; PADDING-LEFT: 8px; FONT-SIZE:
            12px;FONT-FAMILY:tahoma;COLOR:#000000; BACKGROUND: #efefef;
            PADDING-BOTTOM: 8px; PADDING-TOP: 8px">
            <div><b>From:</b> <a href="mailto:rebecca@nuviainc.com"
                moz-do-not-send="true">Rebecca Cran</a></div>
            <div><b>Date:</b> 2021-12-13 02:08</div>
            <div><b>To:</b> <a href="mailto:devel@edk2.groups.io"
                moz-do-not-send="true">devel</a>; <a
                href="mailto:ardb+tianocore@kernel.org"
                moz-do-not-send="true">Ard Biesheuvel</a>; <a
                href="mailto:kraxel@redhat.com" moz-do-not-send="true">Gerd
                Hoffmann</a>; <a
                href="mailto:samer.el-haj-mahmoud@arm.com"
                moz-do-not-send="true">Samer El-Haj-Mahmoud</a>; <a
                href="mailto:leif@nuviainc.com" moz-do-not-send="true">Leif
                Lindholm</a>; <a href="mailto:jian.j.wang@intel.com"
                moz-do-not-send="true">Jian J Wang</a>; <a
                href="mailto:gaoliming@byosoft.com.cn"
                moz-do-not-send="true">Liming Gao</a>; <a
                href="mailto:nd@arm.com" moz-do-not-send="true">nd</a>;
              <a href="mailto:sami.mujawar@arm.com"
                moz-do-not-send="true">Sami Mujawar</a></div>
            <div><b>CC:</b> <a href="mailto:rebecca@nuviainc.com"
                moz-do-not-send="true">Rebecca Cran</a></div>
            <div><b>Subject:</b> [edk2-devel] [PATCH v4 1/1]
              MdeModulePkg: Add MpServicesTest application to exercise
              MP Services</div>
          </div>
        </div>
        <div>
          <div>Add a new MpServicesTest application under
            MdeModulePkg/Application that</div>
          <div>exercises the EFI_MP_SERVICES_PROTOCOL.</div>
          <div> </div>
          <div>Signed-off-by: Rebecca Cran <a class="moz-txt-link-rfc2396E" href="mailto:rebecca@nuviainc.com"><rebecca@nuviainc.com></a></div>
          <div>Reviewed-by: Sami Mujawar <a class="moz-txt-link-rfc2396E" href="mailto:sami.mujawar@arm.com"><sami.mujawar@arm.com></a></div>
          <div>---</div>
          <div>
            MdeModulePkg/Application/MpServicesTest/MpServicesTest.c   |
            422 ++++++++++++++++++++</div>
          <div>
            MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf
            |  38 ++</div>
          <div>
            MdeModulePkg/MdeModulePkg.dsc                             
            |   2 +</div>
          <div> 3 files changed, 462 insertions(+)</div>
          <div> </div>
          <div>diff --git
            a/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c
            b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c</div>
          <div>new file mode 100644</div>
          <div>index 000000000000..933813e19e05</div>
          <div>--- /dev/null</div>
          <div>+++
            b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.c</div>
          <div>@@ -0,0 +1,422 @@</div>
          <div>+/** @file</div>
          <div>+</div>
          <div>+    Copyright (c) 2021, NUVIA Inc. All rights
            reserved.<BR></div>
          <div>+    SPDX-License-Identifier: BSD-2-Clause-Patent</div>
          <div>+**/</div>
          <div>+</div>
          <div>+#include <Uefi.h></div>
          <div>+#include <Library/DebugLib.h></div>
          <div>+#include <Library/RngLib.h></div>
          <div>+#include <Library/UefiBootServicesTableLib.h></div>
          <div>+#include <Library/UefiLib.h></div>
          <div>+#include <Pi/PiMultiPhase.h></div>
          <div>+#include <Protocol/MpService.h></div>
          <div>+</div>
          <div>+#define MAX_RANDOM_PROCESSOR_RETRIES  10</div>
          <div>+</div>
          <div>+#define AP_STARTUP_TEST_TIMEOUT_US  50000</div>
          <div>+#define INFINITE_TIMEOUT            0</div>
          <div>+</div>
          <div>+/** The procedure to run with the MP Services interface.</div>
          <div>+</div>
          <div>+  @param Buffer The procedure argument.</div>
          <div>+</div>
          <div>+**/</div>
          <div>+STATIC</div>
          <div>+VOID</div>
          <div>+EFIAPI</div>
          <div>+ApFunction (</div>
          <div>+  IN OUT VOID  *Buffer</div>
          <div>+  )</div>
          <div>+{</div>
          <div>+}</div>
          <div><span style="background-color: transparent;">+</span></div>
          <div>+/** Displays information returned from MP Services
            Protocol.</div>
          <div>+</div>
          <div>+  @param Mp  The MP Services Protocol</div>
          <div>+</div>
          <div>+  @return The number of CPUs in the system.</div>
          <div>+</div>
          <div>+**/</div>
          <div>+STATIC</div>
          <div>+UINTN</div>
          <div>+PrintProcessorInformation (</div>
          <div>+  IN EFI_MP_SERVICES_PROTOCOL  *Mp</div>
          <div>+  )</div>
          <div>+{</div>
          <div>+  EFI_STATUS                 Status;</div>
          <div>+  EFI_PROCESSOR_INFORMATION  CpuInfo;</div>
          <div>+  UINTN                      Index;</div>
          <div>+  UINTN                      NumCpu;</div>
          <div>+  UINTN                      NumEnabledCpu;</div>
          <div>+</div>
          <div>+  Status = Mp->GetNumberOfProcessors (Mp,
            &NumCpu, &NumEnabledCpu);</div>
          <div>+  if (EFI_ERROR (Status)) {</div>
          <div>+    Print (L"GetNumberOfProcessors failed: %r\n",
            Status);</div>
          <div>+  } else {</div>
          <div>+    Print (L"Number of CPUs: %ld, Enabled: %d\n",
            NumCpu, NumEnabledCpu);</div>
          <div>+  }</div>
          <div>+</div>
          <div>+  for (Index = 0; Index < NumCpu; Index++) {</div>
          <div>+    Status = Mp->GetProcessorInfo (Mp,
            CPU_V2_EXTENDED_TOPOLOGY | Index, &CpuInfo);</div>
          <div>+    if (EFI_ERROR (Status)) {</div>
          <div>+      Print (L"GetProcessorInfo for Processor %d failed:
            %r\n", Index, Status);</div>
          <div>+    } else {</div>
          <div>+      Print (</div>
          <div>+        L"Processor %d:\n"</div>
          <div>+        L"\tID: %016lx\n"</div>
          <div>+        L"\tStatus: %s | ",</div>
          <div>+        Index,</div>
          <div>+        CpuInfo.ProcessorId,</div>
          <div>+        (CpuInfo.StatusFlag & PROCESSOR_AS_BSP_BIT)
            ? L"BSP" : L"AP"</div>
          <div>+        );</div>
          <div>+</div>
          <div>+      Print (L"%s | ", (CpuInfo.StatusFlag &
            PROCESSOR_ENABLED_BIT) ? L"Enabled" : L"Disabled");</div>
          <div>+      Print (L"%s\n", (CpuInfo.StatusFlag &
            PROCESSOR_HEALTH_STATUS_BIT) ? L"Healthy" : L"Faulted");</div>
          <div>+</div>
          <div>+      Print (</div>
          <div>+        L"\tLocation: Package %d, Core %d, Thread %d\n"</div>
          <div>+        L"\tExtended Information: Package %d, Module %d,
            Tile %d, Die %d, Core %d, Thread %d\n\n",</div>
          <div>+        CpuInfo.Location.Package,</div>
          <div>+        CpuInfo.Location.Core,</div>
          <div>+        CpuInfo.Location.Thread,</div>
          <div>+        CpuInfo.ExtendedInformation.Location2.Package,</div>
          <div>+        CpuInfo.ExtendedInformation.Location2.Module,</div>
          <div>+        CpuInfo.ExtendedInformation.Location2.Tile,</div>
          <div>+        CpuInfo.ExtendedInformation.Location2.Die,</div>
          <div>+        CpuInfo.ExtendedInformation.Location2.Core,</div>
          <div>+        CpuInfo.ExtendedInformation.Location2.Thread</div>
          <div>+        );</div>
          <div>+    }</div>
          <div>+  }</div>
          <div>+</div>
          <div>+  return NumCpu;</div>
          <div>+}</div>
          <div>+</div>
          <div>+/** Returns the index of an enabled AP selected at
            random.</div>
          <div>+</div>
          <div>+  @param Mp             The MP Services Protocol.</div>
          <div>+  @param ProcessorIndex The index of a random enabled
            AP.</div>
          <div>+</div>
          <div>+  @retval EFI_SUCCESS   An enabled processor was found
            and returned.</div>
          <div>+  @retval EFI_NOT_FOUND A processor was unable to be
            selected.</div>
          <div>+</div>
          <div>+**/</div>
          <div>+STATIC</div>
          <div>+EFI_STATUS</div>
          <div>+GetRandomEnabledProcessorIndex (</div>
          <div>+  IN EFI_MP_SERVICES_PROTOCOL  *Mp,</div>
          <div>+  OUT UINTN                    *ProcessorIndex</div>
          <div>+  )</div>
          <div>+{</div>
          <div>+  UINTN                      Index;</div>
          <div>+  UINTN                      IndexOfEnabledCpu;</div>
          <div>+  UINTN                      NumCpus;</div>
          <div>+  UINTN                      NumEnabledCpus;</div>
          <div>+  UINTN                      IndexOfEnabledCpuToUse;</div>
          <div>+  UINT16                     RandomNumber;</div>
          <div>+  BOOLEAN                    Success;</div>
          <div>+  EFI_STATUS                 Status;</div>
          <div>+  EFI_PROCESSOR_INFORMATION  CpuInfo;</div>
          <div>+</div>
          <div>+  IndexOfEnabledCpu = 0;</div>
          <div>+</div>
          <div>+  Success = GetRandomNumber16 (&RandomNumber);</div>
          <div>+  ASSERT (Success == TRUE);</div>
          <div>+</div>
          <div>+  Status = Mp->GetNumberOfProcessors (Mp,
            &NumCpus, &NumEnabledCpus);</div>
          <div>+  ASSERT_EFI_ERROR (Status);</div>
          <div>+</div>
          <div>+  if (NumEnabledCpus == 1) {</div>
          <div>+    Print (L"All APs are disabled\n");</div>
          <div>+    return EFI_NOT_FOUND;</div>
          <div>+  }</div>
          <div>+</div>
          <div>+  IndexOfEnabledCpuToUse = RandomNumber %
            NumEnabledCpus;</div>
          <div>+</div>
          <div>+  for (Index = 0; Index < NumCpus; Index++) {</div>
          <div>+    Status = Mp->GetProcessorInfo (Mp, Index,
            &CpuInfo);</div>
          <div>+    ASSERT_EFI_ERROR (Status);</div>
          <div>+    if ((CpuInfo.StatusFlag & PROCESSOR_ENABLED_BIT)
            &&</div>
          <div>+        !(CpuInfo.StatusFlag &
            PROCESSOR_AS_BSP_BIT))</div>
          <div>+    {</div>
          <div>+      if (IndexOfEnabledCpuToUse == IndexOfEnabledCpu) {</div>
          <div>+        *ProcessorIndex = Index;</div>
          <div>+        Status          = EFI_SUCCESS;</div>
          <div>+        break;</div>
          <div>+      }</div>
          <div>+</div>
          <div>+      IndexOfEnabledCpu++;</div>
          <div>+    }</div>
          <div>+  }</div>
          <div>+</div>
          <div>+  if (Index == NumCpus) {</div>
          <div>+    Status = EFI_NOT_FOUND;</div>
          <div>+  }</div>
          <div>+</div>
          <div>+  return Status;</div>
          <div>+}</div>
          <div>+</div>
          <div>+/** Tests for the StartupThisAP function.</div>
          <div>+</div>
          <div>+  @param Mp The MP Services Protocol.</div>
          <div>+</div>
          <div>+**/</div>
          <div>+STATIC</div>
          <div>+VOID</div>
          <div>+StartupThisApTests (</div>
          <div>+  IN EFI_MP_SERVICES_PROTOCOL  *Mp</div>
          <div>+  )</div>
          <div>+{</div>
          <div>+  EFI_STATUS  Status;</div>
          <div>+  UINTN       ProcessorIndex;</div>
          <div>+  UINT32      Retries;</div>
          <div>+</div>
          <div>+  Retries = 0;</div>
          <div>+</div>
          <div>+  do {</div>
          <div>+    Status = GetRandomEnabledProcessorIndex (Mp,
            &ProcessorIndex);</div>
          <div>+  } while (EFI_ERROR (Status) && Retries++ <
            MAX_RANDOM_PROCESSOR_RETRIES);</div>
          <div>+</div>
          <div>+  if (EFI_ERROR (Status)) {</div>
          <div>+    return;</div>
          <div>+  }</div>
          <div>+</div>
          <div>+  Print (</div>
          <div>+    L"StartupThisAP on Processor %d with 0 (infinite)
            timeout...",</div>
          <div>+    ProcessorIndex</div>
          <div>+    );</div>
          <div>+</div>
          <div>+  Status = Mp->StartupThisAP (</div>
          <div>+                 Mp,</div>
          <div>+                 ApFunction,</div>
          <div>+                 ProcessorIndex,</div>
          <div>+                 NULL,</div>
          <div>+                 INFINITE_TIMEOUT,</div>
          <div>+                 NULL,</div>
          <div>+                 NULL</div>
          <div>+                 );</div>
          <div>+</div>
          <div>+  if (EFI_ERROR (Status)) {</div>
          <div>+    Print (L"failed: %r\n", Status);</div>
          <div>+    return;</div>
          <div>+  } else {</div>
          <div>+    Print (L"done.\n");</div>
          <div>+  }</div>
          <div>+</div>
          <div>+  Retries = 0;</div>
          <div>+</div>
          <div>+  do {</div>
          <div>+    Status = GetRandomEnabledProcessorIndex (Mp,
            &ProcessorIndex);</div>
          <div>+  } while (EFI_ERROR (Status) && Retries++ <
            MAX_RANDOM_PROCESSOR_RETRIES);</div>
          <div>+</div>
          <div>+  if (EFI_ERROR (Status)) {</div>
          <div>+    return;</div>
          <div>+  }</div>
          <div>+</div>
          <div>+  Print (</div>
          <div>+    L"StartupThisAP on Processor %d with %dms
            timeout...",</div>
          <div>+    ProcessorIndex,</div>
          <div>+    AP_STARTUP_TEST_TIMEOUT_US / 1000</div>
          <div>+    );</div>
          <div>+  Status = Mp->StartupThisAP (</div>
          <div>+                 Mp,</div>
          <div>+                 ApFunction,</div>
          <div>+                 ProcessorIndex,</div>
          <div>+                 NULL,</div>
          <div>+                 AP_STARTUP_TEST_TIMEOUT_US,</div>
          <div>+                 NULL,</div>
          <div>+                 NULL</div>
          <div>+                 );</div>
          <div>+  if (EFI_ERROR (Status)) {</div>
          <div>+    Print (L"failed: %r\n", Status);</div>
          <div>+    return;</div>
          <div>+  } else {</div>
          <div>+    Print (L"done.\n");</div>
          <div>+  }</div>
          <div>+}</div>
          <div>+</div>
          <div>+/** Tests for the StartupAllAPs function.</div>
          <div>+</div>
          <div>+  @param Mp      The MP Services Protocol.</div>
          <div>+  @param NumCpus The number of CPUs in the system.</div>
          <div>+</div>
          <div>+**/</div>
          <div>+STATIC</div>
          <div>+VOID</div>
          <div>+StartupAllAPsTests (</div>
          <div>+  IN EFI_MP_SERVICES_PROTOCOL  *Mp,</div>
          <div>+  IN UINTN                     NumCpus</div>
          <div>+  )</div>
          <div>+{</div>
          <div>+  EFI_STATUS  Status;</div>
          <div>+  UINTN       Timeout;</div>
          <div>+</div>
          <div>+  Print (L"Running with SingleThread FALSE, 0 (infinite)
            timeout...");</div>
          <div>+  Status = Mp->StartupAllAPs (Mp, ApFunction, FALSE,
            NULL, INFINITE_TIMEOUT, NULL, NULL);</div>
          <div>+  if (EFI_ERROR (Status)) {</div>
          <div>+    Print (L"failed: %r\n", Status);</div>
          <div>+    return;</div>
          <div>+  } else {</div>
          <div>+    Print (L"done.\n");</div>
          <div>+  }</div>
          <div>+</div>
          <div>+  Timeout = NumCpus * AP_STARTUP_TEST_TIMEOUT_US;</div>
          <div>+</div>
          <div>+  Print (L"Running with SingleThread TRUE, %dms
            timeout...", Timeout / 1000);</div>
          <div>+  Status = Mp->StartupAllAPs (</div>
          <div>+                 Mp,</div>
          <div>+                 ApFunction,</div>
          <div>+                 TRUE,</div>
          <div>+                 NULL,</div>
          <div>+                 Timeout,</div>
          <div>+                 NULL,</div>
          <div>+                 NULL</div>
          <div>+                 );</div>
          <div>+  if (EFI_ERROR (Status)) {</div>
          <div>+    Print (L"failed: %r\n", Status);</div>
          <div>+    return;</div>
          <div>+  } else {</div>
          <div>+    Print (L"done.\n");</div>
          <div>+  }</div>
          <div>+}</div>
          <div>+</div>
          <div>+/** Tests for the EnableDisableAP function.</div>
          <div>+</div>
          <div>+  @param Mp      The MP Services Protocol.</div>
          <div>+  @param NumCpus The number of CPUs in the system.</div>
          <div>+</div>
          <div>+**/</div>
          <div>+STATIC</div>
          <div>+VOID</div>
          <div>+EnableDisableAPTests (</div>
          <div>+  IN EFI_MP_SERVICES_PROTOCOL  *Mp,</div>
          <div>+  IN UINTN                     NumCpus</div>
          <div>+  )</div>
          <div>+{</div>
          <div>+  EFI_STATUS  Status;</div>
          <div>+  UINTN       Index;</div>
          <div>+  UINT32      HealthFlag;</div>
          <div>+</div>
          <div>+  HealthFlag = 0;</div>
          <div>+</div>
          <div>+  for (Index = 1; Index < NumCpus; Index++) {</div>
          <div>+    Print (L"Disabling Processor %d with HealthFlag
            faulted...", Index);</div>
          <div>+    Status = Mp->EnableDisableAP (Mp, Index, FALSE,
            &HealthFlag);</div>
          <div>+    if (EFI_ERROR (Status)) {</div>
          <div>+      Print (L"failed: %r\n", Status);</div>
          <div>+      return;</div>
          <div>+    } else {</div>
          <div>+      Print (L"done.\n");</div>
          <div>+    }</div>
          <div>+  }</div>
          <div>+</div>
          <div>+  HealthFlag = PROCESSOR_HEALTH_STATUS_BIT;</div>
          <div>+</div>
          <div>+  for (Index = 1; Index < NumCpus; Index++) {</div>
          <div>+    Print (L"Enabling Processor %d with HealthFlag
            healthy...", Index);</div>
          <div>+    Status = Mp->EnableDisableAP (Mp, Index, TRUE,
            &HealthFlag);</div>
          <div>+    if (EFI_ERROR (Status)) {</div>
          <div>+      Print (L"failed: %r\n", Status);</div>
          <div>+      return;</div>
          <div>+    } else {</div>
          <div>+      Print (L"done.\n");</div>
          <div>+    }</div>
          <div>+  }</div>
          <div>+}</div>
          <div>+</div>
          <div>+/**</div>
          <div>+  The user Entry Point for Application. The user code
            starts with this function</div>
          <div>+  as the real entry point for the application.</div>
          <div>+</div>
          <div>+  @param[in] ImageHandle    The firmware allocated
            handle for the EFI image.</div>
          <div>+  @param[in] SystemTable    A pointer to the EFI System
            Table.</div>
          <div>+</div>
          <div>+  @retval EFI_SUCCESS       The entry point is executed
            successfully.</div>
          <div>+  @retval other             Some error occurs when
            executing this entry point.</div>
          <div>+</div>
          <div>+**/</div>
          <div>+EFI_STATUS</div>
          <div>+EFIAPI</div>
          <div>+UefiMain (</div>
          <div>+  IN EFI_HANDLE        ImageHandle,</div>
          <div>+  IN EFI_SYSTEM_TABLE  *SystemTable</div>
          <div>+  )</div>
          <div>+{</div>
          <div>+  EFI_STATUS                Status;</div>
          <div>+  EFI_MP_SERVICES_PROTOCOL  *Mp;</div>
          <div>+  EFI_HANDLE                *pHandle;</div>
          <div>+  UINTN                     HandleCount;</div>
          <div>+  UINTN                     BspId;</div>
          <div>+  UINTN                     NumCpus;</div>
          <div>+  UINTN                     Index;</div>
          <div>+</div>
          <div>+  pHandle     = NULL;</div>
          <div>+  HandleCount = 0;</div>
          <div>+  BspId       = 0;</div>
          <div>+</div>
          <div>+  Status = gBS->LocateHandleBuffer (</div>
          <div>+                  ByProtocol,</div>
          <div>+                  &gEfiMpServiceProtocolGuid,</div>
          <div>+                  NULL,</div>
          <div>+                  &HandleCount,</div>
          <div>+                  &pHandle</div>
          <div>+                  );</div>
          <div>+</div>
          <div>+  if (EFI_ERROR (Status)) {</div>
          <div>+    Print (L"Failed to locate EFI_MP_SERVICES_PROTOCOL
            (%r). Not installed on platform?\n", Status);</div>
          <div>+    return EFI_NOT_FOUND;</div>
          <div>+  }</div>
          <div>+</div>
          <div>+  for (Index = 0; Index < HandleCount; Index++) {</div>
          <div>+    Status = gBS->OpenProtocol (</div>
          <div>+                    *pHandle,</div>
          <div>+                    &gEfiMpServiceProtocolGuid,</div>
          <div>+                    (VOID **)&Mp,</div>
          <div>+                    NULL,</div>
          <div>+                    gImageHandle,</div>
          <div>+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL</div>
          <div>+                    );</div>
          <div>+</div>
          <div>+    if (EFI_ERROR (Status)) {</div>
          <div>+      return Status;</div>
          <div>+    }</div>
          <div>+</div>
          <div>+    pHandle++;</div>
          <div>+  }</div>
          <div>+</div>
          <div><span style="background-color: transparent;">+  Print
              (L"Exercising WhoAmI\n\n");</span></div>
          <div>+  Status = Mp->WhoAmI (Mp, &BspId);</div>
          <div>+  if (EFI_ERROR (Status)) {</div>
          <div>+    Print (L"WhoAmI failed: %r\n", Status);</div>
          <div>+    return Status;</div>
          <div>+  } else {</div>
          <div>+    Print (L"WhoAmI: %016lx\n", BspId);</div>
          <div>+  }</div>
          <div>+</div>
          <div>+  Print (L"\n");</div>
          <div>+  Print (</div>
          <div>+    L"Exercising GetNumberOfProcessors and
            GetProcessorInformation with "</div>
          <div>+    L"CPU_V2_EXTENDED_TOPOLOGY\n\n"</div>
          <div>+    );</div>
          <div>+  NumCpus = PrintProcessorInformation (Mp);</div>
          <div>+  if (NumCpus < 2) {</div>
          <div>+    Print (L"UP system found. Not running further
            tests.\n");</div>
          <div>+    return EFI_INVALID_PARAMETER;</div>
          <div>+  }</div>
          <div>+</div>
          <div>+  Print (L"\n");</div>
          <div>+  Print (L"Exercising StartupThisAP:\n\n");</div>
          <div>+  StartupThisApTests (Mp);</div>
          <div>+</div>
          <div>+  Print (L"\n");</div>
          <div>+  Print (L"Exercising StartupAllAPs:\n\n");</div>
          <div>+  StartupAllAPsTests (Mp, NumCpus);</div>
          <div>+</div>
          <div>+  Print (L"\n");</div>
          <div>+  Print (L"Exercising EnableDisableAP:\n\n");</div>
          <div>+  EnableDisableAPTests (Mp, NumCpus);</div>
          <div>+</div>
          <div>+  gBS->CloseProtocol (pHandle,
            &gEfiMpServiceProtocolGuid, gImageHandle, NULL);</div>
          <div>+  return EFI_SUCCESS;</div>
          <div>+}</div>
          <div>diff --git
            a/MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf
            b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf</div>
          <div>new file mode 100644</div>
          <div>index 000000000000..8a21ca70d8fa</div>
          <div>--- /dev/null</div>
          <div>+++
            b/MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf</div>
          <div>@@ -0,0 +1,38 @@</div>
          <div>+## @file</div>
          <div>+#  UEFI Application to exercise
            EFI_MP_SERVICES_PROTOCOL.</div>
          <div>+#</div>
          <div>+#  Copyright (c) 2021, NUVIA Inc. All rights
            reserved.<BR></div>
          <div>+#</div>
          <div>+#  SPDX-License-Identifier: BSD-2-Clause-Patent</div>
          <div>+#</div>
          <div>+##</div>
          <div>+</div>
          <div>+[Defines]</div>
          <div>+  INF_VERSION                    = 1.29</div>
          <div>+  BASE_NAME                      = MpServicesTest</div>
          <div>+  FILE_GUID                      =
            43e9defa-7209-4b0d-b136-cc4ca02cb469</div>
          <div>+  MODULE_TYPE                    = UEFI_APPLICATION</div>
          <div>+  VERSION_STRING                 = 0.1</div>
          <div>+  ENTRY_POINT                    = UefiMain</div>
          <div>+</div>
          <div>+#</div>
          <div>+# The following information is for reference only and
            not required by the build tools.</div>
          <div>+#</div>
          <div>+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64</div>
          <div>+#</div>
          <div>+</div>
          <div>+[Sources]</div>
          <div>+  MpServicesTest.c</div>
          <div>+</div>
          <div>+[Packages]</div>
          <div>+  MdePkg/MdePkg.dec</div>
          <div>+</div>
          <div>+[LibraryClasses]</div>
          <div>+  BaseLib</div>
          <div>+  RngLib</div>
          <div>+  UefiApplicationEntryPoint</div>
          <div>+  UefiLib</div>
          <div>+</div>
          <div>+[Protocols]</div>
          <div>+  gEfiMpServiceProtocolGuid    ## CONSUMES</div>
          <div>+</div>
          <div>diff --git a/MdeModulePkg/MdeModulePkg.dsc
            b/MdeModulePkg/MdeModulePkg.dsc</div>
          <div>index b1d83461865e..1cf5ccd30d40 100644</div>
          <div>--- a/MdeModulePkg/MdeModulePkg.dsc</div>
          <div>+++ b/MdeModulePkg/MdeModulePkg.dsc</div>
          <div>@@ -164,6 +164,7 @@</div>
          <div>  
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf</div>
          <div>  
            DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf</div>
          <div>  
            FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf</div>
          <div>+  RngLib|MdePkg/Library/DxeRngLib/DxeRngLib.inf</div>
          <div> </div>
          <div> [LibraryClasses.common.MM_STANDALONE]</div>
          <div>  
            HobLib|MdeModulePkg/Library/BaseHobLibNull/BaseHobLibNull.inf</div>
          <div>@@ -215,6 +216,7 @@</div>
          <div>   MdeModulePkg/Application/HelloWorld/HelloWorld.inf</div>
          <div>   MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf</div>
          <div>  
            MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf</div>
          <div>+ 
            MdeModulePkg/Application/MpServicesTest/MpServicesTest.inf</div>
          <div> </div>
          <div>   MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf</div>
          <div>   MdeModulePkg/Logo/Logo.inf</div>
          <div>-- </div>
          <div>2.31.1</div>
          <div> </div>
          <div> </div>
          <div> </div>
          <div> </div>
          <div> </div>
          <div> </div>
        </div>
      </blockquote>
      
    </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/85234">View/Reply Online (#85234)</a> |    |  <a target="_blank" href="https://groups.io/mt/87681342/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>