Update IntelFspPkg to support FSP1.1
[mirror_edk2.git] / IntelFspPkg / Library / BaseFspCommonLib / FspCommonLib.c
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 offset exit +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 ExitOff;
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 Set FSP measurement point timestamp.
294
295 @param[in] Id Measurement point ID.
296
297 @return performance timestamp.
298 **/
299 UINT64
300 EFIAPI
301 SetFspMeasurePoint (
302 IN UINT8 Id
303 )
304 {
305 FSP_GLOBAL_DATA *FspData;
306
307 //
308 // Bit [55: 0] will be the timestamp
309 // Bit [63:56] will be the ID
310 //
311 FspData = GetFspGlobalDataPointer ();
312 if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) {
313 FspData->PerfData[FspData->PerfIdx] = AsmReadTsc ();
314 ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id;
315 }
316
317 return FspData->PerfData[(FspData->PerfIdx)++];
318 }
319
320 /**
321 This function gets the FSP info header pointer.
322
323 @retval FspInfoHeader FSP info header pointer
324 **/
325 FSP_INFO_HEADER *
326 EFIAPI
327 GetFspInfoHeader (
328 VOID
329 )
330 {
331 return GetFspGlobalDataPointer()->FspInfoHeader;
332 }
333
334 /**
335 This function gets the VPD data pointer.
336
337 @return VpdDataRgnPtr VPD data pointer.
338 **/
339 VOID *
340 EFIAPI
341 GetFspVpdDataPointer (
342 VOID
343 )
344 {
345 FSP_INFO_HEADER *FspInfoHeader;
346
347 FspInfoHeader = GetFspInfoHeader ();
348 return (VOID *)(FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset);
349 }
350
351 /**
352 This function gets FSP API calling mode.
353
354 @retval API calling mode
355 **/
356 UINT8
357 EFIAPI
358 GetFspApiCallingMode (
359 VOID
360 )
361 {
362 return GetFspGlobalDataPointer()->ApiMode;
363 }
364
365 /**
366 This function sets FSP API calling mode.
367
368 @param[in] Mode API calling mode
369 **/
370 VOID
371 EFIAPI
372 SetFspApiCallingMode (
373 UINT8 Mode
374 )
375 {
376 FSP_GLOBAL_DATA *FspData;
377
378 FspData = GetFspGlobalDataPointer ();
379 FspData->ApiMode = Mode;
380 }
381