/** @file\r
Enable SMM profile.\r
\r
-Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2012 - 2017, Intel Corporation. All rights reserved.<BR>\r
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
//\r
{{0x00000000, 0x00000000},TRUE,TRUE},\r
\r
+ //\r
+ // SMRAM ranges not covered by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz (to be fixed in runtime).\r
+ // It is always present and instruction fetches are allowed.\r
+ // {{0x00000000, 0x00000000},TRUE,FALSE},\r
+ //\r
+\r
//\r
// Future extended range could be added here.\r
//\r
ClearTrapFlag (SystemContext);\r
}\r
\r
+/**\r
+ Check if the input address is in SMM ranges.\r
+\r
+ @param[in] Address The input address.\r
+\r
+ @retval TRUE The input address is in SMM.\r
+ @retval FALSE The input address is not in SMM.\r
+**/\r
+BOOLEAN\r
+IsInSmmRanges (\r
+ IN EFI_PHYSICAL_ADDRESS Address\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ if ((Address >= mCpuHotPlugData.SmrrBase) && (Address < mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) {\r
+ return TRUE;\r
+ }\r
+ for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {\r
+ if (Address >= mSmmCpuSmramRanges[Index].CpuStart &&\r
+ Address < mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize) {\r
+ return TRUE;\r
+ }\r
+ }\r
+ return FALSE;\r
+}\r
+\r
/**\r
Check if the memory address will be mapped by 4KB-page.\r
\r
{\r
UINTN Index;\r
\r
- *Nx = FALSE;\r
if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {\r
//\r
// Check configuration\r
return FALSE;\r
\r
} else {\r
- if ((Address < mCpuHotPlugData.SmrrBase) ||\r
- (Address >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) {\r
- *Nx = TRUE;\r
+ *Nx = TRUE;\r
+ if (IsInSmmRanges (Address)) {\r
+ *Nx = FALSE;\r
}\r
return TRUE;\r
}\r
{\r
UINTN Index;\r
UINTN NumberOfDescriptors;\r
- UINTN NumberOfMmioDescriptors;\r
+ UINTN NumberOfAddedDescriptors;\r
UINTN NumberOfProtectRange;\r
UINTN NumberOfSpliteRange;\r
EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;\r
UINT64 Low4KBPageSize;\r
\r
NumberOfDescriptors = 0;\r
- NumberOfMmioDescriptors = 0;\r
+ NumberOfAddedDescriptors = mSmmCpuSmramRangeCount;\r
NumberOfSpliteRange = 0;\r
MemorySpaceMap = NULL;\r
\r
);\r
for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {\r
- NumberOfMmioDescriptors++;\r
+ NumberOfAddedDescriptors++;\r
}\r
}\r
\r
- if (NumberOfMmioDescriptors != 0) {\r
- TotalSize = NumberOfMmioDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate);\r
+ if (NumberOfAddedDescriptors != 0) {\r
+ TotalSize = NumberOfAddedDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate);\r
mProtectionMemRange = (MEMORY_PROTECTION_RANGE *) AllocateZeroPool (TotalSize);\r
ASSERT (mProtectionMemRange != NULL);\r
mProtectionMemRangeCount = TotalSize / sizeof (MEMORY_PROTECTION_RANGE);\r
mSplitMemRange = (MEMORY_RANGE *) AllocateZeroPool (TotalSize);\r
ASSERT (mSplitMemRange != NULL);\r
\r
+ //\r
+ // Create SMM ranges which are set to present and execution-enable.\r
+ //\r
+ NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE);\r
+ for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {\r
+ if (mSmmCpuSmramRanges[Index].CpuStart >= mProtectionMemRange[0].Range.Base &&\r
+ mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize < mProtectionMemRange[0].Range.Top) {\r
+ //\r
+ // If the address have been already covered by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz\r
+ //\r
+ break;\r
+ }\r
+ mProtectionMemRange[NumberOfProtectRange].Range.Base = mSmmCpuSmramRanges[Index].CpuStart;\r
+ mProtectionMemRange[NumberOfProtectRange].Range.Top = mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize;\r
+ mProtectionMemRange[NumberOfProtectRange].Present = TRUE;\r
+ mProtectionMemRange[NumberOfProtectRange].Nx = FALSE;\r
+ NumberOfProtectRange++;\r
+ }\r
+\r
//\r
// Create MMIO ranges which are set to present and execution-disable.\r
//\r
- NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE);\r
for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
if (MemorySpaceMap[Index].GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {\r
continue;\r
mProtectionMemRange[NumberOfProtectRange].Nx = TRUE;\r
NumberOfProtectRange++;\r
}\r
+\r
+ //\r
+ // Check and updated actual protected memory ranges count\r
+ //\r
+ ASSERT (NumberOfProtectRange <= mProtectionMemRangeCount);\r
+ mProtectionMemRangeCount = NumberOfProtectRange;\r
}\r
\r
//\r