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 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY
);
142 // Get FSP Header offset
143 // It may have multiple FVs, so look into the last one for FSP header
145 PeiFspData
->FspInfoHeader
= (FSP_INFO_HEADER
*)(UINTN
)AsmGetFspInfoHeader ();
146 SecGetPlatformData (PeiFspData
);
149 // Set API calling mode
151 SetFspApiCallingIndex (ApiIdx
);
156 FspmUpdDataPtr
= (VOID
*)GetFspApiParameter ();
157 if (FspmUpdDataPtr
== NULL
) {
158 FspmUpdDataPtr
= (VOID
*)(UINTN
)(PeiFspData
->FspInfoHeader
->ImageBase
+ PeiFspData
->FspInfoHeader
->CfgRegionOffset
);
161 SetFspUpdDataPointer (FspmUpdDataPtr
);
162 SetFspMemoryInitUpdDataPointer (FspmUpdDataPtr
);
163 SetFspSiliconInitUpdDataPointer (NULL
);
166 // Initialize OnSeparateStack value.
168 if (PcdGet8 (PcdFspHeapSizePercentage
) != 0) {
170 // FSP is running on its own stack and may need switching stack when calling bootloader functions.
172 GetFspGlobalDataPointer ()->OnSeparateStack
= 1;
176 // Initialize serial port
177 // It might have been done in ProcessLibraryConstructorList(), however,
178 // the FSP global data is not initialized at that time. So do it again
181 SerialPortInitialize ();
184 // Ensure the global data pointer is valid
186 ASSERT (GetFspGlobalDataPointer () == PeiFspData
);
188 for (Idx
= 0; Idx
< 8; Idx
++) {
189 ImageId
[Idx
] = PeiFspData
->FspInfoHeader
->ImageId
[Idx
];
195 DEBUG_INFO
| DEBUG_INIT
,
196 "\n============= FSP Spec v%d.%d Header Revision v%x (%a v%x.%x.%x.%x) =============\n", \
197 (PeiFspData
->FspInfoHeader
->SpecVersion
>> 4) & 0xF, \
198 PeiFspData
->FspInfoHeader
->SpecVersion
& 0xF, \
199 PeiFspData
->FspInfoHeader
->HeaderRevision
, \
201 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 24) & 0xFF, \
202 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 16) & 0xFF, \
203 (PeiFspData
->FspInfoHeader
->HeaderRevision
>= 6) ? \
204 (((PeiFspData
->FspInfoHeader
->ImageRevision
>> 8) & 0xFF) | (PeiFspData
->FspInfoHeader
->ExtendedImageRevision
& 0xFF00)) : \
205 ((PeiFspData
->FspInfoHeader
->ImageRevision
>> 8) & 0xFF), \
206 (PeiFspData
->FspInfoHeader
->HeaderRevision
>= 6) ? \
207 ((PeiFspData
->FspInfoHeader
->ImageRevision
& 0xFF) | ((PeiFspData
->FspInfoHeader
->ExtendedImageRevision
& 0xFF) << 8)) : \
208 (PeiFspData
->FspInfoHeader
->ImageRevision
& 0xFF)
214 Adjust the FSP data pointers after the stack is migrated to memory.
216 @param[in] OffsetGap The offset gap between the old stack and the new stack.
220 FspDataPointerFixUp (
224 FSP_GLOBAL_DATA
*NewFspData
;
226 NewFspData
= (FSP_GLOBAL_DATA
*)((UINTN
)GetFspGlobalDataPointer () + (UINTN
)OffsetGap
);
227 SetFspGlobalDataPointer (NewFspData
);