FspCommonLib.c revision 13ca714cd24830d42252fdbd012abf5a5f716246
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 FspInfoHeader +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 FspInfoHeader; 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 parameter passed by the bootlaoder. 93 94 @retval ApiParameter FSP API parameter 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 parameter 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/** 294 This function sets the memory init UPD data pointer. 295 296 @param[in] MemoryInitUpdPtr memory init UPD data pointer. 297**/ 298VOID 299EFIAPI 300SetFspMemoryInitUpdDataPointer ( 301 IN VOID *MemoryInitUpdPtr 302 ) 303{ 304 FSP_GLOBAL_DATA *FspData; 305 306 // 307 // Get the Fsp Global Data Pointer 308 // 309 FspData = GetFspGlobalDataPointer (); 310 311 // 312 // Set the memory init UPD pointer. 313 // 314 FspData->MemoryInitUpdPtr = MemoryInitUpdPtr; 315} 316 317/** 318 This function gets the memory init UPD data pointer. 319 320 @return memory init UPD data pointer. 321**/ 322VOID * 323EFIAPI 324GetFspMemoryInitUpdDataPointer ( 325 VOID 326 ) 327{ 328 FSP_GLOBAL_DATA *FspData; 329 330 FspData = GetFspGlobalDataPointer (); 331 return FspData->MemoryInitUpdPtr; 332} 333 334 335/** 336 This function sets the silicon init UPD data pointer. 337 338 @param[in] SiliconInitUpdPtr silicon init UPD data pointer. 339**/ 340VOID 341EFIAPI 342SetFspSiliconInitUpdDataPointer ( 343 IN VOID *SiliconInitUpdPtr 344 ) 345{ 346 FSP_GLOBAL_DATA *FspData; 347 348 // 349 // Get the Fsp Global Data Pointer 350 // 351 FspData = GetFspGlobalDataPointer (); 352 353 // 354 // Set the silicon init UPD data pointer. 355 // 356 FspData->SiliconInitUpdPtr = SiliconInitUpdPtr; 357} 358 359/** 360 This function gets the silicon init UPD data pointer. 361 362 @return silicon init UPD data pointer. 363**/ 364VOID * 365EFIAPI 366GetFspSiliconInitUpdDataPointer ( 367 VOID 368 ) 369{ 370 FSP_GLOBAL_DATA *FspData; 371 372 FspData = GetFspGlobalDataPointer (); 373 return FspData->SiliconInitUpdPtr; 374} 375 376 377/** 378 Set FSP measurement point timestamp. 379 380 @param[in] Id Measurement point ID. 381 382 @return performance timestamp. 383**/ 384UINT64 385EFIAPI 386SetFspMeasurePoint ( 387 IN UINT8 Id 388 ) 389{ 390 FSP_GLOBAL_DATA *FspData; 391 392 // 393 // Bit [55: 0] will be the timestamp 394 // Bit [63:56] will be the ID 395 // 396 FspData = GetFspGlobalDataPointer (); 397 if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) { 398 FspData->PerfData[FspData->PerfIdx] = AsmReadTsc (); 399 ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id; 400 } 401 402 return FspData->PerfData[(FspData->PerfIdx)++]; 403} 404 405/** 406 This function gets the FSP info header pointer. 407 408 @retval FspInfoHeader FSP info header pointer 409**/ 410FSP_INFO_HEADER * 411EFIAPI 412GetFspInfoHeader ( 413 VOID 414 ) 415{ 416 return GetFspGlobalDataPointer()->FspInfoHeader; 417} 418 419/** 420 This function gets the FSP info header pointer using the API stack context. 421 422 @retval FspInfoHeader FSP info header pointer using the API stack context 423**/ 424FSP_INFO_HEADER * 425EFIAPI 426GetFspInfoHeaderFromApiContext ( 427 VOID 428 ) 429{ 430 FSP_GLOBAL_DATA *FspData; 431 432 FspData = GetFspGlobalDataPointer (); 433 return (FSP_INFO_HEADER *)(*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(FspInfoHeader))); 434} 435 436/** 437 This function gets the VPD data pointer. 438 439 @return VpdDataRgnPtr VPD data pointer. 440**/ 441VOID * 442EFIAPI 443GetFspVpdDataPointer ( 444 VOID 445 ) 446{ 447 FSP_INFO_HEADER *FspInfoHeader; 448 449 FspInfoHeader = GetFspInfoHeader (); 450 return (VOID *)(FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset); 451} 452 453/** 454 This function gets FSP API calling mode. 455 456 @retval API calling mode 457**/ 458UINT8 459EFIAPI 460GetFspApiCallingMode ( 461 VOID 462 ) 463{ 464 return GetFspGlobalDataPointer()->ApiMode; 465} 466 467/** 468 This function sets FSP API calling mode. 469 470 @param[in] Mode API calling mode 471**/ 472VOID 473EFIAPI 474SetFspApiCallingMode ( 475 UINT8 Mode 476 ) 477{ 478 FSP_GLOBAL_DATA *FspData; 479 480 FspData = GetFspGlobalDataPointer (); 481 FspData->ApiMode = Mode; 482} 483 484