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