123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665 |
- /** @file
- MM Core Main Entry Point
- Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
- Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "StandaloneMmCore.h"
- EFI_STATUS
- MmCoreFfsFindMmDriver (
- IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
- );
- EFI_STATUS
- MmDispatcher (
- VOID
- );
- //
- // Globals used to initialize the protocol
- //
- EFI_HANDLE mMmCpuHandle = NULL;
- //
- // Physical pointer to private structure shared between MM IPL and the MM Core
- //
- MM_CORE_PRIVATE_DATA *gMmCorePrivate;
- //
- // MM Core global variable for MM System Table. Only accessed as a physical structure in MMRAM.
- //
- EFI_MM_SYSTEM_TABLE gMmCoreMmst = {
- // The table header for the MMST.
- {
- MM_MMST_SIGNATURE,
- EFI_MM_SYSTEM_TABLE_REVISION,
- sizeof (gMmCoreMmst.Hdr)
- },
- // MmFirmwareVendor
- NULL,
- // MmFirmwareRevision
- 0,
- // MmInstallConfigurationTable
- MmInstallConfigurationTable,
- // I/O Service
- {
- {
- (EFI_MM_CPU_IO)MmEfiNotAvailableYetArg5, // MmMemRead
- (EFI_MM_CPU_IO)MmEfiNotAvailableYetArg5 // MmMemWrite
- },
- {
- (EFI_MM_CPU_IO)MmEfiNotAvailableYetArg5, // MmIoRead
- (EFI_MM_CPU_IO)MmEfiNotAvailableYetArg5 // MmIoWrite
- }
- },
- // Runtime memory services
- MmAllocatePool,
- MmFreePool,
- MmAllocatePages,
- MmFreePages,
- // MP service
- NULL, // MmStartupThisAp
- 0, // CurrentlyExecutingCpu
- 0, // NumberOfCpus
- NULL, // CpuSaveStateSize
- NULL, // CpuSaveState
- 0, // NumberOfTableEntries
- NULL, // MmConfigurationTable
- MmInstallProtocolInterface,
- MmUninstallProtocolInterface,
- MmHandleProtocol,
- MmRegisterProtocolNotify,
- MmLocateHandle,
- MmLocateProtocol,
- MmiManage,
- MmiHandlerRegister,
- MmiHandlerUnRegister
- };
- //
- // Table of MMI Handlers that are registered by the MM Core when it is initialized
- //
- MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = {
- { MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE },
- { MmEndOfDxeHandler, &gEfiEndOfDxeEventGroupGuid, NULL, FALSE },
- { MmExitBootServiceHandler, &gEfiEventExitBootServicesGuid, NULL, FALSE },
- { MmReadyToBootHandler, &gEfiEventReadyToBootGuid, NULL, FALSE },
- { NULL, NULL, NULL, FALSE },
- };
- EFI_SYSTEM_TABLE *mEfiSystemTable;
- UINTN mMmramRangeCount;
- EFI_MMRAM_DESCRIPTOR *mMmramRanges;
- /**
- Place holder function until all the MM System Table Service are available.
- Note: This function is only used by MMRAM invocation. It is never used by DXE invocation.
- @param Arg1 Undefined
- @param Arg2 Undefined
- @param Arg3 Undefined
- @param Arg4 Undefined
- @param Arg5 Undefined
- @return EFI_NOT_AVAILABLE_YET
- **/
- EFI_STATUS
- EFIAPI
- MmEfiNotAvailableYetArg5 (
- UINTN Arg1,
- UINTN Arg2,
- UINTN Arg3,
- UINTN Arg4,
- UINTN Arg5
- )
- {
- //
- // This function should never be executed. If it does, then the architectural protocols
- // have not been designed correctly.
- //
- return EFI_NOT_AVAILABLE_YET;
- }
- /**
- Software MMI handler that is called when a ExitBoot Service event is signaled.
- @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister().
- @param Context Points to an optional handler context which was specified when the handler was registered.
- @param CommBuffer A pointer to a collection of data in memory that will
- be conveyed from a non-MM environment into an MM environment.
- @param CommBufferSize The size of the CommBuffer.
- @return Status Code
- **/
- EFI_STATUS
- EFIAPI
- MmExitBootServiceHandler (
- IN EFI_HANDLE DispatchHandle,
- IN CONST VOID *Context OPTIONAL,
- IN OUT VOID *CommBuffer OPTIONAL,
- IN OUT UINTN *CommBufferSize OPTIONAL
- )
- {
- EFI_HANDLE MmHandle;
- EFI_STATUS Status;
- STATIC BOOLEAN mInExitBootServices = FALSE;
- Status = EFI_SUCCESS;
- if (!mInExitBootServices) {
- MmHandle = NULL;
- Status = MmInstallProtocolInterface (
- &MmHandle,
- &gEfiEventExitBootServicesGuid,
- EFI_NATIVE_INTERFACE,
- NULL
- );
- }
- mInExitBootServices = TRUE;
- return Status;
- }
- /**
- Software MMI handler that is called when a ExitBoot Service event is signaled.
- @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister().
- @param Context Points to an optional handler context which was specified when the handler was registered.
- @param CommBuffer A pointer to a collection of data in memory that will
- be conveyed from a non-MM environment into an MM environment.
- @param CommBufferSize The size of the CommBuffer.
- @return Status Code
- **/
- EFI_STATUS
- EFIAPI
- MmReadyToBootHandler (
- IN EFI_HANDLE DispatchHandle,
- IN CONST VOID *Context OPTIONAL,
- IN OUT VOID *CommBuffer OPTIONAL,
- IN OUT UINTN *CommBufferSize OPTIONAL
- )
- {
- EFI_HANDLE MmHandle;
- EFI_STATUS Status;
- STATIC BOOLEAN mInReadyToBoot = FALSE;
- Status = EFI_SUCCESS;
- if (!mInReadyToBoot) {
- MmHandle = NULL;
- Status = MmInstallProtocolInterface (
- &MmHandle,
- &gEfiEventReadyToBootGuid,
- EFI_NATIVE_INTERFACE,
- NULL
- );
- }
- mInReadyToBoot = TRUE;
- return Status;
- }
- /**
- Software MMI handler that is called when the DxeMmReadyToLock protocol is added
- or if gEfiEventReadyToBootGuid is signaled. This function unregisters the
- Software SMIs that are nor required after MMRAM is locked and installs the
- MM Ready To Lock Protocol so MM Drivers are informed that MMRAM is about
- to be locked.
- @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister().
- @param Context Points to an optional handler context which was specified when the handler was registered.
- @param CommBuffer A pointer to a collection of data in memory that will
- be conveyed from a non-MM environment into an MM environment.
- @param CommBufferSize The size of the CommBuffer.
- @return Status Code
- **/
- 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 Status;
- UINTN Index;
- EFI_HANDLE MmHandle;
- DEBUG ((DEBUG_INFO, "MmReadyToLockHandler\n"));
- //
- // Unregister MMI Handlers that are no longer required after the MM driver dispatch is stopped
- //
- for (Index = 0; mMmCoreMmiHandlers[Index].HandlerType != NULL; Index++) {
- if (mMmCoreMmiHandlers[Index].UnRegister) {
- MmiHandlerUnRegister (mMmCoreMmiHandlers[Index].DispatchHandle);
- }
- }
- //
- // Install MM Ready to lock protocol
- //
- MmHandle = NULL;
- Status = MmInstallProtocolInterface (
- &MmHandle,
- &gEfiMmReadyToLockProtocolGuid,
- EFI_NATIVE_INTERFACE,
- NULL
- );
- //
- // Make sure MM CPU I/O 2 Protocol has been installed into the handle database
- //
- // Status = MmLocateProtocol (&EFI_MM_CPU_IO_PROTOCOL_GUID, NULL, &Interface);
- //
- // Print a message on a debug build if the MM CPU I/O 2 Protocol is not installed
- //
- // if (EFI_ERROR (Status)) {
- // DEBUG ((DEBUG_ERROR, "\nSMM: SmmCpuIo Arch Protocol not present!!\n"));
- // }
- //
- // Assert if the CPU I/O 2 Protocol is not installed
- //
- // ASSERT_EFI_ERROR (Status);
- //
- // Display any drivers that were not dispatched because dependency expression
- // evaluated to false if this is a debug build
- //
- // MmDisplayDiscoveredNotDispatched ();
- return Status;
- }
- /**
- Software MMI handler that is called when the EndOfDxe event is signaled.
- This function installs the MM EndOfDxe Protocol so MM Drivers are informed that
- platform code will invoke 3rd part code.
- @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister().
- @param Context Points to an optional handler context which was specified when the handler was registered.
- @param CommBuffer A pointer to a collection of data in memory that will
- be conveyed from a non-MM environment into an MM environment.
- @param CommBufferSize The size of the CommBuffer.
- @return Status Code
- **/
- EFI_STATUS
- EFIAPI
- MmEndOfDxeHandler (
- IN EFI_HANDLE DispatchHandle,
- IN CONST VOID *Context OPTIONAL,
- IN OUT VOID *CommBuffer OPTIONAL,
- IN OUT UINTN *CommBufferSize OPTIONAL
- )
- {
- EFI_STATUS Status;
- EFI_HANDLE MmHandle;
- DEBUG ((DEBUG_INFO, "MmEndOfDxeHandler\n"));
- //
- // Install MM EndOfDxe protocol
- //
- MmHandle = NULL;
- Status = MmInstallProtocolInterface (
- &MmHandle,
- &gEfiMmEndOfDxeProtocolGuid,
- EFI_NATIVE_INTERFACE,
- NULL
- );
- return Status;
- }
- /**
- The main entry point to MM Foundation.
- Note: This function is only used by MMRAM invocation. It is never used by DXE invocation.
- @param MmEntryContext Processor information and functionality
- needed by MM Foundation.
- **/
- VOID
- EFIAPI
- MmEntryPoint (
- IN CONST EFI_MM_ENTRY_CONTEXT *MmEntryContext
- )
- {
- EFI_STATUS Status;
- EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
- DEBUG ((DEBUG_INFO, "MmEntryPoint ...\n"));
- //
- // Update MMST using the context
- //
- CopyMem (&gMmCoreMmst.MmStartupThisAp, MmEntryContext, sizeof (EFI_MM_ENTRY_CONTEXT));
- //
- // Call platform hook before Mm Dispatch
- //
- // PlatformHookBeforeMmDispatch ();
- //
- // If a legacy boot has occurred, then make sure gMmCorePrivate is not accessed
- //
- //
- // TBD: Mark the InMm flag as TRUE
- //
- gMmCorePrivate->InMm = TRUE;
- //
- // Check to see if this is a Synchronous MMI sent through the MM Communication
- // Protocol or an Asynchronous MMI
- //
- if (gMmCorePrivate->CommunicationBuffer != 0) {
- //
- // Synchronous MMI for MM Core or request from Communicate protocol
- //
- if (!MmIsBufferOutsideMmValid ((UINTN)gMmCorePrivate->CommunicationBuffer, gMmCorePrivate->BufferSize)) {
- //
- // If CommunicationBuffer is not in valid address scope, return EFI_INVALID_PARAMETER
- //
- gMmCorePrivate->CommunicationBuffer = 0;
- gMmCorePrivate->ReturnStatus = EFI_INVALID_PARAMETER;
- } else {
- CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)gMmCorePrivate->CommunicationBuffer;
- gMmCorePrivate->BufferSize -= OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
- Status = MmiManage (
- &CommunicateHeader->HeaderGuid,
- NULL,
- CommunicateHeader->Data,
- (UINTN *)&gMmCorePrivate->BufferSize
- );
- //
- // Update CommunicationBuffer, BufferSize and ReturnStatus
- // Communicate service finished, reset the pointer to CommBuffer to NULL
- //
- gMmCorePrivate->BufferSize += OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);
- gMmCorePrivate->CommunicationBuffer = 0;
- gMmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;
- }
- }
- //
- // Process Asynchronous MMI sources
- //
- MmiManage (NULL, NULL, NULL, NULL);
- //
- // TBD: Do not use private data structure ?
- //
- //
- // Clear the InMm flag as we are going to leave MM
- //
- gMmCorePrivate->InMm = FALSE;
- DEBUG ((DEBUG_INFO, "MmEntryPoint Done\n"));
- }
- /** Register the MM Entry Point provided by the MM Core with the
- MM Configuration protocol.
- @param [in] Protocol Pointer to the protocol.
- @param [in] Interface Pointer to the MM Configuration protocol.
- @param [in] Handle Handle.
- @retval EFI_SUCCESS Success.
- **/
- EFI_STATUS
- EFIAPI
- MmConfigurationMmNotify (
- IN CONST EFI_GUID *Protocol,
- IN VOID *Interface,
- IN EFI_HANDLE Handle
- )
- {
- EFI_STATUS Status;
- EFI_MM_CONFIGURATION_PROTOCOL *MmConfiguration;
- DEBUG ((DEBUG_INFO, "MmConfigurationMmNotify(%g) - %x\n", Protocol, Interface));
- MmConfiguration = Interface;
- //
- // Register the MM Entry Point provided by the MM Core with the MM COnfiguration protocol
- //
- Status = MmConfiguration->RegisterMmEntry (MmConfiguration, (EFI_MM_ENTRY_POINT)(UINTN)gMmCorePrivate->MmEntryPoint);
- ASSERT_EFI_ERROR (Status);
- //
- // Set flag to indicate that the MM Entry Point has been registered which
- // means that MMIs are now fully operational.
- //
- gMmCorePrivate->MmEntryPointRegistered = TRUE;
- //
- // Print debug message showing MM Core entry point address.
- //
- DEBUG ((DEBUG_INFO, "MM Core registered MM Entry Point address %p\n", (VOID *)(UINTN)gMmCorePrivate->MmEntryPoint));
- return EFI_SUCCESS;
- }
- /** Returns the HOB list size.
- @param [in] HobStart Pointer to the start of the HOB list.
- @retval Size of the HOB list.
- **/
- UINTN
- GetHobListSize (
- IN VOID *HobStart
- )
- {
- EFI_PEI_HOB_POINTERS Hob;
- ASSERT (HobStart != NULL);
- Hob.Raw = (UINT8 *)HobStart;
- while (!END_OF_HOB_LIST (Hob)) {
- Hob.Raw = GET_NEXT_HOB (Hob);
- }
- //
- // Need plus END_OF_HOB_LIST
- //
- return (UINTN)Hob.Raw - (UINTN)HobStart + sizeof (EFI_HOB_GENERIC_HEADER);
- }
- /**
- The Entry Point for MM Core
- Install DXE Protocols and reload MM Core into MMRAM and register MM Core
- EntryPoint on the MMI vector.
- Note: This function is called for both DXE invocation and MMRAM invocation.
- @param HobStart Pointer to the start of the HOB list.
- @retval EFI_SUCCESS Success.
- @retval EFI_UNSUPPORTED Unsupported operation.
- **/
- EFI_STATUS
- EFIAPI
- StandaloneMmMain (
- IN VOID *HobStart
- )
- {
- EFI_STATUS Status;
- UINTN Index;
- VOID *MmHobStart;
- UINTN HobSize;
- VOID *Registration;
- EFI_HOB_GUID_TYPE *GuidHob;
- MM_CORE_DATA_HOB_DATA *DataInHob;
- EFI_HOB_GUID_TYPE *MmramRangesHob;
- EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData;
- EFI_MMRAM_DESCRIPTOR *MmramRanges;
- UINTN MmramRangeCount;
- EFI_HOB_FIRMWARE_VOLUME *BfvHob;
- ProcessLibraryConstructorList (HobStart, &gMmCoreMmst);
- DEBUG ((DEBUG_INFO, "MmMain - 0x%x\n", HobStart));
- //
- // Determine if the caller has passed a reference to a MM_CORE_PRIVATE_DATA
- // structure in the Hoblist. This choice will govern how boot information is
- // extracted later.
- //
- GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart);
- if (GuidHob == NULL) {
- //
- // Allocate and zero memory for a MM_CORE_PRIVATE_DATA table and then
- // initialise it
- //
- gMmCorePrivate = (MM_CORE_PRIVATE_DATA *)AllocateRuntimePages (EFI_SIZE_TO_PAGES (sizeof (MM_CORE_PRIVATE_DATA)));
- SetMem ((VOID *)(UINTN)gMmCorePrivate, sizeof (MM_CORE_PRIVATE_DATA), 0);
- gMmCorePrivate->Signature = MM_CORE_PRIVATE_DATA_SIGNATURE;
- gMmCorePrivate->MmEntryPointRegistered = FALSE;
- gMmCorePrivate->InMm = FALSE;
- gMmCorePrivate->ReturnStatus = EFI_SUCCESS;
- //
- // Extract the MMRAM ranges from the MMRAM descriptor HOB
- //
- MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart);
- if (MmramRangesHob == NULL) {
- return EFI_UNSUPPORTED;
- }
- MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);
- ASSERT (MmramRangesHobData != NULL);
- MmramRanges = MmramRangesHobData->Descriptor;
- MmramRangeCount = (UINTN)MmramRangesHobData->NumberOfMmReservedRegions;
- ASSERT (MmramRanges);
- ASSERT (MmramRangeCount);
- //
- // Copy the MMRAM ranges into MM_CORE_PRIVATE_DATA table just in case any
- // code relies on them being present there
- //
- gMmCorePrivate->MmramRangeCount = (UINT64)MmramRangeCount;
- gMmCorePrivate->MmramRanges =
- (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (MmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR));
- ASSERT (gMmCorePrivate->MmramRanges != 0);
- CopyMem (
- (VOID *)(UINTN)gMmCorePrivate->MmramRanges,
- MmramRanges,
- MmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR)
- );
- } else {
- DataInHob = GET_GUID_HOB_DATA (GuidHob);
- gMmCorePrivate = (MM_CORE_PRIVATE_DATA *)(UINTN)DataInHob->Address;
- MmramRanges = (EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate->MmramRanges;
- MmramRangeCount = (UINTN)gMmCorePrivate->MmramRangeCount;
- }
- //
- // Print the MMRAM ranges passed by the caller
- //
- DEBUG ((DEBUG_INFO, "MmramRangeCount - 0x%x\n", MmramRangeCount));
- for (Index = 0; Index < MmramRangeCount; Index++) {
- DEBUG ((
- DEBUG_INFO,
- "MmramRanges[%d]: 0x%016lx - 0x%lx\n",
- Index,
- MmramRanges[Index].CpuStart,
- MmramRanges[Index].PhysicalSize
- ));
- }
- //
- // Copy the MMRAM ranges into private MMRAM
- //
- mMmramRangeCount = MmramRangeCount;
- DEBUG ((DEBUG_INFO, "mMmramRangeCount - 0x%x\n", mMmramRangeCount));
- mMmramRanges = AllocatePool (mMmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR));
- DEBUG ((DEBUG_INFO, "mMmramRanges - 0x%x\n", mMmramRanges));
- ASSERT (mMmramRanges != NULL);
- CopyMem (mMmramRanges, (VOID *)(UINTN)MmramRanges, mMmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR));
- //
- // Get Boot Firmware Volume address from the BFV Hob
- //
- BfvHob = GetFirstHob (EFI_HOB_TYPE_FV);
- if (BfvHob != NULL) {
- DEBUG ((DEBUG_INFO, "BFV address - 0x%x\n", BfvHob->BaseAddress));
- DEBUG ((DEBUG_INFO, "BFV size - 0x%x\n", BfvHob->Length));
- gMmCorePrivate->StandaloneBfvAddress = BfvHob->BaseAddress;
- }
- gMmCorePrivate->Mmst = (EFI_PHYSICAL_ADDRESS)(UINTN)&gMmCoreMmst;
- gMmCorePrivate->MmEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)MmEntryPoint;
- //
- // No need to initialize memory service.
- // It is done in the constructor of StandaloneMmCoreMemoryAllocationLib(),
- // so that the library linked with StandaloneMmCore can use AllocatePool() in
- // the constructor.
- DEBUG ((DEBUG_INFO, "MmInstallConfigurationTable For HobList\n"));
- //
- // Install HobList
- //
- HobSize = GetHobListSize (HobStart);
- DEBUG ((DEBUG_INFO, "HobSize - 0x%x\n", HobSize));
- MmHobStart = AllocatePool (HobSize);
- DEBUG ((DEBUG_INFO, "MmHobStart - 0x%x\n", MmHobStart));
- ASSERT (MmHobStart != NULL);
- CopyMem (MmHobStart, HobStart, HobSize);
- Status = MmInstallConfigurationTable (&gMmCoreMmst, &gEfiHobListGuid, MmHobStart, HobSize);
- ASSERT_EFI_ERROR (Status);
- //
- // Register notification for EFI_MM_CONFIGURATION_PROTOCOL registration and
- // use it to register the MM Foundation entrypoint
- //
- DEBUG ((DEBUG_INFO, "MmRegisterProtocolNotify - MmConfigurationMmProtocol\n"));
- Status = MmRegisterProtocolNotify (
- &gEfiMmConfigurationProtocolGuid,
- MmConfigurationMmNotify,
- &Registration
- );
- ASSERT_EFI_ERROR (Status);
- //
- // Dispatch standalone BFV
- //
- DEBUG ((DEBUG_INFO, "Mm Dispatch StandaloneBfvAddress - 0x%08x\n", gMmCorePrivate->StandaloneBfvAddress));
- if (gMmCorePrivate->StandaloneBfvAddress != 0) {
- MmCoreFfsFindMmDriver ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)gMmCorePrivate->StandaloneBfvAddress);
- MmDispatcher ();
- }
- //
- // Register all handlers in the core table
- //
- for (Index = 0; mMmCoreMmiHandlers[Index].HandlerType != NULL; Index++) {
- Status = MmiHandlerRegister (
- mMmCoreMmiHandlers[Index].Handler,
- mMmCoreMmiHandlers[Index].HandlerType,
- &mMmCoreMmiHandlers[Index].DispatchHandle
- );
- DEBUG ((DEBUG_INFO, "MmiHandlerRegister - GUID %g - Status %d\n", mMmCoreMmiHandlers[Index].HandlerType, Status));
- }
- DEBUG ((DEBUG_INFO, "MmMain Done!\n"));
- return EFI_SUCCESS;
- }
|