Home | History | Annotate | Download | only in DxeMain
      1 /** @file
      2   DXE Core Main Entry Point
      3 
      4 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "DxeMain.h"
     16 
     17 //
     18 // DXE Core Global Variables for Protocols from PEI
     19 //
     20 EFI_HANDLE                                mDecompressHandle = NULL;
     21 
     22 //
     23 // DXE Core globals for Architecture Protocols
     24 //
     25 EFI_SECURITY_ARCH_PROTOCOL        *gSecurity      = NULL;
     26 EFI_SECURITY2_ARCH_PROTOCOL       *gSecurity2     = NULL;
     27 EFI_CPU_ARCH_PROTOCOL             *gCpu           = NULL;
     28 EFI_METRONOME_ARCH_PROTOCOL       *gMetronome     = NULL;
     29 EFI_TIMER_ARCH_PROTOCOL           *gTimer         = NULL;
     30 EFI_BDS_ARCH_PROTOCOL             *gBds           = NULL;
     31 EFI_WATCHDOG_TIMER_ARCH_PROTOCOL  *gWatchdogTimer = NULL;
     32 
     33 //
     34 // DXE Core globals for optional protocol dependencies
     35 //
     36 EFI_SMM_BASE2_PROTOCOL            *gSmmBase2      = NULL;
     37 
     38 //
     39 // DXE Core Global used to update core loaded image protocol handle
     40 //
     41 EFI_GUID                           *gDxeCoreFileName;
     42 EFI_LOADED_IMAGE_PROTOCOL          *gDxeCoreLoadedImage;
     43 
     44 //
     45 // DXE Core Module Variables
     46 //
     47 EFI_BOOT_SERVICES mBootServices = {
     48   {
     49     EFI_BOOT_SERVICES_SIGNATURE,                                                          // Signature
     50     EFI_BOOT_SERVICES_REVISION,                                                           // Revision
     51     sizeof (EFI_BOOT_SERVICES),                                                           // HeaderSize
     52     0,                                                                                    // CRC32
     53     0                                                                                     // Reserved
     54   },
     55   (EFI_RAISE_TPL)                               CoreRaiseTpl,                             // RaiseTPL
     56   (EFI_RESTORE_TPL)                             CoreRestoreTpl,                           // RestoreTPL
     57   (EFI_ALLOCATE_PAGES)                          CoreAllocatePages,                        // AllocatePages
     58   (EFI_FREE_PAGES)                              CoreFreePages,                            // FreePages
     59   (EFI_GET_MEMORY_MAP)                          CoreGetMemoryMap,                         // GetMemoryMap
     60   (EFI_ALLOCATE_POOL)                           CoreAllocatePool,                         // AllocatePool
     61   (EFI_FREE_POOL)                               CoreFreePool,                             // FreePool
     62   (EFI_CREATE_EVENT)                            CoreCreateEvent,                          // CreateEvent
     63   (EFI_SET_TIMER)                               CoreSetTimer,                             // SetTimer
     64   (EFI_WAIT_FOR_EVENT)                          CoreWaitForEvent,                         // WaitForEvent
     65   (EFI_SIGNAL_EVENT)                            CoreSignalEvent,                          // SignalEvent
     66   (EFI_CLOSE_EVENT)                             CoreCloseEvent,                           // CloseEvent
     67   (EFI_CHECK_EVENT)                             CoreCheckEvent,                           // CheckEvent
     68   (EFI_INSTALL_PROTOCOL_INTERFACE)              CoreInstallProtocolInterface,             // InstallProtocolInterface
     69   (EFI_REINSTALL_PROTOCOL_INTERFACE)            CoreReinstallProtocolInterface,           // ReinstallProtocolInterface
     70   (EFI_UNINSTALL_PROTOCOL_INTERFACE)            CoreUninstallProtocolInterface,           // UninstallProtocolInterface
     71   (EFI_HANDLE_PROTOCOL)                         CoreHandleProtocol,                       // HandleProtocol
     72   (VOID *)                                      NULL,                                     // Reserved
     73   (EFI_REGISTER_PROTOCOL_NOTIFY)                CoreRegisterProtocolNotify,               // RegisterProtocolNotify
     74   (EFI_LOCATE_HANDLE)                           CoreLocateHandle,                         // LocateHandle
     75   (EFI_LOCATE_DEVICE_PATH)                      CoreLocateDevicePath,                     // LocateDevicePath
     76   (EFI_INSTALL_CONFIGURATION_TABLE)             CoreInstallConfigurationTable,            // InstallConfigurationTable
     77   (EFI_IMAGE_LOAD)                              CoreLoadImage,                            // LoadImage
     78   (EFI_IMAGE_START)                             CoreStartImage,                           // StartImage
     79   (EFI_EXIT)                                    CoreExit,                                 // Exit
     80   (EFI_IMAGE_UNLOAD)                            CoreUnloadImage,                          // UnloadImage
     81   (EFI_EXIT_BOOT_SERVICES)                      CoreExitBootServices,                     // ExitBootServices
     82   (EFI_GET_NEXT_MONOTONIC_COUNT)                CoreEfiNotAvailableYetArg1,               // GetNextMonotonicCount
     83   (EFI_STALL)                                   CoreStall,                                // Stall
     84   (EFI_SET_WATCHDOG_TIMER)                      CoreSetWatchdogTimer,                     // SetWatchdogTimer
     85   (EFI_CONNECT_CONTROLLER)                      CoreConnectController,                    // ConnectController
     86   (EFI_DISCONNECT_CONTROLLER)                   CoreDisconnectController,                 // DisconnectController
     87   (EFI_OPEN_PROTOCOL)                           CoreOpenProtocol,                         // OpenProtocol
     88   (EFI_CLOSE_PROTOCOL)                          CoreCloseProtocol,                        // CloseProtocol
     89   (EFI_OPEN_PROTOCOL_INFORMATION)               CoreOpenProtocolInformation,              // OpenProtocolInformation
     90   (EFI_PROTOCOLS_PER_HANDLE)                    CoreProtocolsPerHandle,                   // ProtocolsPerHandle
     91   (EFI_LOCATE_HANDLE_BUFFER)                    CoreLocateHandleBuffer,                   // LocateHandleBuffer
     92   (EFI_LOCATE_PROTOCOL)                         CoreLocateProtocol,                       // LocateProtocol
     93   (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)    CoreInstallMultipleProtocolInterfaces,    // InstallMultipleProtocolInterfaces
     94   (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)  CoreUninstallMultipleProtocolInterfaces,  // UninstallMultipleProtocolInterfaces
     95   (EFI_CALCULATE_CRC32)                         CoreEfiNotAvailableYetArg3,               // CalculateCrc32
     96   (EFI_COPY_MEM)                                CopyMem,                                  // CopyMem
     97   (EFI_SET_MEM)                                 SetMem,                                   // SetMem
     98   (EFI_CREATE_EVENT_EX)                         CoreCreateEventEx                         // CreateEventEx
     99 };
    100 
    101 EFI_DXE_SERVICES mDxeServices = {
    102   {
    103     DXE_SERVICES_SIGNATURE,                                           // Signature
    104     DXE_SERVICES_REVISION,                                            // Revision
    105     sizeof (DXE_SERVICES),                                            // HeaderSize
    106     0,                                                                    // CRC32
    107     0                                                                     // Reserved
    108   },
    109   (EFI_ADD_MEMORY_SPACE)             CoreAddMemorySpace,                  // AddMemorySpace
    110   (EFI_ALLOCATE_MEMORY_SPACE)        CoreAllocateMemorySpace,             // AllocateMemorySpace
    111   (EFI_FREE_MEMORY_SPACE)            CoreFreeMemorySpace,                 // FreeMemorySpace
    112   (EFI_REMOVE_MEMORY_SPACE)          CoreRemoveMemorySpace,               // RemoveMemorySpace
    113   (EFI_GET_MEMORY_SPACE_DESCRIPTOR)  CoreGetMemorySpaceDescriptor,        // GetMemorySpaceDescriptor
    114   (EFI_SET_MEMORY_SPACE_ATTRIBUTES)  CoreSetMemorySpaceAttributes,        // SetMemorySpaceAttributes
    115   (EFI_GET_MEMORY_SPACE_MAP)         CoreGetMemorySpaceMap,               // GetMemorySpaceMap
    116   (EFI_ADD_IO_SPACE)                 CoreAddIoSpace,                      // AddIoSpace
    117   (EFI_ALLOCATE_IO_SPACE)            CoreAllocateIoSpace,                 // AllocateIoSpace
    118   (EFI_FREE_IO_SPACE)                CoreFreeIoSpace,                     // FreeIoSpace
    119   (EFI_REMOVE_IO_SPACE)              CoreRemoveIoSpace,                   // RemoveIoSpace
    120   (EFI_GET_IO_SPACE_DESCRIPTOR)      CoreGetIoSpaceDescriptor,            // GetIoSpaceDescriptor
    121   (EFI_GET_IO_SPACE_MAP)             CoreGetIoSpaceMap,                   // GetIoSpaceMap
    122   (EFI_DISPATCH)                     CoreDispatcher,                      // Dispatch
    123   (EFI_SCHEDULE)                     CoreSchedule,                        // Schedule
    124   (EFI_TRUST)                        CoreTrust,                           // Trust
    125   (EFI_PROCESS_FIRMWARE_VOLUME)      CoreProcessFirmwareVolume,           // ProcessFirmwareVolume
    126   (EFI_SET_MEMORY_SPACE_CAPABILITIES)CoreSetMemorySpaceCapabilities,      // SetMemorySpaceCapabilities
    127 };
    128 
    129 EFI_SYSTEM_TABLE mEfiSystemTableTemplate = {
    130   {
    131     EFI_SYSTEM_TABLE_SIGNATURE,                                           // Signature
    132     EFI_SYSTEM_TABLE_REVISION,                                            // Revision
    133     sizeof (EFI_SYSTEM_TABLE),                                            // HeaderSize
    134     0,                                                                    // CRC32
    135     0                                                                     // Reserved
    136   },
    137   NULL,                                                                   // FirmwareVendor
    138   0,                                                                      // FirmwareRevision
    139   NULL,                                                                   // ConsoleInHandle
    140   NULL,                                                                   // ConIn
    141   NULL,                                                                   // ConsoleOutHandle
    142   NULL,                                                                   // ConOut
    143   NULL,                                                                   // StandardErrorHandle
    144   NULL,                                                                   // StdErr
    145   NULL,                                                                   // RuntimeServices
    146   &mBootServices,                                                         // BootServices
    147   0,                                                                      // NumberOfConfigurationTableEntries
    148   NULL                                                                    // ConfigurationTable
    149 };
    150 
    151 EFI_RUNTIME_SERVICES mEfiRuntimeServicesTableTemplate = {
    152   {
    153     EFI_RUNTIME_SERVICES_SIGNATURE,                               // Signature
    154     EFI_RUNTIME_SERVICES_REVISION,                                // Revision
    155     sizeof (EFI_RUNTIME_SERVICES),                                // HeaderSize
    156     0,                                                            // CRC32
    157     0                                                             // Reserved
    158   },
    159   (EFI_GET_TIME)                    CoreEfiNotAvailableYetArg2,   // GetTime
    160   (EFI_SET_TIME)                    CoreEfiNotAvailableYetArg1,   // SetTime
    161   (EFI_GET_WAKEUP_TIME)             CoreEfiNotAvailableYetArg3,   // GetWakeupTime
    162   (EFI_SET_WAKEUP_TIME)             CoreEfiNotAvailableYetArg2,   // SetWakeupTime
    163   (EFI_SET_VIRTUAL_ADDRESS_MAP)     CoreEfiNotAvailableYetArg4,   // SetVirtualAddressMap
    164   (EFI_CONVERT_POINTER)             CoreEfiNotAvailableYetArg2,   // ConvertPointer
    165   (EFI_GET_VARIABLE)                CoreEfiNotAvailableYetArg5,   // GetVariable
    166   (EFI_GET_NEXT_VARIABLE_NAME)      CoreEfiNotAvailableYetArg3,   // GetNextVariableName
    167   (EFI_SET_VARIABLE)                CoreEfiNotAvailableYetArg5,   // SetVariable
    168   (EFI_GET_NEXT_HIGH_MONO_COUNT)    CoreEfiNotAvailableYetArg1,   // GetNextHighMonotonicCount
    169   (EFI_RESET_SYSTEM)                CoreEfiNotAvailableYetArg4,   // ResetSystem
    170   (EFI_UPDATE_CAPSULE)              CoreEfiNotAvailableYetArg3,   // UpdateCapsule
    171   (EFI_QUERY_CAPSULE_CAPABILITIES)  CoreEfiNotAvailableYetArg4,   // QueryCapsuleCapabilities
    172   (EFI_QUERY_VARIABLE_INFO)         CoreEfiNotAvailableYetArg4    // QueryVariableInfo
    173 };
    174 
    175 EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate = {
    176   INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.ImageHead),
    177   INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.EventHead),
    178 
    179   //
    180   // Make sure Size != sizeof (EFI_MEMORY_DESCRIPTOR). This will
    181   // prevent people from having pointer math bugs in their code.
    182   // now you have to use *DescriptorSize to make things work.
    183   //
    184   sizeof (EFI_MEMORY_DESCRIPTOR) + sizeof (UINT64) - (sizeof (EFI_MEMORY_DESCRIPTOR) % sizeof (UINT64)),
    185   EFI_MEMORY_DESCRIPTOR_VERSION,
    186   0,
    187   NULL,
    188   NULL,
    189   FALSE,
    190   FALSE
    191 };
    192 
    193 EFI_RUNTIME_ARCH_PROTOCOL *gRuntime = &gRuntimeTemplate;
    194 
    195 //
    196 // DXE Core Global Variables for the EFI System Table, Boot Services Table,
    197 // DXE Services Table, and Runtime Services Table
    198 //
    199 EFI_DXE_SERVICES      *gDxeCoreDS = &mDxeServices;
    200 EFI_SYSTEM_TABLE      *gDxeCoreST = NULL;
    201 
    202 //
    203 // For debug initialize gDxeCoreRT to template. gDxeCoreRT must be allocated from RT memory
    204 //  but gDxeCoreRT is used for ASSERT () and DEBUG () type macros so lets give it
    205 //  a value that will not cause debug infrastructure to crash early on.
    206 //
    207 EFI_RUNTIME_SERVICES  *gDxeCoreRT = &mEfiRuntimeServicesTableTemplate;
    208 EFI_HANDLE            gDxeCoreImageHandle = NULL;
    209 
    210 
    211 //
    212 // EFI Decompress Protocol
    213 //
    214 EFI_DECOMPRESS_PROTOCOL  gEfiDecompress = {
    215   DxeMainUefiDecompressGetInfo,
    216   DxeMainUefiDecompress
    217 };
    218 
    219 //
    220 // For Loading modules at fixed address feature, the configuration table is to cache the top address below which to load
    221 // Runtime code&boot time code
    222 //
    223 GLOBAL_REMOVE_IF_UNREFERENCED EFI_LOAD_FIXED_ADDRESS_CONFIGURATION_TABLE    gLoadModuleAtFixAddressConfigurationTable = {0, 0};
    224 
    225 // Main entry point to the DXE Core
    226 //
    227 
    228 /**
    229   Main entry point to DXE Core.
    230 
    231   @param  HobStart               Pointer to the beginning of the HOB List from PEI.
    232 
    233   @return This function should never return.
    234 
    235 **/
    236 VOID
    237 EFIAPI
    238 DxeMain (
    239   IN  VOID *HobStart
    240   )
    241 {
    242   EFI_STATUS                    Status;
    243   EFI_PHYSICAL_ADDRESS          MemoryBaseAddress;
    244   UINT64                        MemoryLength;
    245   PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;
    246   UINTN                         Index;
    247   EFI_HOB_GUID_TYPE             *GuidHob;
    248   EFI_VECTOR_HANDOFF_INFO       *VectorInfoList;
    249   EFI_VECTOR_HANDOFF_INFO       *VectorInfo;
    250 
    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 **/
    528 EFI_STATUS
    529 EFIAPI
    530 CoreEfiNotAvailableYetArg0 (
    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 **/
    553 EFI_STATUS
    554 EFIAPI
    555 CoreEfiNotAvailableYetArg1 (
    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 **/
    578 EFI_STATUS
    579 EFIAPI
    580 CoreEfiNotAvailableYetArg2 (
    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 **/
    605 EFI_STATUS
    606 EFIAPI
    607 CoreEfiNotAvailableYetArg3 (
    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 **/
    634 EFI_STATUS
    635 EFIAPI
    636 CoreEfiNotAvailableYetArg4 (
    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 **/
    665 EFI_STATUS
    666 EFIAPI
    667 CoreEfiNotAvailableYetArg5 (
    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 **/
    692 VOID
    693 CalculateEfiHdrCrc (
    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 **/
    721 EFI_STATUS
    722 EFIAPI
    723 CoreExitBootServices (
    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 **/
    840 EFI_STATUS
    841 EFIAPI
    842 DxeMainUefiDecompressGetInfo (
    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 **/
    891 EFI_STATUS
    892 EFIAPI
    893 DxeMainUefiDecompress (
    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