41#define KNOWN_HANDLE_SIGNATURE SIGNATURE_32('k','n','o','w')
88BOOLEAN gDispatcherRunning =
FALSE;
93BOOLEAN gRequestDispatch =
FALSE;
98EFI_FV_FILETYPE mSmmFileTypes[] = {
100 EFI_FV_FILETYPE_COMBINED_SMM_DXE,
101 EFI_FV_FILETYPE_SMM_CORE,
145 UINT32 SmmCodePageNumber;
148 UINTN BaseOffsetPageNumber;
149 UINTN TopOffsetPageNumber;
155 SmmCodePageNumber =
PcdGet32 (PcdLoadFixAddressSmmCodePageNumber);
157 SmmCodeBase = gLoadModuleAtFixAddressSmramBase;
163 if (mSmmCodeMemoryRangeUsageBitMap ==
NULL) {
164 mSmmCodeMemoryRangeUsageBitMap =
AllocateZeroPool (((SmmCodePageNumber / 64) + 1)*
sizeof (UINT64));
170 if (mSmmCodeMemoryRangeUsageBitMap ==
NULL) {
171 return EFI_NOT_FOUND;
177 if ((SmmCodeBase + SmmCodeSize < ImageBase + ImageSize) || (SmmCodeBase > ImageBase)) {
178 return EFI_NOT_FOUND;
185 TopOffsetPageNumber =
EFI_SIZE_TO_PAGES ((UINT32)(ImageBase + ImageSize - SmmCodeBase));
186 for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index++) {
187 if ((mSmmCodeMemoryRangeUsageBitMap[Index / 64] &
LShiftU64 (1, (Index % 64))) != 0) {
191 return EFI_NOT_FOUND;
198 for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index++) {
199 mSmmCodeMemoryRangeUsageBitMap[Index / 64] |=
LShiftU64 (1, (Index % 64));
220 UINTN SectionHeaderOffset;
227 UINT16 NumberOfSections;
228 UINT64 ValueInSectionHeader;
230 FixLoadingAddress = 0;
231 Status = EFI_NOT_FOUND;
237 SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +
240 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader;
241 NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
246 for (Index = 0; Index < NumberOfSections; Index++) {
251 Status = ImageContext->ImageRead (
252 ImageContext->Handle,
257 if (EFI_ERROR (Status)) {
261 Status = EFI_NOT_FOUND;
270 ValueInSectionHeader =
ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations);
271 if (ValueInSectionHeader != 0) {
276 FixLoadingAddress = (
EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + (INT64)ValueInSectionHeader);
281 if (!EFI_ERROR (Status)) {
285 ImageContext->ImageAddress = FixLoadingAddress;
295 DEBUG ((DEBUG_INFO|DEBUG_LOAD,
"LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r\n", FixLoadingAddress, Status));
313 UINT32 AuthenticationStatus;
330 CHAR8 EfiFileName[512];
340 OriginalFilePath = FilePath;
341 HandleFilePath = FilePath;
345 AuthenticationStatus = 0;
350 Status =
gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &HandleFilePath, &DeviceHandle);
351 if (EFI_ERROR (Status)) {
358 if (mSecurity2 ==
NULL) {
359 gBS->LocateProtocol (&gEfiSecurity2ArchProtocolGuid,
NULL, (
VOID **)&mSecurity2);
362 if (mSecurity ==
NULL) {
363 gBS->LocateProtocol (&gEfiSecurityArchProtocolGuid,
NULL, (
VOID **)&mSecurity);
369 ASSERT (mSecurity2 ==
NULL || mSecurity !=
NULL);
374 FilePath = OriginalFilePath;
375 Status =
gBS->HandleProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid, (
VOID **)&HandleFilePath);
376 if (!EFI_ERROR (Status)) {
384 Status = Fv->ReadSection (
391 &AuthenticationStatus
394 if (EFI_ERROR (Status)) {
400 Status = Fv->ReadSection (
407 &AuthenticationStatus
411 if (EFI_ERROR (Status)) {
412 if (Buffer !=
NULL) {
413 gBS->FreePool (Buffer);
422 if (mSecurity2 !=
NULL) {
423 SecurityStatus = mSecurity2->FileAuthentication (
437 if (!EFI_ERROR (SecurityStatus) && (mSecurity !=
NULL)) {
438 SecurityStatus = mSecurity->FileAuthenticationState (
440 AuthenticationStatus,
445 if (EFI_ERROR (SecurityStatus) && (SecurityStatus != EFI_SECURITY_VIOLATION)) {
446 Status = SecurityStatus;
453 ImageContext.
Handle = Buffer;
460 if (EFI_ERROR (Status)) {
461 if (Buffer !=
NULL) {
462 gBS->FreePool (Buffer);
472 if (
PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) {
477 if (!EFI_ERROR (Status)) {
483 DstBuffer = (
UINTN)gLoadModuleAtFixAddressSmramBase;
485 DEBUG ((DEBUG_INFO|DEBUG_LOAD,
"LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
490 DstBuffer = (
UINTN)(-1);
498 if (EFI_ERROR (Status)) {
499 if (Buffer !=
NULL) {
500 gBS->FreePool (Buffer);
510 DstBuffer = (
UINTN)(-1);
518 if (EFI_ERROR (Status)) {
519 if (Buffer !=
NULL) {
520 gBS->FreePool (Buffer);
539 if (EFI_ERROR (Status)) {
540 if (Buffer !=
NULL) {
541 gBS->FreePool (Buffer);
552 if (EFI_ERROR (Status)) {
553 if (Buffer !=
NULL) {
554 gBS->FreePool (Buffer);
577 if (EFI_ERROR (Status)) {
578 if (Buffer !=
NULL) {
579 gBS->FreePool (Buffer);
594 DriverEntry->LoadedImage->DeviceHandle = DeviceHandle;
599 DriverEntry->SmmLoadedImage.DeviceHandle = DeviceHandle;
605 if (EFI_ERROR (Status)) {
606 if (Buffer !=
NULL) {
607 gBS->FreePool (Buffer);
625 if (EFI_ERROR (Status)) {
626 if (Buffer !=
NULL) {
627 gBS->FreePool (Buffer);
646 Status =
gBS->InstallMultipleProtocolInterfaces (
648 &gEfiLoadedImageProtocolGuid,
659 &gEfiLoadedImageProtocolGuid,
671 DEBUG_INFO | DEBUG_LOAD,
672 "Loading SMM driver at 0x%11p EntryPoint=0x%11p ",
683 for (Index = 0; ImageContext.
PdbPointer[Index] != 0; Index++) {
685 StartIndex = Index + 1;
694 for (Index = 0; Index <
sizeof (EfiFileName) - 4; Index++) {
695 EfiFileName[Index] = ImageContext.
PdbPointer[Index + StartIndex];
696 if (EfiFileName[Index] == 0) {
697 EfiFileName[Index] =
'.';
700 if (EfiFileName[Index] ==
'.') {
701 EfiFileName[Index + 1] =
'e';
702 EfiFileName[Index + 2] =
'f';
703 EfiFileName[Index + 3] =
'i';
704 EfiFileName[Index + 4] = 0;
709 if (Index ==
sizeof (EfiFileName) - 4) {
710 EfiFileName[Index] = 0;
713 DEBUG ((DEBUG_INFO | DEBUG_LOAD,
"%a", EfiFileName));
716 DEBUG ((DEBUG_INFO | DEBUG_LOAD,
"\n"));
724 Status =
gBS->FreePool (Buffer);
725 if (!EFI_ERROR (Status) && EFI_ERROR (SecurityStatus)) {
726 Status = SecurityStatus;
783 EFI_SECTION_TYPE SectionType;
784 UINT32 AuthenticationStatus;
793 SectionType = EFI_SECTION_SMM_DEPEX;
794 Status = Fv->ReadSection (
801 &AuthenticationStatus
803 if (EFI_ERROR (Status)) {
804 if (Status == EFI_PROTOCOL_ERROR) {
854 BOOLEAN PreviousSmmEntryPointRegistered;
856 if (!gRequestDispatch) {
857 return EFI_NOT_FOUND;
860 if (gDispatcherRunning) {
864 return EFI_ALREADY_STARTED;
867 gDispatcherRunning =
TRUE;
875 mScheduledQueue.ForwardLink,
878 EFI_SMM_DRIVER_ENTRY_SIGNATURE
892 if (EFI_ERROR (Status)) {
914 EFI_SOFTWARE_SMM_DRIVER | EFI_SW_PC_INIT_BEGIN,
931 if (EFI_ERROR (Status)) {
934 "Error: SMM image at %11p start failed: %r\n",
943 Status =
gBS->UninstallProtocolInterface (
945 &gEfiLoadedImageProtocolGuid,
948 if (!EFI_ERROR (Status)) {
958 &gEfiLoadedImageProtocolGuid,
961 if (!EFI_ERROR (Status)) {
970 EFI_SOFTWARE_SMM_DRIVER | EFI_SW_PC_INIT_END,
984 gRequestDispatch =
TRUE;
985 gDispatcherRunning =
FALSE;
986 return EFI_NOT_READY;
994 for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
1011 }
while (ReadyToRun);
1016 gRequestDispatch =
FALSE;
1017 for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
1024 gRequestDispatch =
TRUE;
1029 gDispatcherRunning =
FALSE;
1056 for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
1059 DEBUG ((DEBUG_DISPATCH,
"Evaluate SMM DEPEX for FFS(%g)\n", &
DriverEntry->FileName));
1060 DEBUG ((DEBUG_DISPATCH,
" BEFORE FFS(%g) = ", &
DriverEntry->BeforeAfterGuid));
1065 DEBUG ((DEBUG_DISPATCH,
"TRUE\n END\n RESULT = TRUE\n"));
1068 DEBUG ((DEBUG_DISPATCH,
"FALSE\n END\n RESULT = FALSE\n"));
1077 InsertedDriverEntry->Dependent =
FALSE;
1078 InsertedDriverEntry->Scheduled =
TRUE;
1079 InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink);
1084 for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
1087 DEBUG ((DEBUG_DISPATCH,
"Evaluate SMM DEPEX for FFS(%g)\n", &
DriverEntry->FileName));
1088 DEBUG ((DEBUG_DISPATCH,
" AFTER FFS(%g) = ", &
DriverEntry->BeforeAfterGuid));
1093 DEBUG ((DEBUG_DISPATCH,
"TRUE\n END\n RESULT = TRUE\n"));
1096 DEBUG ((DEBUG_DISPATCH,
"FALSE\n END\n RESULT = FALSE\n"));
1120 for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {
1121 KnownHandle =
CR (Link,
KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);
1122 if (KnownHandle->Handle == FvHandle) {
1146 ASSERT (KnownHandle !=
NULL);
1148 KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;
1149 KnownHandle->Handle = FvHandle;
1180 Status =
gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (
VOID **)&FvDevicePath);
1181 if (EFI_ERROR (Status)) {
1182 FileNameDevicePath =
NULL;
1199 return FileNameDevicePath;
1238 DriverEntry->Signature = EFI_SMM_DRIVER_ENTRY_SIGNATURE;
1247 gRequestDispatch =
TRUE;
1295 EFI_FV_FILETYPE Type;
1300 UINTN AprioriEntryCount;
1305 UINT32 AuthenticationStatus;
1308 HandleBuffer =
NULL;
1309 Status =
gBS->LocateHandleBuffer (
1311 &gEfiFirmwareVolume2ProtocolGuid,
1316 if (EFI_ERROR (Status)) {
1317 return EFI_NOT_FOUND;
1322 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
1323 FvHandle = HandleBuffer[HandleIndex];
1337 Status =
gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (
VOID **)&Fv);
1338 if (EFI_ERROR (Status)) {
1346 Status =
gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (
VOID **)&FvDevicePath);
1347 if (EFI_ERROR (Status)) {
1359 for (SmmTypeIndex = 0; SmmTypeIndex <
sizeof (mSmmFileTypes)/
sizeof (EFI_FV_FILETYPE); SmmTypeIndex++) {
1365 Type = mSmmFileTypes[SmmTypeIndex];
1366 GetNextFileStatus = Fv->GetNextFile (
1374 if (!EFI_ERROR (GetNextFileStatus)) {
1375 if (Type == EFI_FV_FILETYPE_SMM_CORE) {
1390 Status =
gBS->AllocatePool (
1401 if (mSmmCoreDriverEntry->SmmLoadedImage.
FilePath ==
NULL) {
1420 mSmmCoreDriverEntry->SmmLoadedImage.
DeviceHandle = FvHandle;
1426 }
while (!EFI_ERROR (GetNextFileStatus));
1434 Status = Fv->ReadSection (
1439 (
VOID **)&AprioriFile,
1441 &AuthenticationStatus
1443 if (!EFI_ERROR (Status)) {
1444 AprioriEntryCount = SizeOfBuffer /
sizeof (
EFI_GUID);
1446 AprioriEntryCount = 0;
1455 for (AprioriIndex = 0; AprioriIndex < AprioriEntryCount; AprioriIndex++) {
1456 for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
1464 DEBUG ((DEBUG_DISPATCH,
"Evaluate SMM DEPEX for FFS(%g)\n", &
DriverEntry->FileName));
1465 DEBUG ((DEBUG_DISPATCH,
" RESULT = TRUE (Apriori)\n"));
1477 gBS->FreePool (AprioriFile);
1489 if ((CommBuffer !=
NULL) && (CommBufferSize !=
NULL)) {
1490 if (*CommBufferSize > 0) {
1491 if (Status == EFI_NOT_READY) {
1496 *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_RESTART;
1497 }
else if (!EFI_ERROR (Status)) {
1501 *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_SUCCESS;
1528 for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
1531 DEBUG ((DEBUG_LOAD,
"SMM Driver %g was discovered but not loaded!!\n", &
DriverEntry->FileName));
#define FUNCTION_ENTRY_POINT(FunctionPointer)
VOID *EFIAPI InvalidateInstructionCacheRange(IN VOID *Address, IN UINTN Length)
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
UINT64 EFIAPI ReadUnaligned64(IN CONST VOID *Buffer)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL)
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
VOID EFIAPI SetDevicePathEndNode(OUT VOID *Node)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
#define EFI_LOADED_IMAGE_PROTOCOL_REVISION
BOOLEAN FvHasBeenProcessed(IN EFI_HANDLE FvHandle)
KNOWN_HANDLE * FvIsBeingProcessed(IN EFI_HANDLE FvHandle)
BOOLEAN SmmIsSchedulable(IN EFI_SMM_DRIVER_ENTRY *DriverEntry)
VOID SmmDisplayDiscoveredNotDispatched(VOID)
EFI_STATUS SmmPreProcessDepex(IN EFI_SMM_DRIVER_ENTRY *DriverEntry)
EFI_STATUS GetPeCoffImageFixLoadingAssignedAddress(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
VOID SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter(IN EFI_SMM_DRIVER_ENTRY *InsertedDriverEntry)
EFI_STATUS SmmDispatcher(VOID)
EFI_STATUS SmmGetDepexSectionAndPreProccess(IN EFI_SMM_DRIVER_ENTRY *DriverEntry)
EFI_DEVICE_PATH_PROTOCOL * SmmFvToDevicePath(IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, IN EFI_HANDLE FvHandle, IN EFI_GUID *DriverName)
EFI_STATUS CheckAndMarkFixLoadingMemoryUsageBitMap(IN EFI_PHYSICAL_ADDRESS ImageBase, IN UINTN ImageSize)
EFI_STATUS EFIAPI SmmDriverDispatchHandler(IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context OPTIONAL, IN OUT VOID *CommBuffer OPTIONAL, IN OUT UINTN *CommBufferSize OPTIONAL)
EFI_STATUS SmmAddToDriverList(IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, IN EFI_HANDLE FvHandle, IN EFI_GUID *DriverName)
EFI_STATUS EFIAPI SmmLoadImage(IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry)
EFI_STATUS EFIAPI SmmUninstallProtocolInterface(IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN VOID *Interface)
EFI_STATUS EFIAPI SmmInstallProtocolInterface(IN OUT EFI_HANDLE *UserHandle, IN EFI_GUID *Protocol, IN EFI_INTERFACE_TYPE InterfaceType, IN VOID *Interface)
EFI_STATUS EFIAPI SmmFreePages(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages)
EFI_STATUS EFIAPI SmmAllocatePages(IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN NumberOfPages, OUT EFI_PHYSICAL_ADDRESS *Memory)
#define GLOBAL_REMOVE_IF_UNREFERENCED
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define CR(Record, TYPE, Field, TestSignature)
#define REPORT_STATUS_CODE_WITH_EXTENDED_DATA(Type, Value, ExtendedData, ExtendedDataSize)
#define PcdGet64(TokenName)
#define PcdGet32(TokenName)
RETURN_STATUS EFIAPI PeCoffLoaderLoadImage(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
RETURN_STATUS EFIAPI PeCoffLoaderRelocateImage(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
RETURN_STATUS EFIAPI PeCoffLoaderGetImageInfo(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
RETURN_STATUS EFIAPI PeCoffLoaderImageReadFromMemory(IN VOID *FileHandle, IN UINTN FileOffset, IN OUT UINTN *ReadSize, OUT VOID *Buffer)
#define EFI_IMAGE_SCN_CNT_CODE
0x00000020
UINT32 EFI_FV_FILE_ATTRIBUTES
EFI_STATUS UnregisterSmramProfileImage(IN EFI_SMM_DRIVER_ENTRY *DriverEntry, IN BOOLEAN UnregisterToDxe)
EFI_STATUS EFIAPI SmmFreePool(IN VOID *Buffer)
EFI_STATUS EFIAPI SmmAllocatePool(IN EFI_MEMORY_TYPE PoolType, IN UINTN Size, OUT VOID **Buffer)
EFI_STATUS RegisterSmramProfileImage(IN EFI_SMM_DRIVER_ENTRY *DriverEntry, IN BOOLEAN RegisterToDxe)
#define COMM_BUFFER_SMM_DISPATCH_ERROR
#define EFI_PROGRESS_CODE
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS EFIAPI DriverEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_PAGES_TO_SIZE(Pages)
#define EFI_SIZE_TO_PAGES(Size)
VOID EFIAPI EfiInitializeFwVolDevicepathNode(IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode, IN CONST EFI_GUID *NameGuid)
EFI_STATUS(EFIAPI * EFI_IMAGE_ENTRY_POINT)(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_DEVICE_PATH_PROTOCOL * FilePath
EFI_HANDLE DeviceHandle
The device handle that the EFI Image was loaded from.
PE_COFF_LOADER_READ_FILE ImageRead
PHYSICAL_ADDRESS EntryPoint
PHYSICAL_ADDRESS ImageAddress
EFI_HANDLE SmmIplImageHandle
BOOLEAN SmmEntryPointRegistered