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