The

  Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/CpuArchDxe

driver applies any MTRR changes to APs, if the EFI_MP_SERVICES_PROTOCOL is
available. We should do the same.

Additionally, the broadcast should occur at MP startup as well, not only
when MTRR settings are changed. The inspiration is taken from

  Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/CpuMpDxe/

(see the EarlyMpInit() function and its call sites in
"ProcessorConfig.c").

Cc: Jeff Fan <jeff....@intel.com>
Cc: Chen Fan <chen.fan.f...@cn.fujitsu.com>
Cc: Jordan Justen <jordan.l.jus...@intel.com>
Cc: Michael Kinney <michael.d.kin...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <ler...@redhat.com>
---

Notes:
    v2:
    - This patch replaces the following patches from v1:
      - UefiCpuPkg: CpuDxe: optionally save MTRR settings to AcpiNVS memory
        block
      - UefiCpuPkg: CpuDxe: broadcast MTRR changes to APs
      - UefiCpuPkg: CpuDxe: sync MTRR settings to APs at MP startup
      - UefiCpuPkg: CpuDxe: provide EFI_MP_SERVICES_PROTOCOL when there's no
        AP
    
      The first v1 patch was deemed inappropriate for general use, and Mike
      suggested a good alternative for OVMF (=> grab MTRR settings in
      CpuS3DataDxe at EndOfDxe).
    
      The second and third v1 patches are now squashed together into this v2
      patch; they are small and belong together logically.
    
      The fourth v1 patch is redundant now; the same has been covered by
      Mike.

 UefiCpuPkg/CpuDxe/CpuMp.h  | 13 ++++++++
 UefiCpuPkg/CpuDxe/CpuDxe.c | 26 +++++++++++++++
 UefiCpuPkg/CpuDxe/CpuMp.c  | 34 +++++++++++++++++++-
 3 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h
index d2866e4..503f3ae 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.h
+++ b/UefiCpuPkg/CpuDxe/CpuMp.h
@@ -643,5 +643,18 @@ ResetApStackless (
   IN UINT32 ProcessorId
   );
 
+/**
+  A minimal wrapper function that allows MtrrSetAllMtrrs() to be passed to
+  EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() as Procedure.
+
+  @param[in] Buffer  Pointer to an MTRR_SETTINGS object, to be passed to
+                     MtrrSetAllMtrrs().
+**/
+VOID
+EFIAPI
+SetMtrrsFromBuffer (
+  IN VOID *Buffer
+  );
+
 #endif // _CPU_MP_H_
 
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.c b/UefiCpuPkg/CpuDxe/CpuDxe.c
index c9df4e1..daf97bd 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.c
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.c
@@ -350,6 +350,9 @@ CpuSetMemoryAttributes (
 {
   RETURN_STATUS             Status;
   MTRR_MEMORY_CACHE_TYPE    CacheType;
+  EFI_STATUS                MpStatus;
+  EFI_MP_SERVICES_PROTOCOL  *MpService;
+  MTRR_SETTINGS             MtrrSettings;
 
   if (!IsMtrrSupported ()) {
     return EFI_UNSUPPORTED;
@@ -405,6 +408,29 @@ CpuSetMemoryAttributes (
              CacheType
              );
 
+  if (!RETURN_ERROR (Status)) {
+    MpStatus = gBS->LocateProtocol (
+                      &gEfiMpServiceProtocolGuid,
+                      NULL,
+                      (VOID **)&MpService
+                      );
+    //
+    // Synchronize the update with all APs
+    //
+    if (!EFI_ERROR (MpStatus)) {
+      MtrrGetAllMtrrs (&MtrrSettings);
+      MpStatus = MpService->StartupAllAPs (
+                              MpService,          // This
+                              SetMtrrsFromBuffer, // Procedure
+                              TRUE,               // SingleThread
+                              NULL,               // WaitEvent
+                              0,                  // TimeoutInMicrosecsond
+                              &MtrrSettings,      // ProcedureArgument
+                              NULL                // FailedCpuList
+                              );
+      ASSERT (MpStatus == EFI_SUCCESS || MpStatus == EFI_NOT_STARTED);
+    }
+  }
   return (EFI_STATUS) Status;
 }
 
diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c
index da3686e..fbe43f5 100644
--- a/UefiCpuPkg/CpuDxe/CpuMp.c
+++ b/UefiCpuPkg/CpuDxe/CpuMp.c
@@ -1626,6 +1626,22 @@ ExitBootServicesCallback (
 }
 
 /**
+  A minimal wrapper function that allows MtrrSetAllMtrrs() to be passed to
+  EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() as Procedure.
+
+  @param[in] Buffer  Pointer to an MTRR_SETTINGS object, to be passed to
+                     MtrrSetAllMtrrs().
+**/
+VOID
+EFIAPI
+SetMtrrsFromBuffer (
+  IN VOID *Buffer
+  )
+{
+  MtrrSetAllMtrrs (Buffer);
+}
+
+/**
   Initialize Multi-processor support.
 
 **/
@@ -1634,7 +1650,8 @@ InitializeMpSupport (
   VOID
   )
 {
-  EFI_STATUS Status;
+  EFI_STATUS    Status;
+  MTRR_SETTINGS MtrrSettings;
 
   gMaxLogicalProcessorNumber = (UINTN) PcdGet32 
(PcdCpuMaxLogicalProcessorNumber);
   if (gMaxLogicalProcessorNumber < 1) {
@@ -1690,6 +1707,21 @@ InitializeMpSupport (
   //
   CollectBistDataFromHob ();
 
+  //
+  // Synchronize MTRR settings to APs.
+  //
+  MtrrGetAllMtrrs (&MtrrSettings);
+  Status = mMpServicesTemplate.StartupAllAPs (
+                                 &mMpServicesTemplate, // This
+                                 SetMtrrsFromBuffer,   // Procedure
+                                 TRUE,                 // SingleThread
+                                 NULL,                 // WaitEvent
+                                 0,                    // TimeoutInMicrosecsond
+                                 &MtrrSettings,        // ProcedureArgument
+                                 NULL                  // FailedCpuList
+                                 );
+  ASSERT (Status == EFI_SUCCESS || Status == EFI_NOT_STARTED);
+
   Status = gBS->InstallMultipleProtocolInterfaces (
                   &mMpServiceHandle,
                   &gEfiMpServiceProtocolGuid,  &mMpServicesTemplate,
-- 
1.8.3.1


_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to