TianoCore EDK2 master
Loading...
Searching...
No Matches
Dispatcher.c
Go to the documentation of this file.
1
36#include "PiSmmCore.h"
37
38//
39// SMM Dispatcher Data structures
40//
41#define KNOWN_HANDLE_SIGNATURE SIGNATURE_32('k','n','o','w')
42typedef struct {
43 UINTN Signature;
44 LIST_ENTRY Link; // mFvHandleList
45 EFI_HANDLE Handle;
47
48//
49// Function Prototypes
50//
51
63VOID
65 IN EFI_SMM_DRIVER_ENTRY *InsertedDriverEntry
66 );
67
68//
69// The Driver List contains one copy of every driver that has been discovered.
70// Items are never removed from the driver list. List of EFI_SMM_DRIVER_ENTRY
71//
72LIST_ENTRY mDiscoveredList = INITIALIZE_LIST_HEAD_VARIABLE (mDiscoveredList);
73
74//
75// Queue of drivers that are ready to dispatch. This queue is a subset of the
76// mDiscoveredList.list of EFI_SMM_DRIVER_ENTRY.
77//
78LIST_ENTRY mScheduledQueue = INITIALIZE_LIST_HEAD_VARIABLE (mScheduledQueue);
79
80//
81// List of handles who's Fv's have been parsed and added to the mFwDriverList.
82//
83LIST_ENTRY mFvHandleList = INITIALIZE_LIST_HEAD_VARIABLE (mFvHandleList);
84
85//
86// Flag for the SMM Dispatcher. TRUE if dispatcher is executing.
87//
88BOOLEAN gDispatcherRunning = FALSE;
89
90//
91// Flag for the SMM Dispatcher. TRUE if there is one or more SMM drivers ready to be dispatched
92//
93BOOLEAN gRequestDispatch = FALSE;
94
95//
96// List of file types supported by dispatcher
97//
98EFI_FV_FILETYPE mSmmFileTypes[] = {
99 EFI_FV_FILETYPE_SMM,
100 EFI_FV_FILETYPE_COMBINED_SMM_DXE,
101 EFI_FV_FILETYPE_SMM_CORE,
102 //
103 // Note: DXE core will process the FV image file, so skip it in SMM core
104 // EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
105 //
106};
107
108typedef struct {
112
113FV_FILEPATH_DEVICE_PATH mFvDevicePath;
114
115//
116// DXE Architecture Protocols
117//
120
121//
122// The global variable is defined for Loading modules at fixed address feature to track the SMM code
123// memory range usage. It is a bit mapped array in which every bit indicates the corresponding
124// memory page available or not.
125//
126GLOBAL_REMOVE_IF_UNREFERENCED UINT64 *mSmmCodeMemoryRangeUsageBitMap = NULL;
127
141 IN EFI_PHYSICAL_ADDRESS ImageBase,
142 IN UINTN ImageSize
143 )
144{
145 UINT32 SmmCodePageNumber;
146 UINT64 SmmCodeSize;
147 EFI_PHYSICAL_ADDRESS SmmCodeBase;
148 UINTN BaseOffsetPageNumber;
149 UINTN TopOffsetPageNumber;
150 UINTN Index;
151
152 //
153 // Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber
154 //
155 SmmCodePageNumber = PcdGet32 (PcdLoadFixAddressSmmCodePageNumber);
156 SmmCodeSize = EFI_PAGES_TO_SIZE (SmmCodePageNumber);
157 SmmCodeBase = gLoadModuleAtFixAddressSmramBase;
158
159 //
160 // If the memory usage bit map is not initialized, do it. Every bit in the array
161 // indicate the status of the corresponding memory page, available or not
162 //
163 if (mSmmCodeMemoryRangeUsageBitMap == NULL) {
164 mSmmCodeMemoryRangeUsageBitMap = AllocateZeroPool (((SmmCodePageNumber / 64) + 1)*sizeof (UINT64));
165 }
166
167 //
168 // If the Dxe code memory range is not allocated or the bit map array allocation failed, return EFI_NOT_FOUND
169 //
170 if (mSmmCodeMemoryRangeUsageBitMap == NULL) {
171 return EFI_NOT_FOUND;
172 }
173
174 //
175 // see if the memory range for loading the image is in the SMM code range.
176 //
177 if ((SmmCodeBase + SmmCodeSize < ImageBase + ImageSize) || (SmmCodeBase > ImageBase)) {
178 return EFI_NOT_FOUND;
179 }
180
181 //
182 // Test if the memory is available or not.
183 //
184 BaseOffsetPageNumber = EFI_SIZE_TO_PAGES ((UINT32)(ImageBase - SmmCodeBase));
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) {
188 //
189 // This page is already used.
190 //
191 return EFI_NOT_FOUND;
192 }
193 }
194
195 //
196 // Being here means the memory range is available. So mark the bits for the memory range
197 //
198 for (Index = BaseOffsetPageNumber; Index < TopOffsetPageNumber; Index++) {
199 mSmmCodeMemoryRangeUsageBitMap[Index / 64] |= LShiftU64 (1, (Index % 64));
200 }
201
202 return EFI_SUCCESS;
203}
204
218 )
219{
220 UINTN SectionHeaderOffset;
221 EFI_STATUS Status;
222 EFI_IMAGE_SECTION_HEADER SectionHeader;
224 EFI_PHYSICAL_ADDRESS FixLoadingAddress;
225 UINT16 Index;
226 UINTN Size;
227 UINT16 NumberOfSections;
228 UINT64 ValueInSectionHeader;
229
230 FixLoadingAddress = 0;
231 Status = EFI_NOT_FOUND;
232
233 //
234 // Get PeHeader pointer
235 //
236 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
237 SectionHeaderOffset = ImageContext->PeCoffHeaderOffset +
238 sizeof (UINT32) +
239 sizeof (EFI_IMAGE_FILE_HEADER) +
240 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader;
241 NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
242
243 //
244 // Get base address from the first section header that doesn't point to code section.
245 //
246 for (Index = 0; Index < NumberOfSections; Index++) {
247 //
248 // Read section header from file
249 //
250 Size = sizeof (EFI_IMAGE_SECTION_HEADER);
251 Status = ImageContext->ImageRead (
252 ImageContext->Handle,
253 SectionHeaderOffset,
254 &Size,
255 &SectionHeader
256 );
257 if (EFI_ERROR (Status)) {
258 return Status;
259 }
260
261 Status = EFI_NOT_FOUND;
262
263 if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
264 //
265 // Build tool will save the address in PointerToRelocations & PointerToLineNumbers fields in the first section header
266 // that doesn't point to code section in image header.So there is an assumption that when the feature is enabled,
267 // if a module with a loading address assigned by tools, the PointerToRelocations & PointerToLineNumbers fields
268 // should not be Zero, or else, these 2 fields should be set to Zero
269 //
270 ValueInSectionHeader = ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations);
271 if (ValueInSectionHeader != 0) {
272 //
273 // Found first section header that doesn't point to code section in which build tool saves the
274 // offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields
275 //
276 FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(gLoadModuleAtFixAddressSmramBase + (INT64)ValueInSectionHeader);
277 //
278 // Check if the memory range is available.
279 //
280 Status = CheckAndMarkFixLoadingMemoryUsageBitMap (FixLoadingAddress, (UINTN)(ImageContext->ImageSize + ImageContext->SectionAlignment));
281 if (!EFI_ERROR (Status)) {
282 //
283 // The assigned address is valid. Return the specified loading address
284 //
285 ImageContext->ImageAddress = FixLoadingAddress;
286 }
287 }
288
289 break;
290 }
291
292 SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
293 }
294
295 DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r\n", FixLoadingAddress, Status));
296 return Status;
297}
298
308EFIAPI
311 )
312{
313 UINT32 AuthenticationStatus;
314 UINTN FilePathSize;
315 VOID *Buffer;
316 UINTN Size;
317 UINTN PageCount;
318 EFI_GUID *NameGuid;
319 EFI_STATUS Status;
320 EFI_STATUS SecurityStatus;
321 EFI_HANDLE DeviceHandle;
322 EFI_PHYSICAL_ADDRESS DstBuffer;
323 EFI_DEVICE_PATH_PROTOCOL *FilePath;
324 EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath;
325 EFI_DEVICE_PATH_PROTOCOL *HandleFilePath;
327 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
328 UINTN Index;
329 UINTN StartIndex;
330 CHAR8 EfiFileName[512];
331
332 PERF_LOAD_IMAGE_BEGIN (DriverEntry->ImageHandle);
333
334 Buffer = NULL;
335 Size = 0;
336 Fv = DriverEntry->Fv;
337 NameGuid = &DriverEntry->FileName;
338 FilePath = DriverEntry->FvFileDevicePath;
339
340 OriginalFilePath = FilePath;
341 HandleFilePath = FilePath;
342 DeviceHandle = NULL;
343 SecurityStatus = EFI_SUCCESS;
344 Status = EFI_SUCCESS;
345 AuthenticationStatus = 0;
346
347 //
348 // Try to get the image device handle by checking the match protocol.
349 //
350 Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &HandleFilePath, &DeviceHandle);
351 if (EFI_ERROR (Status)) {
352 return Status;
353 }
354
355 //
356 // If the Security2 and Security Architectural Protocol has not been located yet, then attempt to locate it
357 //
358 if (mSecurity2 == NULL) {
359 gBS->LocateProtocol (&gEfiSecurity2ArchProtocolGuid, NULL, (VOID **)&mSecurity2);
360 }
361
362 if (mSecurity == NULL) {
363 gBS->LocateProtocol (&gEfiSecurityArchProtocolGuid, NULL, (VOID **)&mSecurity);
364 }
365
366 //
367 // When Security2 is installed, Security Architectural Protocol must be published.
368 //
369 ASSERT (mSecurity2 == NULL || mSecurity != NULL);
370
371 //
372 // Pull out just the file portion of the DevicePath for the LoadedImage FilePath
373 //
374 FilePath = OriginalFilePath;
375 Status = gBS->HandleProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath);
376 if (!EFI_ERROR (Status)) {
377 FilePathSize = GetDevicePathSize (HandleFilePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL);
378 FilePath = (EFI_DEVICE_PATH_PROTOCOL *)(((UINT8 *)FilePath) + FilePathSize);
379 }
380
381 //
382 // Try reading PE32 section firstly
383 //
384 Status = Fv->ReadSection (
385 Fv,
386 NameGuid,
388 0,
389 &Buffer,
390 &Size,
391 &AuthenticationStatus
392 );
393
394 if (EFI_ERROR (Status)) {
395 //
396 // Try reading TE section secondly
397 //
398 Buffer = NULL;
399 Size = 0;
400 Status = Fv->ReadSection (
401 Fv,
402 NameGuid,
403 EFI_SECTION_TE,
404 0,
405 &Buffer,
406 &Size,
407 &AuthenticationStatus
408 );
409 }
410
411 if (EFI_ERROR (Status)) {
412 if (Buffer != NULL) {
413 gBS->FreePool (Buffer);
414 }
415
416 return Status;
417 }
418
419 //
420 // Verify File Authentication through the Security2 Architectural Protocol
421 //
422 if (mSecurity2 != NULL) {
423 SecurityStatus = mSecurity2->FileAuthentication (
424 mSecurity2,
425 OriginalFilePath,
426 Buffer,
427 Size,
428 FALSE
429 );
430 }
431
432 //
433 // Verify the Authentication Status through the Security Architectural Protocol
434 // Only on images that have been read using Firmware Volume protocol.
435 // All SMM images are from FV protocol.
436 //
437 if (!EFI_ERROR (SecurityStatus) && (mSecurity != NULL)) {
438 SecurityStatus = mSecurity->FileAuthenticationState (
439 mSecurity,
440 AuthenticationStatus,
441 OriginalFilePath
442 );
443 }
444
445 if (EFI_ERROR (SecurityStatus) && (SecurityStatus != EFI_SECURITY_VIOLATION)) {
446 Status = SecurityStatus;
447 return Status;
448 }
449
450 //
451 // Initialize ImageContext
452 //
453 ImageContext.Handle = Buffer;
455
456 //
457 // Get information about the image being loaded
458 //
459 Status = PeCoffLoaderGetImageInfo (&ImageContext);
460 if (EFI_ERROR (Status)) {
461 if (Buffer != NULL) {
462 gBS->FreePool (Buffer);
463 }
464
465 return Status;
466 }
467
468 //
469 // if Loading module at Fixed Address feature is enabled, then cut out a memory range started from TESG BASE
470 // to hold the Smm driver code
471 //
472 if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) {
473 //
474 // Get the fixed loading address assigned by Build tool
475 //
476 Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext);
477 if (!EFI_ERROR (Status)) {
478 //
479 // Since the memory range to load Smm core already been cut out, so no need to allocate and free this range
480 // following statements is to bypass SmmFreePages
481 //
482 PageCount = 0;
483 DstBuffer = (UINTN)gLoadModuleAtFixAddressSmramBase;
484 } else {
485 DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
486 //
487 // allocate the memory to load the SMM driver
488 //
489 PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
490 DstBuffer = (UINTN)(-1);
491
492 Status = SmmAllocatePages (
495 PageCount,
496 &DstBuffer
497 );
498 if (EFI_ERROR (Status)) {
499 if (Buffer != NULL) {
500 gBS->FreePool (Buffer);
501 }
502
503 return Status;
504 }
505
506 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer;
507 }
508 } else {
509 PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
510 DstBuffer = (UINTN)(-1);
511
512 Status = SmmAllocatePages (
515 PageCount,
516 &DstBuffer
517 );
518 if (EFI_ERROR (Status)) {
519 if (Buffer != NULL) {
520 gBS->FreePool (Buffer);
521 }
522
523 return Status;
524 }
525
526 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer;
527 }
528
529 //
530 // Align buffer on section boundary
531 //
532 ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
533 ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
534
535 //
536 // Load the image to our new buffer
537 //
538 Status = PeCoffLoaderLoadImage (&ImageContext);
539 if (EFI_ERROR (Status)) {
540 if (Buffer != NULL) {
541 gBS->FreePool (Buffer);
542 }
543
544 SmmFreePages (DstBuffer, PageCount);
545 return Status;
546 }
547
548 //
549 // Relocate the image in our new buffer
550 //
551 Status = PeCoffLoaderRelocateImage (&ImageContext);
552 if (EFI_ERROR (Status)) {
553 if (Buffer != NULL) {
554 gBS->FreePool (Buffer);
555 }
556
557 SmmFreePages (DstBuffer, PageCount);
558 return Status;
559 }
560
561 //
562 // Flush the instruction cache so the image data are written before we execute it
563 //
564 InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
565
566 //
567 // Save Image EntryPoint in DriverEntry
568 //
569 DriverEntry->ImageEntryPoint = ImageContext.EntryPoint;
570 DriverEntry->ImageBuffer = DstBuffer;
571 DriverEntry->NumberOfPage = PageCount;
572
573 //
574 // Allocate a Loaded Image Protocol in EfiBootServicesData
575 //
576 Status = gBS->AllocatePool (EfiBootServicesData, sizeof (EFI_LOADED_IMAGE_PROTOCOL), (VOID **)&DriverEntry->LoadedImage);
577 if (EFI_ERROR (Status)) {
578 if (Buffer != NULL) {
579 gBS->FreePool (Buffer);
580 }
581
582 SmmFreePages (DstBuffer, PageCount);
583 return Status;
584 }
585
586 ZeroMem (DriverEntry->LoadedImage, sizeof (EFI_LOADED_IMAGE_PROTOCOL));
587 //
588 // Fill in the remaining fields of the Loaded Image Protocol instance.
589 // Note: ImageBase is an SMRAM address that can not be accessed outside of SMRAM if SMRAM window is closed.
590 //
591 DriverEntry->LoadedImage->Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION;
592 DriverEntry->LoadedImage->ParentHandle = gSmmCorePrivate->SmmIplImageHandle;
593 DriverEntry->LoadedImage->SystemTable = gST;
594 DriverEntry->LoadedImage->DeviceHandle = DeviceHandle;
595
596 DriverEntry->SmmLoadedImage.Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION;
597 DriverEntry->SmmLoadedImage.ParentHandle = gSmmCorePrivate->SmmIplImageHandle;
598 DriverEntry->SmmLoadedImage.SystemTable = gST;
599 DriverEntry->SmmLoadedImage.DeviceHandle = DeviceHandle;
600
601 //
602 // Make an EfiBootServicesData buffer copy of FilePath
603 //
604 Status = gBS->AllocatePool (EfiBootServicesData, GetDevicePathSize (FilePath), (VOID **)&DriverEntry->LoadedImage->FilePath);
605 if (EFI_ERROR (Status)) {
606 if (Buffer != NULL) {
607 gBS->FreePool (Buffer);
608 }
609
610 SmmFreePages (DstBuffer, PageCount);
611 return Status;
612 }
613
614 CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath));
615
616 DriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN)ImageContext.ImageAddress;
617 DriverEntry->LoadedImage->ImageSize = ImageContext.ImageSize;
618 DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode;
619 DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData;
620
621 //
622 // Make a buffer copy of FilePath
623 //
624 Status = SmmAllocatePool (EfiRuntimeServicesData, GetDevicePathSize (FilePath), (VOID **)&DriverEntry->SmmLoadedImage.FilePath);
625 if (EFI_ERROR (Status)) {
626 if (Buffer != NULL) {
627 gBS->FreePool (Buffer);
628 }
629
630 gBS->FreePool (DriverEntry->LoadedImage->FilePath);
631 SmmFreePages (DstBuffer, PageCount);
632 return Status;
633 }
634
635 CopyMem (DriverEntry->SmmLoadedImage.FilePath, FilePath, GetDevicePathSize (FilePath));
636
637 DriverEntry->SmmLoadedImage.ImageBase = (VOID *)(UINTN)ImageContext.ImageAddress;
638 DriverEntry->SmmLoadedImage.ImageSize = ImageContext.ImageSize;
639 DriverEntry->SmmLoadedImage.ImageCodeType = EfiRuntimeServicesCode;
640 DriverEntry->SmmLoadedImage.ImageDataType = EfiRuntimeServicesData;
641
642 //
643 // Create a new image handle in the UEFI handle database for the SMM Driver
644 //
645 DriverEntry->ImageHandle = NULL;
646 Status = gBS->InstallMultipleProtocolInterfaces (
647 &DriverEntry->ImageHandle,
648 &gEfiLoadedImageProtocolGuid,
649 DriverEntry->LoadedImage,
650 NULL
651 );
652
653 //
654 // Create a new image handle in the SMM handle database for the SMM Driver
655 //
656 DriverEntry->SmmImageHandle = NULL;
658 &DriverEntry->SmmImageHandle,
659 &gEfiLoadedImageProtocolGuid,
661 &DriverEntry->SmmLoadedImage
662 );
663
664 PERF_LOAD_IMAGE_END (DriverEntry->ImageHandle);
665
666 //
667 // Print the load address and the PDB file name if it is available
668 //
669
670 DEBUG ((
671 DEBUG_INFO | DEBUG_LOAD,
672 "Loading SMM driver at 0x%11p EntryPoint=0x%11p ",
673 (VOID *)(UINTN)ImageContext.ImageAddress,
674 FUNCTION_ENTRY_POINT (ImageContext.EntryPoint)
675 ));
676
677 //
678 // Print Module Name by Pdb file path.
679 // Windows and Unix style file path are all trimmed correctly.
680 //
681 if (ImageContext.PdbPointer != NULL) {
682 StartIndex = 0;
683 for (Index = 0; ImageContext.PdbPointer[Index] != 0; Index++) {
684 if ((ImageContext.PdbPointer[Index] == '\\') || (ImageContext.PdbPointer[Index] == '/')) {
685 StartIndex = Index + 1;
686 }
687 }
688
689 //
690 // Copy the PDB file name to our temporary string, and replace .pdb with .efi
691 // The PDB file name is limited in the range of 0~255.
692 // If the length is bigger than 255, trim the redundant characters to avoid overflow in array boundary.
693 //
694 for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) {
695 EfiFileName[Index] = ImageContext.PdbPointer[Index + StartIndex];
696 if (EfiFileName[Index] == 0) {
697 EfiFileName[Index] = '.';
698 }
699
700 if (EfiFileName[Index] == '.') {
701 EfiFileName[Index + 1] = 'e';
702 EfiFileName[Index + 2] = 'f';
703 EfiFileName[Index + 3] = 'i';
704 EfiFileName[Index + 4] = 0;
705 break;
706 }
707 }
708
709 if (Index == sizeof (EfiFileName) - 4) {
710 EfiFileName[Index] = 0;
711 }
712
713 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex]));
714 }
715
716 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "\n"));
717
718 //
719 // Free buffer allocated by Fv->ReadSection.
720 //
721 // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection
722 // used the UEFI Boot Services AllocatePool() function
723 //
724 Status = gBS->FreePool (Buffer);
725 if (!EFI_ERROR (Status) && EFI_ERROR (SecurityStatus)) {
726 Status = SecurityStatus;
727 }
728
729 return Status;
730}
731
745 )
746{
747 UINT8 *Iterator;
748
749 Iterator = DriverEntry->Depex;
750 DriverEntry->Dependent = TRUE;
751
752 if (*Iterator == EFI_DEP_BEFORE) {
753 DriverEntry->Before = TRUE;
754 } else if (*Iterator == EFI_DEP_AFTER) {
755 DriverEntry->After = TRUE;
756 }
757
758 if (DriverEntry->Before || DriverEntry->After) {
759 CopyMem (&DriverEntry->BeforeAfterGuid, Iterator + 1, sizeof (EFI_GUID));
760 }
761
762 return EFI_SUCCESS;
763}
764
780 )
781{
782 EFI_STATUS Status;
783 EFI_SECTION_TYPE SectionType;
784 UINT32 AuthenticationStatus;
786
787 Fv = DriverEntry->Fv;
788
789 //
790 // Grab Depex info, it will never be free'ed.
791 // (Note: DriverEntry->Depex is in DXE memory)
792 //
793 SectionType = EFI_SECTION_SMM_DEPEX;
794 Status = Fv->ReadSection (
795 DriverEntry->Fv,
796 &DriverEntry->FileName,
797 SectionType,
798 0,
799 &DriverEntry->Depex,
800 (UINTN *)&DriverEntry->DepexSize,
801 &AuthenticationStatus
802 );
803 if (EFI_ERROR (Status)) {
804 if (Status == EFI_PROTOCOL_ERROR) {
805 //
806 // The section extraction protocol failed so set protocol error flag
807 //
808 DriverEntry->DepexProtocolError = TRUE;
809 } else {
810 //
811 // If no Depex assume depend on all architectural protocols
812 //
813 DriverEntry->Depex = NULL;
814 DriverEntry->Dependent = TRUE;
815 DriverEntry->DepexProtocolError = FALSE;
816 }
817 } else {
818 //
819 // Set Before and After state information based on Depex
820 // Driver will be put in Dependent state
821 //
823 DriverEntry->DepexProtocolError = FALSE;
824 }
825
826 return Status;
827}
828
847 VOID
848 )
849{
850 EFI_STATUS Status;
851 LIST_ENTRY *Link;
853 BOOLEAN ReadyToRun;
854 BOOLEAN PreviousSmmEntryPointRegistered;
855
856 if (!gRequestDispatch) {
857 return EFI_NOT_FOUND;
858 }
859
860 if (gDispatcherRunning) {
861 //
862 // If the dispatcher is running don't let it be restarted.
863 //
864 return EFI_ALREADY_STARTED;
865 }
866
867 gDispatcherRunning = TRUE;
868
869 do {
870 //
871 // Drain the Scheduled Queue
872 //
873 while (!IsListEmpty (&mScheduledQueue)) {
874 DriverEntry = CR (
875 mScheduledQueue.ForwardLink,
877 ScheduledLink,
878 EFI_SMM_DRIVER_ENTRY_SIGNATURE
879 );
880
881 //
882 // Load the SMM Driver image into memory. If the Driver was transitioned from
883 // Untrused to Scheduled it would have already been loaded so we may need to
884 // skip the LoadImage
885 //
886 if (DriverEntry->ImageHandle == NULL) {
887 Status = SmmLoadImage (DriverEntry);
888
889 //
890 // Update the driver state to reflect that it's been loaded
891 //
892 if (EFI_ERROR (Status)) {
893 //
894 // The SMM Driver could not be loaded, and do not attempt to load or start it again.
895 // Take driver from Scheduled to Initialized.
896 //
897 DriverEntry->Initialized = TRUE;
898 DriverEntry->Scheduled = FALSE;
899 RemoveEntryList (&DriverEntry->ScheduledLink);
900
901 //
902 // If it's an error don't try the StartImage
903 //
904 continue;
905 }
906 }
907
908 DriverEntry->Scheduled = FALSE;
909 DriverEntry->Initialized = TRUE;
910 RemoveEntryList (&DriverEntry->ScheduledLink);
911
914 EFI_SOFTWARE_SMM_DRIVER | EFI_SW_PC_INIT_BEGIN,
915 &DriverEntry->ImageHandle,
916 sizeof (DriverEntry->ImageHandle)
917 );
918
919 //
920 // Cache state of SmmEntryPointRegistered before calling entry point
921 //
922 PreviousSmmEntryPointRegistered = gSmmCorePrivate->SmmEntryPointRegistered;
923
924 //
925 // For each SMM driver, pass NULL as ImageHandle
926 //
928 PERF_START_IMAGE_BEGIN (DriverEntry->ImageHandle);
929 Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, gST);
930 PERF_START_IMAGE_END (DriverEntry->ImageHandle);
931 if (EFI_ERROR (Status)) {
932 DEBUG ((
933 DEBUG_ERROR,
934 "Error: SMM image at %11p start failed: %r\n",
935 DriverEntry->SmmLoadedImage.ImageBase,
936 Status
937 ));
939 SmmFreePages (DriverEntry->ImageBuffer, DriverEntry->NumberOfPage);
940 //
941 // Uninstall LoadedImage
942 //
943 Status = gBS->UninstallProtocolInterface (
944 DriverEntry->ImageHandle,
945 &gEfiLoadedImageProtocolGuid,
946 DriverEntry->LoadedImage
947 );
948 if (!EFI_ERROR (Status)) {
949 if (DriverEntry->LoadedImage->FilePath != NULL) {
950 gBS->FreePool (DriverEntry->LoadedImage->FilePath);
951 }
952
953 gBS->FreePool (DriverEntry->LoadedImage);
954 }
955
957 DriverEntry->SmmImageHandle,
958 &gEfiLoadedImageProtocolGuid,
959 &DriverEntry->SmmLoadedImage
960 );
961 if (!EFI_ERROR (Status)) {
962 if (DriverEntry->SmmLoadedImage.FilePath != NULL) {
963 SmmFreePool (DriverEntry->SmmLoadedImage.FilePath);
964 }
965 }
966 }
967
970 EFI_SOFTWARE_SMM_DRIVER | EFI_SW_PC_INIT_END,
971 &DriverEntry->ImageHandle,
972 sizeof (DriverEntry->ImageHandle)
973 );
974
975 if (!PreviousSmmEntryPointRegistered && gSmmCorePrivate->SmmEntryPointRegistered) {
976 //
977 // Return immediately if the SMM Entry Point was registered by the SMM
978 // Driver that was just dispatched. The SMM IPL will reinvoke the SMM
979 // Core Dispatcher. This is required so SMM Mode may be enabled as soon
980 // as all the dependent SMM Drivers for SMM Mode have been dispatched.
981 // Once the SMM Entry Point has been registered, then SMM Mode will be
982 // used.
983 //
984 gRequestDispatch = TRUE;
985 gDispatcherRunning = FALSE;
986 return EFI_NOT_READY;
987 }
988 }
989
990 //
991 // Search DriverList for items to place on Scheduled Queue
992 //
993 ReadyToRun = FALSE;
994 for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
995 DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
996
997 if (DriverEntry->DepexProtocolError) {
998 //
999 // If Section Extraction Protocol did not let the Depex be read before retry the read
1000 //
1002 }
1003
1004 if (DriverEntry->Dependent) {
1007 ReadyToRun = TRUE;
1008 }
1009 }
1010 }
1011 } while (ReadyToRun);
1012
1013 //
1014 // If there is no more SMM driver to dispatch, stop the dispatch request
1015 //
1016 gRequestDispatch = FALSE;
1017 for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
1018 DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
1019
1020 if (!DriverEntry->Initialized) {
1021 //
1022 // We have SMM driver pending to dispatch
1023 //
1024 gRequestDispatch = TRUE;
1025 break;
1026 }
1027 }
1028
1029 gDispatcherRunning = FALSE;
1030
1031 return EFI_SUCCESS;
1032}
1033
1045VOID
1047 IN EFI_SMM_DRIVER_ENTRY *InsertedDriverEntry
1048 )
1049{
1050 LIST_ENTRY *Link;
1052
1053 //
1054 // Process Before Dependency
1055 //
1056 for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
1057 DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
1058 if (DriverEntry->Before && DriverEntry->Dependent && (DriverEntry != InsertedDriverEntry)) {
1059 DEBUG ((DEBUG_DISPATCH, "Evaluate SMM DEPEX for FFS(%g)\n", &DriverEntry->FileName));
1060 DEBUG ((DEBUG_DISPATCH, " BEFORE FFS(%g) = ", &DriverEntry->BeforeAfterGuid));
1061 if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
1062 //
1063 // Recursively process BEFORE
1064 //
1065 DEBUG ((DEBUG_DISPATCH, "TRUE\n END\n RESULT = TRUE\n"));
1067 } else {
1068 DEBUG ((DEBUG_DISPATCH, "FALSE\n END\n RESULT = FALSE\n"));
1069 }
1070 }
1071 }
1072
1073 //
1074 // Convert driver from Dependent to Scheduled state
1075 //
1076
1077 InsertedDriverEntry->Dependent = FALSE;
1078 InsertedDriverEntry->Scheduled = TRUE;
1079 InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink);
1080
1081 //
1082 // Process After Dependency
1083 //
1084 for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
1085 DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
1086 if (DriverEntry->After && DriverEntry->Dependent && (DriverEntry != InsertedDriverEntry)) {
1087 DEBUG ((DEBUG_DISPATCH, "Evaluate SMM DEPEX for FFS(%g)\n", &DriverEntry->FileName));
1088 DEBUG ((DEBUG_DISPATCH, " AFTER FFS(%g) = ", &DriverEntry->BeforeAfterGuid));
1089 if (CompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
1090 //
1091 // Recursively process AFTER
1092 //
1093 DEBUG ((DEBUG_DISPATCH, "TRUE\n END\n RESULT = TRUE\n"));
1095 } else {
1096 DEBUG ((DEBUG_DISPATCH, "FALSE\n END\n RESULT = FALSE\n"));
1097 }
1098 }
1099 }
1100}
1101
1112BOOLEAN
1114 IN EFI_HANDLE FvHandle
1115 )
1116{
1117 LIST_ENTRY *Link;
1118 KNOWN_HANDLE *KnownHandle;
1119
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) {
1123 return TRUE;
1124 }
1125 }
1126
1127 return FALSE;
1128}
1129
1138VOID
1140 IN EFI_HANDLE FvHandle
1141 )
1142{
1143 KNOWN_HANDLE *KnownHandle;
1144
1145 KnownHandle = AllocatePool (sizeof (KNOWN_HANDLE));
1146 ASSERT (KnownHandle != NULL);
1147
1148 KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;
1149 KnownHandle->Handle = FvHandle;
1150 InsertTailList (&mFvHandleList, &KnownHandle->Link);
1151}
1152
1169 IN EFI_HANDLE FvHandle,
1170 IN EFI_GUID *DriverName
1171 )
1172{
1173 EFI_STATUS Status;
1174 EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;
1175 EFI_DEVICE_PATH_PROTOCOL *FileNameDevicePath;
1176
1177 //
1178 // Remember the device path of the FV
1179 //
1180 Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
1181 if (EFI_ERROR (Status)) {
1182 FileNameDevicePath = NULL;
1183 } else {
1184 //
1185 // Build a device path to the file in the FV to pass into gBS->LoadImage
1186 //
1187 EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, DriverName);
1188 SetDevicePathEndNode (&mFvDevicePath.End);
1189
1190 //
1191 // Note: FileNameDevicePath is in DXE memory
1192 //
1193 FileNameDevicePath = AppendDevicePath (
1194 FvDevicePath,
1195 (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
1196 );
1197 }
1198
1199 return FileNameDevicePath;
1200}
1201
1225 IN EFI_HANDLE FvHandle,
1226 IN EFI_GUID *DriverName
1227 )
1228{
1230
1231 //
1232 // Create the Driver Entry for the list. ZeroPool initializes lots of variables to
1233 // NULL or FALSE.
1234 //
1236 ASSERT (DriverEntry != NULL);
1237
1238 DriverEntry->Signature = EFI_SMM_DRIVER_ENTRY_SIGNATURE;
1239 CopyGuid (&DriverEntry->FileName, DriverName);
1240 DriverEntry->FvHandle = FvHandle;
1241 DriverEntry->Fv = Fv;
1242 DriverEntry->FvFileDevicePath = SmmFvToDevicePath (Fv, FvHandle, DriverName);
1243
1245
1246 InsertTailList (&mDiscoveredList, &DriverEntry->Link);
1247 gRequestDispatch = TRUE;
1248
1249 return EFI_SUCCESS;
1250}
1251
1278EFIAPI
1280 IN EFI_HANDLE DispatchHandle,
1281 IN CONST VOID *Context OPTIONAL,
1282 IN OUT VOID *CommBuffer OPTIONAL,
1283 IN OUT UINTN *CommBufferSize OPTIONAL
1284 )
1285{
1286 EFI_STATUS Status;
1287 UINTN HandleCount;
1288 EFI_HANDLE *HandleBuffer;
1289 EFI_STATUS GetNextFileStatus;
1291 EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;
1292 EFI_HANDLE FvHandle;
1293 EFI_GUID NameGuid;
1294 UINTN Key;
1295 EFI_FV_FILETYPE Type;
1296 EFI_FV_FILE_ATTRIBUTES Attributes;
1297 UINTN Size;
1299 EFI_GUID *AprioriFile;
1300 UINTN AprioriEntryCount;
1301 UINTN HandleIndex;
1302 UINTN SmmTypeIndex;
1303 UINTN AprioriIndex;
1304 LIST_ENTRY *Link;
1305 UINT32 AuthenticationStatus;
1306 UINTN SizeOfBuffer;
1307
1308 HandleBuffer = NULL;
1309 Status = gBS->LocateHandleBuffer (
1310 ByProtocol,
1311 &gEfiFirmwareVolume2ProtocolGuid,
1312 NULL,
1313 &HandleCount,
1314 &HandleBuffer
1315 );
1316 if (EFI_ERROR (Status)) {
1317 return EFI_NOT_FOUND;
1318 }
1319
1320 PERF_CALLBACK_BEGIN (&gEfiEventDxeDispatchGuid);
1321
1322 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
1323 FvHandle = HandleBuffer[HandleIndex];
1324
1325 if (FvHasBeenProcessed (FvHandle)) {
1326 //
1327 // This Fv has already been processed so lets skip it!
1328 //
1329 continue;
1330 }
1331
1332 //
1333 // Since we are about to process this Fv mark it as processed.
1334 //
1335 FvIsBeingProcessed (FvHandle);
1336
1337 Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
1338 if (EFI_ERROR (Status)) {
1339 //
1340 // FvHandle must have a Firmware Volume2 Protocol thus we should never get here.
1341 //
1342 ASSERT (FALSE);
1343 continue;
1344 }
1345
1346 Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
1347 if (EFI_ERROR (Status)) {
1348 //
1349 // The Firmware volume doesn't have device path, can't be dispatched.
1350 //
1351 continue;
1352 }
1353
1354 //
1355 // Discover Drivers in FV and add them to the Discovered Driver List.
1356 // Process EFI_FV_FILETYPE_SMM type and then EFI_FV_FILETYPE_COMBINED_SMM_DXE
1357 // EFI_FV_FILETYPE_SMM_CORE is processed to produce a Loaded Image protocol for the core
1358 //
1359 for (SmmTypeIndex = 0; SmmTypeIndex < sizeof (mSmmFileTypes)/sizeof (EFI_FV_FILETYPE); SmmTypeIndex++) {
1360 //
1361 // Initialize the search key
1362 //
1363 Key = 0;
1364 do {
1365 Type = mSmmFileTypes[SmmTypeIndex];
1366 GetNextFileStatus = Fv->GetNextFile (
1367 Fv,
1368 &Key,
1369 &Type,
1370 &NameGuid,
1371 &Attributes,
1372 &Size
1373 );
1374 if (!EFI_ERROR (GetNextFileStatus)) {
1375 if (Type == EFI_FV_FILETYPE_SMM_CORE) {
1376 //
1377 // If this is the SMM core fill in it's DevicePath & DeviceHandle
1378 //
1379 if (mSmmCoreLoadedImage->FilePath == NULL) {
1380 //
1381 // Maybe one special FV contains only one SMM_CORE module, so its device path must
1382 // be initialized completely.
1383 //
1384 EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid);
1385 SetDevicePathEndNode (&mFvDevicePath.End);
1386
1387 //
1388 // Make an EfiBootServicesData buffer copy of FilePath
1389 //
1390 Status = gBS->AllocatePool (
1392 GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath),
1393 (VOID **)&mSmmCoreLoadedImage->FilePath
1394 );
1395 ASSERT_EFI_ERROR (Status);
1396 CopyMem (mSmmCoreLoadedImage->FilePath, &mFvDevicePath, GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath));
1397
1398 mSmmCoreLoadedImage->DeviceHandle = FvHandle;
1399 }
1400
1401 if (mSmmCoreDriverEntry->SmmLoadedImage.FilePath == NULL) {
1402 //
1403 // Maybe one special FV contains only one SMM_CORE module, so its device path must
1404 // be initialized completely.
1405 //
1406 EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid);
1407 SetDevicePathEndNode (&mFvDevicePath.End);
1408
1409 //
1410 // Make a buffer copy FilePath
1411 //
1412 Status = SmmAllocatePool (
1414 GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath),
1415 (VOID **)&mSmmCoreDriverEntry->SmmLoadedImage.FilePath
1416 );
1417 ASSERT_EFI_ERROR (Status);
1418 CopyMem (mSmmCoreDriverEntry->SmmLoadedImage.FilePath, &mFvDevicePath, GetDevicePathSize ((EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath));
1419
1420 mSmmCoreDriverEntry->SmmLoadedImage.DeviceHandle = FvHandle;
1421 }
1422 } else {
1423 SmmAddToDriverList (Fv, FvHandle, &NameGuid);
1424 }
1425 }
1426 } while (!EFI_ERROR (GetNextFileStatus));
1427 }
1428
1429 //
1430 // Read the array of GUIDs from the Apriori file if it is present in the firmware volume
1431 // (Note: AprioriFile is in DXE memory)
1432 //
1433 AprioriFile = NULL;
1434 Status = Fv->ReadSection (
1435 Fv,
1436 &gAprioriGuid,
1437 EFI_SECTION_RAW,
1438 0,
1439 (VOID **)&AprioriFile,
1440 &SizeOfBuffer,
1441 &AuthenticationStatus
1442 );
1443 if (!EFI_ERROR (Status)) {
1444 AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID);
1445 } else {
1446 AprioriEntryCount = 0;
1447 }
1448
1449 //
1450 // Put drivers on Apriori List on the Scheduled queue. The Discovered List includes
1451 // drivers not in the current FV and these must be skipped since the a priori list
1452 // is only valid for the FV that it resided in.
1453 //
1454
1455 for (AprioriIndex = 0; AprioriIndex < AprioriEntryCount; AprioriIndex++) {
1456 for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
1457 DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
1458 if (CompareGuid (&DriverEntry->FileName, &AprioriFile[AprioriIndex]) &&
1459 (FvHandle == DriverEntry->FvHandle))
1460 {
1461 DriverEntry->Dependent = FALSE;
1462 DriverEntry->Scheduled = TRUE;
1463 InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
1464 DEBUG ((DEBUG_DISPATCH, "Evaluate SMM DEPEX for FFS(%g)\n", &DriverEntry->FileName));
1465 DEBUG ((DEBUG_DISPATCH, " RESULT = TRUE (Apriori)\n"));
1466 break;
1467 }
1468 }
1469 }
1470
1471 //
1472 // Free data allocated by Fv->ReadSection ()
1473 //
1474 // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection
1475 // used the UEFI Boot Services AllocatePool() function
1476 //
1477 gBS->FreePool (AprioriFile);
1478 }
1479
1480 //
1481 // Execute the SMM Dispatcher on any newly discovered FVs and previously
1482 // discovered SMM drivers that have been discovered but not dispatched.
1483 //
1484 Status = SmmDispatcher ();
1485
1486 //
1487 // Check to see if CommBuffer and CommBufferSize are valid
1488 //
1489 if ((CommBuffer != NULL) && (CommBufferSize != NULL)) {
1490 if (*CommBufferSize > 0) {
1491 if (Status == EFI_NOT_READY) {
1492 //
1493 // If a the SMM Core Entry Point was just registered, then set flag to
1494 // request the SMM Dispatcher to be restarted.
1495 //
1496 *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_RESTART;
1497 } else if (!EFI_ERROR (Status)) {
1498 //
1499 // Set the flag to show that the SMM Dispatcher executed without errors
1500 //
1501 *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_SUCCESS;
1502 } else {
1503 //
1504 // Set the flag to show that the SMM Dispatcher encountered an error
1505 //
1506 *(UINT8 *)CommBuffer = COMM_BUFFER_SMM_DISPATCH_ERROR;
1507 }
1508 }
1509 }
1510
1511 PERF_CALLBACK_END (&gEfiEventDxeDispatchGuid);
1512 return EFI_SUCCESS;
1513}
1514
1520VOID
1522 VOID
1523 )
1524{
1525 LIST_ENTRY *Link;
1527
1528 for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
1529 DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
1530 if (DriverEntry->Dependent) {
1531 DEBUG ((DEBUG_LOAD, "SMM Driver %g was discovered but not loaded!!\n", &DriverEntry->FileName));
1532 }
1533 }
1534}
UINT64 UINTN
#define FUNCTION_ENTRY_POINT(FunctionPointer)
VOID *EFIAPI InvalidateInstructionCacheRange(IN VOID *Address, IN UINTN Length)
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
UINT64 EFIAPI ReadUnaligned64(IN CONST VOID *Buffer)
Definition: Unaligned.c:191
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)
Definition: BaseLib.h:2884
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
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
Definition: LoadedImage.h:33
BOOLEAN FvHasBeenProcessed(IN EFI_HANDLE FvHandle)
Definition: Dispatcher.c:662
KNOWN_HANDLE * FvIsBeingProcessed(IN EFI_HANDLE FvHandle)
Definition: Dispatcher.c:692
BOOLEAN SmmIsSchedulable(IN EFI_SMM_DRIVER_ENTRY *DriverEntry)
Definition: Dependency.c:168
VOID SmmDisplayDiscoveredNotDispatched(VOID)
Definition: Dispatcher.c:1521
EFI_STATUS SmmPreProcessDepex(IN EFI_SMM_DRIVER_ENTRY *DriverEntry)
Definition: Dispatcher.c:743
EFI_STATUS GetPeCoffImageFixLoadingAssignedAddress(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: Dispatcher.c:216
VOID SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter(IN EFI_SMM_DRIVER_ENTRY *InsertedDriverEntry)
Definition: Dispatcher.c:1046
EFI_STATUS SmmDispatcher(VOID)
Definition: Dispatcher.c:846
EFI_STATUS SmmGetDepexSectionAndPreProccess(IN EFI_SMM_DRIVER_ENTRY *DriverEntry)
Definition: Dispatcher.c:778
EFI_DEVICE_PATH_PROTOCOL * SmmFvToDevicePath(IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, IN EFI_HANDLE FvHandle, IN EFI_GUID *DriverName)
Definition: Dispatcher.c:1167
EFI_STATUS CheckAndMarkFixLoadingMemoryUsageBitMap(IN EFI_PHYSICAL_ADDRESS ImageBase, IN UINTN ImageSize)
Definition: Dispatcher.c:140
EFI_STATUS EFIAPI SmmDriverDispatchHandler(IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context OPTIONAL, IN OUT VOID *CommBuffer OPTIONAL, IN OUT UINTN *CommBufferSize OPTIONAL)
Definition: Dispatcher.c:1279
EFI_STATUS SmmAddToDriverList(IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv, IN EFI_HANDLE FvHandle, IN EFI_GUID *DriverName)
Definition: Dispatcher.c:1223
EFI_STATUS EFIAPI SmmLoadImage(IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry)
Definition: Dispatcher.c:309
EFI_STATUS EFIAPI SmmUninstallProtocolInterface(IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN VOID *Interface)
Definition: Handle.c:366
EFI_STATUS EFIAPI SmmInstallProtocolInterface(IN OUT EFI_HANDLE *UserHandle, IN EFI_GUID *Protocol, IN EFI_INTERFACE_TYPE InterfaceType, IN VOID *Interface)
Definition: Handle.c:174
EFI_STATUS EFIAPI SmmFreePages(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages)
Definition: Page.c:938
EFI_STATUS EFIAPI SmmAllocatePages(IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN NumberOfPages, OUT EFI_PHYSICAL_ADDRESS *Memory)
Definition: Page.c:727
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define VOID
Definition: Base.h:269
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:463
#define DEBUG(Expression)
Definition: DebugLib.h:435
#define CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:660
#define REPORT_STATUS_CODE_WITH_EXTENDED_DATA(Type, Value, ExtendedData, ExtendedDataSize)
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
RETURN_STATUS EFIAPI PeCoffLoaderLoadImage(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: BasePeCoff.c:1248
RETURN_STATUS EFIAPI PeCoffLoaderRelocateImage(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: BasePeCoff.c:957
RETURN_STATUS EFIAPI PeCoffLoaderGetImageInfo(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: BasePeCoff.c:578
RETURN_STATUS EFIAPI PeCoffLoaderImageReadFromMemory(IN VOID *FileHandle, IN UINTN FileOffset, IN OUT UINTN *ReadSize, OUT VOID *Buffer)
Definition: BasePeCoff.c:2000
#define EFI_IMAGE_SCN_CNT_CODE
0x00000020
Definition: PeImage.h:319
#define PERF_LOAD_IMAGE_END(ModuleHandle)
#define PERF_CALLBACK_END(TriggerGuid)
#define PERF_START_IMAGE_END(ModuleHandle)
#define PERF_START_IMAGE_BEGIN(ModuleHandle)
#define PERF_CALLBACK_BEGIN(TriggerGuid)
#define PERF_LOAD_IMAGE_BEGIN(ModuleHandle)
#define EFI_DEP_BEFORE
Definition: PiDependency.h:19
#define EFI_DEP_AFTER
Definition: PiDependency.h:25
#define EFI_SECTION_PE32
UINT32 EFI_FV_FILE_ATTRIBUTES
EFI_STATUS UnregisterSmramProfileImage(IN EFI_SMM_DRIVER_ENTRY *DriverEntry, IN BOOLEAN UnregisterToDxe)
EFI_STATUS EFIAPI SmmFreePool(IN VOID *Buffer)
Definition: Pool.c:449
EFI_STATUS EFIAPI SmmAllocatePool(IN EFI_MEMORY_TYPE PoolType, IN UINTN Size, OUT VOID **Buffer)
Definition: Pool.c:342
EFI_STATUS RegisterSmramProfileImage(IN EFI_SMM_DRIVER_ENTRY *DriverEntry, IN BOOLEAN RegisterToDxe)
#define COMM_BUFFER_SMM_DISPATCH_ERROR
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:44
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS EFIAPI DriverEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: TdTcg2Dxe.c:2387
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
GUID EFI_GUID
Definition: UefiBaseType.h:25
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_SYSTEM_TABLE * gST
EFI_BOOT_SERVICES * gBS
VOID EFIAPI EfiInitializeFwVolDevicepathNode(IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode, IN CONST EFI_GUID *NameGuid)
Definition: UefiNotTiano.c:325
@ EfiBootServicesData
@ EfiRuntimeServicesCode
@ EfiRuntimeServicesData
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1203
EFI_STATUS(EFIAPI * EFI_IMAGE_ENTRY_POINT)(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: UefiSpec.h:2121
@ ByProtocol
Definition: UefiSpec.h:1528
@ AllocateMaxAddress
Definition: UefiSpec.h:38
EFI_DEVICE_PATH_PROTOCOL * FilePath
Definition: LoadedImage.h:54
EFI_HANDLE DeviceHandle
The device handle that the EFI Image was loaded from.
Definition: LoadedImage.h:53
Definition: Base.h:213
PE_COFF_LOADER_READ_FILE ImageRead
Definition: PeCoffLib.h:100
PHYSICAL_ADDRESS EntryPoint
Definition: PeCoffLib.h:95
PHYSICAL_ADDRESS ImageAddress
Definition: PeCoffLib.h:79