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