Home | History | Annotate | Download | only in BaseFspCommonLib
      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