From 40e8cca588c7bcb63e40dd45be15f584b7902e66 Mon Sep 17 00:00:00 2001 From: jgong5 Date: Tue, 9 Mar 2010 05:47:41 +0000 Subject: 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 --- MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c | 58 ++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 6 deletions(-) (limited to 'MdeModulePkg/Core/PiSmmCore') diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c index 65fd328bfe..608fedfcbe 100644 --- a/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c +++ b/MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c @@ -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)) { -- cgit v1.2.3