VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/IntelFsp2Pkg/Library/BaseFspCommonLib/FspCommonLib.c@ 106129

Last change on this file since 106129 was 105670, checked in by vboxsync, 9 months ago

Devices/EFI/FirmwareNew: Merge edk2-stable-202405 and make it build on aarch64, bugref:4643

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette