Fix the SMRAM caching range base and size. The original code uses the biggest SMRAM range base and size to set the cache attribute by gDS->SetMemorySpaceAttributes(). This is not correct because the platform code might split the TSEG into several ranges. The fix searches and joins all the adjacent ranges to the biggest SMRAM range into a cacheable range so that TSEG can be cached as a whole.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10213 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jgong5 2010-03-09 05:47:41 +00:00
parent 44a8883ec0
commit 40e8cca588
1 changed files with 52 additions and 6 deletions

View File

@ -227,6 +227,8 @@ EFI_SMM_CONTROL2_PROTOCOL *mSmmControl2;
EFI_SMM_ACCESS2_PROTOCOL *mSmmAccess;
EFI_SMRAM_DESCRIPTOR *mCurrentSmramRange;
BOOLEAN mSmmLocked = FALSE;
EFI_PHYSICAL_ADDRESS mSmramCacheBase;
UINT64 mSmramCacheSize;
//
// Table of Protocol notification and GUIDed Event notifications that the SMM IPL requires
@ -272,6 +274,49 @@ SMM_IPL_EVENT_NOTIFICATION mSmmIplEvents[] = {
{ FALSE, FALSE, NULL, NULL, NULL, NULL }
};
/**
Find the maximum SMRAM cache range that covers the range specified by SmramRange.
This function searches and joins all adjacent ranges of SmramRange into a range to be cached.
@param SmramRange The SMRAM range to search from.
@param SmramCacheBase The returned cache range base.
@param SmramCacheSize The returned cache range size.
**/
VOID
GetSmramCacheRange (
IN EFI_SMRAM_DESCRIPTOR *SmramRange,
OUT EFI_PHYSICAL_ADDRESS *SmramCacheBase,
OUT UINT64 *SmramCacheSize
)
{
UINTN Index;
EFI_PHYSICAL_ADDRESS RangeCpuStart;
UINT64 RangePhysicalSize;
BOOLEAN FoundAjacentRange;
*SmramCacheBase = SmramRange->CpuStart;
*SmramCacheSize = SmramRange->PhysicalSize;
do {
FoundAjacentRange = FALSE;
for (Index = 0; Index < gSmmCorePrivate->SmramRangeCount; Index++) {
RangeCpuStart = gSmmCorePrivate->SmramRanges[Index].CpuStart;
RangePhysicalSize = gSmmCorePrivate->SmramRanges[Index].PhysicalSize;
if (RangeCpuStart < *SmramCacheBase && *SmramCacheBase == (RangeCpuStart + RangePhysicalSize)) {
*SmramCacheBase = RangeCpuStart;
*SmramCacheSize += RangePhysicalSize;
FoundAjacentRange = TRUE;
} else if ((*SmramCacheBase + *SmramCacheSize) == RangeCpuStart && RangePhysicalSize > 0) {
*SmramCacheSize += RangePhysicalSize;
FoundAjacentRange = TRUE;
}
}
} while (FoundAjacentRange);
}
/**
Indicate whether the driver is currently executing in the SMM Initialization phase.
@ -515,8 +560,8 @@ SmmIplSmmConfigurationEventNotify (
// Attempt to reset SMRAM cacheability to UC
//
Status = gDS->SetMemorySpaceAttributes(
mCurrentSmramRange->CpuStart,
mCurrentSmramRange->PhysicalSize,
mSmramCacheBase,
mSmramCacheSize,
EFI_MEMORY_UC
);
if (EFI_ERROR (Status)) {
@ -1076,12 +1121,13 @@ SmmIplEntry (
(VOID *)(UINTN)(mCurrentSmramRange->CpuStart + mCurrentSmramRange->PhysicalSize - 1)
));
GetSmramCacheRange (mCurrentSmramRange, &mSmramCacheBase, &mSmramCacheSize);
//
// Attempt to set SMRAM cacheability to WB
//
Status = gDS->SetMemorySpaceAttributes(
mCurrentSmramRange->CpuStart,
mCurrentSmramRange->PhysicalSize,
mSmramCacheBase,
mSmramCacheSize,
EFI_MEMORY_WB
);
if (EFI_ERROR (Status)) {
@ -1129,8 +1175,8 @@ SmmIplEntry (
// Attempt to reset SMRAM cacheability to UC
//
Status = gDS->SetMemorySpaceAttributes(
mCurrentSmramRange->CpuStart,
mCurrentSmramRange->PhysicalSize,
mSmramCacheBase,
mSmramCacheSize,
EFI_MEMORY_UC
);
if (EFI_ERROR (Status)) {