]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c
660e9fc696f5c20edd9cb2f785758f4550982896
[mirror_edk2.git] / IntelFsp2Pkg / Library / BaseFspCommonLib / FspCommonLib.c
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 <PiPei.h>
15 #include <Library/BaseLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/PcdLib.h>
18 #include <FspGlobalData.h>
19 #include <FspEas.h>
20 #include <FspDataTable.h>
21 #include <Library/FspSwitchStackLib.h>
22
23 #pragma pack(1)
24
25 //
26 // API Parameter +0x34
27 // API return address +0x30
28 //
29 // push FspInfoHeader +0x2C
30 // pushfd +0x28
31 // cli
32 // pushad +0x24
33 // sub esp, 8 +0x00
34 // sidt fword ptr [esp]
35 //
36 typedef struct {
37 UINT16 IdtrLimit;
38 UINT32 IdtrBase;
39 UINT16 Reserved;
40 UINT32 Edi;
41 UINT32 Esi;
42 UINT32 Ebp;
43 UINT32 Esp;
44 UINT32 Ebx;
45 UINT32 Edx;
46 UINT32 Ecx;
47 UINT32 Eax;
48 UINT16 Flags[2];
49 UINT32 FspInfoHeader;
50 UINT32 ApiRet;
51 UINT32 ApiParam[2];
52 } CONTEXT_STACK;
53
54 #define CONTEXT_STACK_OFFSET(x) (UINT32)&((CONTEXT_STACK *)(UINTN)0)->x
55
56 #pragma pack()
57
58 /**
59 This function sets the FSP global data pointer.
60
61 @param[in] FspData Fsp global data pointer.
62
63 **/
64 VOID
65 EFIAPI
66 SetFspGlobalDataPointer (
67 IN FSP_GLOBAL_DATA *FspData
68 )
69 {
70 ASSERT (FspData != NULL);
71 *((volatile UINT32 *)(UINTN)PcdGet32(PcdGlobalDataPointerAddress)) = (UINT32)(UINTN)FspData;
72 }
73
74 /**
75 This function gets the FSP global data pointer.
76
77 **/
78 FSP_GLOBAL_DATA *
79 EFIAPI
80 GetFspGlobalDataPointer (
81 VOID
82 )
83 {
84 FSP_GLOBAL_DATA *FspData;
85
86 FspData = *(FSP_GLOBAL_DATA **)(UINTN)PcdGet32(PcdGlobalDataPointerAddress);
87 return FspData;
88 }
89
90 /**
91 This function gets back the FSP API first parameter passed by the bootlaoder.
92
93 @retval ApiParameter FSP API first parameter passed by the bootlaoder.
94 **/
95 UINT32
96 EFIAPI
97 GetFspApiParameter (
98 VOID
99 )
100 {
101 FSP_GLOBAL_DATA *FspData;
102
103 FspData = GetFspGlobalDataPointer ();
104 return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[0]));
105 }
106
107 /**
108 This function gets back the FSP API second parameter passed by the bootlaoder.
109
110 @retval ApiParameter FSP API second parameter passed by the bootlaoder.
111 **/
112 UINT32
113 EFIAPI
114 GetFspApiParameter2 (
115 VOID
116 )
117 {
118 FSP_GLOBAL_DATA *FspData;
119
120 FspData = GetFspGlobalDataPointer ();
121 return *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam[1]));
122 }
123
124 /**
125 This function sets the FSP API parameter in the stack.
126
127 @param[in] Value New parameter value.
128
129 **/
130 VOID
131 EFIAPI
132 SetFspApiParameter (
133 IN UINT32 Value
134 )
135 {
136 FSP_GLOBAL_DATA *FspData;
137
138 FspData = GetFspGlobalDataPointer ();
139 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(ApiParam)) = Value;
140 }
141
142 /**
143 This function set the API status code returned to the BootLoader.
144
145 @param[in] ReturnStatus Status code to return.
146
147 **/
148 VOID
149 EFIAPI
150 SetFspApiReturnStatus (
151 IN UINT32 ReturnStatus
152 )
153 {
154 FSP_GLOBAL_DATA *FspData;
155
156 FspData = GetFspGlobalDataPointer ();
157 *(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(Eax)) = ReturnStatus;
158 }
159
160 /**
161 This function sets the context switching stack to a new stack frame.
162
163 @param[in] NewStackTop New core stack to be set.
164
165 **/
166 VOID
167 EFIAPI
168 SetFspCoreStackPointer (
169 IN VOID *NewStackTop
170 )
171 {
172 FSP_GLOBAL_DATA *FspData;
173 UINT32 *OldStack;
174 UINT32 *NewStack;
175 UINT32 StackContextLen;
176
177 FspData = GetFspGlobalDataPointer ();
178 StackContextLen = sizeof(CONTEXT_STACK) / sizeof(UINT32);
179
180 //
181 // Reserve space for the ContinuationFunc two parameters
182 //
183 OldStack = (UINT32 *)FspData->CoreStack;
184 NewStack = (UINT32 *)NewStackTop - StackContextLen - 2;
185 FspData->CoreStack = (UINT32)NewStack;
186 while (StackContextLen-- != 0) {
187 *NewStack++ = *OldStack++;
188 }
189 }
190
191 /**
192 This function sets the platform specific data pointer.
193
194 @param[in] PlatformData Fsp platform specific data pointer.
195
196 **/
197 VOID
198 EFIAPI
199 SetFspPlatformDataPointer (
200 IN VOID *PlatformData
201 )
202 {
203 FSP_GLOBAL_DATA *FspData;
204
205 FspData = GetFspGlobalDataPointer ();
206 FspData->PlatformData.DataPtr = PlatformData;
207 }
208
209
210 /**
211 This function gets the platform specific data pointer.
212
213 @param[in] PlatformData Fsp platform specific data pointer.
214
215 **/
216 VOID *
217 EFIAPI
218 GetFspPlatformDataPointer (
219 VOID
220 )
221 {
222 FSP_GLOBAL_DATA *FspData;
223
224 FspData = GetFspGlobalDataPointer ();
225 return FspData->PlatformData.DataPtr;
226 }
227
228
229 /**
230 This function sets the UPD data pointer.
231
232 @param[in] UpdDataPtr UPD data pointer.
233 **/
234 VOID
235 EFIAPI
236 SetFspUpdDataPointer (
237 IN VOID *UpdDataPtr
238 )
239 {
240 FSP_GLOBAL_DATA *FspData;
241
242 //
243 // Get the Fsp Global Data Pointer
244 //
245 FspData = GetFspGlobalDataPointer ();
246
247 //
248 // Set the UPD pointer.
249 //
250 FspData->UpdDataPtr = UpdDataPtr;
251 }
252
253 /**
254 This function gets the UPD data pointer.
255
256 @return UpdDataPtr UPD data pointer.
257 **/
258 VOID *
259 EFIAPI
260 GetFspUpdDataPointer (
261 VOID
262 )
263 {
264 FSP_GLOBAL_DATA *FspData;
265
266 FspData = GetFspGlobalDataPointer ();
267 return FspData->UpdDataPtr;
268 }
269
270
271 /**
272 This function sets the memory init UPD data pointer.
273
274 @param[in] MemoryInitUpdPtr memory init UPD data pointer.
275 **/
276 VOID
277 EFIAPI
278 SetFspMemoryInitUpdDataPointer (
279 IN VOID *MemoryInitUpdPtr
280 )
281 {
282 FSP_GLOBAL_DATA *FspData;
283
284 //
285 // Get the Fsp Global Data Pointer
286 //
287 FspData = GetFspGlobalDataPointer ();
288
289 //
290 // Set the memory init UPD pointer.
291 //
292 FspData->MemoryInitUpdPtr = MemoryInitUpdPtr;
293 }
294
295 /**
296 This function gets the memory init UPD data pointer.
297
298 @return memory init UPD data pointer.
299 **/
300 VOID *
301 EFIAPI
302 GetFspMemoryInitUpdDataPointer (
303 VOID
304 )
305 {
306 FSP_GLOBAL_DATA *FspData;
307
308 FspData = GetFspGlobalDataPointer ();
309 return FspData->MemoryInitUpdPtr;
310 }
311
312
313 /**
314 This function sets the silicon init UPD data pointer.
315
316 @param[in] SiliconInitUpdPtr silicon init UPD data pointer.
317 **/
318 VOID
319 EFIAPI
320 SetFspSiliconInitUpdDataPointer (
321 IN VOID *SiliconInitUpdPtr
322 )
323 {
324 FSP_GLOBAL_DATA *FspData;
325
326 //
327 // Get the Fsp Global Data Pointer
328 //
329 FspData = GetFspGlobalDataPointer ();
330
331 //
332 // Set the silicon init UPD data pointer.
333 //
334 FspData->SiliconInitUpdPtr = SiliconInitUpdPtr;
335 }
336
337 /**
338 This function gets the silicon init UPD data pointer.
339
340 @return silicon init UPD data pointer.
341 **/
342 VOID *
343 EFIAPI
344 GetFspSiliconInitUpdDataPointer (
345 VOID
346 )
347 {
348 FSP_GLOBAL_DATA *FspData;
349
350 FspData = GetFspGlobalDataPointer ();
351 return FspData->SiliconInitUpdPtr;
352 }
353
354
355 /**
356 Set FSP measurement point timestamp.
357
358 @param[in] Id Measurement point ID.
359
360 @return performance timestamp.
361 **/
362 UINT64
363 EFIAPI
364 SetFspMeasurePoint (
365 IN UINT8 Id
366 )
367 {
368 FSP_GLOBAL_DATA *FspData;
369
370 //
371 // Bit [55: 0] will be the timestamp
372 // Bit [63:56] will be the ID
373 //
374 FspData = GetFspGlobalDataPointer ();
375 if (FspData->PerfIdx < sizeof(FspData->PerfData) / sizeof(FspData->PerfData[0])) {
376 FspData->PerfData[FspData->PerfIdx] = AsmReadTsc ();
377 ((UINT8 *)(&FspData->PerfData[FspData->PerfIdx]))[7] = Id;
378 }
379
380 return FspData->PerfData[(FspData->PerfIdx)++];
381 }
382
383 /**
384 This function gets the FSP info header pointer.
385
386 @retval FspInfoHeader FSP info header pointer
387 **/
388 FSP_INFO_HEADER *
389 EFIAPI
390 GetFspInfoHeader (
391 VOID
392 )
393 {
394 return GetFspGlobalDataPointer()->FspInfoHeader;
395 }
396
397 /**
398 This function sets the FSP info header pointer.
399
400 @param[in] FspInfoHeader FSP info header pointer
401 **/
402 VOID
403 EFIAPI
404 SetFspInfoHeader (
405 FSP_INFO_HEADER *FspInfoHeader
406 )
407 {
408 GetFspGlobalDataPointer()->FspInfoHeader = FspInfoHeader;
409 }
410
411 /**
412 This function gets the FSP info header pointer using the API stack context.
413
414 @retval FspInfoHeader FSP info header pointer using the API stack context
415 **/
416 FSP_INFO_HEADER *
417 EFIAPI
418 GetFspInfoHeaderFromApiContext (
419 VOID
420 )
421 {
422 FSP_GLOBAL_DATA *FspData;
423
424 FspData = GetFspGlobalDataPointer ();
425 return (FSP_INFO_HEADER *)(*(UINT32 *)(UINTN)(FspData->CoreStack + CONTEXT_STACK_OFFSET(FspInfoHeader)));
426 }
427
428 /**
429 This function gets the CfgRegion data pointer.
430
431 @return CfgRegion data pointer.
432 **/
433 VOID *
434 EFIAPI
435 GetFspCfgRegionDataPointer (
436 VOID
437 )
438 {
439 FSP_INFO_HEADER *FspInfoHeader;
440
441 FspInfoHeader = GetFspInfoHeader ();
442 return (VOID *)(FspInfoHeader->ImageBase + FspInfoHeader->CfgRegionOffset);
443 }
444
445 /**
446 This function gets FSP API calling index.
447
448 @retval API calling index
449 **/
450 UINT8
451 EFIAPI
452 GetFspApiCallingIndex (
453 VOID
454 )
455 {
456 return GetFspGlobalDataPointer()->ApiIdx;
457 }
458
459 /**
460 This function sets FSP API calling mode.
461
462 @param[in] Index API calling index
463 **/
464 VOID
465 EFIAPI
466 SetFspApiCallingIndex (
467 UINT8 Index
468 )
469 {
470 FSP_GLOBAL_DATA *FspData;
471
472 FspData = GetFspGlobalDataPointer ();
473 FspData->ApiIdx = Index;
474 }
475
476 /**
477 This function gets FSP Phase StatusCode.
478
479 @retval StatusCode
480 **/
481 UINT32
482 EFIAPI
483 GetPhaseStatusCode (
484 VOID
485 )
486 {
487 return GetFspGlobalDataPointer()->StatusCode;
488 }
489
490 /**
491 This function sets FSP Phase StatusCode.
492
493 @param[in] Mode Phase StatusCode
494 **/
495 VOID
496 EFIAPI
497 SetPhaseStatusCode (
498 UINT32 StatusCode
499 )
500 {
501 FSP_GLOBAL_DATA *FspData;
502
503 FspData = GetFspGlobalDataPointer ();
504 FspData->StatusCode = StatusCode;
505 }
506
507 /**
508 This function updates the return status of the FSP API with requested reset type and returns to Boot Loader.
509
510 @param[in] FspResetType Reset type that needs to returned as API return status
511
512 **/
513 VOID
514 EFIAPI
515 FspApiReturnStatusReset (
516 IN UINT32 FspResetType
517 )
518 {
519 volatile BOOLEAN LoopUntilReset;
520
521 LoopUntilReset = TRUE;
522 DEBUG ((DEBUG_INFO, "FSP returning control to Bootloader with reset required return status %x\n",FspResetType));
523 ///
524 /// Below code is not an infinite loop.The control will go back to API calling function in BootLoader each time BootLoader
525 /// calls the FSP API without honoring the reset request by FSP
526 ///
527 do {
528 SetFspApiReturnStatus ((EFI_STATUS)FspResetType);
529 Pei2LoaderSwitchStack ();
530 DEBUG ((DEBUG_ERROR, "!!!ERROR: FSP has requested BootLoader for reset. But BootLoader has not honored the reset\n"));
531 DEBUG ((DEBUG_ERROR, "!!!ERROR: Please add support in BootLoader to honour the reset request from FSP\n"));
532 } while (LoopUntilReset);
533 }