MdeModulePkg DxeCore/PiSmmCore: Add UEFI memory and SMRAM profile support.

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@16335 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Star Zeng
2014-11-12 03:27:48 +00:00
committed by lzeng14
parent dad83a8c12
commit 84edd20bd0
28 changed files with 5235 additions and 106 deletions

View File

@@ -69,6 +69,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Guid/IdleLoopEvent.h>
#include <Guid/VectorHandoffTable.h>
#include <Ppi/VectorHandoffInfo.h>
#include <Guid/ZeroGuid.h>
#include <Guid/MemoryProfile.h>
#include <Library/DxeCoreEntryPoint.h>
#include <Library/DebugLib.h>
@@ -191,6 +193,56 @@ typedef struct {
EFI_HANDLE DeviceHandle;
} EFI_GCD_MAP_ENTRY;
#define LOADED_IMAGE_PRIVATE_DATA_SIGNATURE SIGNATURE_32('l','d','r','i')
typedef struct {
UINTN Signature;
/// Image handle
EFI_HANDLE Handle;
/// Image type
UINTN Type;
/// If entrypoint has been called
BOOLEAN Started;
/// The image's entry point
EFI_IMAGE_ENTRY_POINT EntryPoint;
/// loaded image protocol
EFI_LOADED_IMAGE_PROTOCOL Info;
/// Location in memory
EFI_PHYSICAL_ADDRESS ImageBasePage;
/// Number of pages
UINTN NumberOfPages;
/// Original fixup data
CHAR8 *FixupData;
/// Tpl of started image
EFI_TPL Tpl;
/// Status returned by started image
EFI_STATUS Status;
/// Size of ExitData from started image
UINTN ExitDataSize;
/// Pointer to exit data from started image
VOID *ExitData;
/// Pointer to pool allocation for context save/retore
VOID *JumpBuffer;
/// Pointer to buffer for context save/retore
BASE_LIBRARY_JUMP_BUFFER *JumpContext;
/// Machine type from PE image
UINT16 Machine;
/// EBC Protocol pointer
EFI_EBC_PROTOCOL *Ebc;
/// Runtime image list
EFI_RUNTIME_IMAGE_ENTRY *RuntimeData;
/// Pointer to Loaded Image Device Path Protocl
EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
/// PeCoffLoader ImageContext
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
/// Status returned by LoadImage() service.
EFI_STATUS LoadImageStatus;
} LOADED_IMAGE_PRIVATE_DATA;
#define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \
CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE)
//
// DXE Core Global Variables
//
@@ -1192,7 +1244,32 @@ CoreAllocatePages (
IN OUT EFI_PHYSICAL_ADDRESS *Memory
);
/**
Allocates pages from the memory map.
@param Type The type of allocation to perform
@param MemoryType The type of memory to turn the allocated pages
into
@param NumberOfPages The number of pages to allocate
@param Memory A pointer to receive the base allocated memory
address
@return Status. On success, Memory is filled in with the base address allocated
@retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in
spec.
@retval EFI_NOT_FOUND Could not allocate pages match the requirement.
@retval EFI_OUT_OF_RESOURCES No enough pages to allocate.
@retval EFI_SUCCESS Pages successfully allocated.
**/
EFI_STATUS
EFIAPI
CoreInternalAllocatePages (
IN EFI_ALLOCATE_TYPE Type,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN NumberOfPages,
IN OUT EFI_PHYSICAL_ADDRESS *Memory
);
/**
Frees previous allocated pages.
@@ -1212,7 +1289,23 @@ CoreFreePages (
IN UINTN NumberOfPages
);
/**
Frees previous allocated pages.
@param Memory Base address of memory being freed
@param NumberOfPages The number of pages to free
@retval EFI_NOT_FOUND Could not find the entry that covers the range
@retval EFI_INVALID_PARAMETER Address not aligned
@return EFI_SUCCESS -Pages successfully freed.
**/
EFI_STATUS
EFIAPI
CoreInternalFreePages (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NumberOfPages
);
/**
This function returns a copy of the current memory map. The map is an array of
@@ -1277,7 +1370,26 @@ CoreAllocatePool (
OUT VOID **Buffer
);
/**
Allocate pool of a particular type.
@param PoolType Type of pool to allocate
@param Size The amount of pool to allocate
@param Buffer The address to return a pointer to the allocated
pool
@retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL
@retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed.
@retval EFI_SUCCESS Pool successfully allocated.
**/
EFI_STATUS
EFIAPI
CoreInternalAllocatePool (
IN EFI_MEMORY_TYPE PoolType,
IN UINTN Size,
OUT VOID **Buffer
);
/**
Frees pool.
@@ -1294,7 +1406,20 @@ CoreFreePool (
IN VOID *Buffer
);
/**
Frees pool.
@param Buffer The allocated pool entry to free
@retval EFI_INVALID_PARAMETER Buffer is not a valid value.
@retval EFI_SUCCESS Pool successfully freed.
**/
EFI_STATUS
EFIAPI
CoreInternalFreePool (
IN VOID *Buffer
);
/**
Loads an EFI image into memory and returns a handle to the image.
@@ -2619,4 +2744,76 @@ VerifyFvHeaderChecksum (
IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
);
/**
Initialize memory profile.
@param HobStart The start address of the HOB.
**/
VOID
MemoryProfileInit (
IN VOID *HobStart
);
/**
Install memory profile protocol.
**/
VOID
MemoryProfileInstallProtocol (
VOID
);
/**
Register image to memory profile.
@param DriverEntry Image info.
@param FileType Image file type.
@retval TRUE Register success.
@retval FALSE Register fail.
**/
BOOLEAN
RegisterMemoryProfileImage (
IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry,
IN EFI_FV_FILETYPE FileType
);
/**
Unregister image from memory profile.
@param DriverEntry Image info.
@retval TRUE Unregister success.
@retval FALSE Unregister fail.
**/
BOOLEAN
UnregisterMemoryProfileImage (
IN LOADED_IMAGE_PRIVATE_DATA *DriverEntry
);
/**
Update memory profile information.
@param CallerAddress Address of caller who call Allocate or Free.
@param Action This Allocate or Free action.
@param MemoryType Memory type.
@param Size Buffer size.
@param Buffer Buffer address.
@retval TRUE Profile udpate success.
@retval FALSE Profile update fail.
**/
BOOLEAN
CoreUpdateProfile (
IN EFI_PHYSICAL_ADDRESS CallerAddress,
IN MEMORY_PROFILE_ACTION Action,
IN EFI_MEMORY_TYPE MemoryType, // Valid for AllocatePages/AllocatePool
IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool
IN VOID *Buffer
);
#endif

View File

@@ -52,6 +52,7 @@
Mem/Page.c
Mem/MemData.c
Mem/Imem.h
Mem/MemoryProfileRecord.c
FwVolBlock/FwVolBlock.c
FwVolBlock/FwVolBlock.h
FwVol/FwVolWrite.c
@@ -120,6 +121,8 @@
gIdleLoopEventGuid
gEventExitBootServicesFailedGuid ## SOMETIMES_PRODUCES ## Event
gEfiVectorHandoffTableGuid ## SOMETIMES_PRODUCES ## SystemTable
gEdkiiMemoryProfileGuid ## SOMETIMES_PRODUCES ## GUID # Install protocol
gZeroGuid ## SOMETIMES_CONSUMES ## GUID
[Ppis]
gEfiVectorHandoffInfoPpiGuid ## UNDEFINED # HOB
@@ -177,6 +180,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressRuntimeCodePageNumber ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxEfiSystemTablePointerAddress ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileMemoryType ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfilePropertyMask ## CONSUMES
# [Hob]
# RESOURCE_DESCRIPTOR ## CONSUMES
@@ -190,4 +195,4 @@
#
[UserExtensions.TianoCore."ExtraFiles"]
DxeCoreExtra.uni
DxeCoreExtra.uni

View File

@@ -268,6 +268,8 @@ DxeMain (
//
CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength);
MemoryProfileInit (HobStart);
//
// Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData
// Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table
@@ -382,6 +384,8 @@ DxeMain (
Status = CoreInitializeEventServices ();
ASSERT_EFI_ERROR (Status);
MemoryProfileInstallProtocol ();
//
// Get persisted vector hand-off info from GUIDeed HOB again due to HobStart may be updated,
// and install configuration table

View File

@@ -1626,6 +1626,7 @@ CoreStartImage (
// Subsequent calls to LongJump() cause a non-zero value to be returned by SetJump().
//
if (SetJumpFlag == 0) {
RegisterMemoryProfileImage (Image, (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION ? EFI_FV_FILETYPE_APPLICATION : EFI_FV_FILETYPE_DRIVER));
//
// Call the image's entry point
//
@@ -1851,6 +1852,7 @@ CoreUnloadImage (
Status = EFI_INVALID_PARAMETER;
goto Done;
}
UnregisterMemoryProfileImage (Image);
if (Image->Started) {
//

View File

@@ -16,56 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef _IMAGE_H_
#define _IMAGE_H_
#define LOADED_IMAGE_PRIVATE_DATA_SIGNATURE SIGNATURE_32('l','d','r','i')
typedef struct {
UINTN Signature;
/// Image handle
EFI_HANDLE Handle;
/// Image type
UINTN Type;
/// If entrypoint has been called
BOOLEAN Started;
/// The image's entry point
EFI_IMAGE_ENTRY_POINT EntryPoint;
/// loaded image protocol
EFI_LOADED_IMAGE_PROTOCOL Info;
/// Location in memory
EFI_PHYSICAL_ADDRESS ImageBasePage;
/// Number of pages
UINTN NumberOfPages;
/// Original fixup data
CHAR8 *FixupData;
/// Tpl of started image
EFI_TPL Tpl;
/// Status returned by started image
EFI_STATUS Status;
/// Size of ExitData from started image
UINTN ExitDataSize;
/// Pointer to exit data from started image
VOID *ExitData;
/// Pointer to pool allocation for context save/retore
VOID *JumpBuffer;
/// Pointer to buffer for context save/retore
BASE_LIBRARY_JUMP_BUFFER *JumpContext;
/// Machine type from PE image
UINT16 Machine;
/// EBC Protocol pointer
EFI_EBC_PROTOCOL *Ebc;
/// Runtime image list
EFI_RUNTIME_IMAGE_ENTRY *RuntimeData;
/// Pointer to Loaded Image Device Path Protocl
EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
/// PeCoffLoader ImageContext
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
/// Status returned by LoadImage() service.
EFI_STATUS LoadImageStatus;
} LOADED_IMAGE_PRIVATE_DATA;
#define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \
CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE)
#define LOAD_PE32_IMAGE_PRIVATE_DATA_SIGNATURE SIGNATURE_32('l','p','e','i')
typedef struct {

File diff suppressed because it is too large Load Diff

View File

@@ -1106,7 +1106,7 @@ FindFreePages (
**/
EFI_STATUS
EFIAPI
CoreAllocatePages (
CoreInternalAllocatePages (
IN EFI_ALLOCATE_TYPE Type,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN NumberOfPages,
@@ -1192,6 +1192,41 @@ Done:
return Status;
}
/**
Allocates pages from the memory map.
@param Type The type of allocation to perform
@param MemoryType The type of memory to turn the allocated pages
into
@param NumberOfPages The number of pages to allocate
@param Memory A pointer to receive the base allocated memory
address
@return Status. On success, Memory is filled in with the base address allocated
@retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in
spec.
@retval EFI_NOT_FOUND Could not allocate pages match the requirement.
@retval EFI_OUT_OF_RESOURCES No enough pages to allocate.
@retval EFI_SUCCESS Pages successfully allocated.
**/
EFI_STATUS
EFIAPI
CoreAllocatePages (
IN EFI_ALLOCATE_TYPE Type,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN NumberOfPages,
OUT EFI_PHYSICAL_ADDRESS *Memory
)
{
EFI_STATUS Status;
Status = CoreInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory);
if (!EFI_ERROR (Status)) {
CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionAllocatePages, MemoryType, EFI_PAGES_TO_SIZE (NumberOfPages), (VOID *) (UINTN) *Memory);
}
return Status;
}
/**
Frees previous allocated pages.
@@ -1206,7 +1241,7 @@ Done:
**/
EFI_STATUS
EFIAPI
CoreFreePages (
CoreInternalFreePages (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NumberOfPages
)
@@ -1267,6 +1302,33 @@ Done:
return Status;
}
/**
Frees previous allocated pages.
@param Memory Base address of memory being freed
@param NumberOfPages The number of pages to free
@retval EFI_NOT_FOUND Could not find the entry that covers the range
@retval EFI_INVALID_PARAMETER Address not aligned
@return EFI_SUCCESS -Pages successfully freed.
**/
EFI_STATUS
EFIAPI
CoreFreePages (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NumberOfPages
)
{
EFI_STATUS Status;
Status = CoreInternalFreePages (Memory, NumberOfPages);
if (!EFI_ERROR (Status)) {
CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionFreePages, 0, EFI_PAGES_TO_SIZE (NumberOfPages), (VOID *) (UINTN) Memory);
}
return Status;
}
/**
This function checks to see if the last memory map descriptor in a memory map
can be merged with any of the other memory map descriptors in a memorymap.

View File

@@ -175,7 +175,7 @@ LookupPoolHead (
**/
EFI_STATUS
EFIAPI
CoreAllocatePool (
CoreInternalAllocatePool (
IN EFI_MEMORY_TYPE PoolType,
IN UINTN Size,
OUT VOID **Buffer
@@ -218,7 +218,35 @@ CoreAllocatePool (
return (*Buffer != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
}
/**
Allocate pool of a particular type.
@param PoolType Type of pool to allocate
@param Size The amount of pool to allocate
@param Buffer The address to return a pointer to the allocated
pool
@retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL.
@retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed.
@retval EFI_SUCCESS Pool successfully allocated.
**/
EFI_STATUS
EFIAPI
CoreAllocatePool (
IN EFI_MEMORY_TYPE PoolType,
IN UINTN Size,
OUT VOID **Buffer
)
{
EFI_STATUS Status;
Status = CoreInternalAllocatePool (PoolType, Size, Buffer);
if (!EFI_ERROR (Status)) {
CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionAllocatePool, PoolType, Size, *Buffer);
}
return Status;
}
/**
Internal function to allocate pool of a particular type.
@@ -373,7 +401,7 @@ Done:
**/
EFI_STATUS
EFIAPI
CoreFreePool (
CoreInternalFreePool (
IN VOID *Buffer
)
{
@@ -389,7 +417,29 @@ CoreFreePool (
return Status;
}
/**
Frees pool.
@param Buffer The allocated pool entry to free
@retval EFI_INVALID_PARAMETER Buffer is not a valid value.
@retval EFI_SUCCESS Pool successfully freed.
**/
EFI_STATUS
EFIAPI
CoreFreePool (
IN VOID *Buffer
)
{
EFI_STATUS Status;
Status = CoreInternalFreePool (Buffer);
if (!EFI_ERROR (Status)) {
CoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionFreePool, 0, 0, Buffer);
}
return Status;
}
/**
Internal function to free a pool entry.
@@ -558,3 +608,4 @@ CoreFreePoolI (
return EFI_SUCCESS;
}

View File

@@ -874,10 +874,12 @@ SmmDispatcher (
//
// For each SMM driver, pass NULL as ImageHandle
//
RegisterSmramProfileImage (DriverEntry, TRUE);
PERF_START (DriverEntry->ImageHandle, "StartImage:", NULL, 0);
Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, gST);
PERF_END (DriverEntry->ImageHandle, "StartImage:", NULL, 0);
if (EFI_ERROR(Status)){
UnregisterSmramProfileImage (DriverEntry, TRUE);
SmmFreePages(DriverEntry->ImageBuffer, DriverEntry->NumberOfPage);
}

View File

@@ -1,7 +1,7 @@
/** @file
SMM Memory page management functions.
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
@@ -16,11 +16,6 @@
#define TRUNCATE_TO_PAGES(a) ((a) >> EFI_PAGE_SHIFT)
typedef struct {
LIST_ENTRY Link;
UINTN NumberOfPages;
} FREE_PAGE_LIST;
LIST_ENTRY mSmmMemoryMap = INITIALIZE_LIST_HEAD_VARIABLE (mSmmMemoryMap);
/**
@@ -151,7 +146,7 @@ InternalAllocAddress (
**/
EFI_STATUS
EFIAPI
SmmAllocatePages (
SmmInternalAllocatePages (
IN EFI_ALLOCATE_TYPE Type,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN NumberOfPages,
@@ -202,6 +197,40 @@ SmmAllocatePages (
return EFI_SUCCESS;
}
/**
Allocates pages from the memory map.
@param Type The type of allocation to perform.
@param MemoryType The type of memory to turn the allocated pages
into.
@param NumberOfPages The number of pages to allocate.
@param Memory A pointer to receive the base allocated memory
address.
@retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec.
@retval EFI_NOT_FOUND Could not allocate pages match the requirement.
@retval EFI_OUT_OF_RESOURCES No enough pages to allocate.
@retval EFI_SUCCESS Pages successfully allocated.
**/
EFI_STATUS
EFIAPI
SmmAllocatePages (
IN EFI_ALLOCATE_TYPE Type,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN NumberOfPages,
OUT EFI_PHYSICAL_ADDRESS *Memory
)
{
EFI_STATUS Status;
Status = SmmInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory);
if (!EFI_ERROR (Status)) {
SmmCoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionAllocatePages, MemoryType, EFI_PAGES_TO_SIZE (NumberOfPages), (VOID *) (UINTN) *Memory);
}
return Status;
}
/**
Internal Function. Merge two adjacent nodes.
@@ -242,7 +271,7 @@ InternalMergeNodes (
**/
EFI_STATUS
EFIAPI
SmmFreePages (
SmmInternalFreePages (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NumberOfPages
)
@@ -293,6 +322,33 @@ SmmFreePages (
return EFI_SUCCESS;
}
/**
Frees previous allocated pages.
@param Memory Base address of memory being freed.
@param NumberOfPages The number of pages to free.
@retval EFI_NOT_FOUND Could not find the entry that covers the range.
@retval EFI_INVALID_PARAMETER Address not aligned.
@return EFI_SUCCESS Pages successfully freed.
**/
EFI_STATUS
EFIAPI
SmmFreePages (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NumberOfPages
)
{
EFI_STATUS Status;
Status = SmmInternalFreePages (Memory, NumberOfPages);
if (!EFI_ERROR (Status)) {
SmmCoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionFreePages, 0, EFI_PAGES_TO_SIZE (NumberOfPages), (VOID *) (UINTN) Memory);
}
return Status;
}
/**
Add free SMRAM region for use by memory service.

View File

@@ -1,7 +1,7 @@
/** @file
SMM Core Main Entry Point
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
@@ -82,6 +82,9 @@ SMM_CORE_SMI_HANDLERS mSmmCoreSmiHandlers[] = {
{ NULL, NULL, NULL, FALSE }
};
UINTN mFullSmramRangeCount;
EFI_SMRAM_DESCRIPTOR *mFullSmramRanges;
/**
Place holder function until all the SMM System Table Service are available.
@@ -226,6 +229,8 @@ SmmReadyToLockHandler (
gST = NULL;
gBS = NULL;
SmramProfileReadyToLock ();
return Status;
}
@@ -401,6 +406,16 @@ SmmMain (
//
SmmInitializeMemoryServices (gSmmCorePrivate->SmramRangeCount, gSmmCorePrivate->SmramRanges);
SmramProfileInit ();
//
// Copy FullSmramRanges to SMRAM
//
mFullSmramRangeCount = gSmmCorePrivate->FullSmramRangeCount;
mFullSmramRanges = AllocatePool (mFullSmramRangeCount * sizeof (EFI_SMRAM_DESCRIPTOR));
ASSERT (mFullSmramRanges != NULL);
CopyMem (mFullSmramRanges, gSmmCorePrivate->FullSmramRanges, mFullSmramRangeCount * sizeof (EFI_SMRAM_DESCRIPTOR));
//
// Register all SMI Handlers required by the SMM Core
//
@@ -412,6 +427,8 @@ SmmMain (
);
ASSERT_EFI_ERROR (Status);
}
RegisterSmramProfileHandler ();
return EFI_SUCCESS;
}

View File

@@ -2,7 +2,7 @@
The internal header file includes the common header files, defines
internal structure and functions used by SmmCore module.
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
@@ -33,6 +33,8 @@
#include <Guid/Apriori.h>
#include <Guid/EventGroup.h>
#include <Guid/EventLegacyBios.h>
#include <Guid/ZeroGuid.h>
#include <Guid/MemoryProfile.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
@@ -271,6 +273,31 @@ SmmAllocatePages (
OUT EFI_PHYSICAL_ADDRESS *Memory
);
/**
Allocates pages from the memory map.
@param Type The type of allocation to perform
@param MemoryType The type of memory to turn the allocated pages
into
@param NumberOfPages The number of pages to allocate
@param Memory A pointer to receive the base allocated memory
address
@retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec.
@retval EFI_NOT_FOUND Could not allocate pages match the requirement.
@retval EFI_OUT_OF_RESOURCES No enough pages to allocate.
@retval EFI_SUCCESS Pages successfully allocated.
**/
EFI_STATUS
EFIAPI
SmmInternalAllocatePages (
IN EFI_ALLOCATE_TYPE Type,
IN EFI_MEMORY_TYPE MemoryType,
IN UINTN NumberOfPages,
OUT EFI_PHYSICAL_ADDRESS *Memory
);
/**
Frees previous allocated pages.
@@ -289,6 +316,24 @@ SmmFreePages (
IN UINTN NumberOfPages
);
/**
Frees previous allocated pages.
@param Memory Base address of memory being freed
@param NumberOfPages The number of pages to free
@retval EFI_NOT_FOUND Could not find the entry that covers the range
@retval EFI_INVALID_PARAMETER Address not aligned
@return EFI_SUCCESS Pages successfully freed.
**/
EFI_STATUS
EFIAPI
SmmInternalFreePages (
IN EFI_PHYSICAL_ADDRESS Memory,
IN UINTN NumberOfPages
);
/**
Allocate pool of a particular type.
@@ -310,6 +355,27 @@ SmmAllocatePool (
OUT VOID **Buffer
);
/**
Allocate pool of a particular type.
@param PoolType Type of pool to allocate
@param Size The amount of pool to allocate
@param Buffer The address to return a pointer to the allocated
pool
@retval EFI_INVALID_PARAMETER PoolType not valid
@retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed.
@retval EFI_SUCCESS Pool successfully allocated.
**/
EFI_STATUS
EFIAPI
SmmInternalAllocatePool (
IN EFI_MEMORY_TYPE PoolType,
IN UINTN Size,
OUT VOID **Buffer
);
/**
Frees pool.
@@ -325,6 +391,21 @@ SmmFreePool (
IN VOID *Buffer
);
/**
Frees pool.
@param Buffer The allocated pool entry to free
@retval EFI_INVALID_PARAMETER Buffer is not a valid value.
@retval EFI_SUCCESS Pool successfully freed.
**/
EFI_STATUS
EFIAPI
SmmInternalFreePool (
IN VOID *Buffer
);
/**
Installs a protocol interface into the boot services environment.
@@ -741,4 +822,101 @@ SmmIsSchedulable (
IN EFI_SMM_DRIVER_ENTRY *DriverEntry
);
//
// SmramProfile
//
/**
Initialize SMRAM profile.
**/
VOID
SmramProfileInit (
VOID
);
/**
Register SMM image to SMRAM profile.
@param DriverEntry SMM image info.
@param RegisterToDxe Register image to DXE.
@retval TRUE Register success.
@retval FALSE Register fail.
**/
BOOLEAN
RegisterSmramProfileImage (
IN EFI_SMM_DRIVER_ENTRY *DriverEntry,
IN BOOLEAN RegisterToDxe
);
/**
Unregister image from SMRAM profile.
@param DriverEntry SMM image info.
@param UnregisterToDxe Unregister image from DXE.
@retval TRUE Unregister success.
@retval FALSE Unregister fail.
**/
BOOLEAN
UnregisterSmramProfileImage (
IN EFI_SMM_DRIVER_ENTRY *DriverEntry,
IN BOOLEAN UnregisterToDxe
);
/**
Update SMRAM profile information.
@param CallerAddress Address of caller who call Allocate or Free.
@param Action This Allocate or Free action.
@param MemoryType Memory type.
@param Size Buffer size.
@param Buffer Buffer address.
@retval TRUE Profile udpate success.
@retval FALSE Profile update fail.
**/
BOOLEAN
SmmCoreUpdateProfile (
IN EFI_PHYSICAL_ADDRESS CallerAddress,
IN MEMORY_PROFILE_ACTION Action,
IN EFI_MEMORY_TYPE MemoryType, // Valid for AllocatePages/AllocatePool
IN UINTN Size, // Valid for AllocatePages/FreePages/AllocatePool
IN VOID *Buffer
);
/**
Register SMRAM profile handler.
**/
VOID
RegisterSmramProfileHandler (
VOID
);
/**
SMRAM profile ready to lock callback function.
**/
VOID
SmramProfileReadyToLock (
VOID
);
/**
Dump SMRAM infromation.
**/
VOID
DumpSmramInfo (
VOID
);
extern UINTN mFullSmramRangeCount;
extern EFI_SMRAM_DESCRIPTOR *mFullSmramRanges;
#endif

View File

@@ -37,6 +37,7 @@
Dispatcher.c
Smi.c
InstallConfigurationTable.c
SmramProfileRecord.c
[Packages]
MdePkg/MdePkg.dec
@@ -73,12 +74,18 @@
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadFixAddressSmmCodePageNumber ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfileMemoryType ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMemoryProfilePropertyMask ## CONSUMES
[Guids]
gAprioriGuid ## SOMETIMES_CONSUMES ## File
gEfiEventDxeDispatchGuid ## PRODUCES ## GUID # SmiHandlerRegister
gEfiEventLegacyBootGuid ## PRODUCES ## GUID # SmiHandlerRegister
gEfiEndOfDxeEventGroupGuid ## PRODUCES ## GUID # SmiHandlerRegister
## SOMETIMES_CONSUMES ## GUID # Locate protocol
## SOMETIMES_PRODUCES ## GUID # SmiHandlerRegister
gEdkiiMemoryProfileGuid
gZeroGuid ## SOMETIMES_CONSUMES ## GUID
[UserExtensions.TianoCore."ExtraFiles"]
PiSmmCoreExtra.uni

View File

@@ -2,7 +2,7 @@
The internal header file that declared a data structure that is shared
between the SMM IPL and the SMM Core.
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
@@ -116,6 +116,57 @@ typedef struct {
/// 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;
//
// Page management
//
typedef struct {
LIST_ENTRY Link;
UINTN NumberOfPages;
} FREE_PAGE_LIST;
extern LIST_ENTRY mSmmMemoryMap;
//
// Pool management
//
//
// MIN_POOL_SHIFT must not be less than 5
//
#define MIN_POOL_SHIFT 6
#define MIN_POOL_SIZE (1 << MIN_POOL_SHIFT)
//
// MAX_POOL_SHIFT must not be less than EFI_PAGE_SHIFT - 1
//
#define MAX_POOL_SHIFT (EFI_PAGE_SHIFT - 1)
#define MAX_POOL_SIZE (1 << MAX_POOL_SHIFT)
//
// MAX_POOL_INDEX are calculated by maximum and minimum pool sizes
//
#define MAX_POOL_INDEX (MAX_POOL_SHIFT - MIN_POOL_SHIFT + 1)
typedef struct {
UINTN Size;
BOOLEAN Available;
} POOL_HEADER;
typedef struct {
POOL_HEADER Header;
LIST_ENTRY Link;
} FREE_POOL_HEADER;
extern LIST_ENTRY mSmmPoolLists[MAX_POOL_INDEX];
#endif

View File

@@ -979,6 +979,13 @@ ExecuteSmmCoreFromSmram (
//
DEBUG ((DEBUG_INFO, "SMM IPL calling SMM Core at SMRAM address %p\n", (VOID *)(UINTN)ImageContext.EntryPoint));
gSmmCorePrivate->PiSmmCoreImageBase = ImageContext.ImageAddress;
gSmmCorePrivate->PiSmmCoreImageSize = ImageContext.ImageSize;
DEBUG ((DEBUG_INFO, "PiSmmCoreImageBase - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageBase));
DEBUG ((DEBUG_INFO, "PiSmmCoreImageSize - 0x%016lx\n", gSmmCorePrivate->PiSmmCoreImageSize));
gSmmCorePrivate->PiSmmCoreEntryPoint = ImageContext.EntryPoint;
//
// Execute image
//
@@ -1076,6 +1083,14 @@ SmmIplEntry (
gSmmCorePrivate->SmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
//
// Save a full copy
//
gSmmCorePrivate->FullSmramRangeCount = gSmmCorePrivate->SmramRangeCount;
gSmmCorePrivate->FullSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool (Size);
ASSERT (gSmmCorePrivate->FullSmramRanges != NULL);
CopyMem (gSmmCorePrivate->FullSmramRanges, gSmmCorePrivate->SmramRanges, Size);
//
// Open all SMRAM ranges
//

View File

@@ -1,7 +1,7 @@
/** @file
SMM Memory pool management functions.
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
@@ -14,33 +14,6 @@
#include "PiSmmCore.h"
//
// MIN_POOL_SHIFT must not be less than 5
//
#define MIN_POOL_SHIFT 6
#define MIN_POOL_SIZE (1 << MIN_POOL_SHIFT)
//
// MAX_POOL_SHIFT must not be less than EFI_PAGE_SHIFT - 1
//
#define MAX_POOL_SHIFT (EFI_PAGE_SHIFT - 1)
#define MAX_POOL_SIZE (1 << MAX_POOL_SHIFT)
//
// MAX_POOL_INDEX are calculated by maximum and minimum pool sizes
//
#define MAX_POOL_INDEX (MAX_POOL_SHIFT - MIN_POOL_SHIFT + 1)
typedef struct {
UINTN Size;
BOOLEAN Available;
} POOL_HEADER;
typedef struct {
POOL_HEADER Header;
LIST_ENTRY Link;
} FREE_POOL_HEADER;
LIST_ENTRY mSmmPoolLists[MAX_POOL_INDEX];
//
// To cache the SMRAM base since when Loading modules At fixed address feature is enabled,
@@ -141,16 +114,18 @@ InternalAllocPoolByIndex (
OUT FREE_POOL_HEADER **FreePoolHdr
)
{
EFI_STATUS Status;
FREE_POOL_HEADER *Hdr;
EFI_STATUS Status;
FREE_POOL_HEADER *Hdr;
EFI_PHYSICAL_ADDRESS Address;
ASSERT (PoolIndex <= MAX_POOL_INDEX);
Status = EFI_SUCCESS;
if (PoolIndex == MAX_POOL_INDEX) {
Hdr = (FREE_POOL_HEADER *)AllocatePages (EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1));
if (Hdr == NULL) {
Status = SmmInternalAllocatePages (AllocateAnyPages, EfiRuntimeServicesData, EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1), &Address);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
Hdr = (FREE_POOL_HEADER *) (UINTN) Address;
} else if (!IsListEmpty (&mSmmPoolLists[PoolIndex])) {
Hdr = BASE_CR (GetFirstNode (&mSmmPoolLists[PoolIndex]), FREE_POOL_HEADER, Link);
RemoveEntryList (&Hdr->Link);
@@ -214,7 +189,7 @@ InternalFreePoolByIndex (
**/
EFI_STATUS
EFIAPI
SmmAllocatePool (
SmmInternalAllocatePool (
IN EFI_MEMORY_TYPE PoolType,
IN UINTN Size,
OUT VOID **Buffer
@@ -234,7 +209,7 @@ SmmAllocatePool (
Size += sizeof (*PoolHdr);
if (Size > MAX_POOL_SIZE) {
Size = EFI_SIZE_TO_PAGES (Size);
Status = SmmAllocatePages (AllocateAnyPages, PoolType, Size, &Address);
Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType, Size, &Address);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -257,6 +232,36 @@ SmmAllocatePool (
return Status;
}
/**
Allocate pool of a particular type.
@param PoolType Type of pool to allocate.
@param Size The amount of pool to allocate.
@param Buffer The address to return a pointer to the allocated
pool.
@retval EFI_INVALID_PARAMETER PoolType not valid.
@retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed.
@retval EFI_SUCCESS Pool successfully allocated.
**/
EFI_STATUS
EFIAPI
SmmAllocatePool (
IN EFI_MEMORY_TYPE PoolType,
IN UINTN Size,
OUT VOID **Buffer
)
{
EFI_STATUS Status;
Status = SmmInternalAllocatePool (PoolType, Size, Buffer);
if (!EFI_ERROR (Status)) {
SmmCoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionAllocatePool, PoolType, Size, *Buffer);
}
return Status;
}
/**
Frees pool.
@@ -268,7 +273,7 @@ SmmAllocatePool (
**/
EFI_STATUS
EFIAPI
SmmFreePool (
SmmInternalFreePool (
IN VOID *Buffer
)
{
@@ -284,10 +289,34 @@ SmmFreePool (
if (FreePoolHdr->Header.Size > MAX_POOL_SIZE) {
ASSERT (((UINTN)FreePoolHdr & EFI_PAGE_MASK) == 0);
ASSERT ((FreePoolHdr->Header.Size & EFI_PAGE_MASK) == 0);
return SmmFreePages (
return SmmInternalFreePages (
(EFI_PHYSICAL_ADDRESS)(UINTN)FreePoolHdr,
EFI_SIZE_TO_PAGES (FreePoolHdr->Header.Size)
);
}
return InternalFreePoolByIndex (FreePoolHdr);
}
/**
Frees pool.
@param Buffer The allocated pool entry to free.
@retval EFI_INVALID_PARAMETER Buffer is not a valid value.
@retval EFI_SUCCESS Pool successfully freed.
**/
EFI_STATUS
EFIAPI
SmmFreePool (
IN VOID *Buffer
)
{
EFI_STATUS Status;
Status = SmmInternalFreePool (Buffer);
if (!EFI_ERROR (Status)) {
SmmCoreUpdateProfile ((EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0), MemoryProfileActionFreePool, 0, 0, Buffer);
}
return Status;
}

File diff suppressed because it is too large Load Diff