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