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 // 37 typedef 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 **/ 65 VOID 66 EFIAPI 67 SetFspGlobalDataPointer ( 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 **/ 79 FSP_GLOBAL_DATA * 80 EFIAPI 81 GetFspGlobalDataPointer ( 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 **/ 96 UINT32 97 EFIAPI 98 GetFspApiParameter ( 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 **/ 114 VOID 115 EFIAPI 116 SetFspApiParameter ( 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 **/ 132 VOID 133 EFIAPI 134 SetFspContinuationFuncParameter ( 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 **/ 152 VOID 153 EFIAPI 154 SetFspApiReturnAddress ( 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 **/ 170 VOID 171 EFIAPI 172 SetFspApiReturnStatus ( 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 **/ 188 VOID 189 EFIAPI 190 SetFspCoreStackPointer ( 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 **/ 219 VOID 220 EFIAPI 221 SetFspPlatformDataPointer ( 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 **/ 238 VOID * 239 EFIAPI 240 GetFspPlatformDataPointer ( 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 **/ 256 VOID 257 EFIAPI 258 SetFspUpdDataPointer ( 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 **/ 280 VOID * 281 EFIAPI 282 GetFspUpdDataPointer ( 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 **/ 298 VOID 299 EFIAPI 300 SetFspMemoryInitUpdDataPointer ( 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 **/ 322 VOID * 323 EFIAPI 324 GetFspMemoryInitUpdDataPointer ( 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 **/ 340 VOID 341 EFIAPI 342 SetFspSiliconInitUpdDataPointer ( 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 **/ 364 VOID * 365 EFIAPI 366 GetFspSiliconInitUpdDataPointer ( 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 **/ 384 UINT64 385 EFIAPI 386 SetFspMeasurePoint ( 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 **/ 410 FSP_INFO_HEADER * 411 EFIAPI 412 GetFspInfoHeader ( 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 **/ 424 FSP_INFO_HEADER * 425 EFIAPI 426 GetFspInfoHeaderFromApiContext ( 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 **/ 441 VOID * 442 EFIAPI 443 GetFspVpdDataPointer ( 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 **/ 458 UINT8 459 EFIAPI 460 GetFspApiCallingMode ( 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 **/ 472 VOID 473 EFIAPI 474 SetFspApiCallingMode ( 475 UINT8 Mode 476 ) 477 { 478 FSP_GLOBAL_DATA *FspData; 479 480 FspData = GetFspGlobalDataPointer (); 481 FspData->ApiMode = Mode; 482 } 483 484