]> git.proxmox.com Git - mirror_edk2.git/blame - StandaloneMmPkg/Core/StandaloneMmCore.c
StandaloneMmPkg/Core: remove legacy boot support
[mirror_edk2.git] / StandaloneMmPkg / Core / StandaloneMmCore.c
CommitLineData
6b46d772
SV
1/** @file\r
2 MM Core Main Entry Point\r
3\r
4 Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\r
5 Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>\r
6 This program and the accompanying materials are licensed and made available\r
7 under the terms and conditions of the BSD License which accompanies this\r
8 distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "StandaloneMmCore.h"\r
17\r
18EFI_STATUS\r
19MmCoreFfsFindMmDriver (\r
20 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader\r
21 );\r
22\r
23EFI_STATUS\r
24MmDispatcher (\r
25 VOID\r
26 );\r
27\r
28//\r
29// Globals used to initialize the protocol\r
30//\r
31EFI_HANDLE mMmCpuHandle = NULL;\r
32\r
33//\r
34// Physical pointer to private structure shared between MM IPL and the MM Core\r
35//\r
36MM_CORE_PRIVATE_DATA *gMmCorePrivate;\r
37\r
38//\r
39// MM Core global variable for MM System Table. Only accessed as a physical structure in MMRAM.\r
40//\r
41EFI_MM_SYSTEM_TABLE gMmCoreMmst = {\r
42\r
43 // The table header for the MMST.\r
44 {\r
45 MM_MMST_SIGNATURE,\r
46 EFI_MM_SYSTEM_TABLE_REVISION,\r
47 sizeof (gMmCoreMmst.Hdr)\r
48 },\r
49 // MmFirmwareVendor\r
50 NULL,\r
51 // MmFirmwareRevision\r
52 0,\r
53 // MmInstallConfigurationTable\r
54 MmInstallConfigurationTable,\r
55 // I/O Service\r
56 {\r
57 {\r
58 (EFI_MM_CPU_IO) MmEfiNotAvailableYetArg5, // MmMemRead\r
59 (EFI_MM_CPU_IO) MmEfiNotAvailableYetArg5 // MmMemWrite\r
60 },\r
61 {\r
62 (EFI_MM_CPU_IO) MmEfiNotAvailableYetArg5, // MmIoRead\r
63 (EFI_MM_CPU_IO) MmEfiNotAvailableYetArg5 // MmIoWrite\r
64 }\r
65 },\r
66 // Runtime memory services\r
67 MmAllocatePool,\r
68 MmFreePool,\r
69 MmAllocatePages,\r
70 MmFreePages,\r
71 // MP service\r
72 NULL, // MmStartupThisAp\r
73 0, // CurrentlyExecutingCpu\r
74 0, // NumberOfCpus\r
75 NULL, // CpuSaveStateSize\r
76 NULL, // CpuSaveState\r
77 0, // NumberOfTableEntries\r
78 NULL, // MmConfigurationTable\r
79 MmInstallProtocolInterface,\r
80 MmUninstallProtocolInterface,\r
81 MmHandleProtocol,\r
82 MmRegisterProtocolNotify,\r
83 MmLocateHandle,\r
84 MmLocateProtocol,\r
85 MmiManage,\r
86 MmiHandlerRegister,\r
87 MmiHandlerUnRegister\r
88};\r
89\r
6b46d772
SV
90//\r
91// Table of MMI Handlers that are registered by the MM Core when it is initialized\r
92//\r
93MM_CORE_MMI_HANDLERS mMmCoreMmiHandlers[] = {\r
6b46d772
SV
94 { MmReadyToLockHandler, &gEfiDxeMmReadyToLockProtocolGuid, NULL, TRUE },\r
95 { MmEndOfDxeHandler, &gEfiEndOfDxeEventGroupGuid, NULL, FALSE },\r
6b46d772
SV
96 { MmExitBootServiceHandler,&gEfiEventExitBootServicesGuid, NULL, FALSE },\r
97 { MmReadyToBootHandler, &gEfiEventReadyToBootGuid, NULL, FALSE },\r
98 { NULL, NULL, NULL, FALSE },\r
99};\r
100\r
101EFI_SYSTEM_TABLE *mEfiSystemTable;\r
102UINTN mMmramRangeCount;\r
103EFI_MMRAM_DESCRIPTOR *mMmramRanges;\r
104\r
105/**\r
106 Place holder function until all the MM System Table Service are available.\r
107\r
108 Note: This function is only used by MMRAM invocation. It is never used by DXE invocation.\r
109\r
110 @param Arg1 Undefined\r
111 @param Arg2 Undefined\r
112 @param Arg3 Undefined\r
113 @param Arg4 Undefined\r
114 @param Arg5 Undefined\r
115\r
116 @return EFI_NOT_AVAILABLE_YET\r
117\r
118**/\r
119EFI_STATUS\r
120EFIAPI\r
121MmEfiNotAvailableYetArg5 (\r
122 UINTN Arg1,\r
123 UINTN Arg2,\r
124 UINTN Arg3,\r
125 UINTN Arg4,\r
126 UINTN Arg5\r
127 )\r
128{\r
129 //\r
130 // This function should never be executed. If it does, then the architectural protocols\r
131 // have not been designed correctly.\r
132 //\r
133 return EFI_NOT_AVAILABLE_YET;\r
134}\r
135\r
6b46d772
SV
136/**\r
137 Software MMI handler that is called when a ExitBoot Service event is signaled.\r
138\r
139 @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister().\r
140 @param Context Points to an optional handler context which was specified when the handler was registered.\r
141 @param CommBuffer A pointer to a collection of data in memory that will\r
142 be conveyed from a non-MM environment into an MM environment.\r
143 @param CommBufferSize The size of the CommBuffer.\r
144\r
145 @return Status Code\r
146\r
147**/\r
148EFI_STATUS\r
149EFIAPI\r
150MmExitBootServiceHandler (\r
151 IN EFI_HANDLE DispatchHandle,\r
152 IN CONST VOID *Context, OPTIONAL\r
153 IN OUT VOID *CommBuffer, OPTIONAL\r
154 IN OUT UINTN *CommBufferSize OPTIONAL\r
155 )\r
156{\r
157 EFI_HANDLE MmHandle;\r
158 EFI_STATUS Status = EFI_SUCCESS;\r
159 STATIC BOOLEAN mInExitBootServices = FALSE;\r
160\r
161 if (!mInExitBootServices) {\r
162 MmHandle = NULL;\r
163 Status = MmInstallProtocolInterface (\r
164 &MmHandle,\r
165 &gEfiEventExitBootServicesGuid,\r
166 EFI_NATIVE_INTERFACE,\r
167 NULL\r
168 );\r
169 }\r
170 mInExitBootServices = TRUE;\r
171 return Status;\r
172}\r
173\r
174/**\r
175 Software MMI handler that is called when a ExitBoot Service event is signaled.\r
176\r
177 @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister().\r
178 @param Context Points to an optional handler context which was specified when the handler was registered.\r
179 @param CommBuffer A pointer to a collection of data in memory that will\r
180 be conveyed from a non-MM environment into an MM environment.\r
181 @param CommBufferSize The size of the CommBuffer.\r
182\r
183 @return Status Code\r
184\r
185**/\r
186EFI_STATUS\r
187EFIAPI\r
188MmReadyToBootHandler (\r
189 IN EFI_HANDLE DispatchHandle,\r
190 IN CONST VOID *Context, OPTIONAL\r
191 IN OUT VOID *CommBuffer, OPTIONAL\r
192 IN OUT UINTN *CommBufferSize OPTIONAL\r
193 )\r
194{\r
195 EFI_HANDLE MmHandle;\r
196 EFI_STATUS Status = EFI_SUCCESS;\r
197 STATIC BOOLEAN mInReadyToBoot = FALSE;\r
198\r
199 if (!mInReadyToBoot) {\r
200 MmHandle = NULL;\r
201 Status = MmInstallProtocolInterface (\r
202 &MmHandle,\r
203 &gEfiEventReadyToBootGuid,\r
204 EFI_NATIVE_INTERFACE,\r
205 NULL\r
206 );\r
207 }\r
208 mInReadyToBoot = TRUE;\r
209 return Status;\r
210}\r
211\r
212/**\r
213 Software MMI handler that is called when the DxeMmReadyToLock protocol is added\r
214 or if gEfiEventReadyToBootGuid is signaled. This function unregisters the\r
215 Software SMIs that are nor required after MMRAM is locked and installs the\r
216 MM Ready To Lock Protocol so MM Drivers are informed that MMRAM is about\r
217 to be locked.\r
218\r
219 @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister().\r
220 @param Context Points to an optional handler context which was specified when the handler was registered.\r
221 @param CommBuffer A pointer to a collection of data in memory that will\r
222 be conveyed from a non-MM environment into an MM environment.\r
223 @param CommBufferSize The size of the CommBuffer.\r
224\r
225 @return Status Code\r
226\r
227**/\r
228EFI_STATUS\r
229EFIAPI\r
230MmReadyToLockHandler (\r
231 IN EFI_HANDLE DispatchHandle,\r
232 IN CONST VOID *Context, OPTIONAL\r
233 IN OUT VOID *CommBuffer, OPTIONAL\r
234 IN OUT UINTN *CommBufferSize OPTIONAL\r
235 )\r
236{\r
237 EFI_STATUS Status;\r
238 UINTN Index;\r
239 EFI_HANDLE MmHandle;\r
240\r
241 DEBUG ((DEBUG_INFO, "MmReadyToLockHandler\n"));\r
242\r
243 //\r
244 // Unregister MMI Handlers that are no longer required after the MM driver dispatch is stopped\r
245 //\r
246 for (Index = 0; mMmCoreMmiHandlers[Index].HandlerType != NULL; Index++) {\r
247 if (mMmCoreMmiHandlers[Index].UnRegister) {\r
248 MmiHandlerUnRegister (mMmCoreMmiHandlers[Index].DispatchHandle);\r
249 }\r
250 }\r
251\r
252 //\r
253 // Install MM Ready to lock protocol\r
254 //\r
255 MmHandle = NULL;\r
256 Status = MmInstallProtocolInterface (\r
257 &MmHandle,\r
258 &gEfiMmReadyToLockProtocolGuid,\r
259 EFI_NATIVE_INTERFACE,\r
260 NULL\r
261 );\r
262\r
263 //\r
264 // Make sure MM CPU I/O 2 Protocol has been installed into the handle database\r
265 //\r
266 //Status = MmLocateProtocol (&EFI_MM_CPU_IO_PROTOCOL_GUID, NULL, &Interface);\r
267\r
268 //\r
269 // Print a message on a debug build if the MM CPU I/O 2 Protocol is not installed\r
270 //\r
271 //if (EFI_ERROR (Status)) {\r
272 //DEBUG ((DEBUG_ERROR, "\nSMM: SmmCpuIo Arch Protocol not present!!\n"));\r
273 //}\r
274\r
275\r
276 //\r
277 // Assert if the CPU I/O 2 Protocol is not installed\r
278 //\r
279 //ASSERT_EFI_ERROR (Status);\r
280\r
281 //\r
282 // Display any drivers that were not dispatched because dependency expression\r
283 // evaluated to false if this is a debug build\r
284 //\r
285 //MmDisplayDiscoveredNotDispatched ();\r
286\r
287 return Status;\r
288}\r
289\r
290/**\r
291 Software MMI handler that is called when the EndOfDxe event is signaled.\r
292 This function installs the MM EndOfDxe Protocol so MM Drivers are informed that\r
293 platform code will invoke 3rd part code.\r
294\r
295 @param DispatchHandle The unique handle assigned to this handler by MmiHandlerRegister().\r
296 @param Context Points to an optional handler context which was specified when the handler was registered.\r
297 @param CommBuffer A pointer to a collection of data in memory that will\r
298 be conveyed from a non-MM environment into an MM environment.\r
299 @param CommBufferSize The size of the CommBuffer.\r
300\r
301 @return Status Code\r
302\r
303**/\r
304EFI_STATUS\r
305EFIAPI\r
306MmEndOfDxeHandler (\r
307 IN EFI_HANDLE DispatchHandle,\r
308 IN CONST VOID *Context, OPTIONAL\r
309 IN OUT VOID *CommBuffer, OPTIONAL\r
310 IN OUT UINTN *CommBufferSize OPTIONAL\r
311 )\r
312{\r
313 EFI_STATUS Status;\r
314 EFI_HANDLE MmHandle;\r
315\r
316 DEBUG ((DEBUG_INFO, "MmEndOfDxeHandler\n"));\r
317 //\r
318 // Install MM EndOfDxe protocol\r
319 //\r
320 MmHandle = NULL;\r
321 Status = MmInstallProtocolInterface (\r
322 &MmHandle,\r
323 &gEfiMmEndOfDxeProtocolGuid,\r
324 EFI_NATIVE_INTERFACE,\r
325 NULL\r
326 );\r
327 return Status;\r
328}\r
329\r
330\r
331\r
332/**\r
333 The main entry point to MM Foundation.\r
334\r
335 Note: This function is only used by MMRAM invocation. It is never used by DXE invocation.\r
336\r
337 @param MmEntryContext Processor information and functionality\r
338 needed by MM Foundation.\r
339\r
340**/\r
341VOID\r
342EFIAPI\r
343MmEntryPoint (\r
344 IN CONST EFI_MM_ENTRY_CONTEXT *MmEntryContext\r
345)\r
346{\r
347 EFI_STATUS Status;\r
348 EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;\r
6b46d772
SV
349\r
350 DEBUG ((DEBUG_INFO, "MmEntryPoint ...\n"));\r
351\r
352 //\r
353 // Update MMST using the context\r
354 //\r
355 CopyMem (&gMmCoreMmst.MmStartupThisAp, MmEntryContext, sizeof (EFI_MM_ENTRY_CONTEXT));\r
356\r
357 //\r
358 // Call platform hook before Mm Dispatch\r
359 //\r
360 //PlatformHookBeforeMmDispatch ();\r
361\r
362 //\r
363 // If a legacy boot has occured, then make sure gMmCorePrivate is not accessed\r
364 //\r
6b46d772 365\r
b2877855
AB
366 //\r
367 // TBD: Mark the InMm flag as TRUE\r
368 //\r
369 gMmCorePrivate->InMm = TRUE;\r
370\r
371 //\r
372 // Check to see if this is a Synchronous MMI sent through the MM Communication\r
373 // Protocol or an Asynchronous MMI\r
374 //\r
375 if (gMmCorePrivate->CommunicationBuffer != 0) {\r
6b46d772 376 //\r
b2877855 377 // Synchronous MMI for MM Core or request from Communicate protocol\r
6b46d772 378 //\r
b2877855 379 if (!MmIsBufferOutsideMmValid ((UINTN)gMmCorePrivate->CommunicationBuffer, gMmCorePrivate->BufferSize)) {\r
6b46d772 380 //\r
b2877855 381 // If CommunicationBuffer is not in valid address scope, return EFI_INVALID_PARAMETER\r
6b46d772 382 //\r
b2877855
AB
383 gMmCorePrivate->CommunicationBuffer = 0;\r
384 gMmCorePrivate->ReturnStatus = EFI_INVALID_PARAMETER;\r
385 } else {\r
386 CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)gMmCorePrivate->CommunicationBuffer;\r
387 gMmCorePrivate->BufferSize -= OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);\r
388 Status = MmiManage (\r
389 &CommunicateHeader->HeaderGuid,\r
390 NULL,\r
391 CommunicateHeader->Data,\r
392 (UINTN *)&gMmCorePrivate->BufferSize\r
393 );\r
394 //\r
395 // Update CommunicationBuffer, BufferSize and ReturnStatus\r
396 // Communicate service finished, reset the pointer to CommBuffer to NULL\r
397 //\r
398 gMmCorePrivate->BufferSize += OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);\r
399 gMmCorePrivate->CommunicationBuffer = 0;\r
400 gMmCorePrivate->ReturnStatus = (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_NOT_FOUND;\r
6b46d772
SV
401 }\r
402 }\r
403\r
404 //\r
405 // Process Asynchronous MMI sources\r
406 //\r
407 MmiManage (NULL, NULL, NULL, NULL);\r
408\r
409 //\r
410 // TBD: Do not use private data structure ?\r
411 //\r
412\r
413 //\r
b2877855 414 // Clear the InMm flag as we are going to leave MM\r
6b46d772 415 //\r
b2877855 416 gMmCorePrivate->InMm = FALSE;\r
6b46d772
SV
417\r
418 DEBUG ((DEBUG_INFO, "MmEntryPoint Done\n"));\r
419}\r
420\r
421EFI_STATUS\r
422EFIAPI\r
423MmConfigurationMmNotify (\r
424 IN CONST EFI_GUID *Protocol,\r
425 IN VOID *Interface,\r
426 IN EFI_HANDLE Handle\r
427 )\r
428{\r
429 EFI_STATUS Status;\r
430 EFI_MM_CONFIGURATION_PROTOCOL *MmConfiguration;\r
431\r
432 DEBUG ((DEBUG_INFO, "MmConfigurationMmNotify(%g) - %x\n", Protocol, Interface));\r
433\r
434 MmConfiguration = Interface;\r
435\r
436 //\r
437 // Register the MM Entry Point provided by the MM Core with the MM COnfiguration protocol\r
438 //\r
439 Status = MmConfiguration->RegisterMmEntry (MmConfiguration, (EFI_MM_ENTRY_POINT)(UINTN)gMmCorePrivate->MmEntryPoint);\r
440 ASSERT_EFI_ERROR (Status);\r
441\r
442 //\r
443 // Set flag to indicate that the MM Entry Point has been registered which\r
444 // means that MMIs are now fully operational.\r
445 //\r
446 gMmCorePrivate->MmEntryPointRegistered = TRUE;\r
447\r
448 //\r
449 // Print debug message showing MM Core entry point address.\r
450 //\r
451 DEBUG ((DEBUG_INFO, "MM Core registered MM Entry Point address %p\n", (VOID *)(UINTN)gMmCorePrivate->MmEntryPoint));\r
452 return EFI_SUCCESS;\r
453}\r
454\r
455UINTN\r
456GetHobListSize (\r
457 IN VOID *HobStart\r
458 )\r
459{\r
460 EFI_PEI_HOB_POINTERS Hob;\r
461\r
462 ASSERT (HobStart != NULL);\r
463\r
464 Hob.Raw = (UINT8 *) HobStart;\r
465 while (!END_OF_HOB_LIST (Hob)) {\r
466 Hob.Raw = GET_NEXT_HOB (Hob);\r
467 }\r
468 //\r
469 // Need plus END_OF_HOB_LIST\r
470 //\r
471 return (UINTN)Hob.Raw - (UINTN)HobStart + sizeof (EFI_HOB_GENERIC_HEADER);\r
472}\r
473\r
474/**\r
475 The Entry Point for MM Core\r
476\r
477 Install DXE Protocols and reload MM Core into MMRAM and register MM Core\r
478 EntryPoint on the MMI vector.\r
479\r
480 Note: This function is called for both DXE invocation and MMRAM invocation.\r
481\r
482 @param ImageHandle The firmware allocated handle for the EFI image.\r
483 @param SystemTable A pointer to the EFI System Table.\r
484\r
485 @retval EFI_SUCCESS The entry point is executed successfully.\r
486 @retval Other Some error occurred when executing this entry point.\r
487\r
488**/\r
489EFI_STATUS\r
490EFIAPI\r
491StandaloneMmMain (\r
492 IN VOID *HobStart\r
493 )\r
494{\r
495 EFI_STATUS Status;\r
496 UINTN Index;\r
497 VOID *MmHobStart;\r
498 UINTN HobSize;\r
499 VOID *Registration;\r
500 EFI_HOB_GUID_TYPE *GuidHob;\r
501 MM_CORE_DATA_HOB_DATA *DataInHob;\r
502 EFI_HOB_GUID_TYPE *MmramRangesHob;\r
503 EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData;\r
504 EFI_MMRAM_DESCRIPTOR *MmramRanges;\r
505 UINT32 MmramRangeCount;\r
506 EFI_HOB_FIRMWARE_VOLUME *BfvHob;\r
507\r
508 ProcessLibraryConstructorList (HobStart, &gMmCoreMmst);\r
509\r
510 DEBUG ((DEBUG_INFO, "MmMain - 0x%x\n", HobStart));\r
511\r
512 //\r
513 // Determine if the caller has passed a reference to a MM_CORE_PRIVATE_DATA\r
514 // structure in the Hoblist. This choice will govern how boot information is\r
515 // extracted later.\r
516 //\r
517 GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart);\r
518 if (GuidHob == NULL) {\r
519 //\r
520 // Allocate and zero memory for a MM_CORE_PRIVATE_DATA table and then\r
521 // initialise it\r
522 //\r
523 gMmCorePrivate = (MM_CORE_PRIVATE_DATA *) AllocateRuntimePages(EFI_SIZE_TO_PAGES(sizeof (MM_CORE_PRIVATE_DATA)));\r
524 SetMem ((VOID *)(UINTN)gMmCorePrivate, sizeof (MM_CORE_PRIVATE_DATA), 0);\r
525 gMmCorePrivate->Signature = MM_CORE_PRIVATE_DATA_SIGNATURE;\r
526 gMmCorePrivate->MmEntryPointRegistered = FALSE;\r
527 gMmCorePrivate->InMm = FALSE;\r
528 gMmCorePrivate->ReturnStatus = EFI_SUCCESS;\r
529\r
530 //\r
531 // Extract the MMRAM ranges from the MMRAM descriptor HOB\r
532 //\r
533 MmramRangesHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart);\r
534 if (MmramRangesHob == NULL)\r
535 return EFI_UNSUPPORTED;\r
536\r
537 MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);\r
538 ASSERT (MmramRangesHobData != NULL);\r
539 MmramRanges = MmramRangesHobData->Descriptor;\r
540 MmramRangeCount = MmramRangesHobData->NumberOfMmReservedRegions;\r
541 ASSERT (MmramRanges);\r
542 ASSERT (MmramRangeCount);\r
543\r
544 //\r
545 // Copy the MMRAM ranges into MM_CORE_PRIVATE_DATA table just in case any\r
546 // code relies on them being present there\r
547 //\r
548 gMmCorePrivate->MmramRangeCount = MmramRangeCount;\r
549 gMmCorePrivate->MmramRanges =\r
550 (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (MmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR));\r
551 ASSERT (gMmCorePrivate->MmramRanges != 0);\r
552 CopyMem (\r
553 (VOID *)(UINTN)gMmCorePrivate->MmramRanges,\r
554 MmramRanges,\r
555 MmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR)\r
556 );\r
557 } else {\r
558 DataInHob = GET_GUID_HOB_DATA (GuidHob);\r
559 gMmCorePrivate = (MM_CORE_PRIVATE_DATA *)(UINTN)DataInHob->Address;\r
560 MmramRanges = (EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate->MmramRanges;\r
561 MmramRangeCount = gMmCorePrivate->MmramRangeCount;\r
562 }\r
563\r
564 //\r
565 // Print the MMRAM ranges passed by the caller\r
566 //\r
567 DEBUG ((DEBUG_INFO, "MmramRangeCount - 0x%x\n", MmramRangeCount));\r
568 for (Index = 0; Index < MmramRangeCount; Index++) {\r
569 DEBUG ((DEBUG_INFO, "MmramRanges[%d]: 0x%016lx - 0x%lx\n", Index,\r
570 MmramRanges[Index].CpuStart,\r
571 MmramRanges[Index].PhysicalSize));\r
572 }\r
573\r
574 //\r
575 // Copy the MMRAM ranges into private MMRAM\r
576 //\r
577 mMmramRangeCount = MmramRangeCount;\r
578 DEBUG ((DEBUG_INFO, "mMmramRangeCount - 0x%x\n", mMmramRangeCount));\r
579 mMmramRanges = AllocatePool (mMmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR));\r
580 DEBUG ((DEBUG_INFO, "mMmramRanges - 0x%x\n", mMmramRanges));\r
581 ASSERT (mMmramRanges != NULL);\r
582 CopyMem (mMmramRanges, (VOID *)(UINTN)MmramRanges, mMmramRangeCount * sizeof (EFI_MMRAM_DESCRIPTOR));\r
583\r
584 //\r
585 // Get Boot Firmware Volume address from the BFV Hob\r
586 //\r
587 BfvHob = GetFirstHob (EFI_HOB_TYPE_FV);\r
588 if (BfvHob != NULL) {\r
589 DEBUG ((DEBUG_INFO, "BFV address - 0x%x\n", BfvHob->BaseAddress));\r
590 DEBUG ((DEBUG_INFO, "BFV size - 0x%x\n", BfvHob->Length));\r
591 gMmCorePrivate->StandaloneBfvAddress = BfvHob->BaseAddress;\r
592 }\r
593\r
594 gMmCorePrivate->Mmst = (EFI_PHYSICAL_ADDRESS)(UINTN)&gMmCoreMmst;\r
595 gMmCorePrivate->MmEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)MmEntryPoint;\r
596\r
597 //\r
598 // No need to initialize memory service.\r
599 // It is done in constructor of StandaloneMmCoreMemoryAllocationLib(),\r
600 // so that the library linked with StandaloneMmCore can use AllocatePool() in constuctor.\r
601 //\r
602\r
603 DEBUG ((DEBUG_INFO, "MmInstallConfigurationTable For HobList\n"));\r
604 //\r
605 // Install HobList\r
606 //\r
607 HobSize = GetHobListSize (HobStart);\r
608 DEBUG ((DEBUG_INFO, "HobSize - 0x%x\n", HobSize));\r
609 MmHobStart = AllocatePool (HobSize);\r
610 DEBUG ((DEBUG_INFO, "MmHobStart - 0x%x\n", MmHobStart));\r
611 ASSERT (MmHobStart != NULL);\r
612 CopyMem (MmHobStart, HobStart, HobSize);\r
613 Status = MmInstallConfigurationTable (&gMmCoreMmst, &gEfiHobListGuid, MmHobStart, HobSize);\r
614 ASSERT_EFI_ERROR (Status);\r
615\r
616 //\r
617 // Register notification for EFI_MM_CONFIGURATION_PROTOCOL registration and\r
618 // use it to register the MM Foundation entrypoint\r
619 //\r
620 DEBUG ((DEBUG_INFO, "MmRegisterProtocolNotify - MmConfigurationMmProtocol\n"));\r
621 Status = MmRegisterProtocolNotify (\r
622 &gEfiMmConfigurationProtocolGuid,\r
623 MmConfigurationMmNotify,\r
624 &Registration\r
625 );\r
626 ASSERT_EFI_ERROR (Status);\r
627\r
628 //\r
629 // Dispatch standalone BFV\r
630 //\r
631 DEBUG ((DEBUG_INFO, "Mm Dispatch StandaloneBfvAddress - 0x%08x\n", gMmCorePrivate->StandaloneBfvAddress));\r
632 if (gMmCorePrivate->StandaloneBfvAddress != 0) {\r
633 MmCoreFfsFindMmDriver ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)gMmCorePrivate->StandaloneBfvAddress);\r
634 MmDispatcher ();\r
635 }\r
636\r
637 //\r
638 // Register all handlers in the core table\r
639 //\r
640 for (Index = 0; mMmCoreMmiHandlers[Index].HandlerType != NULL; Index++) {\r
641 Status = MmiHandlerRegister (\r
642 mMmCoreMmiHandlers[Index].Handler,\r
643 mMmCoreMmiHandlers[Index].HandlerType,\r
644 &mMmCoreMmiHandlers[Index].DispatchHandle\r
645 );\r
646 DEBUG ((DEBUG_INFO, "MmiHandlerRegister - GUID %g - Status %d\n", mMmCoreMmiHandlers[Index].HandlerType, Status));\r
647 }\r
648\r
649 DEBUG ((DEBUG_INFO, "MmMain Done!\n"));\r
650\r
651 return EFI_SUCCESS;\r
652}\r