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