3 Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
12 Calculate the FSP IDT gate descriptor.
14 @param[in] IdtEntryTemplate IDT gate descriptor template.
16 @return FSP specific IDT gate descriptor.
19 IA32_IDT_GATE_DESCRIPTOR
20 FspGetExceptionHandler (
21 IN UINT64 IdtEntryTemplate
25 IA32_IDT_GATE_DESCRIPTOR ExceptionHandler
;
26 IA32_IDT_GATE_DESCRIPTOR
*IdtGateDescriptor
;
27 FSP_INFO_HEADER
*FspInfoHeader
;
29 ZeroMem ((VOID
*)&ExceptionHandler
, sizeof (IA32_IDT_GATE_DESCRIPTOR
));
30 FspInfoHeader
= (FSP_INFO_HEADER
*)(UINTN
)AsmGetFspInfoHeader ();
31 *(UINT64
*) &ExceptionHandler
= IdtEntryTemplate
;
32 IdtGateDescriptor
= &ExceptionHandler
;
33 Entry
= (IdtGateDescriptor
->Bits
.OffsetHigh
<< 16) | IdtGateDescriptor
->Bits
.OffsetLow
;
34 Entry
= FspInfoHeader
->ImageBase
+ FspInfoHeader
->ImageSize
- (~Entry
+ 1);
35 IdtGateDescriptor
->Bits
.OffsetHigh
= (UINT16
)(Entry
>> 16);
36 IdtGateDescriptor
->Bits
.OffsetLow
= (UINT16
)Entry
;
38 return ExceptionHandler
;
42 This interface fills platform specific data.
44 @param[in,out] FspData Pointer to the FSP global data.
50 IN OUT FSP_GLOBAL_DATA
*FspData
53 FSP_PLAT_DATA
*FspPlatformData
;
58 FspPlatformData
= &FspData
->PlatformData
;
61 // The entries of platform information, together with the number of them,
62 // reside in the bottom of stack, left untouched by normal stack operation.
65 FspPlatformData
->DataPtr
= NULL
;
66 FspPlatformData
->MicrocodeRegionBase
= 0;
67 FspPlatformData
->MicrocodeRegionSize
= 0;
68 FspPlatformData
->CodeRegionBase
= 0;
69 FspPlatformData
->CodeRegionSize
= 0;
72 // Pointer to the size field
74 TopOfCar
= PcdGet32 (PcdTemporaryRamBase
) + PcdGet32 (PcdTemporaryRamSize
);
75 StackPtr
= (UINT32
*)(TopOfCar
- sizeof (UINT32
));
77 if (*(StackPtr
- 1) == FSP_MCUD_SIGNATURE
) {
78 while (*StackPtr
!= 0) {
79 if (*(StackPtr
- 1) == FSP_MCUD_SIGNATURE
) {
81 // This following data was pushed onto stack after TempRamInit API
84 StackPtr
= StackPtr
- 1 - DwordSize
;
85 CopyMem (&(FspPlatformData
->MicrocodeRegionBase
), StackPtr
, (DwordSize
<< 2));
87 } else if (*(StackPtr
- 1) == FSP_PER0_SIGNATURE
) {
89 // This is the performance data for InitTempMemory API entry/exit
92 StackPtr
= StackPtr
- 1 - DwordSize
;
93 CopyMem (FspData
->PerfData
, StackPtr
, (DwordSize
<< 2));
95 ((UINT8
*)(&FspData
->PerfData
[0]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY
;
96 ((UINT8
*)(&FspData
->PerfData
[1]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_EXIT
;
100 StackPtr
-= (*StackPtr
);
108 Initialize the FSP global data region.
109 It needs to be done as soon as possible after the stack is setup.
111 @param[in,out] PeiFspData Pointer of the FSP global data.
112 @param[in] BootLoaderStack BootLoader stack.
113 @param[in] ApiIdx The index of the FSP API.
118 IN OUT FSP_GLOBAL_DATA
*PeiFspData
,
119 IN UINTN BootLoaderStack
,
123 VOID
*FspmUpdDataPtr
;
128 // Set FSP Global Data pointer
130 SetFspGlobalDataPointer (PeiFspData
);
131 ZeroMem ((VOID
*)PeiFspData
, sizeof (FSP_GLOBAL_DATA
));
133 PeiFspData
->Signature
= FSP_GLOBAL_DATA_SIGNATURE
;
134 PeiFspData
->Version
= FSP_GLOBAL_DATA_VERSION
;
135 PeiFspData
->CoreStack
= BootLoaderStack
;
136 PeiFspData
->PerfIdx
= 2;
137 PeiFspData
->PerfSig
= FSP_PERFORMANCE_DATA_SIGNATURE
;
139 // Cache FspHobList pointer passed by bootloader via ApiParameter2
141 PeiFspData
->FspHobListPtr
= (VOID
**)GetFspApiParameter2 ();
143 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY
);
146 // Get FSP Header offset
147 // It may have multiple FVs, so look into the last one for FSP header
149 PeiFspData
->FspInfoHeader
= (FSP_INFO_HEADER
*)(UINTN
)AsmGetFspInfoHeader ();
150 SecGetPlatformData (PeiFspData
);
153 // Set API calling mode
155 SetFspApiCallingIndex (ApiIdx
);
160 FspmUpdDataPtr
= (VOID
*)GetFspApiParameter ();
161 if (FspmUpdDataPtr
== NULL
) {
162 FspmUpdDataPtr
= (VOID
*)(UINTN
)(PeiFspData
->FspInfoHeader
->ImageBase
+ PeiFspData
->FspInfoHeader
->CfgRegionOffset
);
165 SetFspUpdDataPointer (FspmUpdDataPtr
);
166 SetFspMemoryInitUpdDataPointer (FspmUpdDataPtr
);
167 SetFspSiliconInitUpdDataPointer (NULL
);
170 // Initialize OnSeparateStack value.
172 if (PcdGet8 (PcdFspHeapSizePercentage
) != 0) {
174 // FSP is running on its own stack and may need switching stack when calling bootloader functions.
176 GetFspGlobalDataPointer ()->OnSeparateStack
= 1;
180 // Initialize serial port
181 // It might have been done in ProcessLibraryConstructorList(), however,
182 // the FSP global data is not initialized at that time. So do it again
185 SerialPortInitialize ();
188 // Ensure the global data pointer is valid
190 ASSERT (GetFspGlobalDataPointer () == PeiFspData
);
192 for (Idx
= 0; Idx
< 8; Idx
++) {
193 ImageId
[Idx
] = PeiFspData
->FspInfoHeader
->ImageId
[Idx
];
199 DEBUG_INFO
| DEBUG_INIT
,
200 "\n============= FSP Spec v%d.%d Header Revision v%x (%a v%x.%x.%x.%x) =============\n", \
201 (PeiFspData
->FspInfoHeader
->SpecVersion
>> 4) & 0xF, \
202 PeiFspData
->FspInfoHeader
->SpecVersion
& 0xF, \
203 PeiFspData
->FspInfoHeader
->HeaderRevision
, \
205 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 24) & 0xFF, \
206 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 16) & 0xFF, \
207 (PeiFspData
->FspInfoHeader
->HeaderRevision
>= 6) ? \
208 (((PeiFspData
->FspInfoHeader
->ImageRevision
>> 8) & 0xFF) | (PeiFspData
->FspInfoHeader
->ExtendedImageRevision
& 0xFF00)) : \
209 ((PeiFspData
->FspInfoHeader
->ImageRevision
>> 8) & 0xFF), \
210 (PeiFspData
->FspInfoHeader
->HeaderRevision
>= 6) ? \
211 ((PeiFspData
->FspInfoHeader
->ImageRevision
& 0xFF) | ((PeiFspData
->FspInfoHeader
->ExtendedImageRevision
& 0xFF) << 8)) : \
212 (PeiFspData
->FspInfoHeader
->ImageRevision
& 0xFF)
218 Adjust the FSP data pointers after the stack is migrated to memory.
220 @param[in] OffsetGap The offset gap between the old stack and the new stack.
224 FspDataPointerFixUp (
228 FSP_GLOBAL_DATA
*NewFspData
;
230 NewFspData
= (FSP_GLOBAL_DATA
*)((UINTN
)GetFspGlobalDataPointer () + (UINTN
)OffsetGap
);
231 SetFspGlobalDataPointer (NewFspData
);