TianoCore EDK2 master
Loading...
Searching...
No Matches
StandaloneMmCore.c
Go to the documentation of this file.
1
10#include "StandaloneMmCore.h"
11
14 VOID
15 );
16
17//
18// Globals used to initialize the protocol
19//
20EFI_HANDLE mMmCpuHandle = NULL;
21
22//
23// MM Core global variable for MM System Table. Only accessed as a physical structure in MMRAM.
24//
25EFI_MM_SYSTEM_TABLE gMmCoreMmst = {
26 // The table header for the MMST.
27 {
29 EFI_MM_SYSTEM_TABLE_REVISION,
30 sizeof (gMmCoreMmst.Hdr)
31 },
32 // MmFirmwareVendor
33 NULL,
34 // MmFirmwareRevision
35 0,
36 // MmInstallConfigurationTable
38 // I/O Service
39 {
40 {
43 },
44 {
47 }
48 },
49 // Runtime memory services
54 // MP service
55 NULL, // MmStartupThisAp
56 0, // CurrentlyExecutingCpu
57 0, // NumberOfCpus
58 NULL, // CpuSaveStateSize
59 NULL, // CpuSaveState
60 0, // NumberOfTableEntries
61 NULL, // MmConfigurationTable
71};
72
73//
74// Table of MMI Handlers that are registered by the MM Core when it is initialized
75//
76MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = {
77 { MmDriverDispatchHandler, &gEventMmDispatchGuid, NULL, FALSE },
78 { MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE },
79 { MmEndOfPeiHandler, &gEfiMmEndOfPeiProtocol, NULL, FALSE },
80 { MmEndOfDxeHandler, &gEfiEndOfDxeEventGroupGuid, NULL, FALSE },
81 { MmExitBootServiceHandler, &gEfiEventExitBootServicesGuid, NULL, FALSE },
82 { MmReadyToBootHandler, &gEfiEventReadyToBootGuid, NULL, FALSE },
83 { NULL, NULL, NULL, FALSE },
84};
85
86BOOLEAN mMmEntryPointRegistered = FALSE;
87MM_COMM_BUFFER *mMmCommunicationBuffer;
88VOID *mInternalCommBufferCopy;
90
106EFIAPI
108 UINTN Arg1,
109 UINTN Arg2,
110 UINTN Arg3,
111 UINTN Arg4,
112 UINTN Arg5
113 )
114{
115 //
116 // This function should never be executed. If it does, then the architectural protocols
117 // have not been designed correctly.
118 //
120}
121
135EFIAPI
137 IN EFI_HANDLE DispatchHandle,
138 IN CONST VOID *Context OPTIONAL,
139 IN OUT VOID *CommBuffer OPTIONAL,
140 IN OUT UINTN *CommBufferSize OPTIONAL
141 )
142{
143 EFI_HANDLE MmHandle;
144 EFI_STATUS Status;
145 STATIC BOOLEAN mInExitBootServices = FALSE;
146
147 Status = EFI_SUCCESS;
148 if (!mInExitBootServices) {
149 MmHandle = NULL;
151 &MmHandle,
152 &gEfiEventExitBootServicesGuid,
154 NULL
155 );
156 }
157
158 mInExitBootServices = TRUE;
159 return Status;
160}
161
175EFIAPI
177 IN EFI_HANDLE DispatchHandle,
178 IN CONST VOID *Context OPTIONAL,
179 IN OUT VOID *CommBuffer OPTIONAL,
180 IN OUT UINTN *CommBufferSize OPTIONAL
181 )
182{
183 EFI_HANDLE MmHandle;
184 EFI_STATUS Status;
185 STATIC BOOLEAN mInReadyToBoot = FALSE;
186
187 Status = EFI_SUCCESS;
188 if (!mInReadyToBoot) {
189 MmHandle = NULL;
191 &MmHandle,
192 &gEfiEventReadyToBootGuid,
194 NULL
195 );
196 }
197
198 mInReadyToBoot = TRUE;
199 return Status;
200}
201
219EFIAPI
221 IN EFI_HANDLE DispatchHandle,
222 IN CONST VOID *Context OPTIONAL,
223 IN OUT VOID *CommBuffer OPTIONAL,
224 IN OUT UINTN *CommBufferSize OPTIONAL
225 )
226{
227 EFI_STATUS Status;
228 UINTN Index;
229 EFI_HANDLE MmHandle;
230
231 DEBUG ((DEBUG_INFO, "MmReadyToLockHandler\n"));
232
233 //
234 // Unregister MMI Handlers that are no longer required after the MM driver dispatch is stopped
235 //
236 for (Index = 0; mMmCoreMmiHandlers[Index].HandlerType != NULL; Index++) {
237 if (mMmCoreMmiHandlers[Index].UnRegister) {
238 MmiHandlerUnRegister (mMmCoreMmiHandlers[Index].DispatchHandle);
239 }
240 }
241
242 //
243 // Install MM Ready to lock protocol
244 //
245 MmHandle = NULL;
247 &MmHandle,
248 &gEfiMmReadyToLockProtocolGuid,
250 NULL
251 );
252
253 //
254 // Make sure MM CPU I/O 2 Protocol has been installed into the handle database
255 //
256 // Status = MmLocateProtocol (&EFI_MM_CPU_IO_PROTOCOL_GUID, NULL, &Interface);
257
258 //
259 // Print a message on a debug build if the MM CPU I/O 2 Protocol is not installed
260 //
261 // if (EFI_ERROR (Status)) {
262 // DEBUG ((DEBUG_ERROR, "\nSMM: SmmCpuIo Arch Protocol not present!!\n"));
263 // }
264
265 //
266 // Assert if the CPU I/O 2 Protocol is not installed
267 //
268 // ASSERT_EFI_ERROR (Status);
269
270 //
271 // Display any drivers that were not dispatched because dependency expression
272 // evaluated to false if this is a debug build
273 //
274 // MmDisplayDiscoveredNotDispatched ();
275
276 return Status;
277}
278
294EFIAPI
296 IN EFI_HANDLE DispatchHandle,
297 IN CONST VOID *Context OPTIONAL,
298 IN OUT VOID *CommBuffer OPTIONAL,
299 IN OUT UINTN *CommBufferSize OPTIONAL
300 )
301{
302 EFI_STATUS Status;
303 EFI_HANDLE MmHandle;
304
305 DEBUG ((DEBUG_INFO, "MmEndOfPeiHandler\n"));
306 //
307 // Install MM EndOfDxe protocol
308 //
309 MmHandle = NULL;
311 &MmHandle,
312 &gEfiMmEndOfPeiProtocol,
314 NULL
315 );
316 return Status;
317}
318
334EFIAPI
336 IN EFI_HANDLE DispatchHandle,
337 IN CONST VOID *Context OPTIONAL,
338 IN OUT VOID *CommBuffer OPTIONAL,
339 IN OUT UINTN *CommBufferSize OPTIONAL
340 )
341{
342 EFI_STATUS Status;
343 EFI_HANDLE MmHandle;
344
345 DEBUG ((DEBUG_INFO, "MmEndOfDxeHandler\n"));
346 //
347 // Install MM EndOfDxe protocol
348 //
349 MmHandle = NULL;
351 &MmHandle,
352 &gEfiMmEndOfDxeProtocolGuid,
354 NULL
355 );
356 return Status;
357}
358
363VOID
365 VOID
366 )
367{
368 EFI_STATUS Status;
369 EFI_PHYSICAL_ADDRESS MmCoreImageBaseAddress;
370 UINT64 MmCoreImageLength;
372 EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
373 EFI_HANDLE ImageHandle;
374
375 //
376 // Searching for Memory Allocation HOB
377 //
378 Hob.Raw = GetHobList ();
379 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
380 //
381 // Find MM Core HOB
382 //
383 if (CompareGuid (
384 &Hob.MemoryAllocationModule->MemoryAllocationHeader.Name,
385 &gEfiHobMemoryAllocModuleGuid
386 ))
387 {
388 if (CompareGuid (&Hob.MemoryAllocationModule->ModuleName, &gEfiCallerIdGuid)) {
389 break;
390 }
391 }
392
393 Hob.Raw = GET_NEXT_HOB (Hob);
394 }
395
396 if (Hob.Raw == NULL) {
397 return;
398 }
399
400 MmCoreImageBaseAddress = Hob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress;
401 MmCoreImageLength = Hob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength;
402
403 //
404 // Allocate a Loaded Image Protocol in MM
405 //
406 LoadedImage = AllocatePool (sizeof (EFI_LOADED_IMAGE_PROTOCOL));
407 ASSERT (LoadedImage != NULL);
408 if (LoadedImage == NULL) {
409 return;
410 }
411
412 ZeroMem (LoadedImage, sizeof (EFI_LOADED_IMAGE_PROTOCOL));
413
414 //
415 // Fill in the remaining fields of the Loaded Image Protocol instance.
416 //
418 LoadedImage->ParentHandle = NULL;
419 LoadedImage->SystemTable = NULL;
420
421 LoadedImage->ImageBase = (VOID *)(UINTN)MmCoreImageBaseAddress;
422 LoadedImage->ImageSize = MmCoreImageLength;
425
426 //
427 // Create a new image handle in the MM handle database for the MM Core
428 //
429 ImageHandle = NULL;
431 &ImageHandle,
432 &gEfiLoadedImageProtocolGuid,
434 LoadedImage
435 );
436 ASSERT_EFI_ERROR (Status);
437}
438
442VOID
444 VOID
445 )
446{
447 EFI_STATUS Status;
448 EFI_HOB_GUID_TYPE *GuidHob;
450
451 mMmCommunicationBuffer = NULL;
452 mInternalCommBufferCopy = NULL;
453
454 GuidHob = GetFirstGuidHob (&gMmCommBufferHobGuid);
455 ASSERT (GuidHob != NULL);
456 if (GuidHob == NULL) {
457 return;
458 }
459
460 mMmCommunicationBuffer = (MM_COMM_BUFFER *)GET_GUID_HOB_DATA (GuidHob);
461 DEBUG ((
462 DEBUG_INFO,
463 "MM Communication Buffer is at %x, number of pages is %x\n",
464 mMmCommunicationBuffer->PhysicalStart,
465 mMmCommunicationBuffer->NumberOfPages
466 ));
467 ASSERT (mMmCommunicationBuffer->PhysicalStart != 0 && mMmCommunicationBuffer->NumberOfPages != 0);
468
470 mMmCommunicationBuffer->PhysicalStart,
471 EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)
472 ))
473 {
474 mMmCommunicationBuffer = NULL;
475 DEBUG ((DEBUG_ERROR, "MM Communication Buffer is invalid!\n"));
476 ASSERT (FALSE);
477 return;
478 }
479
480 Status = MmAllocatePages (
483 mMmCommunicationBuffer->NumberOfPages,
484 &Buffer
485 );
486 ASSERT_EFI_ERROR (Status);
487 if (EFI_ERROR (Status)) {
488 return;
489 }
490
491 mInternalCommBufferCopy = (VOID *)(UINTN)Buffer;
492 DEBUG ((DEBUG_INFO, "Internal Communication Buffer Copy is at %p\n", mInternalCommBufferCopy));
493}
494
504VOID
505EFIAPI
507 IN CONST EFI_MM_ENTRY_CONTEXT *MmEntryContext
508 )
509{
510 EFI_STATUS Status;
511 EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
512 MM_COMM_BUFFER_STATUS *CommunicationStatus;
513 UINTN BufferSize;
514
515 DEBUG ((DEBUG_INFO, "MmEntryPoint ...\n"));
516
517 //
518 // Update MMST using the context
519 //
520 CopyMem (&gMmCoreMmst.MmStartupThisAp, MmEntryContext, sizeof (EFI_MM_ENTRY_CONTEXT));
521
522 //
523 // Call platform hook before Mm Dispatch
524 //
525 // PlatformHookBeforeMmDispatch ();
526
527 //
528 // Check to see if this is a Synchronous MMI sent through the MM Communication
529 // Protocol or an Asynchronous MMI
530 //
531 if ((mMmCommunicationBuffer != NULL) && (mInternalCommBufferCopy != NULL)) {
532 CommunicationStatus = (MM_COMM_BUFFER_STATUS *)(UINTN)mMmCommunicationBuffer->Status;
533 if (CommunicationStatus->IsCommBufferValid) {
534 //
535 // Synchronous MMI for MM Core or request from Communicate protocol
536 //
537 CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)mMmCommunicationBuffer->PhysicalStart;
538 BufferSize = OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data) + CommunicateHeader->MessageLength;
539 if (BufferSize <= EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)) {
540 //
541 // Shadow the data from MM Communication Buffer to internal buffer
542 //
543 CopyMem (
544 mInternalCommBufferCopy,
545 (VOID *)(UINTN)mMmCommunicationBuffer->PhysicalStart,
546 BufferSize
547 );
548 ZeroMem (
549 (UINT8 *)mInternalCommBufferCopy + BufferSize,
550 EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages) - BufferSize
551 );
552
553 CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mInternalCommBufferCopy;
554 BufferSize = CommunicateHeader->MessageLength;
555 Status = MmiManage (
556 &CommunicateHeader->HeaderGuid,
557 NULL,
558 CommunicateHeader->Data,
559 &BufferSize
560 );
561
562 BufferSize = BufferSize + OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
563 if (BufferSize <= EFI_PAGES_TO_SIZE (mMmCommunicationBuffer->NumberOfPages)) {
564 //
565 // Copy the data back to MM Communication Buffer
566 //
567 CopyMem (
568 (VOID *)(UINTN)mMmCommunicationBuffer->PhysicalStart,
569 mInternalCommBufferCopy,
570 BufferSize
571 );
572 } else {
573 DEBUG ((DEBUG_ERROR, "Returned buffer size is larger than the size of MM Communication Buffer\n"));
574 ASSERT (FALSE);
575 }
576
577 //
578 // Update ReturnBufferSize and ReturnStatus
579 // Communicate service finished, reset IsCommBufferValid to FALSE
580 //
581 CommunicationStatus->IsCommBufferValid = FALSE;
582 CommunicationStatus->ReturnBufferSize = BufferSize;
583 CommunicationStatus->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;
584 } else {
585 DEBUG ((DEBUG_ERROR, "Input buffer size is larger than the size of MM Communication Buffer\n"));
586 ASSERT (FALSE);
587 }
588 }
589 } else {
590 DEBUG ((DEBUG_ERROR, "No valid communication buffer, no Synchronous MMI will be processed\n"));
591 }
592
593 //
594 // Process Asynchronous MMI sources
595 //
597
598 //
599 // TBD: Do not use private data structure ?
600 //
601
602 DEBUG ((DEBUG_INFO, "MmEntryPoint Done\n"));
603}
604
615EFIAPI
617 IN CONST EFI_GUID *Protocol,
618 IN VOID *Interface,
619 IN EFI_HANDLE Handle
620 )
621{
622 EFI_STATUS Status;
623 EFI_MM_CONFIGURATION_PROTOCOL *MmConfiguration;
624
625 DEBUG ((DEBUG_INFO, "MmConfigurationMmNotify(%g) - %x\n", Protocol, Interface));
626
627 MmConfiguration = Interface;
628
629 //
630 // Register the MM Entry Point provided by the MM Core with the MM COnfiguration protocol
631 //
632 Status = MmConfiguration->RegisterMmEntry (MmConfiguration, (EFI_MM_ENTRY_POINT)MmEntryPoint);
633 ASSERT_EFI_ERROR (Status);
634
635 //
636 // Set flag to indicate that the MM Entry Point has been registered which
637 // means that MMIs are now fully operational.
638 //
639 mMmEntryPointRegistered = TRUE;
640
641 //
642 // Print debug message showing MM Core entry point address.
643 //
644 DEBUG ((DEBUG_INFO, "MM Core registered MM Entry Point address %p\n", MmEntryPoint));
645 return EFI_SUCCESS;
646}
647
655VOID
657 IN VOID *HobStart
658 )
659{
661 EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob;
662 VOID *MemoryInMmram;
663
664 MemoryAllocationHob = NULL;
665 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, HobStart);
666 while (Hob.Raw != NULL) {
667 MemoryAllocationHob = (EFI_HOB_MEMORY_ALLOCATION *)Hob.Raw;
668 if (MemoryAllocationHob->AllocDescriptor.MemoryType == EfiBootServicesData) {
669 if (!IsZeroGuid (&MemoryAllocationHob->AllocDescriptor.Name)) {
670 MemoryInMmram = AllocatePages (EFI_SIZE_TO_PAGES (MemoryAllocationHob->AllocDescriptor.MemoryLength));
671 if (MemoryInMmram != NULL) {
672 DEBUG ((
673 DEBUG_INFO,
674 "Migrate Memory Allocation Hob (%g) from %08x to %08p\n",
675 &MemoryAllocationHob->AllocDescriptor.Name,
676 MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress,
677 MemoryInMmram
678 ));
679 CopyMem (
680 MemoryInMmram,
681 (VOID *)(UINTN)MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress,
682 MemoryAllocationHob->AllocDescriptor.MemoryLength
683 );
684 MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryInMmram;
686 }
687 } else {
688 DEBUG ((
689 DEBUG_ERROR,
690 "Error - Memory Allocation Hob [%08x, %08x] doesn't have a GUID name specified\n",
691 MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress,
692 MemoryAllocationHob->AllocDescriptor.MemoryLength
693 ));
694 }
695 }
696
697 Hob.Raw = GET_NEXT_HOB (Hob);
698 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);
699 }
700}
701
712VOID *
714 IN VOID *HobStart,
715 IN EFI_MMRAM_DESCRIPTOR *MmramRanges,
716 IN UINTN MmramRangeCount
717 )
718{
719 VOID *MmHobStart;
720 UINTN HobSize;
721 EFI_STATUS Status;
723 UINTN Index;
724 EFI_PHYSICAL_ADDRESS MmramBase;
725 EFI_PHYSICAL_ADDRESS MmramEnd;
726 EFI_PHYSICAL_ADDRESS ResourceHobBase;
727 EFI_PHYSICAL_ADDRESS ResourceHobEnd;
728
729 ASSERT (HobStart != NULL);
730
731 Hob.Raw = (UINT8 *)HobStart;
732 while (!END_OF_HOB_LIST (Hob)) {
733 Hob.Raw = GET_NEXT_HOB (Hob);
734 if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
735 ResourceHobBase = Hob.ResourceDescriptor->PhysicalStart;
736 ResourceHobEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength;
737
738 for (Index = 0; Index < MmramRangeCount; Index++) {
739 MmramBase = MmramRanges[Index].PhysicalStart;
740 MmramEnd = MmramRanges[Index].PhysicalStart + MmramRanges[Index].PhysicalSize;
741
742 if ((MmramBase < ResourceHobEnd) && (MmramEnd > ResourceHobBase)) {
743 //
744 // The Resource HOB is to describe the accessible non-Mmram range.
745 // All Resource HOB should not overlapp with any Mmram range.
746 //
747 DEBUG ((
748 DEBUG_ERROR,
749 "The resource HOB range [0x%lx, 0x%lx] overlaps with MMRAM range\n",
750 ResourceHobBase,
751 ResourceHobEnd
752 ));
753 CpuDeadLoop ();
754 }
755 }
756 }
757 }
758
759 //
760 // Need plus END_OF_HOB_LIST
761 //
762 HobSize = (UINTN)Hob.Raw - (UINTN)HobStart + sizeof (EFI_HOB_GENERIC_HEADER);
763 DEBUG ((DEBUG_INFO, "HobSize - 0x%x\n", HobSize));
764
765 MmHobStart = AllocatePool (HobSize);
766 DEBUG ((DEBUG_INFO, "MmHobStart - 0x%x\n", MmHobStart));
767 ASSERT (MmHobStart != NULL);
768 CopyMem (MmHobStart, HobStart, HobSize);
769
770 DEBUG ((DEBUG_INFO, "MmInstallConfigurationTable For HobList\n"));
771 Status = MmInstallConfigurationTable (&gMmCoreMmst, &gEfiHobListGuid, MmHobStart, HobSize);
772 ASSERT_EFI_ERROR (Status);
773
774 MigrateMemoryAllocationHobs (MmHobStart);
775
776 return MmHobStart;
777}
778
793EFIAPI
795 IN VOID *HobStart
796 )
797{
798 EFI_STATUS Status;
799 UINTN Index;
800 VOID *Registration;
801 EFI_HOB_GUID_TYPE *MmramRangesHob;
802 EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData;
803 EFI_MMRAM_DESCRIPTOR *MmramRanges;
804 UINTN MmramRangeCount;
806
807 ProcessLibraryConstructorList (HobStart, &gMmCoreMmst);
808
809 DEBUG ((DEBUG_INFO, "MmMain - 0x%x\n", HobStart));
810
811 DEBUG_CODE (
812 PrintHobList (HobStart, NULL);
813 );
814
815 //
816 // Extract the MMRAM ranges from the MMRAM descriptor HOB
817 //
818 MmramRangesHob = GetNextGuidHob (&gEfiSmmSmramMemoryGuid, HobStart);
819 if (MmramRangesHob == NULL) {
820 MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart);
821 if (MmramRangesHob == NULL) {
822 return EFI_UNSUPPORTED;
823 }
824 }
825
826 MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);
827 ASSERT (MmramRangesHobData != NULL);
828 MmramRanges = MmramRangesHobData->Descriptor;
829 MmramRangeCount = (UINTN)MmramRangesHobData->NumberOfMmReservedRegions;
830 ASSERT (MmramRanges);
831 ASSERT (MmramRangeCount);
832
833 //
834 // Print the MMRAM ranges passed by the caller
835 //
836 DEBUG ((DEBUG_INFO, "MmramRangeCount - 0x%x\n", MmramRangeCount));
837 for (Index = 0; Index < MmramRangeCount; Index++) {
838 DEBUG ((
839 DEBUG_INFO,
840 "MmramRanges[%d]: 0x%016lx - 0x%lx\n",
841 Index,
842 MmramRanges[Index].CpuStart,
843 MmramRanges[Index].PhysicalSize
844 ));
845 }
846
847 //
848 // No need to initialize memory service.
849 // It is done in the constructor of StandaloneMmCoreMemoryAllocationLib(),
850 // so that the library linked with StandaloneMmCore can use AllocatePool() in
851 // the constructor.
852 //
853 //
854 // Install HobList
855 //
856 gHobList = InitializeMmHobList (HobStart, MmramRanges, MmramRangeCount);
857
858 //
859 // Register notification for EFI_MM_CONFIGURATION_PROTOCOL registration and
860 // use it to register the MM Foundation entrypoint
861 //
862 DEBUG ((DEBUG_INFO, "MmRegisterProtocolNotify - MmConfigurationMmProtocol\n"));
863 Status = MmRegisterProtocolNotify (
864 &gEfiMmConfigurationProtocolGuid,
866 &Registration
867 );
868 ASSERT_EFI_ERROR (Status);
869
870 //
871 // Get Boot Firmware Volume address from the BFV Hob
872 //
873 BfvHob = GetFirstHob (EFI_HOB_TYPE_FV);
874 if (BfvHob != NULL) {
875 DEBUG ((DEBUG_INFO, "BFV address - 0x%x\n", BfvHob->BaseAddress));
876 DEBUG ((DEBUG_INFO, "BFV size - 0x%x\n", BfvHob->Length));
877 //
878 // Dispatch standalone BFV
879 //
880 if (BfvHob->BaseAddress != 0) {
881 //
882 // Shadow standalone BFV into MMRAM
883 //
884 mBfv = AllocatePool (BfvHob->Length);
885 if (mBfv != NULL) {
886 CopyMem ((VOID *)mBfv, (VOID *)(UINTN)BfvHob->BaseAddress, BfvHob->Length);
887 DEBUG ((DEBUG_INFO, "Mm Dispatch StandaloneBfvAddress - 0x%08x\n", mBfv));
888 MmCoreFfsFindMmDriver (mBfv, 0);
889 MmDispatcher ();
890 if (!FeaturePcdGet (PcdRestartMmDispatcherOnceMmEntryRegistered)) {
891 FreePool (mBfv);
892 }
893 }
894 }
895 }
896
897 //
898 // Register all handlers in the core table
899 //
900 for (Index = 0; mMmCoreMmiHandlers[Index].HandlerType != NULL; Index++) {
901 Status = MmiHandlerRegister (
902 mMmCoreMmiHandlers[Index].Handler,
903 mMmCoreMmiHandlers[Index].HandlerType,
904 &mMmCoreMmiHandlers[Index].DispatchHandle
905 );
906 DEBUG ((DEBUG_INFO, "MmiHandlerRegister - GUID %g - Status %d\n", mMmCoreMmiHandlers[Index].HandlerType, Status));
907 }
908
910
911 //
912 // Install Loaded Image Protocol form MM Core
913 //
915
916 DEBUG ((DEBUG_INFO, "MmMain Done!\n"));
917
918 return EFI_SUCCESS;
919}
UINT64 UINTN
VOID *EFIAPI GetFirstHob(IN UINT16 Type)
Definition: HobLib.c:142
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
Definition: HobLib.c:103
VOID *EFIAPI GetNextGuidHob(IN CONST EFI_GUID *Guid, IN CONST VOID *HobStart)
Definition: HobLib.c:176
VOID *EFIAPI GetHobList(VOID)
Definition: HobLib.c:76
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
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
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
BOOLEAN EFIAPI IsZeroGuid(IN CONST GUID *Guid)
Definition: MemLibGuid.c:156
VOID * gHobList
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID EFIAPI PrintHobList(IN CONST VOID *HobStart, IN HOB_PRINT_HANDLER PrintHandler OPTIONAL)
Definition: HobPrintLib.c:410
#define EFI_LOADED_IMAGE_PROTOCOL_REVISION
Definition: LoadedImage.h:33
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE(Expression)
Definition: DebugLib.h:590
EFI_STATUS(EFIAPI * EFI_MM_CPU_IO)(IN CONST EFI_MM_CPU_IO_PROTOCOL *This, IN EFI_MM_IO_WIDTH Width, IN UINT64 Address, IN UINTN Count, IN OUT VOID *Buffer)
Definition: MmCpuIo.h:55
EFI_STATUS EFIAPI MmiHandlerRegister(IN EFI_MM_HANDLER_ENTRY_POINT Handler, IN CONST EFI_GUID *HandlerType OPTIONAL, OUT EFI_HANDLE *DispatchHandle)
Definition: Mmi.c:356
EFI_STATUS EFIAPI MmiManage(IN CONST EFI_GUID *HandlerType, IN CONST VOID *Context OPTIONAL, IN OUT VOID *CommBuffer OPTIONAL, IN OUT UINTN *CommBufferSize OPTIONAL)
Definition: Mmi.c:160
EFI_STATUS EFIAPI MmiHandlerUnRegister(IN EFI_HANDLE DispatchHandle)
Definition: Mmi.c:416
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
VOID(EFIAPI * EFI_MM_ENTRY_POINT)(IN CONST EFI_MM_ENTRY_CONTEXT *MmEntryContext)
Definition: PiMmCis.h:238
#define MM_MMST_SIGNATURE
Definition: PiMmCis.h:21
#define EFI_NOT_AVAILABLE_YET
Definition: PiMultiPhase.h:54
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
EFI_STATUS EFIAPI MmReadyToBootHandler(IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context OPTIONAL, IN OUT VOID *CommBuffer OPTIONAL, IN OUT UINTN *CommBufferSize OPTIONAL)
EFI_STATUS MmDispatcher(VOID)
Definition: Dispatcher.c:379
EFI_STATUS EFIAPI MmEndOfPeiHandler(IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context OPTIONAL, IN OUT VOID *CommBuffer OPTIONAL, IN OUT UINTN *CommBufferSize OPTIONAL)
EFI_STATUS EFIAPI MmConfigurationMmNotify(IN CONST EFI_GUID *Protocol, IN VOID *Interface, IN EFI_HANDLE Handle)
VOID MmCoreInstallLoadedImage(VOID)
EFI_STATUS EFIAPI MmReadyToLockHandler(IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context OPTIONAL, IN OUT VOID *CommBuffer OPTIONAL, IN OUT UINTN *CommBufferSize OPTIONAL)
EFI_STATUS EFIAPI MmEfiNotAvailableYetArg5(UINTN Arg1, UINTN Arg2, UINTN Arg3, UINTN Arg4, UINTN Arg5)
VOID MmCorePrepareCommunicationBuffer(VOID)
VOID * InitializeMmHobList(IN VOID *HobStart, IN EFI_MMRAM_DESCRIPTOR *MmramRanges, IN UINTN MmramRangeCount)
EFI_STATUS EFIAPI StandaloneMmMain(IN VOID *HobStart)
VOID MigrateMemoryAllocationHobs(IN VOID *HobStart)
VOID EFIAPI MmEntryPoint(IN CONST EFI_MM_ENTRY_CONTEXT *MmEntryContext)
EFI_STATUS EFIAPI MmExitBootServiceHandler(IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context OPTIONAL, IN OUT VOID *CommBuffer OPTIONAL, IN OUT UINTN *CommBufferSize OPTIONAL)
EFI_STATUS EFIAPI MmEndOfDxeHandler(IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context OPTIONAL, IN OUT VOID *CommBuffer OPTIONAL, IN OUT UINTN *CommBufferSize OPTIONAL)
BOOLEAN EFIAPI MmIsBufferOutsideMmValid(IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length)
EFI_STATUS EFIAPI MmDriverDispatchHandler(IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context OPTIONAL, IN OUT VOID *CommBuffer OPTIONAL, IN OUT UINTN *CommBufferSize OPTIONAL)
Definition: Dispatcher.c:736
EFI_STATUS MmCoreFfsFindMmDriver(IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader, IN UINT32 Depth)
Definition: FwVol.c:55
EFI_STATUS EFIAPI MmHandleProtocol(IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, OUT VOID **Interface)
Definition: Handle.c:489
EFI_STATUS EFIAPI MmInstallProtocolInterface(IN OUT EFI_HANDLE *UserHandle, IN EFI_GUID *Protocol, IN EFI_INTERFACE_TYPE InterfaceType, IN VOID *Interface)
Definition: Handle.c:175
EFI_STATUS EFIAPI MmUninstallProtocolInterface(IN EFI_HANDLE UserHandle, IN EFI_GUID *Protocol, IN VOID *Interface)
Definition: Handle.c:364
EFI_STATUS EFIAPI MmInstallConfigurationTable(IN CONST EFI_MM_SYSTEM_TABLE *SystemTable, IN CONST EFI_GUID *Guid, IN VOID *Table, IN UINTN TableSize)
EFI_STATUS EFIAPI MmLocateProtocol(IN EFI_GUID *Protocol, IN VOID *Registration OPTIONAL, OUT VOID **Interface)
Definition: Locate.c:195
EFI_STATUS EFIAPI MmLocateHandle(IN EFI_LOCATE_SEARCH_TYPE SearchType, IN EFI_GUID *Protocol OPTIONAL, IN VOID *SearchKey OPTIONAL, IN OUT UINTN *BufferSize, OUT EFI_HANDLE *Buffer)
Definition: Locate.c:272
EFI_STATUS EFIAPI MmRegisterProtocolNotify(IN CONST EFI_GUID *Protocol, IN EFI_MM_NOTIFY_FN Function, OUT VOID **Registration)
Definition: Notify.c:97
EFI_STATUS EFIAPI MmAllocatePages(IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN NumberOfPages, OUT EFI_PHYSICAL_ADDRESS *Memory)
Definition: Page.c:702
EFI_STATUS EFIAPI MmFreePages(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages)
Definition: Page.c:853
EFI_STATUS EFIAPI MmAllocatePool(IN EFI_MEMORY_TYPE PoolType, IN UINTN Size, OUT VOID **Buffer)
Definition: Pool.c:253
EFI_STATUS EFIAPI MmFreePool(IN VOID *Buffer)
Definition: Pool.c:312
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
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
@ EfiBootServicesData
@ EfiRuntimeServicesCode
@ EfiRuntimeServicesData
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
@ AllocateAnyPages
Definition: UefiSpec.h:33
EFI_TABLE_HEADER Hdr
Definition: PiMmCis.h:253
EFI_MM_STARTUP_THIS_AP MmStartupThisAp
Definition: PiMmCis.h:282
EFI_PHYSICAL_ADDRESS BaseAddress
Definition: PiHob.h:364
EFI_PHYSICAL_ADDRESS MemoryBaseAddress
Definition: PiHob.h:119
EFI_MEMORY_TYPE MemoryType
Definition: PiHob.h:131
EFI_HOB_MEMORY_ALLOCATION_HEADER MemoryAllocationHeader
Definition: PiHob.h:207
EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor
Definition: PiHob.h:153
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: PiHob.h:328
EFI_MEMORY_TYPE ImageDataType
The memory type that the data sections were loaded as.
Definition: LoadedImage.h:70
EFI_MEMORY_TYPE ImageCodeType
The memory type that the code sections were loaded as.
Definition: LoadedImage.h:69
UINT64 ImageSize
The size in bytes of the loaded image.
Definition: LoadedImage.h:68
EFI_SYSTEM_TABLE * SystemTable
the image's EFI system table pointer.
Definition: LoadedImage.h:48
VOID * ImageBase
The base address at which the image was loaded.
Definition: LoadedImage.h:67
EFI_MMRAM_DESCRIPTOR Descriptor[1]
Definition: Base.h:213