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