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