FspCommonLib.c revision d5fb1edfb16a2af29486ffbf5aa32a036da9caa4
1/** @file 2 3 Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php. 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12**/ 13 14#include <PiPei.h> 15#include <Library/BaseLib.h> 16#include <Library/DebugLib.h> 17#include <Library/PcdLib.h> 18#include <FspGlobalData.h> 19#include <FspApi.h> 20 21#pragma pack(1) 22 23// 24// Cont Func Parameter 2 +0x3C 25// Cont Func Parameter 1 +0x38 26// 27// API Parameter +0x34 28// API return address +0x30 29// 30// push offset exit +0x2C 31// pushfd +0x28 32// cli 33// pushad +0x24 34// sub esp, 8 +0x00 35// sidt fword ptr [esp] 36// 37typedef struct { 38 UINT16 IdtrLimit; 39 UINT32 IdtrBase; 40 UINT16 Reserved; 41 UINT32 Edi; 42 UINT32 Esi; 43 UINT32 Ebp; 44 UINT32 Esp; 45 UINT32 Ebx; 46 UINT32 Edx; 47 UINT32 Ecx; 48 UINT32 Eax; 49 UINT16 Flags[2]; 50 UINT32 ExitOff; 51 UINT32 ApiRet; 52 UINT32 ApiParam; 53} CONTEXT_STACK; 54 55#define CONTEXT_STACK_OFFSET(x) (UINT32)&((CONTEXT_STACK *)(UINTN)0)->x 56 57#pragma pack() 58 59/** 60 This function sets the FSP global data pointer. 61 62 @param[in] FspData Fsp global data pointer. 63 64**/ 65VOID 66EFIAPI 67SetFspGlobalDataPointer ( 68 IN FSP_GLOBAL_DATA *FspData 69 ) 70{ 71 ASSERT (FspData != NULL); 72 *((volatile UINT32 *)(UINTN)PcdGet32(PcdGlobalDataPointerAddress)) = (UINT32)(UINTN)FspData; 73} 74 75/** 76 This function gets the FSP global data pointer. 77 78**/ 79FSP_GLOBAL_DATA * 80EFIAPI 81GetFspGlobalDataPointer ( 82 VOID 83 ) 84{ 85 FSP_GLOBAL_DATA *FspData; 86 87 FspData = *(FSP_GLOBAL_DATA **)(UINTN)PcdGet32(PcdGlobalDataPointerAddress); 88 return FspData; 89} 90 91/** 92 This function gets back the FSP API paramter passed by the bootlaoder. 93 94 @retval ApiParameter FSP API paramter passed by the bootlaoder. 95**/ 96UINT32 97EFIAPI 98GetFspApiParameter ( 99 VOID 100 ) 101{ 102 FSP_GLOBAL_DATA *FspData; 103 104 FspData = GetFspGlobalDataPointer (); 105 return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam)); 106} 107 108/** 109 This function sets the FSP API paramter in the stack. 110 111 @param[in] Value New parameter value. 112 113**/ 114VOID 115EFIAPI 116SetFspApiParameter ( 117 IN UINT32 Value 118 ) 119{ 120 FSP_GLOBAL_DATA *FspData; 121 122 FspData = GetFspGlobalDataPointer (); 123 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam)) = Value; 124} 125 126/** 127 This function sets the FSP continuation function parameters in the stack. 128 129 @param[in] Value New parameter value to set. 130 @param[in] Index Parameter index. 131**/ 132VOID 133EFIAPI 134SetFspContinuationFuncParameter ( 135 IN UINT32 Value, 136 IN UINT32 Index 137 ) 138{ 139 FSP_GLOBAL_DATA *FspData; 140 141 FspData = GetFspGlobalDataPointer (); 142 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam) + (Index + 1) * sizeof(UINT32)) = Value; 143} 144 145 146/** 147 This function changes the Bootloader return address in stack. 148 149 @param[in] ReturnAddress Address to return. 150 151**/ 152VOID 153EFIAPI 154SetFspApiReturnAddress ( 155 IN UINT32 ReturnAddress 156 ) 157{ 158 FSP_GLOBAL_DATA *FspData; 159 160 FspData = GetFspGlobalDataPointer (); 161 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiRet)) = ReturnAddress; 162} 163 164/** 165 This function set the API status code returned to the bootloader. 166 167 @param[in] ReturnStatus Status code to return. 168 169**/ 170VOID 171EFIAPI 172SetFspApiReturnStatus ( 173 IN UINT32 ReturnStatus 174 ) 175{ 176 FSP_GLOBAL_DATA *FspData; 177 178 FspData = GetFspGlobalDataPointer (); 179 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(Eax)) = ReturnStatus; 180} 181 182/** 183 This function sets the context switching stack to a new stack frame. 184 185 @param[in] NewStackTop New core stack to be set. 186 187**/ 188VOID 189EFIAPI 190SetFspCoreStackPointer ( 191 IN VOID *NewStackTop 192 ) 193{ 194 FSP_GLOBAL_DATA *FspData; 195 UINT32 *OldStack; 196 UINT32 *NewStack; 197 UINT32 StackContextLen; 198 199 FspData = GetFspGlobalDataPointer (); 200 StackContextLen = sizeof(CONTEXT_STACK) / sizeof(UINT32); 201 202 // 203 // Reserve space for the ContinuationFunc two parameters 204 // 205 OldStack = (UINT32 *)FspData->CoreStack; 206 NewStack = (UINT32 *)NewStackTop - StackContextLen - 2; 207 FspData->CoreStack = (UINT32)NewStack; 208 while (StackContextLen-- != 0) { 209 *NewStack++ = *OldStack++; 210 } 211} 212 213/** 214 This function sets the platform specific data pointer. 215 216 @param[in] PlatformData Fsp platform specific data pointer. 217 218**/ 219VOID 220EFIAPI 221SetFspPlatformDataPointer ( 222 IN VOID *PlatformData 223 ) 224{ 225 FSP_GLOBAL_DATA *FspData; 226 227 FspData = GetFspGlobalDataPointer (); 228 FspData->PlatformData.DataPtr = PlatformData; 229} 230 231 232/** 233 This function gets the platform specific data pointer. 234 235 @param[in] PlatformData Fsp platform specific data pointer. 236 237**/ 238VOID * 239EFIAPI 240GetFspPlatformDataPointer ( 241 VOID 242 ) 243{ 244 FSP_GLOBAL_DATA *FspData; 245 246 FspData = GetFspGlobalDataPointer (); 247 return FspData->PlatformData.DataPtr; 248} 249 250 251/** 252 This function sets the UPD data pointer. 253 254 @param[in] UpdDataRgnPtr UPD data pointer. 255**/ 256VOID 257EFIAPI 258SetFspUpdDataPointer ( 259 IN VOID *UpdDataRgnPtr 260 ) 261{ 262 FSP_GLOBAL_DATA *FspData; 263 264 // 265 // Get the Fsp Global Data Pointer 266 // 267 FspData = GetFspGlobalDataPointer (); 268 269 // 270 // Set the UPD pointer. 271 // 272 FspData->UpdDataRgnPtr = UpdDataRgnPtr; 273} 274 275/** 276 This function gets the UPD data pointer. 277 278 @return UpdDataRgnPtr UPD data pointer. 279**/ 280VOID * 281EFIAPI 282GetFspUpdDataPointer ( 283 VOID 284 ) 285{ 286 FSP_GLOBAL_DATA *FspData; 287 288 FspData = GetFspGlobalDataPointer (); 289 return FspData->UpdDataRgnPtr; 290} 291 292/** 293 Set FSP measurement point timestamp. 294 295 @param[in] Id Measurement point ID. 296 297 @return performance timestamp. 298**/ 299UINT64 300EFIAPI 301SetFspMeasurePoint ( 302 IN UINT8 Id 303 ) 304{ 305 FSP_GLOBAL_DATA *FspData; 306 307 // 308 // Bit [55: 0] will be the timestamp 309 // Bit [63:56] will be the ID 310 // 311 FspData = GetFspGlobalDataPointer (); 312 if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) { 313 FspData->PerfData[FspData->PerfIdx] = AsmReadTsc (); 314 ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id; 315 } 316 317 return FspData->PerfData[(FspData->PerfIdx)++]; 318} 319 320/** 321 This function gets the FSP info header pointer. 322 323 @retval FspInfoHeader FSP info header pointer 324**/ 325FSP_INFO_HEADER * 326EFIAPI 327GetFspInfoHeader ( 328 VOID 329 ) 330{ 331 return GetFspGlobalDataPointer()->FspInfoHeader; 332} 333 334/** 335 This function gets FSP API calling mode 336 337 @retval API calling mode 338**/ 339UINT8 340EFIAPI 341GetFspApiCallingMode ( 342 VOID 343 ) 344{ 345 return GetFspGlobalDataPointer()->ApiMode; 346} 347 348/** 349 This function sets FSP API calling mode 350 351 @param[in] Mode API calling mode 352**/ 353VOID 354EFIAPI 355SetFspApiCallingMode ( 356 UINT8 Mode 357 ) 358{ 359 FSP_GLOBAL_DATA *FspData; 360 361 FspData = GetFspGlobalDataPointer (); 362 FspData->ApiMode = Mode; 363} 364 365