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