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 BOOLEAN               gMemoryMapTerminated = FALSE;
211 
212 //
213 // EFI Decompress Protocol
214 //
215 EFI_DECOMPRESS_PROTOCOL  gEfiDecompress = {
216   DxeMainUefiDecompressGetInfo,
217   DxeMainUefiDecompress
218 };
219 
220 //
221 // For Loading modules at fixed address feature, the configuration table is to cache the top address below which to load
222 // Runtime code&boot time code
223 //
224 GLOBAL_REMOVE_IF_UNREFERENCED EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE    gLoadModuleAtFixAddressConfigurationTable = {0, 0};
225 
226 // Main entry point to the DXE Core
227 //
228 
229 /**
230   Main entry point to DXE Core.
231 
232   @param  HobStart               Pointer to the beginning of the HOB List from PEI.
233 
234   @return This function should never return.
235 
236 **/
237 VOID
238 EFIAPI
DxeMain(IN VOID * HobStart)239 DxeMain (
240   IN  VOID *HobStart
241   )
242 {
243   EFI_STATUS                    Status;
244   EFI_PHYSICAL_ADDRESS          MemoryBaseAddress;
245   UINT64                        MemoryLength;
246   PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;
247   UINTN                         Index;
248   EFI_HOB_GUID_TYPE             *GuidHob;
249   EFI_VECTOR_HANDOFF_INFO       *VectorInfoList;
250   EFI_VECTOR_HANDOFF_INFO       *VectorInfo;
251   VOID                          *EntryPoint;
252 
253   //
254   // Setup the default exception handlers
255   //
256   VectorInfoList = NULL;
257   GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart);
258   if (GuidHob != NULL) {
259     VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob));
260   }
261   Status = InitializeCpuExceptionHandlers (VectorInfoList);
262   ASSERT_EFI_ERROR (Status);
263 
264   //
265   // Initialize Debug Agent to support source level debug in DXE phase
266   //
267   InitializeDebugAgent (DEBUG_AGENT_INIT_DXE_CORE, HobStart, NULL);
268 
269   //
270   // Initialize Memory Services
271   //
272   CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength);
273 
274   MemoryProfileInit (HobStart);
275 
276   //
277   // Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData
278   // Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table
279   //
280   gDxeCoreST = AllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate);
281   ASSERT (gDxeCoreST != NULL);
282 
283   gDxeCoreRT = AllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate);
284   ASSERT (gDxeCoreRT != NULL);
285 
286   gDxeCoreST->RuntimeServices = gDxeCoreRT;
287 
288   //
289   // Start the Image Services.
290   //
291   Status = CoreInitializeImageServices (HobStart);
292   ASSERT_EFI_ERROR (Status);
293 
294   //
295   // Initialize the Global Coherency Domain Services
296   //
297   Status = CoreInitializeGcdServices (&HobStart, MemoryBaseAddress, MemoryLength);
298   ASSERT_EFI_ERROR (Status);
299 
300   //
301   // Call constructor for all libraries
302   //
303   ProcessLibraryConstructorList (gDxeCoreImageHandle, gDxeCoreST);
304   PERF_END   (NULL,"PEI", NULL, 0) ;
305   PERF_START (NULL,"DXE", NULL, 0) ;
306 
307   //
308   // Report DXE Core image information to the PE/COFF Extra Action Library
309   //
310   ZeroMem (&ImageContext, sizeof (ImageContext));
311   ImageContext.ImageAddress   = (EFI_PHYSICAL_ADDRESS)(UINTN)gDxeCoreLoadedImage->ImageBase;
312   ImageContext.PdbPointer     = PeCoffLoaderGetPdbPointer ((VOID*)(UINTN)ImageContext.ImageAddress);
313   ImageContext.SizeOfHeaders  = PeCoffGetSizeOfHeaders ((VOID*)(UINTN)ImageContext.ImageAddress);
314   Status = PeCoffLoaderGetEntryPoint ((VOID*)(UINTN)ImageContext.ImageAddress, &EntryPoint);
315   if (Status == EFI_SUCCESS) {
316     ImageContext.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)EntryPoint;
317   }
318   ImageContext.Handle         = (VOID *)(UINTN)gDxeCoreLoadedImage->ImageBase;
319   ImageContext.ImageRead      = PeCoffLoaderImageReadFromMemory;
320   PeCoffLoaderRelocateImageExtraAction (&ImageContext);
321 
322   //
323   // Install the DXE Services Table into the EFI System Tables's Configuration Table
324   //
325   Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDxeCoreDS);
326   ASSERT_EFI_ERROR (Status);
327 
328   //
329   // Install the HOB List into the EFI System Tables's Configuration Table
330   //
331   Status = CoreInstallConfigurationTable (&gEfiHobListGuid, HobStart);
332   ASSERT_EFI_ERROR (Status);
333 
334   //
335   // Install Memory Type Information Table into the EFI System Tables's Configuration Table
336   //
337   Status = CoreInstallConfigurationTable (&gEfiMemoryTypeInformationGuid, &gMemoryTypeInformation);
338   ASSERT_EFI_ERROR (Status);
339 
340   //
341   // If Loading modules At fixed address feature is enabled, install Load moduels at fixed address
342   // Configuration Table so that user could easily to retrieve the top address to load Dxe and PEI
343   // Code and Tseg base to load SMM driver.
344   //
345   if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {
346     Status = CoreInstallConfigurationTable (&gLoadFixedAddressConfigurationTableGuid, &gLoadModuleAtFixAddressConfigurationTable);
347     ASSERT_EFI_ERROR (Status);
348   }
349   //
350   // Report Status Code here for DXE_ENTRY_POINT once it is available
351   //
352   REPORT_STATUS_CODE (
353     EFI_PROGRESS_CODE,
354     (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT)
355     );
356 
357   //
358   // Create the aligned system table pointer structure that is used by external
359   // debuggers to locate the system table...  Also, install debug image info
360   // configuration table.
361   //
362   CoreInitializeDebugImageInfoTable ();
363   CoreNewDebugImageInfoEntry (
364     EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,
365     gDxeCoreLoadedImage,
366     gDxeCoreImageHandle
367     );
368 
369   DEBUG ((DEBUG_INFO | DEBUG_LOAD, "HOBLIST address in DXE = 0x%p\n", HobStart));
370 
371   DEBUG_CODE_BEGIN ();
372     EFI_PEI_HOB_POINTERS               Hob;
373 
374     for (Hob.Raw = HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
375       if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
376         DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Memory Allocation 0x%08x 0x%0lx - 0x%0lx\n", \
377           Hob.MemoryAllocation->AllocDescriptor.MemoryType,                      \
378           Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress,               \
379           Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress + Hob.MemoryAllocation->AllocDescriptor.MemoryLength - 1));
380       }
381     }
382     for (Hob.Raw = HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
383       if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV2) {
384         DEBUG ((DEBUG_INFO | DEBUG_LOAD, "FV2 Hob           0x%0lx - 0x%0lx\n", Hob.FirmwareVolume2->BaseAddress, Hob.FirmwareVolume2->BaseAddress + Hob.FirmwareVolume2->Length - 1));
385       } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) {
386         DEBUG ((DEBUG_INFO | DEBUG_LOAD, "FV Hob            0x%0lx - 0x%0lx\n", Hob.FirmwareVolume->BaseAddress, Hob.FirmwareVolume->BaseAddress + Hob.FirmwareVolume->Length - 1));
387       }
388     }
389   DEBUG_CODE_END ();
390 
391   //
392   // Initialize the Event Services
393   //
394   Status = CoreInitializeEventServices ();
395   ASSERT_EFI_ERROR (Status);
396 
397   MemoryProfileInstallProtocol ();
398 
399   CoreInitializePropertiesTable ();
400   CoreInitializeMemoryAttributesTable ();
401 
402   //
403   // Get persisted vector hand-off info from GUIDeed HOB again due to HobStart may be updated,
404   // and install configuration table
405   //
406   GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart);
407   if (GuidHob != NULL) {
408     VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob));
409     VectorInfo = VectorInfoList;
410     Index = 1;
411     while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {
412       VectorInfo ++;
413       Index ++;
414     }
415     VectorInfo = AllocateCopyPool (sizeof (EFI_VECTOR_HANDOFF_INFO) * Index, (VOID *) VectorInfoList);
416     ASSERT (VectorInfo != NULL);
417     Status = CoreInstallConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID *) VectorInfo);
418     ASSERT_EFI_ERROR (Status);
419   }
420 
421   //
422   // Get the Protocols that were passed in from PEI to DXE through GUIDed HOBs
423   //
424   // These Protocols are not architectural. This implementation is sharing code between
425   // PEI and DXE in order to save FLASH space. These Protocols could also be implemented
426   // as part of the DXE Core. However, that would also require the DXE Core to be ported
427   // each time a different CPU is used, a different Decompression algorithm is used, or a
428   // different Image type is used. By placing these Protocols in PEI, the DXE Core remains
429   // generic, and only PEI and the Arch Protocols need to be ported from Platform to Platform,
430   // and from CPU to CPU.
431   //
432 
433   //
434   // Publish the EFI, Tiano, and Custom Decompress protocols for use by other DXE components
435   //
436   Status = CoreInstallMultipleProtocolInterfaces (
437              &mDecompressHandle,
438              &gEfiDecompressProtocolGuid,           &gEfiDecompress,
439              NULL
440              );
441   ASSERT_EFI_ERROR (Status);
442 
443   //
444   // Register for the GUIDs of the Architectural Protocols, so the rest of the
445   // EFI Boot Services and EFI Runtime Services tables can be filled in.
446   // Also register for the GUIDs of optional protocols.
447   //
448   CoreNotifyOnProtocolInstallation ();
449 
450   //
451   // Produce Firmware Volume Protocols, one for each FV in the HOB list.
452   //
453   Status = FwVolBlockDriverInit (gDxeCoreImageHandle, gDxeCoreST);
454   ASSERT_EFI_ERROR (Status);
455 
456   Status = FwVolDriverInit (gDxeCoreImageHandle, gDxeCoreST);
457   ASSERT_EFI_ERROR (Status);
458 
459   //
460   // Produce the Section Extraction Protocol
461   //
462   Status = InitializeSectionExtraction (gDxeCoreImageHandle, gDxeCoreST);
463   ASSERT_EFI_ERROR (Status);
464 
465   //
466   // Initialize the DXE Dispatcher
467   //
468   PERF_START (NULL,"CoreInitializeDispatcher", "DxeMain", 0) ;
469   CoreInitializeDispatcher ();
470   PERF_END (NULL,"CoreInitializeDispatcher", "DxeMain", 0) ;
471 
472   //
473   // Invoke the DXE Dispatcher
474   //
475   PERF_START (NULL, "CoreDispatcher", "DxeMain", 0);
476   CoreDispatcher ();
477   PERF_END (NULL, "CoreDispatcher", "DxeMain", 0);
478 
479   //
480   // Display Architectural protocols that were not loaded if this is DEBUG build
481   //
482   DEBUG_CODE_BEGIN ();
483     CoreDisplayMissingArchProtocols ();
484   DEBUG_CODE_END ();
485 
486   //
487   // Display any drivers that were not dispatched because dependency expression
488   // evaluated to false if this is a debug build
489   //
490   DEBUG_CODE_BEGIN ();
491     CoreDisplayDiscoveredNotDispatched ();
492   DEBUG_CODE_END ();
493 
494   //
495   // Assert if the Architectural Protocols are not present.
496   //
497   Status = CoreAllEfiServicesAvailable ();
498   if (EFI_ERROR(Status)) {
499     //
500     // Report Status code that some Architectural Protocols are not present.
501     //
502     REPORT_STATUS_CODE (
503       EFI_ERROR_CODE | EFI_ERROR_MAJOR,
504       (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_EC_NO_ARCH)
505       );
506   }
507   ASSERT_EFI_ERROR (Status);
508 
509   //
510   // Report Status code before transfer control to BDS
511   //
512   REPORT_STATUS_CODE (
513     EFI_PROGRESS_CODE,
514     (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT)
515     );
516 
517   //
518   // Transfer control to the BDS Architectural Protocol
519   //
520   gBds->Entry (gBds);
521 
522   //
523   // BDS should never return
524   //
525   ASSERT (FALSE);
526   CpuDeadLoop ();
527 
528   UNREACHABLE ();
529 }
530 
531 
532 
533 /**
534   Place holder function until all the Boot Services and Runtime Services are
535   available.
536 
537   @return EFI_NOT_AVAILABLE_YET
538 
539 **/
540 EFI_STATUS
541 EFIAPI
CoreEfiNotAvailableYetArg0(VOID)542 CoreEfiNotAvailableYetArg0 (
543   VOID
544   )
545 {
546   //
547   // This function should never be executed.  If it does, then the architectural protocols
548   // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the
549   // DXE Core and all the Architectural Protocols are complete.
550   //
551 
552   return EFI_NOT_AVAILABLE_YET;
553 }
554 
555 
556 /**
557   Place holder function until all the Boot Services and Runtime Services are
558   available.
559 
560   @param  Arg1                   Undefined
561 
562   @return EFI_NOT_AVAILABLE_YET
563 
564 **/
565 EFI_STATUS
566 EFIAPI
CoreEfiNotAvailableYetArg1(UINTN Arg1)567 CoreEfiNotAvailableYetArg1 (
568   UINTN Arg1
569   )
570 {
571   //
572   // This function should never be executed.  If it does, then the architectural protocols
573   // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the
574   // DXE Core and all the Architectural Protocols are complete.
575   //
576 
577   return EFI_NOT_AVAILABLE_YET;
578 }
579 
580 
581 /**
582   Place holder function until all the Boot Services and Runtime Services are available.
583 
584   @param  Arg1                   Undefined
585   @param  Arg2                   Undefined
586 
587   @return EFI_NOT_AVAILABLE_YET
588 
589 **/
590 EFI_STATUS
591 EFIAPI
CoreEfiNotAvailableYetArg2(UINTN Arg1,UINTN Arg2)592 CoreEfiNotAvailableYetArg2 (
593   UINTN Arg1,
594   UINTN Arg2
595   )
596 {
597   //
598   // This function should never be executed.  If it does, then the architectural protocols
599   // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the
600   // DXE Core and all the Architectural Protocols are complete.
601   //
602 
603   return EFI_NOT_AVAILABLE_YET;
604 }
605 
606 
607 /**
608   Place holder function until all the Boot Services and Runtime Services are available.
609 
610   @param  Arg1                   Undefined
611   @param  Arg2                   Undefined
612   @param  Arg3                   Undefined
613 
614   @return EFI_NOT_AVAILABLE_YET
615 
616 **/
617 EFI_STATUS
618 EFIAPI
CoreEfiNotAvailableYetArg3(UINTN Arg1,UINTN Arg2,UINTN Arg3)619 CoreEfiNotAvailableYetArg3 (
620   UINTN Arg1,
621   UINTN Arg2,
622   UINTN Arg3
623   )
624 {
625   //
626   // This function should never be executed.  If it does, then the architectural protocols
627   // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the
628   // DXE Core and all the Architectural Protocols are complete.
629   //
630 
631   return EFI_NOT_AVAILABLE_YET;
632 }
633 
634 
635 /**
636   Place holder function until all the Boot Services and Runtime Services are available.
637 
638   @param  Arg1                   Undefined
639   @param  Arg2                   Undefined
640   @param  Arg3                   Undefined
641   @param  Arg4                   Undefined
642 
643   @return EFI_NOT_AVAILABLE_YET
644 
645 **/
646 EFI_STATUS
647 EFIAPI
CoreEfiNotAvailableYetArg4(UINTN Arg1,UINTN Arg2,UINTN Arg3,UINTN Arg4)648 CoreEfiNotAvailableYetArg4 (
649   UINTN Arg1,
650   UINTN Arg2,
651   UINTN Arg3,
652   UINTN Arg4
653   )
654 {
655   //
656   // This function should never be executed.  If it does, then the architectural protocols
657   // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the
658   // DXE Core and all the Architectural Protocols are complete.
659   //
660 
661   return EFI_NOT_AVAILABLE_YET;
662 }
663 
664 
665 /**
666   Place holder function until all the Boot Services and Runtime Services are available.
667 
668   @param  Arg1                   Undefined
669   @param  Arg2                   Undefined
670   @param  Arg3                   Undefined
671   @param  Arg4                   Undefined
672   @param  Arg5                   Undefined
673 
674   @return EFI_NOT_AVAILABLE_YET
675 
676 **/
677 EFI_STATUS
678 EFIAPI
CoreEfiNotAvailableYetArg5(UINTN Arg1,UINTN Arg2,UINTN Arg3,UINTN Arg4,UINTN Arg5)679 CoreEfiNotAvailableYetArg5 (
680   UINTN Arg1,
681   UINTN Arg2,
682   UINTN Arg3,
683   UINTN Arg4,
684   UINTN Arg5
685   )
686 {
687   //
688   // This function should never be executed.  If it does, then the architectural protocols
689   // have not been designed correctly.  The CpuBreakpoint () is commented out for now until the
690   // DXE Core and all the Architectural Protocols are complete.
691   //
692 
693   return EFI_NOT_AVAILABLE_YET;
694 }
695 
696 
697 /**
698   Calcualte the 32-bit CRC in a EFI table using the service provided by the
699   gRuntime service.
700 
701   @param  Hdr                    Pointer to an EFI standard header
702 
703 **/
704 VOID
CalculateEfiHdrCrc(IN OUT EFI_TABLE_HEADER * Hdr)705 CalculateEfiHdrCrc (
706   IN  OUT EFI_TABLE_HEADER    *Hdr
707   )
708 {
709   UINT32 Crc;
710 
711   Hdr->CRC32 = 0;
712 
713   //
714   // If gBS->CalculateCrce32 () == CoreEfiNotAvailableYet () then
715   //  Crc will come back as zero if we set it to zero here
716   //
717   Crc = 0;
718   gBS->CalculateCrc32 ((UINT8 *)Hdr, Hdr->HeaderSize, &Crc);
719   Hdr->CRC32 = Crc;
720 }
721 
722 
723 /**
724   Terminates all boot services.
725 
726   @param  ImageHandle            Handle that identifies the exiting image.
727   @param  MapKey                 Key to the latest memory map.
728 
729   @retval EFI_SUCCESS            Boot Services terminated
730   @retval EFI_INVALID_PARAMETER  MapKey is incorrect.
731 
732 **/
733 EFI_STATUS
734 EFIAPI
CoreExitBootServices(IN EFI_HANDLE ImageHandle,IN UINTN MapKey)735 CoreExitBootServices (
736   IN EFI_HANDLE   ImageHandle,
737   IN UINTN        MapKey
738   )
739 {
740   EFI_STATUS                Status;
741 
742   //
743   // Disable Timer
744   //
745   gTimer->SetTimerPeriod (gTimer, 0);
746 
747   //
748   // Terminate memory services if the MapKey matches
749   //
750   Status = CoreTerminateMemoryMap (MapKey);
751   if (EFI_ERROR (Status)) {
752     //
753     // Notify other drivers that ExitBootServices fail
754     //
755     CoreNotifySignalList (&gEventExitBootServicesFailedGuid);
756     return Status;
757   }
758 
759   gMemoryMapTerminated = TRUE;
760 
761   //
762   // Notify other drivers that we are exiting boot services.
763   //
764   CoreNotifySignalList (&gEfiEventExitBootServicesGuid);
765 
766   //
767   // Report that ExitBootServices() has been called
768   //
769   REPORT_STATUS_CODE (
770     EFI_PROGRESS_CODE,
771     (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)
772     );
773 
774   //
775   // Disable interrupt of Debug timer.
776   //
777   SaveAndSetDebugTimerInterrupt (FALSE);
778 
779   //
780   // Disable CPU Interrupts
781   //
782   gCpu->DisableInterrupt (gCpu);
783 
784   //
785   // Clear the non-runtime values of the EFI System Table
786   //
787   gDxeCoreST->BootServices        = NULL;
788   gDxeCoreST->ConIn               = NULL;
789   gDxeCoreST->ConsoleInHandle     = NULL;
790   gDxeCoreST->ConOut              = NULL;
791   gDxeCoreST->ConsoleOutHandle    = NULL;
792   gDxeCoreST->StdErr              = NULL;
793   gDxeCoreST->StandardErrorHandle = NULL;
794 
795   //
796   // Recompute the 32-bit CRC of the EFI System Table
797   //
798   CalculateEfiHdrCrc (&gDxeCoreST->Hdr);
799 
800   //
801   // Zero out the Boot Service Table
802   //
803   ZeroMem (gBS, sizeof (EFI_BOOT_SERVICES));
804   gBS = NULL;
805 
806   //
807   // Update the AtRuntime field in Runtiem AP.
808   //
809   gRuntime->AtRuntime = TRUE;
810 
811   return Status;
812 }
813 
814 
815 /**
816   Given a compressed source buffer, this function retrieves the size of the
817   uncompressed buffer and the size of the scratch buffer required to decompress
818   the compressed source buffer.
819 
820   The GetInfo() function retrieves the size of the uncompressed buffer and the
821   temporary scratch buffer required to decompress the buffer specified by Source
822   and SourceSize. If the size of the uncompressed buffer or the size of the
823   scratch buffer cannot be determined from the compressed data specified by
824   Source and SourceData, then EFI_INVALID_PARAMETER is returned. Otherwise, the
825   size of the uncompressed buffer is returned in DestinationSize, the size of
826   the scratch buffer is returned in ScratchSize, and EFI_SUCCESS is returned.
827   The GetInfo() function does not have scratch buffer available to perform a
828   thorough checking of the validity of the source data. It just retrieves the
829   "Original Size" field from the beginning bytes of the source data and output
830   it as DestinationSize. And ScratchSize is specific to the decompression
831   implementation.
832 
833   @param  This               A pointer to the EFI_DECOMPRESS_PROTOCOL instance.
834   @param  Source             The source buffer containing the compressed data.
835   @param  SourceSize         The size, in bytes, of the source buffer.
836   @param  DestinationSize    A pointer to the size, in bytes, of the
837                              uncompressed buffer that will be generated when the
838                              compressed buffer specified by Source and
839                              SourceSize is decompressed.
840   @param  ScratchSize        A pointer to the size, in bytes, of the scratch
841                              buffer that is required to decompress the
842                              compressed buffer specified by Source and
843                              SourceSize.
844 
845   @retval EFI_SUCCESS        The size of the uncompressed data was returned in
846                              DestinationSize and the size of the scratch buffer
847                              was returned in ScratchSize.
848   @retval EFI_INVALID_PARAMETER The size of the uncompressed data or the size of
849                                 the scratch buffer cannot be determined from the
850                                 compressed data specified by Source and
851                                 SourceSize.
852 
853 **/
854 EFI_STATUS
855 EFIAPI
DxeMainUefiDecompressGetInfo(IN EFI_DECOMPRESS_PROTOCOL * This,IN VOID * Source,IN UINT32 SourceSize,OUT UINT32 * DestinationSize,OUT UINT32 * ScratchSize)856 DxeMainUefiDecompressGetInfo (
857   IN EFI_DECOMPRESS_PROTOCOL            *This,
858   IN   VOID                             *Source,
859   IN   UINT32                           SourceSize,
860   OUT  UINT32                           *DestinationSize,
861   OUT  UINT32                           *ScratchSize
862   )
863 {
864   if (Source == NULL || DestinationSize == NULL || ScratchSize == NULL) {
865     return EFI_INVALID_PARAMETER;
866   }
867   return UefiDecompressGetInfo (Source, SourceSize, DestinationSize, ScratchSize);
868 }
869 
870 
871 /**
872   Decompresses a compressed source buffer.
873 
874   The Decompress() function extracts decompressed data to its original form.
875   This protocol is designed so that the decompression algorithm can be
876   implemented without using any memory services. As a result, the Decompress()
877   Function is not allowed to call AllocatePool() or AllocatePages() in its
878   implementation. It is the caller's responsibility to allocate and free the
879   Destination and Scratch buffers.
880   If the compressed source data specified by Source and SourceSize is
881   successfully decompressed into Destination, then EFI_SUCCESS is returned. If
882   the compressed source data specified by Source and SourceSize is not in a
883   valid compressed data format, then EFI_INVALID_PARAMETER is returned.
884 
885   @param  This                A pointer to the EFI_DECOMPRESS_PROTOCOL instance.
886   @param  Source              The source buffer containing the compressed data.
887   @param  SourceSize          SourceSizeThe size of source data.
888   @param  Destination         On output, the destination buffer that contains
889                               the uncompressed data.
890   @param  DestinationSize     The size of the destination buffer.  The size of
891                               the destination buffer needed is obtained from
892                               EFI_DECOMPRESS_PROTOCOL.GetInfo().
893   @param  Scratch             A temporary scratch buffer that is used to perform
894                               the decompression.
895   @param  ScratchSize         The size of scratch buffer. The size of the
896                               scratch buffer needed is obtained from GetInfo().
897 
898   @retval EFI_SUCCESS         Decompression completed successfully, and the
899                               uncompressed buffer is returned in Destination.
900   @retval EFI_INVALID_PARAMETER  The source buffer specified by Source and
901                                  SourceSize is corrupted (not in a valid
902                                  compressed format).
903 
904 **/
905 EFI_STATUS
906 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)907 DxeMainUefiDecompress (
908   IN     EFI_DECOMPRESS_PROTOCOL          *This,
909   IN     VOID                             *Source,
910   IN     UINT32                           SourceSize,
911   IN OUT VOID                             *Destination,
912   IN     UINT32                           DestinationSize,
913   IN OUT VOID                             *Scratch,
914   IN     UINT32                           ScratchSize
915   )
916 {
917   EFI_STATUS  Status;
918   UINT32      TestDestinationSize;
919   UINT32      TestScratchSize;
920 
921   if (Source == NULL || Destination== NULL || Scratch == NULL) {
922     return EFI_INVALID_PARAMETER;
923   }
924 
925   Status = UefiDecompressGetInfo (Source, SourceSize, &TestDestinationSize, &TestScratchSize);
926   if (EFI_ERROR (Status)) {
927     return Status;
928   }
929 
930   if (ScratchSize < TestScratchSize || DestinationSize < TestDestinationSize) {
931     return RETURN_INVALID_PARAMETER;
932   }
933 
934   return UefiDecompress (Source, Destination, Scratch);
935 }
936