1 /** @file 2 Provide FSP API related function. 3 4 Copyright (c) 2014 - 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 <PiPei.h> 16 17 #include <Library/FspWrapperApiLib.h> 18 #include <Library/BaseLib.h> 19 #include <Library/BaseMemoryLib.h> 20 21 /** 22 Wrapper for a thunk to transition from long mode to compatibility mode to execute 32-bit code and then transit back to 23 long mode. 24 25 @param[in] Function The 32bit code entry to be executed. 26 @param[in] Param1 The first parameter to pass to 32bit code. 27 @param[in] Param2 The second parameter to pass to 32bit code. 28 29 @return EFI_STATUS. 30 **/ 31 EFI_STATUS 32 Execute32BitCode ( 33 IN UINT64 Function, 34 IN UINT64 Param1, 35 IN UINT64 Param2 36 ); 37 38 /** 39 Find FSP header pointer. 40 41 @param[in] FlashFvFspBase Flash address of FSP FV. 42 43 @return FSP header pointer. 44 **/ 45 FSP_INFO_HEADER * 46 EFIAPI 47 FspFindFspHeader ( 48 IN EFI_PHYSICAL_ADDRESS FlashFvFspBase 49 ) 50 { 51 UINT8 *CheckPointer; 52 53 CheckPointer = (UINT8 *) (UINTN) FlashFvFspBase; 54 55 if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->Signature != EFI_FVH_SIGNATURE) { 56 return NULL; 57 } 58 59 if (((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->ExtHeaderOffset != 0) { 60 CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->ExtHeaderOffset; 61 CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_EXT_HEADER *)CheckPointer)->ExtHeaderSize; 62 CheckPointer = (UINT8 *) ALIGN_POINTER (CheckPointer, 8); 63 } else { 64 CheckPointer = CheckPointer + ((EFI_FIRMWARE_VOLUME_HEADER *)CheckPointer)->HeaderLength; 65 } 66 67 68 CheckPointer = CheckPointer + sizeof (EFI_FFS_FILE_HEADER); 69 70 if (((EFI_RAW_SECTION *)CheckPointer)->Type != EFI_SECTION_RAW) { 71 return NULL; 72 } 73 74 CheckPointer = CheckPointer + sizeof (EFI_RAW_SECTION); 75 76 return (FSP_INFO_HEADER *)CheckPointer; 77 } 78 79 /** 80 Call FSP API - FspNotifyPhase. 81 82 @param[in] NotifyPhaseParams Address pointer to the NOTIFY_PHASE_PARAMS structure. 83 84 @return EFI status returned by FspNotifyPhase API. 85 **/ 86 EFI_STATUS 87 EFIAPI 88 CallFspNotifyPhase ( 89 IN NOTIFY_PHASE_PARAMS *NotifyPhaseParams 90 ) 91 { 92 FSP_INFO_HEADER *FspHeader; 93 FSP_NOTIFY_PHASE NotifyPhaseApi; 94 EFI_STATUS Status; 95 BOOLEAN InterruptState; 96 97 FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress)); 98 if (FspHeader == NULL) { 99 return EFI_DEVICE_ERROR; 100 } 101 102 NotifyPhaseApi = (FSP_NOTIFY_PHASE)(UINTN)(FspHeader->ImageBase + FspHeader->NotifyPhaseEntryOffset); 103 InterruptState = SaveAndDisableInterrupts (); 104 Status = Execute32BitCode ((UINTN)NotifyPhaseApi, (UINTN)NotifyPhaseParams, (UINTN)NULL); 105 SetInterruptState (InterruptState); 106 107 return Status; 108 } 109 110 /** 111 Call FSP API - FspMemoryInit. 112 113 @param[in] FspmUpdDataPtr Address pointer to the FSP_MEMORY_INIT_PARAMS structure. 114 @param[out] HobListPtr Address of the HobList pointer. 115 116 @return EFI status returned by FspMemoryInit API. 117 **/ 118 EFI_STATUS 119 EFIAPI 120 CallFspMemoryInit ( 121 IN VOID *FspmUpdDataPtr, 122 OUT VOID **HobListPtr 123 ) 124 { 125 FSP_INFO_HEADER *FspHeader; 126 FSP_MEMORY_INIT FspMemoryInitApi; 127 EFI_STATUS Status; 128 BOOLEAN InterruptState; 129 130 FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress)); 131 if (FspHeader == NULL) { 132 return EFI_DEVICE_ERROR; 133 } 134 135 FspMemoryInitApi = (FSP_MEMORY_INIT)(UINTN)(FspHeader->ImageBase + FspHeader->FspMemoryInitEntryOffset); 136 InterruptState = SaveAndDisableInterrupts (); 137 Status = Execute32BitCode ((UINTN)FspMemoryInitApi, (UINTN)FspmUpdDataPtr, (UINTN)HobListPtr); 138 SetInterruptState (InterruptState); 139 140 return Status; 141 } 142 143 /** 144 Call FSP API - TempRamExit. 145 146 @param[in] TempRamExitParam Address pointer to the TempRamExit parameters structure. 147 148 @return EFI status returned by TempRamExit API. 149 **/ 150 EFI_STATUS 151 EFIAPI 152 CallTempRamExit ( 153 IN VOID *TempRamExitParam 154 ) 155 { 156 FSP_INFO_HEADER *FspHeader; 157 FSP_TEMP_RAM_EXIT TempRamExitApi; 158 EFI_STATUS Status; 159 BOOLEAN InterruptState; 160 161 FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress)); 162 if (FspHeader == NULL) { 163 return EFI_DEVICE_ERROR; 164 } 165 166 TempRamExitApi = (FSP_TEMP_RAM_EXIT)(UINTN)(FspHeader->ImageBase + FspHeader->TempRamExitEntryOffset); 167 InterruptState = SaveAndDisableInterrupts (); 168 Status = Execute32BitCode ((UINTN)TempRamExitApi, (UINTN)TempRamExitParam, (UINTN)NULL); 169 SetInterruptState (InterruptState); 170 171 return Status; 172 } 173 174 /** 175 Call FSP API - FspSiliconInit. 176 177 @param[in] FspsUpdDataPtr Address pointer to the Silicon Init parameters structure. 178 179 @return EFI status returned by FspSiliconInit API. 180 **/ 181 EFI_STATUS 182 EFIAPI 183 CallFspSiliconInit ( 184 IN VOID *FspsUpdDataPtr 185 ) 186 { 187 FSP_INFO_HEADER *FspHeader; 188 FSP_SILICON_INIT FspSiliconInitApi; 189 EFI_STATUS Status; 190 BOOLEAN InterruptState; 191 192 FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress)); 193 if (FspHeader == NULL) { 194 return EFI_DEVICE_ERROR; 195 } 196 197 FspSiliconInitApi = (FSP_SILICON_INIT)(UINTN)(FspHeader->ImageBase + FspHeader->FspSiliconInitEntryOffset); 198 InterruptState = SaveAndDisableInterrupts (); 199 Status = Execute32BitCode ((UINTN)FspSiliconInitApi, (UINTN)FspsUpdDataPtr, (UINTN)NULL); 200 SetInterruptState (InterruptState); 201 202 return Status; 203 } 204