Home | History | Annotate | Download | only in X64
      1 /** @file
      2   x64-specifc functionality for DxeLoad.
      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 "DxeIpl.h"
     16 #include "X64/VirtualMemory.h"
     17 
     18 
     19 
     20 /**
     21    Transfers control to DxeCore.
     22 
     23    This function performs a CPU architecture specific operations to execute
     24    the entry point of DxeCore with the parameters of HobList.
     25    It also installs EFI_END_OF_PEI_PPI to signal the end of PEI phase.
     26 
     27    @param DxeCoreEntryPoint         The entry point of DxeCore.
     28    @param HobList                   The start of HobList passed to DxeCore.
     29 
     30 **/
     31 VOID
     32 HandOffToDxeCore (
     33   IN EFI_PHYSICAL_ADDRESS   DxeCoreEntryPoint,
     34   IN EFI_PEI_HOB_POINTERS   HobList
     35   )
     36 {
     37   VOID                            *BaseOfStack;
     38   VOID                            *TopOfStack;
     39   EFI_STATUS                      Status;
     40   UINTN                           PageTables;
     41   UINT32                          Index;
     42   EFI_VECTOR_HANDOFF_INFO         *VectorInfo;
     43   EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;
     44 
     45   //
     46   // Get Vector Hand-off Info PPI and build Guided HOB
     47   //
     48   Status = PeiServicesLocatePpi (
     49              &gEfiVectorHandoffInfoPpiGuid,
     50              0,
     51              NULL,
     52              (VOID **)&VectorHandoffInfoPpi
     53              );
     54   if (Status == EFI_SUCCESS) {
     55     DEBUG ((EFI_D_INFO, "Vector Hand-off Info PPI is gotten, GUIDed HOB is created!\n"));
     56     VectorInfo = VectorHandoffInfoPpi->Info;
     57     Index = 1;
     58     while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {
     59       VectorInfo ++;
     60       Index ++;
     61     }
     62     BuildGuidDataHob (
     63       &gEfiVectorHandoffInfoPpiGuid,
     64       VectorHandoffInfoPpi->Info,
     65       sizeof (EFI_VECTOR_HANDOFF_INFO) * Index
     66       );
     67   }
     68 
     69   //
     70   // Allocate 128KB for the Stack
     71   //
     72   BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (STACK_SIZE));
     73   ASSERT (BaseOfStack != NULL);
     74 
     75   //
     76   // Compute the top of the stack we were allocated. Pre-allocate a UINTN
     77   // for safety.
     78   //
     79   TopOfStack = (VOID *) ((UINTN) BaseOfStack + EFI_SIZE_TO_PAGES (STACK_SIZE) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
     80   TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
     81 
     82   PageTables = 0;
     83   if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
     84     //
     85     // Create page table and save PageMapLevel4 to CR3
     86     //
     87     PageTables = CreateIdentityMappingPageTables ((EFI_PHYSICAL_ADDRESS) (UINTN) BaseOfStack, STACK_SIZE);
     88   } else {
     89     //
     90     // Set NX for stack feature also require PcdDxeIplBuildPageTables be TRUE
     91     // for the DxeIpl and the DxeCore are both X64.
     92     //
     93     ASSERT (PcdGetBool (PcdSetNxForStack) == FALSE);
     94   }
     95 
     96   //
     97   // End of PEI phase signal
     98   //
     99   Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
    100   ASSERT_EFI_ERROR (Status);
    101 
    102   if (FeaturePcdGet (PcdDxeIplBuildPageTables)) {
    103     AsmWriteCr3 (PageTables);
    104   }
    105 
    106   //
    107   // Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
    108   //
    109   UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN) BaseOfStack, STACK_SIZE);
    110 
    111   //
    112   // Transfer the control to the entry point of DxeCore.
    113   //
    114   SwitchStack (
    115     (SWITCH_STACK_ENTRY_POINT)(UINTN)DxeCoreEntryPoint,
    116     HobList.Raw,
    117     NULL,
    118     TopOfStack
    119     );
    120 }
    121