Home | History | Annotate | Download | only in FspSecCore
      1 /** @file
      2 
      3   Copyright (c) 2014 - 2016, 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 "SecFsp.h"
     15 
     16 /**
     17 
     18   Calculate the FSP IDT gate descriptor.
     19 
     20   @param[in] IdtEntryTemplate     IDT gate descriptor template.
     21 
     22   @return                     FSP specific IDT gate descriptor.
     23 
     24 **/
     25 UINT64
     26 FspGetExceptionHandler(
     27   IN  UINT64  IdtEntryTemplate
     28   )
     29 {
     30   UINT32                    Entry;
     31   UINT64                    ExceptionHandler;
     32   IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor;
     33   FSP_INFO_HEADER          *FspInfoHeader;
     34 
     35   FspInfoHeader     = (FSP_INFO_HEADER *)AsmGetFspInfoHeader();
     36   ExceptionHandler  = IdtEntryTemplate;
     37   IdtGateDescriptor = (IA32_IDT_GATE_DESCRIPTOR *)&ExceptionHandler;
     38   Entry = (IdtGateDescriptor->Bits.OffsetHigh << 16) | IdtGateDescriptor->Bits.OffsetLow;
     39   Entry = FspInfoHeader->ImageBase + FspInfoHeader->ImageSize - (~Entry + 1);
     40   IdtGateDescriptor->Bits.OffsetHigh = (UINT16)(Entry >> 16);
     41   IdtGateDescriptor->Bits.OffsetLow  = (UINT16)Entry;
     42 
     43   return ExceptionHandler;
     44 }
     45 
     46 /**
     47   This interface fills platform specific data.
     48 
     49   @param[in,out]  FspData           Pointer to the FSP global data.
     50 
     51 **/
     52 VOID
     53 EFIAPI
     54 SecGetPlatformData (
     55   IN OUT  FSP_GLOBAL_DATA    *FspData
     56   )
     57 {
     58   FSP_PLAT_DATA    *FspPlatformData;
     59   UINT32            TopOfCar;
     60   UINT32           *StackPtr;
     61   UINT32            DwordSize;
     62 
     63   FspPlatformData = &FspData->PlatformData;
     64 
     65   //
     66   // The entries of platform information, together with the number of them,
     67   // reside in the bottom of stack, left untouched by normal stack operation.
     68   //
     69 
     70   FspPlatformData->DataPtr   = NULL;
     71   FspPlatformData->MicrocodeRegionBase = 0;
     72   FspPlatformData->MicrocodeRegionSize = 0;
     73   FspPlatformData->CodeRegionBase      = 0;
     74   FspPlatformData->CodeRegionSize      = 0;
     75 
     76   //
     77   // Pointer to the size field
     78   //
     79   TopOfCar = PcdGet32(PcdTemporaryRamBase) + PcdGet32(PcdTemporaryRamSize);
     80   StackPtr = (UINT32 *)(TopOfCar - sizeof (UINT32));
     81 
     82   if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {
     83     while (*StackPtr != 0) {
     84       if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {
     85         //
     86         // This following data was pushed onto stack after TempRamInit API
     87         //
     88         DwordSize = 4;
     89         StackPtr  = StackPtr - 1 - DwordSize;
     90         CopyMem (&(FspPlatformData->MicrocodeRegionBase), StackPtr, (DwordSize << 2));
     91         StackPtr--;
     92       } else if (*(StackPtr - 1) == FSP_PER0_SIGNATURE) {
     93         //
     94         // This is the performance data for InitTempMemory API entry/exit
     95         //
     96         DwordSize = 4;
     97         StackPtr  = StackPtr - 1 - DwordSize;
     98         CopyMem (FspData->PerfData, StackPtr, (DwordSize << 2));
     99 
    100         ((UINT8 *)(&FspData->PerfData[0]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY;
    101         ((UINT8 *)(&FspData->PerfData[1]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_EXIT;
    102 
    103         StackPtr--;
    104       } else {
    105         StackPtr -= (*StackPtr);
    106       }
    107     }
    108   }
    109 }
    110 
    111 /**
    112 
    113   Initialize the FSP global data region.
    114   It needs to be done as soon as possible after the stack is setup.
    115 
    116   @param[in,out] PeiFspData             Pointer of the FSP global data.
    117   @param[in]     BootLoaderStack        BootLoader stack.
    118   @param[in]     ApiIdx                 The index of the FSP API.
    119 
    120 **/
    121 VOID
    122 FspGlobalDataInit (
    123   IN OUT  FSP_GLOBAL_DATA    *PeiFspData,
    124   IN UINT32                   BootLoaderStack,
    125   IN UINT8                    ApiIdx
    126   )
    127 {
    128   VOID              *FspmUpdDataPtr;
    129   CHAR8              ImageId[9];
    130   UINTN              Idx;
    131 
    132   //
    133   // Set FSP Global Data pointer
    134   //
    135   SetFspGlobalDataPointer    (PeiFspData);
    136   ZeroMem  ((VOID *)PeiFspData, sizeof(FSP_GLOBAL_DATA));
    137 
    138   PeiFspData->Signature            = FSP_GLOBAL_DATA_SIGNATURE;
    139   PeiFspData->Version              = 0;
    140   PeiFspData->CoreStack            = BootLoaderStack;
    141   PeiFspData->PerfIdx              = 2;
    142   PeiFspData->PerfSig              = FSP_PERFORMANCE_DATA_SIGNATURE;
    143 
    144   SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY);
    145 
    146   //
    147   // Get FSP Header offset
    148   // It may have multiple FVs, so look into the last one for FSP header
    149   //
    150   PeiFspData->FspInfoHeader      = (FSP_INFO_HEADER *)AsmGetFspInfoHeader();
    151   SecGetPlatformData (PeiFspData);
    152 
    153   //
    154   // Set API calling mode
    155   //
    156   SetFspApiCallingIndex (ApiIdx);
    157 
    158   //
    159   // Set UPD pointer
    160   //
    161   FspmUpdDataPtr = (VOID *) GetFspApiParameter ();
    162   if (FspmUpdDataPtr == NULL) {
    163     FspmUpdDataPtr = (VOID *)(PeiFspData->FspInfoHeader->ImageBase + PeiFspData->FspInfoHeader->CfgRegionOffset);
    164   }
    165   SetFspUpdDataPointer (FspmUpdDataPtr);
    166   SetFspMemoryInitUpdDataPointer (FspmUpdDataPtr);
    167   SetFspSiliconInitUpdDataPointer (NULL);
    168 
    169   //
    170   // Initialize serial port
    171   // It might have been done in ProcessLibraryConstructorList(), however,
    172   // the FSP global data is not initialized at that time. So do it again
    173   // for safe.
    174   //
    175   SerialPortInitialize ();
    176 
    177   //
    178   // Ensure the golbal data pointer is valid
    179   //
    180   ASSERT (GetFspGlobalDataPointer () == PeiFspData);
    181 
    182   for (Idx = 0; Idx < 8; Idx++) {
    183     ImageId[Idx] = PeiFspData->FspInfoHeader->ImageId[Idx];
    184   }
    185   ImageId[Idx] = 0;
    186 
    187   DEBUG ((DEBUG_INFO | DEBUG_INIT, "\n============= FSP Spec v%d.%d Header Revision v%x (%a v%x.%x.%x.%x) =============\n", \
    188          (PeiFspData->FspInfoHeader->SpecVersion >> 4) & 0xF, \
    189          PeiFspData->FspInfoHeader->SpecVersion & 0xF, \
    190          PeiFspData->FspInfoHeader->HeaderRevision, \
    191          ImageId, \
    192          (PeiFspData->FspInfoHeader->ImageRevision >> 24) & 0xFF, \
    193          (PeiFspData->FspInfoHeader->ImageRevision >> 16) & 0xFF, \
    194          (PeiFspData->FspInfoHeader->ImageRevision >> 8) & 0xFF, \
    195          PeiFspData->FspInfoHeader->ImageRevision & 0xFF));
    196 }
    197 
    198 /**
    199 
    200   Adjust the FSP data pointers after the stack is migrated to memory.
    201 
    202   @param[in] OffsetGap             The offset gap between the old stack and the new stack.
    203 
    204 **/
    205 VOID
    206 FspDataPointerFixUp (
    207   IN UINT32   OffsetGap
    208   )
    209 {
    210   FSP_GLOBAL_DATA  *NewFspData;
    211 
    212   NewFspData = (FSP_GLOBAL_DATA *)((UINTN)GetFspGlobalDataPointer() + (UINTN)OffsetGap);
    213   SetFspGlobalDataPointer (NewFspData);
    214 }
    215