33#define EFI_MEMORY_PRESENT 0x0100000000000000ULL
34#define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL
35#define EFI_MEMORY_TESTED 0x0400000000000000ULL
38UINTN mSmmMemLibInternalSmramCount;
45UINTN mMemoryMapEntryCount;
50UINTN mSmmMemLibGcdMemNumberOfDesc = 0;
54VOID *mRegistrationEndOfDxe;
55VOID *mRegistrationReadyToLock;
57BOOLEAN mSmmMemLibSmmReadyToLock =
FALSE;
70 UINT8 PhysicalAddressBits;
77 PhysicalAddressBits = ((
EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;
80 if (RegEax >= 0x80000008) {
82 PhysicalAddressBits = (UINT8)RegEax;
84 PhysicalAddressBits = 36;
91 ASSERT (PhysicalAddressBits <= 52);
92 if (PhysicalAddressBits > 48) {
93 PhysicalAddressBits = 48;
100 DEBUG ((DEBUG_INFO,
"mSmmMemLibInternalMaximumSupportAddress = 0x%lx\n", mSmmMemLibInternalMaximumSupportAddress));
125 if ((Length > mSmmMemLibInternalMaximumSupportAddress) ||
126 (Buffer > mSmmMemLibInternalMaximumSupportAddress) ||
127 ((Length != 0) && (Buffer > (mSmmMemLibInternalMaximumSupportAddress - (Length - 1)))))
134 "SmmIsBufferOutsideSmmValid: Overflow: Buffer (0x%lx) - Length (0x%lx), MaximumSupportAddress (0x%lx)\n",
137 mSmmMemLibInternalMaximumSupportAddress
142 for (Index = 0; Index < mSmmMemLibInternalSmramCount; Index++) {
143 if (((Buffer >= mSmmMemLibInternalSmramRanges[Index].CpuStart) && (Buffer < mSmmMemLibInternalSmramRanges[Index].CpuStart + mSmmMemLibInternalSmramRanges[Index].PhysicalSize)) ||
144 ((mSmmMemLibInternalSmramRanges[Index].CpuStart >= Buffer) && (mSmmMemLibInternalSmramRanges[Index].CpuStart < Buffer + Length)))
148 "SmmIsBufferOutsideSmmValid: Overlap: Buffer (0x%lx) - Length (0x%lx), ",
154 "CpuStart (0x%lx) - PhysicalSize (0x%lx)\n",
155 mSmmMemLibInternalSmramRanges[Index].CpuStart,
156 mSmmMemLibInternalSmramRanges[Index].PhysicalSize
165 if (mSmmMemLibSmmReadyToLock) {
167 BOOLEAN InValidCommunicationRegion;
169 InValidCommunicationRegion =
FALSE;
170 MemoryMap = mMemoryMap;
171 for (Index = 0; Index < mMemoryMapEntryCount; Index++) {
175 InValidCommunicationRegion =
TRUE;
178 MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, mDescriptorSize);
181 if (!InValidCommunicationRegion) {
184 "SmmIsBufferOutsideSmmValid: Not in ValidCommunicationRegion: Buffer (0x%lx) - Length (0x%lx)\n",
194 for (Index = 0; Index < mSmmMemLibGcdMemNumberOfDesc; Index++) {
195 if (((Buffer >= mSmmMemLibGcdMemSpace[Index].BaseAddress) && (Buffer < mSmmMemLibGcdMemSpace[Index].BaseAddress + mSmmMemLibGcdMemSpace[Index].Length)) ||
196 ((mSmmMemLibGcdMemSpace[Index].BaseAddress >= Buffer) && (mSmmMemLibGcdMemSpace[Index].BaseAddress < Buffer + Length)))
200 "SmmIsBufferOutsideSmmValid: In Untested Memory Region: Buffer (0x%lx) - Length (0x%lx)\n",
211 if (mSmmMemLibMemoryAttributesTable !=
NULL) {
215 for (Index = 0; Index < mSmmMemLibMemoryAttributesTable->NumberOfEntries; Index++) {
217 if ((Entry->Attribute & EFI_MEMORY_RO) != 0) {
218 if (((Buffer >= Entry->PhysicalStart) && (Buffer < Entry->PhysicalStart +
LShiftU64 (Entry->NumberOfPages, EFI_PAGE_SHIFT))) ||
219 ((Entry->PhysicalStart >= Buffer) && (Entry->PhysicalStart < Buffer + Length)))
223 "SmmIsBufferOutsideSmmValid: In RuntimeCode Region: Buffer (0x%lx) - Length (0x%lx)\n",
232 Entry = NEXT_MEMORY_DESCRIPTOR (Entry, mSmmMemLibMemoryAttributesTable->DescriptorSize);
260 OUT VOID *DestinationBuffer,
266 DEBUG ((DEBUG_ERROR,
"SmmCopyMemToSmram: Security Violation: Source (0x%x), Length (0x%x)\n", SourceBuffer, Length));
267 return EFI_SECURITY_VIOLATION;
270 CopyMem (DestinationBuffer, SourceBuffer, Length);
294 OUT VOID *DestinationBuffer,
300 DEBUG ((DEBUG_ERROR,
"SmmCopyMemFromSmram: Security Violation: Destination (0x%x), Length (0x%x)\n", DestinationBuffer, Length));
301 return EFI_SECURITY_VIOLATION;
304 CopyMem (DestinationBuffer, SourceBuffer, Length);
329 OUT VOID *DestinationBuffer,
335 DEBUG ((DEBUG_ERROR,
"SmmCopyMem: Security Violation: Destination (0x%x), Length (0x%x)\n", DestinationBuffer, Length));
336 return EFI_SECURITY_VIOLATION;
340 DEBUG ((DEBUG_ERROR,
"SmmCopyMem: Security Violation: Source (0x%x), Length (0x%x)\n", SourceBuffer, Length));
341 return EFI_SECURITY_VIOLATION;
344 CopyMem (DestinationBuffer, SourceBuffer, Length);
373 DEBUG ((DEBUG_ERROR,
"SmmSetMem: Security Violation: Source (0x%x), Length (0x%x)\n", Buffer, Length));
374 return EFI_SECURITY_VIOLATION;
377 SetMem (Buffer, Length, Value);
390 UINTN NumberOfDescriptors;
395 Status =
gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap);
396 if (EFI_ERROR (Status)) {
400 mSmmMemLibGcdMemNumberOfDesc = 0;
401 for (Index = 0; Index < NumberOfDescriptors; Index++) {
403 ((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
404 (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))
407 mSmmMemLibGcdMemNumberOfDesc++;
412 ASSERT (mSmmMemLibGcdMemSpace !=
NULL);
413 if (mSmmMemLibGcdMemSpace ==
NULL) {
414 mSmmMemLibGcdMemNumberOfDesc = 0;
415 gBS->FreePool (MemSpaceMap);
419 mSmmMemLibGcdMemNumberOfDesc = 0;
420 for (Index = 0; Index < NumberOfDescriptors; Index++) {
422 ((MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
423 (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))
427 &mSmmMemLibGcdMemSpace[mSmmMemLibGcdMemNumberOfDesc],
431 mSmmMemLibGcdMemNumberOfDesc++;
435 gBS->FreePool (MemSpaceMap);
448 UINTN MemoryAttributesTableSize;
451 if (!EFI_ERROR (Status) && (MemoryAttributesTable !=
NULL)) {
452 MemoryAttributesTableSize =
sizeof (
EFI_MEMORY_ATTRIBUTES_TABLE) + MemoryAttributesTable->DescriptorSize * MemoryAttributesTable->NumberOfEntries;
453 mSmmMemLibMemoryAttributesTable =
AllocateCopyPool (MemoryAttributesTableSize, MemoryAttributesTable);
454 ASSERT (mSmmMemLibMemoryAttributesTable !=
NULL);
481 UINTN MemoryMapEntryCount;
482 UINTN DescriptorSize;
483 UINT32 DescriptorVersion;
488 Status =
gBS->GetMemoryMap (
495 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
499 ASSERT (MemoryMap !=
NULL);
501 Status =
gBS->GetMemoryMap (
508 if (EFI_ERROR (Status)) {
509 gBS->FreePool (MemoryMap);
511 }
while (Status == EFI_BUFFER_TOO_SMALL);
516 mDescriptorSize = DescriptorSize;
517 MemoryMapEntryCount = MemoryMapSize/DescriptorSize;
518 MemoryMapStart = MemoryMap;
519 mMemoryMapEntryCount = 0;
520 for (Index = 0; Index < MemoryMapEntryCount; Index++) {
521 switch (MemoryMap->
Type) {
526 mMemoryMapEntryCount++;
530 MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, DescriptorSize);
533 MemoryMap = MemoryMapStart;
538 mMemoryMap =
AllocatePool (mMemoryMapEntryCount*DescriptorSize);
539 ASSERT (mMemoryMap !=
NULL);
540 SmmMemoryMapStart = mMemoryMap;
541 for (Index = 0; Index < MemoryMapEntryCount; Index++) {
542 switch (MemoryMap->
Type) {
547 CopyMem (mMemoryMap, MemoryMap, DescriptorSize);
548 mMemoryMap = NEXT_MEMORY_DESCRIPTOR (mMemoryMap, DescriptorSize);
552 MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, DescriptorSize);
555 mMemoryMap = SmmMemoryMapStart;
556 MemoryMap = MemoryMapStart;
558 gBS->FreePool (MemoryMap);
590 mSmmMemLibSmmReadyToLock =
TRUE;
617 Status =
gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid,
NULL, (VOID **)&SmmAccess);
621 Status = SmmAccess->GetCapabilities (SmmAccess, &Size,
NULL);
622 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
625 ASSERT (mSmmMemLibInternalSmramRanges !=
NULL);
627 Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmmMemLibInternalSmramRanges);
667 FreePool (mSmmMemLibInternalSmramRanges);
669 gSmst->SmmRegisterProtocolNotify (&gEfiSmmEndOfDxeProtocolGuid,
NULL, &mRegistrationEndOfDxe);
670 gSmst->SmmRegisterProtocolNotify (&gEfiSmmReadyToLockProtocolGuid,
NULL, &mRegistrationReadyToLock);
VOID *EFIAPI GetFirstHob(IN UINT16 Type)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
@ EfiGcdMemoryTypeReserved
EFI_SMM_SYSTEM_TABLE2 * gSmst
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID SmmMemLibInternalGetGcdMemoryMap(VOID)
EFI_STATUS EFIAPI SmmLibInternalReadyToLockNotify(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
EFI_STATUS EFIAPI SmmLibInternalEndOfDxeNotify(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
EFI_STATUS EFIAPI SmmCopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_STATUS EFIAPI SmmSetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
VOID SmmMemLibInternalGetUefiMemoryAttributesTable(VOID)
EFI_STATUS EFIAPI SmmMemLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
VOID SmmMemLibInternalCalculateMaximumSupportAddress(VOID)
EFI_STATUS EFIAPI SmmCopyMemFromSmram(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_STATUS EFIAPI SmmMemLibDestructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
BOOLEAN EFIAPI SmmIsBufferOutsideSmmValid(IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length)
EFI_STATUS EFIAPI SmmCopyMemToSmram(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
UINT64 EFI_PHYSICAL_ADDRESS
EFI_STATUS EFIAPI EfiGetSystemConfigurationTable(IN EFI_GUID *TableGuid, OUT VOID **Table)
EFI_PHYSICAL_ADDRESS PhysicalStart