MdeModulePkg PiSmmCoreMemoryAllocationLib: Get SMRAM ranges
from FullSmramRanges and FullSmramRangeCount in SmmCorePrivate by Constructor. 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. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17463 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@ -21,52 +21,8 @@
|
|||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include "PiSmmCoreMemoryAllocationServices.h"
|
#include "PiSmmCoreMemoryAllocationServices.h"
|
||||||
|
|
||||||
EFI_SMRAM_DESCRIPTOR *mSmramRanges = NULL;
|
EFI_SMRAM_DESCRIPTOR *mSmmCoreMemoryAllocLibSmramRanges = NULL;
|
||||||
UINTN mSmramRangeCount = 0;
|
UINTN mSmmCoreMemoryAllocLibSmramRangeCount = 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Check whether the start address of buffer is within any of the SMRAM ranges.
|
Check whether the start address of buffer is within any of the SMRAM ranges.
|
||||||
@ -84,16 +40,9 @@ BufferInSmram (
|
|||||||
{
|
{
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
|
|
||||||
if (mSmramRanges == NULL) {
|
for (Index = 0; Index < mSmmCoreMemoryAllocLibSmramRangeCount; Index ++) {
|
||||||
//
|
if (((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer >= mSmmCoreMemoryAllocLibSmramRanges[Index].CpuStart) &&
|
||||||
// SMRAM ranges is not got. Try to get them all.
|
((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer < (mSmmCoreMemoryAllocLibSmramRanges[Index].CpuStart + mSmmCoreMemoryAllocLibSmramRanges[Index].PhysicalSize))) {
|
||||||
//
|
|
||||||
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))) {
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -953,11 +902,19 @@ PiSmmCoreMemoryAllocationLibConstructor (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
SMM_CORE_PRIVATE_DATA *SmmCorePrivate;
|
SMM_CORE_PRIVATE_DATA *SmmCorePrivate;
|
||||||
|
UINTN Size;
|
||||||
|
|
||||||
SmmCorePrivate = (SMM_CORE_PRIVATE_DATA *)ImageHandle;
|
SmmCorePrivate = (SMM_CORE_PRIVATE_DATA *)ImageHandle;
|
||||||
//
|
//
|
||||||
// Initialize memory service using free SMRAM
|
// Initialize memory service using free SMRAM
|
||||||
//
|
//
|
||||||
SmmInitializeMemoryServices (SmmCorePrivate->SmramRangeCount, SmmCorePrivate->SmramRanges);
|
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;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -18,24 +18,85 @@
|
|||||||
#ifndef _PI_SMM_CORE_MEMORY_ALLOCATION_SERVICES_H_
|
#ifndef _PI_SMM_CORE_MEMORY_ALLOCATION_SERVICES_H_
|
||||||
#define _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 {
|
typedef struct {
|
||||||
UINTN Signature;
|
UINTN Signature;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The ImageHandle passed into the entry point of the SMM IPL. This ImageHandle
|
/// 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
|
/// 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.
|
/// Image Protocol for each SMM Driver that is dispatched by the SMM Core.
|
||||||
///
|
///
|
||||||
EFI_HANDLE SmmIplImageHandle;
|
EFI_HANDLE SmmIplImageHandle;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The number of SMRAM ranges passed from the SMM IPL to the SMM Core. The SMM
|
/// 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.
|
/// Core uses these ranges of SMRAM to initialize the SMM Core memory manager.
|
||||||
///
|
///
|
||||||
UINTN SmramRangeCount;
|
UINTN SmramRangeCount;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// A table of SMRAM ranges passed from the SMM IPL to the SMM Core. The SMM
|
/// 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.
|
/// Core uses these ranges of SMRAM to initialize the SMM Core memory manager.
|
||||||
///
|
///
|
||||||
EFI_SMRAM_DESCRIPTOR *SmramRanges;
|
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;
|
} SMM_CORE_PRIVATE_DATA;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user