Home | History | Annotate | Download | only in DxeMain
      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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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