16#define EFI_MEMORY_PRESENT 0x0100000000000000ULL
17#define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL
18#define EFI_MEMORY_TESTED 0x0400000000000000ULL
20#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
21 ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
24UINTN mUefiMemoryMapSize;
25UINTN mUefiDescriptorSize;
28UINTN mGcdMemNumberOfDesc = 0;
53 MemoryMapEntry = MemoryMap;
54 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
56 while (MemoryMapEntry < MemoryMapEnd) {
57 while (NextMemoryMapEntry < MemoryMapEnd) {
64 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
67 MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
68 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
89 switch (MemoryMap->Type) {
127 UINT64 MemoryBlockLength;
131 MemoryMapEntry = MemoryMap;
132 NewMemoryMapEntry = MemoryMap;
134 while ((
UINTN)MemoryMapEntry < (
UINTN)MemoryMapEnd) {
136 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
140 if (((
UINTN)NextMemoryMapEntry < (
UINTN)MemoryMapEnd) &&
145 if (NewMemoryMapEntry != MemoryMapEntry) {
149 NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
152 MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);
157 MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);
158 NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize);
161 *MemoryMapSize = (
UINTN)NewMemoryMapEntry - (
UINTN)MemoryMap;
174 UINTN NumberOfDescriptors;
179 Status =
gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap);
180 if (EFI_ERROR (Status)) {
184 mGcdMemNumberOfDesc = 0;
185 for (Index = 0; Index < NumberOfDescriptors; Index++) {
187 ((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
188 (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))
191 mGcdMemNumberOfDesc++;
196 ASSERT (mGcdMemSpace !=
NULL);
197 if (mGcdMemSpace ==
NULL) {
198 mGcdMemNumberOfDesc = 0;
199 gBS->FreePool (MemSpaceMap);
203 mGcdMemNumberOfDesc = 0;
204 for (Index = 0; Index < NumberOfDescriptors; Index++) {
206 ((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
207 (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))
211 &mGcdMemSpace[mGcdMemNumberOfDesc],
215 mGcdMemNumberOfDesc++;
219 gBS->FreePool (MemSpaceMap);
232 UINTN MemoryAttributesTableSize;
235 if (!EFI_ERROR (Status) && (MemoryAttributesTable !=
NULL)) {
236 MemoryAttributesTableSize =
sizeof (
EFI_MEMORY_ATTRIBUTES_TABLE) + MemoryAttributesTable->DescriptorSize * MemoryAttributesTable->NumberOfEntries;
237 mUefiMemoryAttributesTable =
AllocateCopyPool (MemoryAttributesTableSize, MemoryAttributesTable);
238 ASSERT (mUefiMemoryAttributesTable !=
NULL);
252 UINT32 DescriptorVersion;
254 UINTN UefiMemoryMapSize;
256 DEBUG ((DEBUG_INFO,
"GetUefiMemoryMap\n"));
258 UefiMemoryMapSize = 0;
260 Status =
gBS->GetMemoryMap (
264 &mUefiDescriptorSize,
267 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
271 ASSERT (MemoryMap !=
NULL);
272 if (MemoryMap ==
NULL) {
276 Status =
gBS->GetMemoryMap (
280 &mUefiDescriptorSize,
283 if (EFI_ERROR (Status)) {
284 gBS->FreePool (MemoryMap);
287 }
while (Status == EFI_BUFFER_TOO_SMALL);
289 if (MemoryMap ==
NULL) {
293 SortMemoryMap (MemoryMap, UefiMemoryMapSize, mUefiDescriptorSize);
296 mUefiMemoryMapSize = UefiMemoryMapSize;
298 ASSERT (mUefiMemoryMap !=
NULL);
300 gBS->FreePool (MemoryMap);
322 BOOLEAN WriteProtect;
327 UINT64 PreviousAddress;
331 UINTN MemoryMapEntryCount;
334 DEBUG ((DEBUG_INFO,
"UpdateUefiMemMapAttributes Start...\n"));
339 Limit =
LShiftU64 (1, mPhysicalAddressBits);
344 PreviousAddress = ((
FixedPcdGet8 (PcdNullPointerDetectionPropertyMask) & BIT1) != 0) ? BASE_4KB : 0;
350 for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
351 Base = mSmmCpuSmramRanges[Index].
CpuStart;
352 if (Base > PreviousAddress) {
360 if (PreviousAddress < Limit) {
369 if (mUefiMemoryMap !=
NULL) {
370 MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize;
371 MemoryMap = mUefiMemoryMap;
372 for (Index = 0; Index < MemoryMapEntryCount; Index++) {
385 "UefiMemory protection: 0x%lx - 0x%lx %r\n",
392 MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize);
403 if (mGcdMemSpace !=
NULL) {
404 for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) {
408 mGcdMemSpace[Index].BaseAddress,
409 mGcdMemSpace[Index].Length,
416 "GcdMemory protection: 0x%lx - 0x%lx %r\n",
417 mGcdMemSpace[Index].BaseAddress,
418 mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length,
432 if (mUefiMemoryAttributesTable !=
NULL) {
434 for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) {
436 if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {
440 Entry->PhysicalStart,
448 "UefiMemoryAttribute protection: 0x%lx - 0x%lx %r\n",
449 Entry->PhysicalStart,
456 Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize);
475 WRITE_PROTECT_RO_PAGES (WriteProtect, CetEnabled);
477 DEBUG ((DEBUG_INFO,
"UpdateUefiMemMapAttributes Done.\n"));
496 ASSERT (Size !=
NULL);
498 *Size =
PcdGet32 (PcdCpuSmmProfileSize);
501 Status =
gBS->AllocatePages (
545 UINTN MemoryMapEntryCount;
553 if (mUefiMemoryMap !=
NULL) {
554 MemoryMap = mUefiMemoryMap;
555 MemoryMapEntryCount = mUefiMemoryMapSize/mUefiDescriptorSize;
556 for (Index = 0; Index < MemoryMapEntryCount; Index++) {
565 MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mUefiDescriptorSize);
569 if (mGcdMemSpace !=
NULL) {
570 for (Index = 0; Index < mGcdMemNumberOfDesc; Index++) {
571 if ((Address >= mGcdMemSpace[Index].BaseAddress) &&
572 (Address < mGcdMemSpace[Index].BaseAddress + mGcdMemSpace[Index].Length))
579 if (mUefiMemoryAttributesTable !=
NULL) {
581 for (Index = 0; Index < mUefiMemoryAttributesTable->NumberOfEntries; Index++) {
583 if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {
584 if ((Address >= Entry->PhysicalStart) &&
585 (Address < Entry->PhysicalStart +
LShiftU64 (Entry->NumberOfPages, EFI_PAGE_SHIFT)))
590 Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mUefiMemoryAttributesTable->DescriptorSize);
616 UINTN NumberOfSpaceDescriptors;
617 UINTN MemoryRegionIndex;
620 MemorySpaceMap =
NULL;
621 NumberOfSpaceDescriptors = 0;
624 ASSERT (MemoryRegion !=
NULL && MemoryRegionCount !=
NULL);
626 *MemoryRegion =
NULL;
627 *MemoryRegionCount = 0;
632 gDS->GetMemorySpaceMap (
633 &NumberOfSpaceDescriptors,
636 for (Index = 0; Index < NumberOfSpaceDescriptors; Index++) {
639 (MemorySpaceMap[Index].Length % SIZE_4KB == 0))
649 "MMIO range [0x%lx, 0x%lx] is skipped since it is not 4k aligned.\n",
650 MemorySpaceMap[Index].BaseAddress,
651 MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length
657 *MemoryRegionCount = Count;
660 ASSERT (*MemoryRegion !=
NULL);
662 MemoryRegionIndex = 0;
663 for (Index = 0; Index < NumberOfSpaceDescriptors; Index++) {
666 (MemorySpaceMap[Index].Length % SIZE_4KB == 0))
668 (*MemoryRegion)[MemoryRegionIndex].Base = MemorySpaceMap[Index].
BaseAddress;
669 (*MemoryRegion)[MemoryRegionIndex].Length = MemorySpaceMap[Index].
Length;
690 IN UINT8 PhysicalAddressBits,
698 UINT64 PreviousAddress;
702 ASSERT (MemoryRegion !=
NULL && MemoryRegionCount !=
NULL);
704 *MemoryRegion =
NULL;
705 *MemoryRegionCount = 0;
707 MaxLength =
LShiftU64 (1, PhysicalAddressBits);
712 Count = mSmmCpuSmramRangeCount + 1;
714 *MemoryRegionCount = Count;
717 ASSERT (*MemoryRegion !=
NULL);
720 for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) {
721 Base = mSmmCpuSmramRanges[Index].
CpuStart;
724 ASSERT (MaxLength > Base + Length);
726 if (Base > PreviousAddress) {
727 (*MemoryRegion)[Index].Base = PreviousAddress;
728 (*MemoryRegion)[Index].Length = Base - PreviousAddress;
729 (*MemoryRegion)[Index].Attribute = 0;
732 PreviousAddress = Base + Length;
738 if (PreviousAddress < MaxLength) {
739 (*MemoryRegion)[Index].Base = PreviousAddress;
740 (*MemoryRegion)[Index].Length = MaxLength - PreviousAddress;
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI CpuFlushTlb(VOID)
RETURN_STATUS ConvertMemoryPageAttributes(IN PAGE_TABLE_LIB_PAGING_CONTEXT *PagingContext OPTIONAL, IN PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes, IN PAGE_ACTION PageAction, IN PAGE_TABLE_LIB_ALLOCATE_PAGES AllocatePagesFunc OPTIONAL, OUT BOOLEAN *IsSplitted OPTIONAL, OUT BOOLEAN *IsModified OPTIONAL)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
UINTN EFIAPI AsmReadCr3(VOID)
BOOLEAN IsRestrictedMemoryAccess(VOID)
#define ADDRESS_IS_ALIGNED(Address, Alignment)
#define ASSERT_EFI_ERROR(StatusParameter)
#define ASSERT_RETURN_ERROR(StatusParameter)
#define DEBUG(Expression)
BOOLEAN IsNonMmramLoggingAddress(IN UINT64 Address)
VOID CreateExtendedProtectionRange(OUT MM_CPU_MEMORY_REGION **MemoryRegion, OUT UINTN *MemoryRegionCount)
BOOLEAN IsUefiPageNotPresent(IN EFI_MEMORY_DESCRIPTOR *MemoryMap)
STATIC VOID MergeMemoryMapForNotPresentEntry(IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, IN OUT UINTN *MemoryMapSize, IN UINTN DescriptorSize)
VOID GetGcdMemoryMap(VOID)
EFI_PHYSICAL_ADDRESS GetSmmProfileData(IN OUT UINT64 *Size)
VOID GetUefiMemoryAttributesTable(VOID)
VOID CreateNonMmramMemMap(IN UINT8 PhysicalAddressBits, OUT MM_CPU_MEMORY_REGION **MemoryRegion, OUT UINTN *MemoryRegionCount)
VOID UpdateUefiMemMapAttributes(VOID)
STATIC VOID SortMemoryMap(IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, IN UINTN MemoryMapSize, IN UINTN DescriptorSize)
VOID GetUefiMemoryMap(VOID)
BOOLEAN IsSmmCommBufferForbiddenAddress(IN UINT64 Address)
#define PcdGet32(TokenName)
#define FixedPcdGet8(TokenName)
@ EfiGcdMemoryTypeReserved
@ EfiGcdMemoryTypeMemoryMappedIo
#define WRITE_UNPROTECT_RO_PAGES(Wp, Cet)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
#define EFI_SIZE_TO_PAGES(Size)
EFI_STATUS EFIAPI EfiGetSystemConfigurationTable(IN EFI_GUID *TableGuid, OUT VOID **Table)
EFI_PHYSICAL_ADDRESS BaseAddress
EFI_PHYSICAL_ADDRESS PhysicalStart
EFI_PHYSICAL_ADDRESS CpuStart