Revision: 18031
http://sourceforge.net/p/edk2/code/18031
Author: jljusten
Date: 2015-07-26 07:38:12 +0000 (Sun, 26 Jul 2015)
Log Message:
-----------
MdeModulePkg PiSmmCore: Remove a hidden assumption of SMRAM reservation
that assumes the SMRAM reserved range is only at the end of the SMRAM
descriptor.
//
// This range has reserved area, calculate the left free size
//
gSmmCorePrivate->SmramRanges[Index].PhysicalSize =
SmramResRegion->SmramReservedStart -
gSmmCorePrivate->SmramRanges[Index].CpuStart;
Imagine the following scenario where we just reserve the first page of the
SMRAM range:
SMRAM Descriptor:
Start: 0x80000000
Size: 0x02000000
Reserved Range:
Start: 0x80000000
Size: 0x00001000
In this case the adjustment to the SMRAM range size yields zero: ReservedStart
- SMRAM Start is 0x80000000 - 0x80000000 = 0.
So even though most of the range is still free the IPL code decides its
unusable.
The problem comes from the email thread: [edk2] PiSmmIpl SMRAM Reservation
Logic.
http://thread.gmane.org/gmane.comp.bios.tianocore.devel/15268
Also to follow the idea in the email thread, the patch is to
1. Keep only one copy of full SMRAM ranges in gSmmCorePrivate->SmramRanges,
split record for SmmConfiguration->SmramReservedRegions and SMM Core that
will be marked to be EFI_ALLOCATED in gSmmCorePrivate->SmramRanges.
2. Handle SmmConfiguration->SmramReservedRegions at beginning of, at end of,
in the middle of, or cross multiple SmramRanges.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <[email protected]>
Reviewed-by: Jiewen Yao <[email protected]>
Modified Paths:
--------------
trunk/edk2/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
trunk/edk2/MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h
trunk/edk2/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c
trunk/edk2/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c
trunk/edk2/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationServices.h
Modified: trunk/edk2/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
===================================================================
--- trunk/edk2/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c 2015-07-26 07:38:06 UTC
(rev 18030)
+++ trunk/edk2/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c 2015-07-26 07:38:12 UTC
(rev 18031)
@@ -523,10 +523,10 @@
//
// Copy FullSmramRanges to SMRAM
//
- mFullSmramRangeCount = gSmmCorePrivate->FullSmramRangeCount;
+ mFullSmramRangeCount = gSmmCorePrivate->SmramRangeCount;
mFullSmramRanges = AllocatePool (mFullSmramRangeCount * sizeof
(EFI_SMRAM_DESCRIPTOR));
ASSERT (mFullSmramRanges != NULL);
- CopyMem (mFullSmramRanges, gSmmCorePrivate->FullSmramRanges,
mFullSmramRangeCount * sizeof (EFI_SMRAM_DESCRIPTOR));
+ CopyMem (mFullSmramRanges, gSmmCorePrivate->SmramRanges,
mFullSmramRangeCount * sizeof (EFI_SMRAM_DESCRIPTOR));
//
// Register all SMI Handlers required by the SMM Core
Modified: trunk/edk2/MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h
===================================================================
--- trunk/edk2/MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h
2015-07-26 07:38:06 UTC (rev 18030)
+++ trunk/edk2/MdeModulePkg/Core/PiSmmCore/PiSmmCorePrivateData.h
2015-07-26 07:38:12 UTC (rev 18031)
@@ -120,9 +120,6 @@
EFI_PHYSICAL_ADDRESS PiSmmCoreImageBase;
UINT64 PiSmmCoreImageSize;
EFI_PHYSICAL_ADDRESS PiSmmCoreEntryPoint;
-
- UINTN FullSmramRangeCount;
- EFI_SMRAM_DESCRIPTOR *FullSmramRanges;
} SMM_CORE_PRIVATE_DATA;
#endif
Modified: trunk/edk2/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c
===================================================================
--- trunk/edk2/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c 2015-07-26 07:38:06 UTC
(rev 18030)
+++ trunk/edk2/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c 2015-07-26 07:38:12 UTC
(rev 18031)
@@ -861,17 +861,21 @@
/**
Load the SMM Core image into SMRAM and executes the SMM Core from SMRAM.
- @param[in] SmramRange Descriptor for the range of SMRAM to reload the
- currently executing image.
- @param[in] Context Context to pass into SMM Core
+ @param[in, out] SmramRange Descriptor for the range of SMRAM to
reload the
+ currently executing image, the rang of
SMRAM to
+ hold SMM Core will be excluded.
+ @param[in, out] SmramRangeSmmCore Descriptor for the range of SMRAM to
hold SMM Core.
+ @param[in] Context Context to pass into SMM Core
+
@return EFI_STATUS
**/
EFI_STATUS
ExecuteSmmCoreFromSmram (
- IN EFI_SMRAM_DESCRIPTOR *SmramRange,
- IN VOID *Context
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramRange,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramRangeSmmCore,
+ IN VOID *Context
)
{
EFI_STATUS Status;
@@ -879,7 +883,6 @@
UINTN SourceSize;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
UINTN PageCount;
- EFI_PHYSICAL_ADDRESS DestinationBuffer;
EFI_IMAGE_ENTRY_POINT EntryPoint;
//
@@ -924,7 +927,7 @@
// Since the memory range to load SMM CORE will be cut out in SMM core,
so no need to allocate and free this range
//
PageCount = 0;
- } else {
+ } else {
DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR: Loading module at fixed
address at address failed\n"));
//
// Allocate memory for the image being loaded from the
EFI_SRAM_DESCRIPTOR
@@ -936,12 +939,15 @@
ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount));
SmramRange->PhysicalSize -= EFI_PAGES_TO_SIZE (PageCount);
- DestinationBuffer = SmramRange->CpuStart + SmramRange->PhysicalSize;
+ SmramRangeSmmCore->CpuStart = SmramRange->CpuStart +
SmramRange->PhysicalSize;
+ SmramRangeSmmCore->PhysicalStart = SmramRange->PhysicalStart +
SmramRange->PhysicalSize;
+ SmramRangeSmmCore->RegionState = SmramRange->RegionState | EFI_ALLOCATED;
+ SmramRangeSmmCore->PhysicalSize = EFI_PAGES_TO_SIZE (PageCount);
//
- // Align buffer on section boundry
+ // Align buffer on section boundary
//
- ImageContext.ImageAddress = DestinationBuffer;
+ ImageContext.ImageAddress = SmramRangeSmmCore->CpuStart;
}
} else {
//
@@ -954,12 +960,15 @@
ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount));
SmramRange->PhysicalSize -= EFI_PAGES_TO_SIZE (PageCount);
- DestinationBuffer = SmramRange->CpuStart + SmramRange->PhysicalSize;
+ SmramRangeSmmCore->CpuStart = SmramRange->CpuStart +
SmramRange->PhysicalSize;
+ SmramRangeSmmCore->PhysicalStart = SmramRange->PhysicalStart +
SmramRange->PhysicalSize;
+ SmramRangeSmmCore->RegionState = SmramRange->RegionState | EFI_ALLOCATED;
+ SmramRangeSmmCore->PhysicalSize = EFI_PAGES_TO_SIZE (PageCount);
//
- // Align buffer on section boundry
+ // Align buffer on section boundary
//
- ImageContext.ImageAddress = DestinationBuffer;
+ ImageContext.ImageAddress = SmramRangeSmmCore->CpuStart;
}
ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
@@ -1006,20 +1015,424 @@
}
//
- // If the load operation, relocate operation, or the image execution return
an
- // error, then free memory allocated from the EFI_SRAM_DESCRIPTOR specified
by
- // SmramRange
+ // Always free memory allocted by GetFileBufferByFilePath ()
//
- if (EFI_ERROR (Status)) {
- SmramRange->PhysicalSize += EFI_PAGES_TO_SIZE (PageCount);
+ FreePool (SourceBuffer);
+
+ return Status;
+}
+
+/**
+ SMM split SMRAM entry.
+
+ @param[in, out] RangeToCompare Pointer to EFI_SMRAM_DESCRIPTOR
to compare.
+ @param[in, out] ReservedRangeToCompare Pointer to
EFI_SMM_RESERVED_SMRAM_REGION to compare.
+ @param[out] Ranges Output pointer to hold split
EFI_SMRAM_DESCRIPTOR entry.
+ @param[in, out] RangeCount Pointer to range count.
+ @param[out] ReservedRanges Output pointer to hold split
EFI_SMM_RESERVED_SMRAM_REGION entry.
+ @param[in, out] ReservedRangeCount Pointer to reserved range count.
+ @param[out] FinalRanges Output pointer to hold split
final EFI_SMRAM_DESCRIPTOR entry
+ that no need to be split anymore.
+ @param[in, out] FinalRangeCount Pointer to final range count.
+
+**/
+VOID
+SmmSplitSmramEntry (
+ IN OUT EFI_SMRAM_DESCRIPTOR *RangeToCompare,
+ IN OUT EFI_SMM_RESERVED_SMRAM_REGION *ReservedRangeToCompare,
+ OUT EFI_SMRAM_DESCRIPTOR *Ranges,
+ IN OUT UINTN *RangeCount,
+ OUT EFI_SMM_RESERVED_SMRAM_REGION *ReservedRanges,
+ IN OUT UINTN *ReservedRangeCount,
+ OUT EFI_SMRAM_DESCRIPTOR *FinalRanges,
+ IN OUT UINTN *FinalRangeCount
+ )
+{
+ UINT64 RangeToCompareEnd;
+ UINT64 ReservedRangeToCompareEnd;
+
+ RangeToCompareEnd = RangeToCompare->CpuStart +
RangeToCompare->PhysicalSize;
+ ReservedRangeToCompareEnd = ReservedRangeToCompare->SmramReservedStart +
ReservedRangeToCompare->SmramReservedSize;
+
+ if ((RangeToCompare->CpuStart >= ReservedRangeToCompare->SmramReservedStart)
&&
+ (RangeToCompare->CpuStart < ReservedRangeToCompareEnd)) {
+ if (RangeToCompareEnd < ReservedRangeToCompareEnd) {
+ //
+ // RangeToCompare ReservedRangeToCompare
+ // ---- ----
--------------------------------------
+ // | | | | -> 1.
ReservedRangeToCompare
+ // ---- | | |--|
--------------------------------------
+ // | | | | | |
+ // | | | | | | -> 2.
FinalRanges[*FinalRangeCount] and increment *FinalRangeCount
+ // | | | | | |
RangeToCompare->PhysicalSize = 0
+ // ---- | | |--|
--------------------------------------
+ // | | | | -> 3.
ReservedRanges[*ReservedRangeCount] and increment *ReservedRangeCount
+ // ---- ----
--------------------------------------
+ //
+
+ //
+ // 1. Update ReservedRangeToCompare.
+ //
+ ReservedRangeToCompare->SmramReservedSize = RangeToCompare->CpuStart -
ReservedRangeToCompare->SmramReservedStart;
+ //
+ // 2. Update FinalRanges[FinalRangeCount] and increment *FinalRangeCount.
+ // Zero RangeToCompare->PhysicalSize.
+ //
+ FinalRanges[*FinalRangeCount].CpuStart = RangeToCompare->CpuStart;
+ FinalRanges[*FinalRangeCount].PhysicalStart =
RangeToCompare->PhysicalStart;
+ FinalRanges[*FinalRangeCount].RegionState =
RangeToCompare->RegionState | EFI_ALLOCATED;
+ FinalRanges[*FinalRangeCount].PhysicalSize =
RangeToCompare->PhysicalSize;
+ *FinalRangeCount += 1;
+ RangeToCompare->PhysicalSize = 0;
+ //
+ // 3. Update ReservedRanges[*ReservedRangeCount] and increment
*ReservedRangeCount.
+ //
+ ReservedRanges[*ReservedRangeCount].SmramReservedStart =
FinalRanges[*FinalRangeCount - 1].CpuStart + FinalRanges[*FinalRangeCount -
1].PhysicalSize;
+ ReservedRanges[*ReservedRangeCount].SmramReservedSize =
ReservedRangeToCompareEnd - RangeToCompareEnd;
+ *ReservedRangeCount += 1;
+ } else {
+ //
+ // RangeToCompare ReservedRangeToCompare
+ // ---- ----
--------------------------------------
+ // | | | | -> 1.
ReservedRangeToCompare
+ // ---- | | |--|
--------------------------------------
+ // | | | | | |
+ // | | | | | | -> 2.
FinalRanges[*FinalRangeCount] and increment *FinalRangeCount
+ // | | | | | |
+ // | | ---- |--|
--------------------------------------
+ // | | | | -> 3. RangeToCompare
+ // ---- ----
--------------------------------------
+ //
+
+ //
+ // 1. Update ReservedRangeToCompare.
+ //
+ ReservedRangeToCompare->SmramReservedSize = RangeToCompare->CpuStart -
ReservedRangeToCompare->SmramReservedStart;
+ //
+ // 2. Update FinalRanges[FinalRangeCount] and increment *FinalRangeCount.
+ //
+ FinalRanges[*FinalRangeCount].CpuStart = RangeToCompare->CpuStart;
+ FinalRanges[*FinalRangeCount].PhysicalStart =
RangeToCompare->PhysicalStart;
+ FinalRanges[*FinalRangeCount].RegionState =
RangeToCompare->RegionState | EFI_ALLOCATED;
+ FinalRanges[*FinalRangeCount].PhysicalSize = ReservedRangeToCompareEnd
- RangeToCompare->CpuStart;
+ *FinalRangeCount += 1;
+ //
+ // 3. Update RangeToCompare.
+ //
+ RangeToCompare->CpuStart += FinalRanges[*FinalRangeCount -
1].PhysicalSize;
+ RangeToCompare->PhysicalStart += FinalRanges[*FinalRangeCount -
1].PhysicalSize;
+ RangeToCompare->PhysicalSize -= FinalRanges[*FinalRangeCount -
1].PhysicalSize;
+ }
+ } else if ((ReservedRangeToCompare->SmramReservedStart >=
RangeToCompare->CpuStart) &&
+ (ReservedRangeToCompare->SmramReservedStart < RangeToCompareEnd))
{
+ if (ReservedRangeToCompareEnd < RangeToCompareEnd) {
+ //
+ // RangeToCompare ReservedRangeToCompare
+ // ---- ----
--------------------------------------
+ // | | | | -> 1. RangeToCompare
+ // | | ---- |--|
--------------------------------------
+ // | | | | | |
+ // | | | | | | -> 2.
FinalRanges[*FinalRangeCount] and increment *FinalRangeCount
+ // | | | | | |
ReservedRangeToCompare->SmramReservedSize = 0
+ // | | ---- |--|
--------------------------------------
+ // | | | | -> 3.
Ranges[*RangeCount] and increment *RangeCount
+ // ---- ----
--------------------------------------
+ //
+
+ //
+ // 1. Update RangeToCompare.
+ //
+ RangeToCompare->PhysicalSize =
ReservedRangeToCompare->SmramReservedStart - RangeToCompare->CpuStart;
+ //
+ // 2. Update FinalRanges[FinalRangeCount] and increment *FinalRangeCount.
+ // ReservedRangeToCompare->SmramReservedSize = 0
+ //
+ FinalRanges[*FinalRangeCount].CpuStart =
ReservedRangeToCompare->SmramReservedStart;
+ FinalRanges[*FinalRangeCount].PhysicalStart =
RangeToCompare->PhysicalStart + RangeToCompare->PhysicalSize;
+ FinalRanges[*FinalRangeCount].RegionState =
RangeToCompare->RegionState | EFI_ALLOCATED;
+ FinalRanges[*FinalRangeCount].PhysicalSize =
ReservedRangeToCompare->SmramReservedSize;
+ *FinalRangeCount += 1;
+ ReservedRangeToCompare->SmramReservedSize = 0;
+ //
+ // 3. Update Ranges[*RangeCount] and increment *RangeCount.
+ //
+ Ranges[*RangeCount].CpuStart = FinalRanges[*FinalRangeCount -
1].CpuStart + FinalRanges[*FinalRangeCount - 1].PhysicalSize;
+ Ranges[*RangeCount].PhysicalStart = FinalRanges[*FinalRangeCount -
1].PhysicalStart + FinalRanges[*FinalRangeCount - 1].PhysicalSize;
+ Ranges[*RangeCount].RegionState = RangeToCompare->RegionState;
+ Ranges[*RangeCount].PhysicalSize = RangeToCompareEnd -
ReservedRangeToCompareEnd;
+ *RangeCount += 1;
+ } else {
+ //
+ // RangeToCompare ReservedRangeToCompare
+ // ---- ----
--------------------------------------
+ // | | | | -> 1. RangeToCompare
+ // | | ---- |--|
--------------------------------------
+ // | | | | | |
+ // | | | | | | -> 2.
FinalRanges[*FinalRangeCount] and increment *FinalRangeCount
+ // | | | | | |
+ // ---- | | |--|
--------------------------------------
+ // | | | | -> 3.
ReservedRangeToCompare
+ // ---- ----
--------------------------------------
+ //
+
+ //
+ // 1. Update RangeToCompare.
+ //
+ RangeToCompare->PhysicalSize =
ReservedRangeToCompare->SmramReservedStart - RangeToCompare->CpuStart;
+ //
+ // 2. Update FinalRanges[FinalRangeCount] and increment *FinalRangeCount.
+ // ReservedRangeToCompare->SmramReservedSize = 0
+ //
+ FinalRanges[*FinalRangeCount].CpuStart =
ReservedRangeToCompare->SmramReservedStart;
+ FinalRanges[*FinalRangeCount].PhysicalStart =
RangeToCompare->PhysicalStart + RangeToCompare->PhysicalSize;
+ FinalRanges[*FinalRangeCount].RegionState =
RangeToCompare->RegionState | EFI_ALLOCATED;
+ FinalRanges[*FinalRangeCount].PhysicalSize = RangeToCompareEnd -
ReservedRangeToCompare->SmramReservedStart;
+ *FinalRangeCount += 1;
+ //
+ // 3. Update ReservedRangeToCompare.
+ //
+ ReservedRangeToCompare->SmramReservedStart +=
FinalRanges[*FinalRangeCount - 1].PhysicalSize;
+ ReservedRangeToCompare->SmramReservedSize -=
FinalRanges[*FinalRangeCount - 1].PhysicalSize;
+ }
}
+}
+/**
+ Returns if SMRAM range and SMRAM reserved range are overlapped.
+
+ @param[in] RangeToCompare Pointer to EFI_SMRAM_DESCRIPTOR to
compare.
+ @param[in] ReservedRangeToCompare Pointer to
EFI_SMM_RESERVED_SMRAM_REGION to compare.
+
+ @retval TRUE There is overlap.
+ @retval FALSE There is no overlap.
+
+**/
+BOOLEAN
+SmmIsSmramOverlap (
+ IN EFI_SMRAM_DESCRIPTOR *RangeToCompare,
+ IN EFI_SMM_RESERVED_SMRAM_REGION *ReservedRangeToCompare
+ )
+{
+ UINT64 RangeToCompareEnd;
+ UINT64 ReservedRangeToCompareEnd;
+
+ RangeToCompareEnd = RangeToCompare->CpuStart +
RangeToCompare->PhysicalSize;
+ ReservedRangeToCompareEnd = ReservedRangeToCompare->SmramReservedStart +
ReservedRangeToCompare->SmramReservedSize;
+
+ if ((RangeToCompare->CpuStart >= ReservedRangeToCompare->SmramReservedStart)
&&
+ (RangeToCompare->CpuStart < ReservedRangeToCompareEnd)) {
+ return TRUE;
+ } else if ((ReservedRangeToCompare->SmramReservedStart >=
RangeToCompare->CpuStart) &&
+ (ReservedRangeToCompare->SmramReservedStart < RangeToCompareEnd))
{
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ Get full SMRAM ranges.
+
+ It will get SMRAM ranges from SmmAccess protocol and SMRAM reserved ranges
from
+ SmmConfiguration protocol, split the entries if there is overlap between
them.
+ It will also reserve one entry for SMM core.
+
+ @param[out] FullSmramRangeCount Output pointer to full SMRAM range count.
+
+ @return Pointer to full SMRAM ranges.
+
+**/
+EFI_SMRAM_DESCRIPTOR *
+GetFullSmramRanges (
+ OUT UINTN *FullSmramRangeCount
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMM_CONFIGURATION_PROTOCOL *SmmConfiguration;
+ UINTN Size;
+ UINTN Index;
+ UINTN Index2;
+ EFI_SMRAM_DESCRIPTOR *FullSmramRanges;
+ UINTN TempSmramRangeCount;
+ EFI_SMRAM_DESCRIPTOR *TempSmramRanges;
+ UINTN SmramRangeCount;
+ EFI_SMRAM_DESCRIPTOR *SmramRanges;
+ UINTN SmramReservedCount;
+ EFI_SMM_RESERVED_SMRAM_REGION *SmramReservedRanges;
+ UINTN MaxCount;
+ BOOLEAN Rescan;
+
//
- // Always free memory allocted by GetFileBufferByFilePath ()
+ // Get SMM Configuration Protocol if it is present.
//
- FreePool (SourceBuffer);
+ SmmConfiguration = NULL;
+ Status = gBS->LocateProtocol (&gEfiSmmConfigurationProtocolGuid, NULL, (VOID
**) &SmmConfiguration);
- return Status;
+ //
+ // Get SMRAM information.
+ //
+ Size = 0;
+ Status = mSmmAccess->GetCapabilities (mSmmAccess, &Size, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+ SmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
+
+ //
+ // Get SMRAM reserved region count.
+ //
+ SmramReservedCount = 0;
+ if (SmmConfiguration != NULL) {
+ while
(SmmConfiguration->SmramReservedRegions[SmramReservedCount].SmramReservedSize
!= 0) {
+ SmramReservedCount++;
+ }
+ }
+
+ if (SmramReservedCount == 0) {
+ //
+ // No reserved SMRAM entry from SMM Configuration Protocol.
+ // Reserve one entry for SMM Core in the full SMRAM ranges.
+ //
+ *FullSmramRangeCount = SmramRangeCount + 1;
+ Size = (*FullSmramRangeCount) * sizeof (EFI_SMRAM_DESCRIPTOR);
+ FullSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool (Size);
+ ASSERT (FullSmramRanges != NULL);
+
+ Status = mSmmAccess->GetCapabilities (mSmmAccess, &Size, FullSmramRanges);
+ ASSERT_EFI_ERROR (Status);
+
+ return FullSmramRanges;
+ }
+
+ //
+ // Why MaxCount = X + 2 * Y?
+ // Take Y = 1 as example below, Y > 1 case is just the iteration of Y = 1.
+ //
+ // X = 1 Y = 1 MaxCount = 3 = 1 + 2 * 1
+ // ---- ----
+ // | | ---- |--|
+ // | | | | -> | |
+ // | | ---- |--|
+ // ---- ----
+ //
+ // X = 2 Y = 1 MaxCount = 4 = 2 + 2 * 1
+ // ---- ----
+ // | | | |
+ // | | ---- |--|
+ // | | | | | |
+ // |--| | | -> |--|
+ // | | | | | |
+ // | | ---- |--|
+ // | | | |
+ // ---- ----
+ //
+ // X = 3 Y = 1 MaxCount = 5 = 3 + 2 * 1
+ // ---- ----
+ // | | | |
+ // | | ---- |--|
+ // |--| | | |--|
+ // | | | | -> | |
+ // |--| | | |--|
+ // | | ---- |--|
+ // | | | |
+ // ---- ----
+ //
+ // ......
+ //
+ MaxCount = SmramRangeCount + 2 * SmramReservedCount;
+
+ Size = MaxCount * sizeof (EFI_SMM_RESERVED_SMRAM_REGION);
+ SmramReservedRanges = (EFI_SMM_RESERVED_SMRAM_REGION *) AllocatePool (Size);
+ ASSERT (SmramReservedRanges != NULL);
+ for (Index = 0; Index < SmramReservedCount; Index++) {
+ CopyMem (&SmramReservedRanges[Index],
&SmmConfiguration->SmramReservedRegions[Index], sizeof
(EFI_SMM_RESERVED_SMRAM_REGION));
+ }
+
+ Size = MaxCount * sizeof (EFI_SMRAM_DESCRIPTOR);
+ TempSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool (Size);
+ ASSERT (TempSmramRanges != NULL);
+ TempSmramRangeCount = 0;
+
+ SmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool (Size);
+ ASSERT (SmramRanges != NULL);
+ Status = mSmmAccess->GetCapabilities (mSmmAccess, &Size, SmramRanges);
+ ASSERT_EFI_ERROR (Status);
+
+ do {
+ Rescan = FALSE;
+ for (Index = 0; (Index < SmramRangeCount) && !Rescan; Index++) {
+ //
+ // Skip zero size entry.
+ //
+ if (SmramRanges[Index].PhysicalSize != 0) {
+ for (Index2 = 0; (Index2 < SmramReservedCount) && !Rescan; Index2++) {
+ //
+ // Skip zero size entry.
+ //
+ if (SmramReservedRanges[Index2].SmramReservedSize != 0) {
+ if (SmmIsSmramOverlap (
+ &SmramRanges[Index],
+ &SmramReservedRanges[Index2]
+ )) {
+ //
+ // There is overlap, need to split entry and then rescan.
+ //
+ SmmSplitSmramEntry (
+ &SmramRanges[Index],
+ &SmramReservedRanges[Index2],
+ SmramRanges,
+ &SmramRangeCount,
+ SmramReservedRanges,
+ &SmramReservedCount,
+ TempSmramRanges,
+ &TempSmramRangeCount
+ );
+ Rescan = TRUE;
+ }
+ }
+ }
+ if (!Rescan) {
+ //
+ // No any overlap, copy the entry to the temp SMRAM ranges.
+ // Zero SmramRanges[Index].PhysicalSize = 0;
+ //
+ CopyMem (&TempSmramRanges[TempSmramRangeCount++],
&SmramRanges[Index], sizeof (EFI_SMRAM_DESCRIPTOR));
+ SmramRanges[Index].PhysicalSize = 0;
+ }
+ }
+ }
+ } while (Rescan);
+ ASSERT (TempSmramRangeCount <= MaxCount);
+
+ //
+ // Sort the entries,
+ // and reserve one entry for SMM Core in the full SMRAM ranges.
+ //
+ FullSmramRanges = AllocatePool ((TempSmramRangeCount + 1) * sizeof
(EFI_SMRAM_DESCRIPTOR));
+ ASSERT (FullSmramRanges != NULL);
+ *FullSmramRangeCount = 0;
+ do {
+ for (Index = 0; Index < TempSmramRangeCount; Index++) {
+ if (TempSmramRanges[Index].PhysicalSize != 0) {
+ break;
+ }
+ }
+ ASSERT (Index < TempSmramRangeCount);
+ for (Index2 = 0; Index2 < TempSmramRangeCount; Index2++) {
+ if ((Index2 != Index) && (TempSmramRanges[Index2].PhysicalSize != 0) &&
(TempSmramRanges[Index2].CpuStart < TempSmramRanges[Index].CpuStart)) {
+ Index = Index2;
+ }
+ }
+ CopyMem (&FullSmramRanges[*FullSmramRangeCount], &TempSmramRanges[Index],
sizeof (EFI_SMRAM_DESCRIPTOR));
+ *FullSmramRangeCount += 1;
+ TempSmramRanges[Index].PhysicalSize = 0;
+ } while (*FullSmramRangeCount < TempSmramRangeCount);
+ ASSERT (*FullSmramRangeCount == TempSmramRangeCount);
+ *FullSmramRangeCount += 1;
+
+ FreePool (SmramRanges);
+ FreePool (SmramReservedRanges);
+ FreePool (TempSmramRanges);
+
+ return FullSmramRanges;
}
/**
@@ -1044,10 +1457,7 @@
)
{
EFI_STATUS Status;
- EFI_SMM_CONFIGURATION_PROTOCOL *SmmConfiguration;
- UINTN Size;
UINTN Index;
- EFI_SMM_RESERVED_SMRAM_REGION *SmramResRegion;
UINT64 MaxSize;
VOID *Registration;
UINT64 SmmCodeSize;
@@ -1074,36 +1484,9 @@
Status = gBS->LocateProtocol (&gEfiSmmControl2ProtocolGuid, NULL, (VOID
**)&mSmmControl2);
ASSERT_EFI_ERROR (Status);
- //
- // Get SMM Configuration Protocol if it is present
- //
- SmmConfiguration = NULL;
- Status = gBS->LocateProtocol (&gEfiSmmConfigurationProtocolGuid, NULL, (VOID
**) &SmmConfiguration);
+ gSmmCorePrivate->SmramRanges = GetFullSmramRanges
(&gSmmCorePrivate->SmramRangeCount);
//
- // Get SMRAM information
- //
- Size = 0;
- Status = mSmmAccess->GetCapabilities (mSmmAccess, &Size, NULL);
- ASSERT (Status == EFI_BUFFER_TOO_SMALL);
-
- gSmmCorePrivate->SmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocatePool (Size);
- ASSERT (gSmmCorePrivate->SmramRanges != NULL);
-
- Status = mSmmAccess->GetCapabilities (mSmmAccess, &Size,
gSmmCorePrivate->SmramRanges);
- ASSERT_EFI_ERROR (Status);
-
- 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
//
Status = mSmmAccess->Open (mSmmAccess);
@@ -1113,26 +1496,6 @@
// Print debug message that the SMRAM window is now open.
//
DEBUG ((DEBUG_INFO, "SMM IPL opened SMRAM window\n"));
-
- //
- // Subtract SMRAM any reserved SMRAM regions.
- //
- if (SmmConfiguration != NULL) {
- SmramResRegion = SmmConfiguration->SmramReservedRegions;
- while (SmramResRegion->SmramReservedSize != 0) {
- for (Index = 0; Index < gSmmCorePrivate->SmramRangeCount; Index ++) {
- if ((SmramResRegion->SmramReservedStart >=
gSmmCorePrivate->SmramRanges[Index].CpuStart) && \
- ((SmramResRegion->SmramReservedStart +
SmramResRegion->SmramReservedSize) <= \
- (gSmmCorePrivate->SmramRanges[Index].CpuStart +
gSmmCorePrivate->SmramRanges[Index].PhysicalSize))) {
- //
- // This range has reserved area, calculate the left free size
- //
- gSmmCorePrivate->SmramRanges[Index].PhysicalSize =
SmramResRegion->SmramReservedStart -
gSmmCorePrivate->SmramRanges[Index].CpuStart;
- }
- }
- SmramResRegion++;
- }
- }
//
// Find the largest SMRAM range between 1MB and 4GB that is at least 256KB -
4K in size
@@ -1214,7 +1577,11 @@
//
// Load SMM Core into SMRAM and execute it from SMRAM
//
- Status = ExecuteSmmCoreFromSmram (mCurrentSmramRange, gSmmCorePrivate);
+ Status = ExecuteSmmCoreFromSmram (
+ mCurrentSmramRange,
+ &gSmmCorePrivate->SmramRanges[gSmmCorePrivate->SmramRangeCount
- 1],
+ gSmmCorePrivate
+ );
if (EFI_ERROR (Status)) {
//
// Print error message that the SMM Core failed to be loaded and
executed.
@@ -1262,7 +1629,6 @@
// Free all allocated resources
//
FreePool (gSmmCorePrivate->SmramRanges);
- FreePool (gSmmCorePrivate->FullSmramRanges);
return EFI_UNSUPPORTED;
}
Modified:
trunk/edk2/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c
===================================================================
---
trunk/edk2/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c
2015-07-26 07:38:06 UTC (rev 18030)
+++
trunk/edk2/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/MemoryAllocationLib.c
2015-07-26 07:38:12 UTC (rev 18031)
@@ -919,11 +919,11 @@
//
SmmInitializeMemoryServices (SmmCorePrivate->SmramRangeCount,
SmmCorePrivate->SmramRanges);
- mSmmCoreMemoryAllocLibSmramRangeCount = SmmCorePrivate->FullSmramRangeCount;
+ mSmmCoreMemoryAllocLibSmramRangeCount = SmmCorePrivate->SmramRangeCount;
Size = mSmmCoreMemoryAllocLibSmramRangeCount * sizeof (EFI_SMRAM_DESCRIPTOR);
mSmmCoreMemoryAllocLibSmramRanges = (EFI_SMRAM_DESCRIPTOR *) AllocatePool
(Size);
ASSERT (mSmmCoreMemoryAllocLibSmramRanges != NULL);
- CopyMem (mSmmCoreMemoryAllocLibSmramRanges, SmmCorePrivate->FullSmramRanges,
Size);
+ CopyMem (mSmmCoreMemoryAllocLibSmramRanges, SmmCorePrivate->SmramRanges,
Size);
return EFI_SUCCESS;
}
Modified:
trunk/edk2/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationServices.h
===================================================================
---
trunk/edk2/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationServices.h
2015-07-26 07:38:06 UTC (rev 18030)
+++
trunk/edk2/MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationServices.h
2015-07-26 07:38:12 UTC (rev 18031)
@@ -94,9 +94,6 @@
EFI_PHYSICAL_ADDRESS PiSmmCoreImageBase;
UINT64 PiSmmCoreImageSize;
EFI_PHYSICAL_ADDRESS PiSmmCoreEntryPoint;
-
- UINTN FullSmramRangeCount;
- EFI_SMRAM_DESCRIPTOR *FullSmramRanges;
} SMM_CORE_PRIVATE_DATA;
/**
------------------------------------------------------------------------------
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits