]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
Remove the global variable of gDxeCoreBS and uses the gBS in UefiBootServicesTableLib...
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / DxeMain / DxeMain.c
1 /** @file
2 DXE Core Main Entry Point
3
4 Copyright (c) 2006 - 2008, Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <DxeMain.h>
16
17 //
18 // DXE Core Global Variables for Protocols from PEI
19 //
20 EFI_HANDLE mDecompressHandle = NULL;
21
22 //
23 // DXE Core globals for Architecture Protocols
24 //
25 EFI_SECURITY_ARCH_PROTOCOL *gSecurity = NULL;
26 EFI_CPU_ARCH_PROTOCOL *gCpu = NULL;
27 EFI_METRONOME_ARCH_PROTOCOL *gMetronome = NULL;
28 EFI_TIMER_ARCH_PROTOCOL *gTimer = NULL;
29 EFI_BDS_ARCH_PROTOCOL *gBds = NULL;
30 EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer = NULL;
31
32 //
33 // DXE Core Global used to update core loaded image protocol handle
34 //
35 EFI_GUID *gDxeCoreFileName;
36 EFI_LOADED_IMAGE_PROTOCOL *gDxeCoreLoadedImage;
37
38 //
39 // BugBug: I'n not runtime, but is the PPI?
40 //
41 EFI_STATUS_CODE_PROTOCOL gStatusCodeInstance = {
42 NULL
43 };
44
45 EFI_STATUS_CODE_PROTOCOL *gStatusCode = &gStatusCodeInstance;
46
47 //
48 // DXE Core Module Variables
49 //
50
51 EFI_BOOT_SERVICES mBootServices = {
52 {
53 EFI_BOOT_SERVICES_SIGNATURE, // Signature
54 EFI_BOOT_SERVICES_REVISION, // Revision
55 sizeof (EFI_BOOT_SERVICES), // HeaderSize
56 0, // CRC32
57 0 // Reserved
58 },
59 (EFI_RAISE_TPL) CoreRaiseTpl, // RaiseTPL
60 (EFI_RESTORE_TPL) CoreRestoreTpl, // RestoreTPL
61 (EFI_ALLOCATE_PAGES) CoreAllocatePages, // AllocatePages
62 (EFI_FREE_PAGES) CoreFreePages, // FreePages
63 (EFI_GET_MEMORY_MAP) CoreGetMemoryMap, // GetMemoryMap
64 (EFI_ALLOCATE_POOL) CoreAllocatePool, // AllocatePool
65 (EFI_FREE_POOL) CoreFreePool, // FreePool
66 (EFI_CREATE_EVENT) CoreCreateEvent, // CreateEvent
67 (EFI_SET_TIMER) CoreSetTimer, // SetTimer
68 (EFI_WAIT_FOR_EVENT) CoreWaitForEvent, // WaitForEvent
69 (EFI_SIGNAL_EVENT) CoreSignalEvent, // SignalEvent
70 (EFI_CLOSE_EVENT) CoreCloseEvent, // CloseEvent
71 (EFI_CHECK_EVENT) CoreCheckEvent, // CheckEvent
72 (EFI_INSTALL_PROTOCOL_INTERFACE) CoreInstallProtocolInterface, // InstallProtocolInterface
73 (EFI_REINSTALL_PROTOCOL_INTERFACE) CoreReinstallProtocolInterface, // ReinstallProtocolInterface
74 (EFI_UNINSTALL_PROTOCOL_INTERFACE) CoreUninstallProtocolInterface, // UninstallProtocolInterface
75 (EFI_HANDLE_PROTOCOL) CoreHandleProtocol, // HandleProtocol
76 (VOID *) NULL, // Reserved
77 (EFI_REGISTER_PROTOCOL_NOTIFY) CoreRegisterProtocolNotify, // RegisterProtocolNotify
78 (EFI_LOCATE_HANDLE) CoreLocateHandle, // LocateHandle
79 (EFI_LOCATE_DEVICE_PATH) CoreLocateDevicePath, // LocateDevicePath
80 (EFI_INSTALL_CONFIGURATION_TABLE) CoreInstallConfigurationTable, // InstallConfigurationTable
81 (EFI_IMAGE_LOAD) CoreLoadImage, // LoadImage
82 (EFI_IMAGE_START) CoreStartImage, // StartImage
83 (EFI_EXIT) CoreExit, // Exit
84 (EFI_IMAGE_UNLOAD) CoreUnloadImage, // UnloadImage
85 (EFI_EXIT_BOOT_SERVICES) CoreExitBootServices, // ExitBootServices
86 (EFI_GET_NEXT_MONOTONIC_COUNT) CoreEfiNotAvailableYetArg1, // GetNextMonotonicCount
87 (EFI_STALL) CoreStall, // Stall
88 (EFI_SET_WATCHDOG_TIMER) CoreSetWatchdogTimer, // SetWatchdogTimer
89 (EFI_CONNECT_CONTROLLER) CoreConnectController, // ConnectController
90 (EFI_DISCONNECT_CONTROLLER) CoreDisconnectController, // DisconnectController
91 (EFI_OPEN_PROTOCOL) CoreOpenProtocol, // OpenProtocol
92 (EFI_CLOSE_PROTOCOL) CoreCloseProtocol, // CloseProtocol
93 (EFI_OPEN_PROTOCOL_INFORMATION) CoreOpenProtocolInformation, // OpenProtocolInformation
94 (EFI_PROTOCOLS_PER_HANDLE) CoreProtocolsPerHandle, // ProtocolsPerHandle
95 (EFI_LOCATE_HANDLE_BUFFER) CoreLocateHandleBuffer, // LocateHandleBuffer
96 (EFI_LOCATE_PROTOCOL) CoreLocateProtocol, // LocateProtocol
97 (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES) CoreInstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces
98 (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES) CoreUninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces
99 (EFI_CALCULATE_CRC32) CoreEfiNotAvailableYetArg3, // CalculateCrc32
100 (EFI_COPY_MEM) CopyMem, // CopyMem
101 (EFI_SET_MEM) SetMem, // SetMem
102 (EFI_CREATE_EVENT_EX) CoreCreateEventEx // CreateEventEx
103 };
104
105 EFI_DXE_SERVICES mDxeServices = {
106 {
107 DXE_SERVICES_SIGNATURE, // Signature
108 DXE_SERVICES_REVISION, // Revision
109 sizeof (DXE_SERVICES), // HeaderSize
110 0, // CRC32
111 0 // Reserved
112 },
113 (EFI_ADD_MEMORY_SPACE) CoreAddMemorySpace, // AddMemorySpace
114 (EFI_ALLOCATE_MEMORY_SPACE) CoreAllocateMemorySpace, // AllocateMemorySpace
115 (EFI_FREE_MEMORY_SPACE) CoreFreeMemorySpace, // FreeMemorySpace
116 (EFI_REMOVE_MEMORY_SPACE) CoreRemoveMemorySpace, // RemoveMemorySpace
117 (EFI_GET_MEMORY_SPACE_DESCRIPTOR) CoreGetMemorySpaceDescriptor, // GetMemorySpaceDescriptor
118 (EFI_SET_MEMORY_SPACE_ATTRIBUTES) CoreSetMemorySpaceAttributes, // SetMemorySpaceAttributes
119 (EFI_GET_MEMORY_SPACE_MAP) CoreGetMemorySpaceMap, // GetMemorySpaceMap
120 (EFI_ADD_IO_SPACE) CoreAddIoSpace, // AddIoSpace
121 (EFI_ALLOCATE_IO_SPACE) CoreAllocateIoSpace, // AllocateIoSpace
122 (EFI_FREE_IO_SPACE) CoreFreeIoSpace, // FreeIoSpace
123 (EFI_REMOVE_IO_SPACE) CoreRemoveIoSpace, // RemoveIoSpace
124 (EFI_GET_IO_SPACE_DESCRIPTOR) CoreGetIoSpaceDescriptor, // GetIoSpaceDescriptor
125 (EFI_GET_IO_SPACE_MAP) CoreGetIoSpaceMap, // GetIoSpaceMap
126 (EFI_DISPATCH) CoreDispatcher, // Dispatch
127 (EFI_SCHEDULE) CoreSchedule, // Schedule
128 (EFI_TRUST) CoreTrust, // Trust
129 (EFI_PROCESS_FIRMWARE_VOLUME) CoreProcessFirmwareVolume, // ProcessFirmwareVolume
130 };
131
132 EFI_SYSTEM_TABLE mEfiSystemTableTemplate = {
133 {
134 EFI_SYSTEM_TABLE_SIGNATURE, // Signature
135 EFI_SYSTEM_TABLE_REVISION, // Revision
136 sizeof (EFI_SYSTEM_TABLE), // HeaderSize
137 0, // CRC32
138 0 // Reserved
139 },
140 NULL, // FirmwareVendor
141 0, // FirmwareRevision
142 NULL, // ConsoleInHandle
143 NULL, // ConIn
144 NULL, // ConsoleOutHandle
145 NULL, // ConOut
146 NULL, // StandardErrorHandle
147 NULL, // StdErr
148 NULL, // RuntimeServices
149 &mBootServices, // BootServices
150 0, // NumberOfConfigurationTableEntries
151 NULL // ConfigurationTable
152 };
153
154 EFI_RUNTIME_SERVICES mEfiRuntimeServicesTableTemplate = {
155 {
156 EFI_RUNTIME_SERVICES_SIGNATURE, // Signature
157 EFI_RUNTIME_SERVICES_REVISION, // Revision
158 sizeof (EFI_RUNTIME_SERVICES), // HeaderSize
159 0, // CRC32
160 0 // Reserved
161 },
162 (EFI_GET_TIME) CoreEfiNotAvailableYetArg2, // GetTime
163 (EFI_SET_TIME) CoreEfiNotAvailableYetArg1, // SetTime
164 (EFI_GET_WAKEUP_TIME) CoreEfiNotAvailableYetArg3, // GetWakeupTime
165 (EFI_SET_WAKEUP_TIME) CoreEfiNotAvailableYetArg2, // SetWakeupTime
166 (EFI_SET_VIRTUAL_ADDRESS_MAP) CoreEfiNotAvailableYetArg4, // SetVirtualAddressMap
167 (EFI_CONVERT_POINTER) CoreEfiNotAvailableYetArg2, // ConvertPointer
168 (EFI_GET_VARIABLE) CoreEfiNotAvailableYetArg5, // GetVariable
169 (EFI_GET_NEXT_VARIABLE_NAME) CoreEfiNotAvailableYetArg3, // GetNextVariableName
170 (EFI_SET_VARIABLE) CoreEfiNotAvailableYetArg5, // SetVariable
171 (EFI_GET_NEXT_HIGH_MONO_COUNT) CoreEfiNotAvailableYetArg1, // GetNextHighMonotonicCount
172 (EFI_RESET_SYSTEM) CoreEfiNotAvailableYetArg4, // ResetSystem
173 (EFI_UPDATE_CAPSULE) CoreEfiNotAvailableYetArg3, // UpdateCapsule
174 (EFI_QUERY_CAPSULE_CAPABILITIES) CoreEfiNotAvailableYetArg4, // QueryCapsuleCapabilities
175 (EFI_QUERY_VARIABLE_INFO) CoreEfiNotAvailableYetArg4 // QueryVariableInfo
176 };
177
178 EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate = {
179 INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.ImageHead),
180 INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.EventHead),
181
182 //
183 // Make sure Size != sizeof (EFI_MEMORY_DESCRIPTOR). This will
184 // prevent people from having pointer math bugs in their code.
185 // now you have to use *DescriptorSize to make things work.
186 //
187 sizeof (EFI_MEMORY_DESCRIPTOR) + sizeof (UINT64) - (sizeof (EFI_MEMORY_DESCRIPTOR) % sizeof (UINT64)),
188 EFI_MEMORY_DESCRIPTOR_VERSION,
189 0,
190 NULL,
191 NULL,
192 FALSE,
193 FALSE
194 };
195
196 EFI_RUNTIME_ARCH_PROTOCOL *gRuntime = &gRuntimeTemplate;
197
198 //
199 // DXE Core Global Variables for the EFI System Table, Boot Services Table,
200 // DXE Services Table, and Runtime Services Table
201 //
202 EFI_DXE_SERVICES *gDxeCoreDS = &mDxeServices;
203 EFI_SYSTEM_TABLE *gDxeCoreST = NULL;
204
205 //
206 // For debug initialize gDxeCoreRT to template. gDxeCoreRT must be allocated from RT memory
207 // but gDxeCoreRT is used for ASSERT () and DEBUG () type macros so lets give it
208 // a value that will not cause debug infrastructure to crash early on.
209 //
210 EFI_RUNTIME_SERVICES *gDxeCoreRT = &mEfiRuntimeServicesTableTemplate;
211 EFI_HANDLE gDxeCoreImageHandle = NULL;
212
213
214 //
215 // EFI Decompress Protocol
216 //
217 EFI_DECOMPRESS_PROTOCOL gEfiDecompress = {
218 DxeMainUefiDecompressGetInfo,
219 DxeMainUefiDecompress
220 };
221
222 //
223 // Main entry point to the DXE Core
224 //
225
226 /**
227 Main entry point to DXE Core.
228
229 @param HobStart Pointer to the beginning of the HOB List from PEI.
230
231 @return This function should never return.
232
233 **/
234 VOID
235 EFIAPI
236 DxeMain (
237 IN VOID *HobStart
238 )
239 {
240 EFI_STATUS Status;
241 EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
242 UINT64 MemoryLength;
243
244 //
245 // Initialize Memory Services
246 //
247 CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength);
248
249 //
250 // Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData
251 // Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table
252 //
253 gDxeCoreST = CoreAllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate);
254 ASSERT (gDxeCoreST != NULL);
255
256 gDxeCoreRT = CoreAllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate);
257 ASSERT (gDxeCoreRT != NULL);
258
259 gDxeCoreST->RuntimeServices = gDxeCoreRT;
260
261 //
262 // Start the Image Services.
263 //
264 Status = CoreInitializeImageServices (HobStart);
265 ASSERT_EFI_ERROR (Status);
266
267 //
268 // Call constructor for all libraries
269 //
270 ProcessLibraryConstructorList (gDxeCoreImageHandle, gDxeCoreST);
271 PERF_END (0,PEI_TOK, NULL, 0) ;
272 PERF_START (0,DXE_TOK, NULL, 0) ;
273
274 //
275 // Initialize the Global Coherency Domain Services
276 //
277 Status = CoreInitializeGcdServices (&HobStart, MemoryBaseAddress, MemoryLength);
278 ASSERT_EFI_ERROR (Status);
279
280 //
281 // Install the DXE Services Table into the EFI System Tables's Configuration Table
282 //
283 Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDxeCoreDS);
284 ASSERT_EFI_ERROR (Status);
285
286 //
287 // Install the HOB List into the EFI System Tables's Configuration Table
288 //
289 Status = CoreInstallConfigurationTable (&gEfiHobListGuid, HobStart);
290 ASSERT_EFI_ERROR (Status);
291
292 //
293 // Install Memory Type Information Table into the EFI System Tables's Configuration Table
294 //
295 Status = CoreInstallConfigurationTable (&gEfiMemoryTypeInformationGuid, &gMemoryTypeInformation);
296 ASSERT_EFI_ERROR (Status);
297
298 //
299 // Initialize the ReportStatusCode with PEI version, if available
300 //
301 CoreGetPeiProtocol (&gEfiStatusCodeRuntimeProtocolGuid, (VOID **) &gStatusCode->ReportStatusCode);
302
303 //
304 // Report Status Code here for DXE_ENTRY_POINT once it is available
305 //
306 CoreReportProgressCode (FixedPcdGet32(PcdStatusCodeValueDxeCoreEntry));
307
308 //
309 // Create the aligned system table pointer structure that is used by external
310 // debuggers to locate the system table... Also, install debug image info
311 // configuration table.
312 //
313 CoreInitializeDebugImageInfoTable ();
314 CoreNewDebugImageInfoEntry (
315 EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,
316 gDxeCoreLoadedImage,
317 gDxeCoreImageHandle
318 );
319
320 DEBUG ((DEBUG_INFO | DEBUG_LOAD, "HOBLIST address in DXE = 0x%p\n", HobStart));
321
322 //
323 // Initialize the Event Services
324 //
325 Status = CoreInitializeEventServices ();
326 ASSERT_EFI_ERROR (Status);
327
328
329 //
330 // Get the Protocols that were passed in from PEI to DXE through GUIDed HOBs
331 //
332 // These Protocols are not architectural. This implementation is sharing code between
333 // PEI and DXE in order to save FLASH space. These Protocols could also be implemented
334 // as part of the DXE Core. However, that would also require the DXE Core to be ported
335 // each time a different CPU is used, a different Decompression algorithm is used, or a
336 // different Image type is used. By placing these Protocols in PEI, the DXE Core remains
337 // generic, and only PEI and the Arch Protocols need to be ported from Platform to Platform,
338 // and from CPU to CPU.
339 //
340
341 //
342 // Publish the EFI, Tiano, and Custom Decompress protocols for use by other DXE components
343 //
344 Status = CoreInstallMultipleProtocolInterfaces (
345 &mDecompressHandle,
346 &gEfiDecompressProtocolGuid, &gEfiDecompress,
347 NULL
348 );
349 ASSERT_EFI_ERROR (Status);
350
351 //
352 // Register for the GUIDs of the Architectural Protocols, so the rest of the
353 // EFI Boot Services and EFI Runtime Services tables can be filled in.
354 //
355 CoreNotifyOnArchProtocolInstallation ();
356
357 //
358 // Produce Firmware Volume Protocols, one for each FV in the HOB list.
359 //
360 Status = FwVolBlockDriverInit (gDxeCoreImageHandle, gDxeCoreST);
361 ASSERT_EFI_ERROR (Status);
362
363 Status = FwVolDriverInit (gDxeCoreImageHandle, gDxeCoreST);
364 ASSERT_EFI_ERROR (Status);
365
366 //
367 // Produce the Section Extraction Protocol
368 //
369 Status = InitializeSectionExtraction (gDxeCoreImageHandle, gDxeCoreST);
370 ASSERT_EFI_ERROR (Status);
371
372 //
373 // Initialize the DXE Dispatcher
374 //
375 PERF_START (0,"CoreInitializeDispatcher", "DxeMain", 0) ;
376 CoreInitializeDispatcher ();
377 PERF_END (0,"CoreInitializeDispatcher", "DxeMain", 0) ;
378
379 //
380 // Invoke the DXE Dispatcher
381 //
382 PERF_START (0, "CoreDispatcher", "DxeMain", 0);
383 CoreDispatcher ();
384 PERF_END (0, "CoreDispatcher", "DxeMain", 0);
385
386 //
387 // Display Architectural protocols that were not loaded if this is DEBUG build
388 //
389 DEBUG_CODE_BEGIN ();
390 CoreDisplayMissingArchProtocols ();
391 DEBUG_CODE_END ();
392
393 //
394 // Assert if the Architectural Protocols are not present.
395 //
396 ASSERT_EFI_ERROR (CoreAllEfiServicesAvailable ());
397
398 //
399 // Report Status code before transfer control to BDS
400 //
401 CoreReportProgressCode (FixedPcdGet32 (PcdStatusCodeValueDxeCoreHandoffToBds));
402
403 //
404 // Display any drivers that were not dispatched because dependency expression
405 // evaluated to false if this is a debug build
406 //
407 DEBUG_CODE_BEGIN ();
408 CoreDisplayDiscoveredNotDispatched ();
409 DEBUG_CODE_END ();
410
411 //
412 // Transfer control to the BDS Architectural Protocol
413 //
414 gBds->Entry (gBds);
415
416 //
417 // BDS should never return
418 //
419 ASSERT (FALSE);
420 CpuDeadLoop ();
421 }
422
423
424
425 /**
426 Place holder function until all the Boot Services and Runtime Services are
427 available.
428
429 @return EFI_NOT_AVAILABLE_YET
430
431 **/
432 EFI_STATUS
433 EFIAPI
434 CoreEfiNotAvailableYetArg0 (
435 VOID
436 )
437 {
438 //
439 // This function should never be executed. If it does, then the architectural protocols
440 // have not been designed correctly. The CpuBreakpoint () is commented out for now until the
441 // DXE Core and all the Architectural Protocols are complete.
442 //
443
444 return EFI_NOT_AVAILABLE_YET;
445 }
446
447
448 /**
449 Place holder function until all the Boot Services and Runtime Services are
450 available.
451
452 @param Arg1 Undefined
453
454 @return EFI_NOT_AVAILABLE_YET
455
456 **/
457 EFI_STATUS
458 EFIAPI
459 CoreEfiNotAvailableYetArg1 (
460 UINTN Arg1
461 )
462 {
463 //
464 // This function should never be executed. If it does, then the architectural protocols
465 // have not been designed correctly. The CpuBreakpoint () is commented out for now until the
466 // DXE Core and all the Architectural Protocols are complete.
467 //
468
469 return EFI_NOT_AVAILABLE_YET;
470 }
471
472
473 /**
474 Place holder function until all the Boot Services and Runtime Services are available.
475
476 @param Arg1 Undefined
477 @param Arg2 Undefined
478
479 @return EFI_NOT_AVAILABLE_YET
480
481 **/
482 EFI_STATUS
483 EFIAPI
484 CoreEfiNotAvailableYetArg2 (
485 UINTN Arg1,
486 UINTN Arg2
487 )
488 {
489 //
490 // This function should never be executed. If it does, then the architectural protocols
491 // have not been designed correctly. The CpuBreakpoint () is commented out for now until the
492 // DXE Core and all the Architectural Protocols are complete.
493 //
494
495 return EFI_NOT_AVAILABLE_YET;
496 }
497
498
499 /**
500 Place holder function until all the Boot Services and Runtime Services are available.
501
502 @param Arg1 Undefined
503 @param Arg2 Undefined
504 @param Arg3 Undefined
505
506 @return EFI_NOT_AVAILABLE_YET
507
508 **/
509 EFI_STATUS
510 EFIAPI
511 CoreEfiNotAvailableYetArg3 (
512 UINTN Arg1,
513 UINTN Arg2,
514 UINTN Arg3
515 )
516 {
517 //
518 // This function should never be executed. If it does, then the architectural protocols
519 // have not been designed correctly. The CpuBreakpoint () is commented out for now until the
520 // DXE Core and all the Architectural Protocols are complete.
521 //
522
523 return EFI_NOT_AVAILABLE_YET;
524 }
525
526
527 /**
528 Place holder function until all the Boot Services and Runtime Services are available.
529
530 @param Arg1 Undefined
531 @param Arg2 Undefined
532 @param Arg3 Undefined
533 @param Arg4 Undefined
534
535 @return EFI_NOT_AVAILABLE_YET
536
537 **/
538 EFI_STATUS
539 EFIAPI
540 CoreEfiNotAvailableYetArg4 (
541 UINTN Arg1,
542 UINTN Arg2,
543 UINTN Arg3,
544 UINTN Arg4
545 )
546 {
547 //
548 // This function should never be executed. If it does, then the architectural protocols
549 // have not been designed correctly. The CpuBreakpoint () is commented out for now until the
550 // DXE Core and all the Architectural Protocols are complete.
551 //
552
553 return EFI_NOT_AVAILABLE_YET;
554 }
555
556
557 /**
558 Place holder function until all the Boot Services and Runtime Services are available.
559
560 @param Arg1 Undefined
561 @param Arg2 Undefined
562 @param Arg3 Undefined
563 @param Arg4 Undefined
564 @param Arg5 Undefined
565
566 @return EFI_NOT_AVAILABLE_YET
567
568 **/
569 EFI_STATUS
570 EFIAPI
571 CoreEfiNotAvailableYetArg5 (
572 UINTN Arg1,
573 UINTN Arg2,
574 UINTN Arg3,
575 UINTN Arg4,
576 UINTN Arg5
577 )
578 {
579 //
580 // This function should never be executed. If it does, then the architectural protocols
581 // have not been designed correctly. The CpuBreakpoint () is commented out for now until the
582 // DXE Core and all the Architectural Protocols are complete.
583 //
584
585 return EFI_NOT_AVAILABLE_YET;
586 }
587
588
589
590 /**
591 Searches for a Protocol Interface passed from PEI through a HOB.
592
593 @param ProtocolGuid The Protocol GUID to search for in the HOB List
594 @param Interface A pointer to the interface for the Protocol GUID
595
596 @retval EFI_SUCCESS The Protocol GUID was found and its interface is
597 returned in Interface
598 @retval EFI_NOT_FOUND The Protocol GUID was not found in the HOB List
599
600 **/
601 EFI_STATUS
602 CoreGetPeiProtocol (
603 IN EFI_GUID *ProtocolGuid,
604 IN VOID **Interface
605 )
606 {
607 EFI_HOB_GUID_TYPE *GuidHob;
608 VOID *Buffer;
609
610 GuidHob = GetFirstGuidHob (ProtocolGuid);
611 if (GuidHob == NULL) {
612 return EFI_NOT_FOUND;
613 }
614
615 Buffer = GET_GUID_HOB_DATA (GuidHob);
616 ASSERT (Buffer != NULL);
617
618 *Interface = (VOID *)(*(UINTN *)(Buffer));
619
620 return EFI_SUCCESS;
621 }
622
623
624
625 /**
626 Calcualte the 32-bit CRC in a EFI table using the service provided by the
627 gRuntime service.
628
629 @param Hdr Pointer to an EFI standard header
630
631 **/
632 VOID
633 CalculateEfiHdrCrc (
634 IN OUT EFI_TABLE_HEADER *Hdr
635 )
636 {
637 UINT32 Crc;
638
639 Hdr->CRC32 = 0;
640
641 //
642 // If gBS->CalculateCrce32 () == CoreEfiNotAvailableYet () then
643 // Crc will come back as zero if we set it to zero here
644 //
645 Crc = 0;
646 gBS->CalculateCrc32 ((UINT8 *)Hdr, Hdr->HeaderSize, &Crc);
647 Hdr->CRC32 = Crc;
648 }
649
650
651
652
653 /**
654 Terminates all boot services.
655
656 @param ImageHandle Handle that identifies the exiting image.
657 @param MapKey Key to the latest memory map.
658
659 @retval EFI_SUCCESS Boot Services terminated
660 @retval EFI_INVALID_PARAMETER MapKey is incorrect.
661
662 **/
663 EFI_STATUS
664 EFIAPI
665 CoreExitBootServices (
666 IN EFI_HANDLE ImageHandle,
667 IN UINTN MapKey
668 )
669 {
670 EFI_STATUS Status;
671 EFI_STATUS StatusTemp;
672 EFI_TCG_PLATFORM_PROTOCOL *TcgPlatformProtocol;
673
674 //
675 // Measure invocation of ExitBootServices,
676 // which is defined by TCG_EFI_Platform_1_20_Final Specification
677 //
678 TcgPlatformProtocol = NULL;
679 Status = CoreLocateProtocol (
680 &gEfiTcgPlatformProtocolGuid,
681 NULL,
682 (VOID **) &TcgPlatformProtocol
683 );
684 if (!EFI_ERROR (Status)) {
685 Status = TcgPlatformProtocol->MeasureAction (EFI_EXIT_BOOT_SERVICES_INVOCATION);
686 ASSERT_EFI_ERROR (Status);
687 }
688
689 //
690 // Terminate memory services if the MapKey matches
691 //
692 Status = CoreTerminateMemoryMap (MapKey);
693 if (EFI_ERROR (Status)) {
694 //
695 // Measure failure of ExitBootServices
696 //
697 if (TcgPlatformProtocol != NULL) {
698 StatusTemp = TcgPlatformProtocol->MeasureAction (EFI_EXIT_BOOT_SERVICES_FAILED);
699 ASSERT_EFI_ERROR (StatusTemp);
700 }
701
702 return Status;
703 }
704
705 //
706 // Notify other drivers that we are exiting boot services.
707 //
708 CoreNotifySignalList (&gEfiEventExitBootServicesGuid);
709
710 //
711 // Disable Timer
712 //
713 gTimer->SetTimerPeriod (gTimer, 0);
714
715 //
716 // Disable CPU Interrupts
717 //
718 gCpu->DisableInterrupt (gCpu);
719
720 //
721 // Report that ExitBootServices() has been called
722 //
723 // We are using gEfiCallerIdGuid as the caller ID for Dxe Core
724 //
725 CoreReportProgressCode (FixedPcdGet32 (PcdStatusCodeValueBootServiceExit));
726
727 //
728 // Clear the non-runtime values of the EFI System Table
729 //
730 gDxeCoreST->BootServices = NULL;
731 gDxeCoreST->ConIn = NULL;
732 gDxeCoreST->ConsoleInHandle = NULL;
733 gDxeCoreST->ConOut = NULL;
734 gDxeCoreST->ConsoleOutHandle = NULL;
735 gDxeCoreST->StdErr = NULL;
736 gDxeCoreST->StandardErrorHandle = NULL;
737
738 //
739 // Recompute the 32-bit CRC of the EFI System Table
740 //
741 CalculateEfiHdrCrc (&gDxeCoreST->Hdr);
742
743 //
744 // Zero out the Boot Service Table
745 //
746 ZeroMem (gBS, sizeof (EFI_BOOT_SERVICES));
747 gBS = NULL;
748
749 //
750 // Update the AtRuntime field in Runtiem AP.
751 //
752 gRuntime->AtRuntime = TRUE;
753
754 //
755 // Measure success of ExitBootServices
756 //
757 if (TcgPlatformProtocol != NULL) {
758 StatusTemp = TcgPlatformProtocol->MeasureAction (EFI_EXIT_BOOT_SERVICES_SUCCEEDED);
759 ASSERT_EFI_ERROR (StatusTemp);
760 }
761
762 return Status;
763 }
764
765
766 /**
767 Given a compressed source buffer, this function retrieves the size of the
768 uncompressed buffer and the size of the scratch buffer required to decompress
769 the compressed source buffer.
770
771 The GetInfo() function retrieves the size of the uncompressed buffer and the
772 temporary scratch buffer required to decompress the buffer specified by Source
773 and SourceSize. If the size of the uncompressed buffer or the size of the
774 scratch buffer cannot be determined from the compressed data specified by
775 Source and SourceData, then EFI_INVALID_PARAMETER is returned. Otherwise, the
776 size of the uncompressed buffer is returned in DestinationSize, the size of
777 the scratch buffer is returned in ScratchSize, and EFI_SUCCESS is returned.
778 The GetInfo() function does not have scratch buffer available to perform a
779 thorough checking of the validity of the source data. It just retrieves the
780 "Original Size" field from the beginning bytes of the source data and output
781 it as DestinationSize. And ScratchSize is specific to the decompression
782 implementation.
783
784 @param This A pointer to the EFI_DECOMPRESS_PROTOCOL instance.
785 @param Source The source buffer containing the compressed data.
786 @param SourceSize The size, in bytes, of the source buffer.
787 @param DestinationSize A pointer to the size, in bytes, of the
788 uncompressed buffer that will be generated when the
789 compressed buffer specified by Source and
790 SourceSize is decompressed.
791 @param ScratchSize A pointer to the size, in bytes, of the scratch
792 buffer that is required to decompress the
793 compressed buffer specified by Source and
794 SourceSize.
795
796 @retval EFI_SUCCESS The size of the uncompressed data was returned in
797 DestinationSize and the size of the scratch buffer
798 was returned in ScratchSize.
799 @retval EFI_INVALID_PARAMETER The size of the uncompressed data or the size of
800 the scratch buffer cannot be determined from the
801 compressed data specified by Source and
802 SourceSize.
803
804 **/
805 EFI_STATUS
806 EFIAPI
807 DxeMainUefiDecompressGetInfo (
808 IN EFI_DECOMPRESS_PROTOCOL *This,
809 IN VOID *Source,
810 IN UINT32 SourceSize,
811 OUT UINT32 *DestinationSize,
812 OUT UINT32 *ScratchSize
813 )
814 {
815 if (Source == NULL || DestinationSize == NULL || ScratchSize == NULL) {
816 return EFI_INVALID_PARAMETER;
817 }
818 return UefiDecompressGetInfo (Source, SourceSize, DestinationSize, ScratchSize);
819 }
820
821
822 /**
823 Decompresses a compressed source buffer.
824
825 The Decompress() function extracts decompressed data to its original form.
826 This protocol is designed so that the decompression algorithm can be
827 implemented without using any memory services. As a result, the Decompress()
828 Function is not allowed to call AllocatePool() or AllocatePages() in its
829 implementation. It is the caller's responsibility to allocate and free the
830 Destination and Scratch buffers.
831 If the compressed source data specified by Source and SourceSize is
832 sucessfully decompressed into Destination, then EFI_SUCCESS is returned. If
833 the compressed source data specified by Source and SourceSize is not in a
834 valid compressed data format, then EFI_INVALID_PARAMETER is returned.
835
836 @param This A pointer to the EFI_DECOMPRESS_PROTOCOL instance.
837 @param Source The source buffer containing the compressed data.
838 @param SourceSize SourceSizeThe size of source data.
839 @param Destination On output, the destination buffer that contains
840 the uncompressed data.
841 @param DestinationSize The size of the destination buffer. The size of
842 the destination buffer needed is obtained from
843 EFI_DECOMPRESS_PROTOCOL.GetInfo().
844 @param Scratch A temporary scratch buffer that is used to perform
845 the decompression.
846 @param ScratchSize The size of scratch buffer. The size of the
847 scratch buffer needed is obtained from GetInfo().
848
849 @retval EFI_SUCCESS Decompression completed successfully, and the
850 uncompressed buffer is returned in Destination.
851 @retval EFI_INVALID_PARAMETER The source buffer specified by Source and
852 SourceSize is corrupted (not in a valid
853 compressed format).
854
855 **/
856 EFI_STATUS
857 EFIAPI
858 DxeMainUefiDecompress (
859 IN EFI_DECOMPRESS_PROTOCOL *This,
860 IN VOID *Source,
861 IN UINT32 SourceSize,
862 IN OUT VOID *Destination,
863 IN UINT32 DestinationSize,
864 IN OUT VOID *Scratch,
865 IN UINT32 ScratchSize
866 )
867 {
868 EFI_STATUS Status;
869 UINT32 TestDestinationSize;
870 UINT32 TestScratchSize;
871
872 if (Source == NULL || Destination== NULL || Scratch == NULL) {
873 return EFI_INVALID_PARAMETER;
874 }
875
876 Status = UefiDecompressGetInfo (Source, SourceSize, &TestDestinationSize, &TestScratchSize);
877 if (EFI_ERROR (Status)) {
878 return Status;
879 }
880
881 if (ScratchSize < TestScratchSize || DestinationSize < TestDestinationSize) {
882 return RETURN_INVALID_PARAMETER;
883 }
884
885 return UefiDecompress (Source, Destination, Scratch);
886 }