It can avoid potential first call to FreePool() -> BufferInSmram() -> if (mSmramRanges == NULL) { GetSmramRanges();} -> gBS->LocateProtocol() at boottime with >= TPL_NOTIFY or after ReadyToLock or at OS runtime.
Cc: Jiewen Yao <jiewen....@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.z...@intel.com> --- .../MemoryAllocationLib.c | 69 ++++------------------ .../PiSmmCoreMemoryAllocationServices.h | 61 +++++++++++++++++++ 2 files changed, 74 insertions(+), 56 deletions(-) diff --git a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c index cae50ff..5378f09 100644 --- a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c +++ b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c @@ -21,52 +21,8 @@ #include <Library/DebugLib.h> #include "PiSmmCoreMemoryAllocationServices.h" -EFI_SMRAM_DESCRIPTOR *mSmramRanges = NULL; -UINTN mSmramRangeCount = 0; - -/** - This function gets and caches SMRAM ranges that are present in the system. - - It will ASSERT() if SMM Access2 Protocol doesn't exist. - It will ASSERT() if SMRAM ranges can't be got. - It will ASSERT() if Resource can't be allocated for cache SMRAM range. - -**/ -VOID -EFIAPI -GetSmramRanges ( - VOID - ) -{ - EFI_STATUS Status; - EFI_SMM_ACCESS2_PROTOCOL *SmmAccess; - UINTN Size; - - // - // Locate SMM Access2 Protocol - // - Status = gBS->LocateProtocol ( - &gEfiSmmAccess2ProtocolGuid, - NULL, - (VOID **)&SmmAccess - ); - ASSERT_EFI_ERROR (Status); - - // - // Get SMRAM range information - // - Size = 0; - Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); - - mSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool (Size); - ASSERT (mSmramRanges != NULL); - - Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges); - ASSERT_EFI_ERROR (Status); - - mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR); -} +EFI_SMRAM_DESCRIPTOR *mSmmCoreMemoryAllocLibSmramRanges = NULL; +UINTN mSmmCoreMemoryAllocLibSmramRangeCount = 0; /** Check whether the start address of buffer is within any of the SMRAM ranges. @@ -84,16 +40,9 @@ BufferInSmram ( { UINTN Index; - if (mSmramRanges == NULL) { - // - // SMRAM ranges is not got. Try to get them all. - // - GetSmramRanges(); - } - - for (Index = 0; Index < mSmramRangeCount; Index ++) { - if (((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer >= mSmramRanges[Index].CpuStart) && - ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer < (mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize))) { + for (Index = 0; Index < mSmmCoreMemoryAllocLibSmramRangeCount; Index ++) { + if (((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer >= mSmmCoreMemoryAllocLibSmramRanges[Index].CpuStart) && + ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer < (mSmmCoreMemoryAllocLibSmramRanges[Index].CpuStart + mSmmCoreMemoryAllocLibSmramRanges[Index].PhysicalSize))) { return TRUE; } } @@ -953,11 +902,19 @@ PiSmmCoreMemoryAllocationLibConstructor ( ) { SMM_CORE_PRIVATE_DATA *SmmCorePrivate; + UINTN Size; SmmCorePrivate = (SMM_CORE_PRIVATE_DATA *)ImageHandle; // // Initialize memory service using free SMRAM // SmmInitializeMemoryServices (SmmCorePrivate->SmramRangeCount, SmmCorePrivate->SmramRanges); + + mSmmCoreMemoryAllocLibSmramRangeCount = SmmCorePrivate->FullSmramRangeCount; + Size = mSmmCoreMemoryAllocLibSmramRangeCount * sizeof (EFI_SMRAM_DESCRIPTOR); + mSmmCoreMemoryAllocLibSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool (Size); + ASSERT (mSmmCoreMemoryAllocLibSmramRanges != NULL); + CopyMem (mSmmCoreMemoryAllocLibSmramRanges, SmmCorePrivate->FullSmramRanges, Size); + return EFI_SUCCESS; } diff --git a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationServices.h b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationServices.h index 5c74045..6ae499b 100644 --- a/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationServices.h +++ b/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationServices.h @@ -18,24 +18,85 @@ #ifndef _PI_SMM_CORE_MEMORY_ALLOCATION_SERVICES_H_ #define _PI_SMM_CORE_MEMORY_ALLOCATION_SERVICES_H_ +// +// It should be aligned with the definition in PiSmmCore. +// typedef struct { UINTN Signature; + /// /// The ImageHandle passed into the entry point of the SMM IPL. This ImageHandle /// is used by the SMM Core to fill in the ParentImageHandle field of the Loaded /// Image Protocol for each SMM Driver that is dispatched by the SMM Core. /// EFI_HANDLE SmmIplImageHandle; + /// /// The number of SMRAM ranges passed from the SMM IPL to the SMM Core. The SMM /// Core uses these ranges of SMRAM to initialize the SMM Core memory manager. /// UINTN SmramRangeCount; + /// /// A table of SMRAM ranges passed from the SMM IPL to the SMM Core. The SMM /// Core uses these ranges of SMRAM to initialize the SMM Core memory manager. /// EFI_SMRAM_DESCRIPTOR *SmramRanges; + + /// + /// The SMM Foundation Entry Point. The SMM Core fills in this field when the + /// SMM Core is initialized. The SMM IPL is responsbile for registering this entry + /// point with the SMM Configuration Protocol. The SMM Configuration Protocol may + /// not be available at the time the SMM IPL and SMM Core are started, so the SMM IPL + /// sets up a protocol notification on the SMM Configuration Protocol and registers + /// the SMM Foundation Entry Point as soon as the SMM Configuration Protocol is + /// available. + /// + EFI_SMM_ENTRY_POINT SmmEntryPoint; + + /// + /// Boolean flag set to TRUE while an SMI is being processed by the SMM Core. + /// + BOOLEAN SmmEntryPointRegistered; + + /// + /// Boolean flag set to TRUE while an SMI is being processed by the SMM Core. + /// + BOOLEAN InSmm; + + /// + /// This field is set by the SMM Core then the SMM Core is initialized. This field is + /// used by the SMM Base 2 Protocol and SMM Communication Protocol implementations in + /// the SMM IPL. + /// + EFI_SMM_SYSTEM_TABLE2 *Smst; + + /// + /// This field is used by the SMM Communicatioon Protocol to pass a buffer into + /// a software SMI handler and for the software SMI handler to pass a buffer back to + /// the caller of the SMM Communication Protocol. + /// + VOID *CommunicationBuffer; + + /// + /// This field is used by the SMM Communicatioon Protocol to pass the size of a buffer, + /// in bytes, into a software SMI handler and for the software SMI handler to pass the + /// size, in bytes, of a buffer back to the caller of the SMM Communication Protocol. + /// + UINTN BufferSize; + + /// + /// This field is used by the SMM Communication Protocol to pass the return status from + /// a software SMI handler back to the caller of the SMM Communication Protocol. + /// + EFI_STATUS ReturnStatus; + + EFI_PHYSICAL_ADDRESS PiSmmCoreImageBase; + UINT64 PiSmmCoreImageSize; + EFI_PHYSICAL_ADDRESS PiSmmCoreEntryPoint; + + UINTN FullSmramRangeCount; + EFI_SMRAM_DESCRIPTOR *FullSmramRanges; } SMM_CORE_PRIVATE_DATA; /** -- 1.9.5.msysgit.0 ------------------------------------------------------------------------------ One dashboard for servers and applications across Physical-Virtual-Cloud Widest out-of-the-box monitoring support with 50+ applications Performance metrics, stats and reports that give you Actionable Insights Deep dive visibility with transaction tracing using APM Insight. http://ad.doubleclick.net/ddm/clk/290420510;117567292;y _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel