Enhance PiSmmCoreMemoryAllocationLib Free function implementation to call gSmst or gBS Free service according to the buffer in or out of SMRAM range.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10701 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lgao4 2010-07-28 01:08:13 +00:00
parent 1d733f731f
commit 344015785a
2 changed files with 125 additions and 3 deletions

View File

@ -14,11 +14,93 @@
#include <PiSmm.h>
#include <Protocol/SmmAccess2.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseMemoryLib.h>
#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);
}
/**
Check whether the start address of buffer is within any of the SMRAM ranges.
@param[in] Buffer The pointer to the buffer to be checked.
@retval TURE The buffer is in SMRAM ranges.
@retval FALSE The buffer is out of SMRAM ranges.
**/
BOOLEAN
EFIAPI
BufferInSmram (
IN VOID *Buffer
)
{
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))) {
return TRUE;
}
}
return FALSE;
}
/**
Allocates one or more 4KB pages of a certain memory type.
@ -145,7 +227,19 @@ FreePages (
EFI_STATUS Status;
ASSERT (Pages != 0);
if (BufferInSmram (Buffer)) {
//
// When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service.
// So, SmmFreePages() service is used to free it.
//
Status = SmmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
} else {
//
// When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
// So, gBS->FreePages() service is used to free it.
//
Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
}
ASSERT_EFI_ERROR (Status);
}
@ -342,7 +436,19 @@ FreeAlignedPages (
EFI_STATUS Status;
ASSERT (Pages != 0);
if (BufferInSmram (Buffer)) {
//
// When Buffer is in SMRAM range, it should be allocated by SmmAllocatePages() service.
// So, SmmFreePages() service is used to free it.
//
Status = SmmFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
} else {
//
// When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePages() service.
// So, gBS->FreePages() service is used to free it.
//
Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);
}
ASSERT_EFI_ERROR (Status);
}
@ -808,7 +914,19 @@ FreePool (
{
EFI_STATUS Status;
if (BufferInSmram (Buffer)) {
//
// When Buffer is in SMRAM range, it should be allocated by SmmAllocatePool() service.
// So, SmmFreePool() service is used to free it.
//
Status = SmmFreePool (Buffer);
} else {
//
// When Buffer is out of SMRAM range, it should be allocated by gBS->AllocatePool() service.
// So, gBS->FreePool() service is used to free it.
//
Status = gBS->FreePool (Buffer);
}
ASSERT_EFI_ERROR (Status);
}

View File

@ -40,3 +40,7 @@
[LibraryClasses]
DebugLib
BaseMemoryLib
UefiBootServicesTableLib
[Protocols]
gEfiSmmAccess2ProtocolGuid ## CONSUMES