• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
FspGetExceptionHandler(IN UINT64 IdtEntryTemplate)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
SecGetPlatformData(IN OUT FSP_GLOBAL_DATA * FspData)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
FspGlobalDataInit(IN OUT FSP_GLOBAL_DATA * PeiFspData,IN UINT32 BootLoaderStack,IN UINT8 ApiIdx)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
FspDataPointerFixUp(IN UINT32 OffsetGap)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