3 Copyright (c) 2014 - 2015, 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.
20 FspGetExceptionHandler(
21 IN UINT64 IdtEntryTemplate
25 UINT64 ExceptionHandler
;
26 IA32_IDT_GATE_DESCRIPTOR
*IdtGateDescriptor
;
27 FSP_INFO_HEADER
*FspInfoHeader
;
29 FspInfoHeader
= (FSP_INFO_HEADER
*)AsmGetFspInfoHeader();
30 ExceptionHandler
= IdtEntryTemplate
;
31 IdtGateDescriptor
= (IA32_IDT_GATE_DESCRIPTOR
*)&ExceptionHandler
;
32 Entry
= (IdtGateDescriptor
->Bits
.OffsetHigh
<< 16) | IdtGateDescriptor
->Bits
.OffsetLow
;
33 Entry
= FspInfoHeader
->ImageBase
+ FspInfoHeader
->ImageSize
- (~Entry
+ 1);
34 IdtGateDescriptor
->Bits
.OffsetHigh
= (UINT16
)(Entry
>> 16);
35 IdtGateDescriptor
->Bits
.OffsetLow
= (UINT16
)Entry
;
37 return ExceptionHandler
;
41 This function gets the FSP UPD region offset in flash.
43 @return the offset of the UPD region.
48 GetFspUpdRegionOffset (
52 FSP_GLOBAL_DATA
*FspData
;
55 FspData
= GetFspGlobalDataPointer ();
58 // It is required to put PcdUpdRegionOffset at offset 0x000C
60 // gPlatformFspPkgTokenSpaceGuid.PcdUpdRegionOffset | 0x000C | 0x12345678
62 Offset
= (UINT32
*)(FspData
->FspInfoHeader
->ImageBase
+ \
63 FspData
->FspInfoHeader
->CfgRegionOffset
+ 0x0C);
69 This interface fills platform specific data.
71 @param[in,out] FspData Pointer to the FSP global data.
77 IN OUT FSP_GLOBAL_DATA
*FspData
80 FSP_PLAT_DATA
*FspPlatformData
;
85 FspPlatformData
= &FspData
->PlatformData
;
88 // The entries of platform information, together with the number of them,
89 // reside in the bottom of stack, left untouched by normal stack operation.
91 TopOfCar
= PcdGet32 (PcdTemporaryRamBase
) + PcdGet32 (PcdTemporaryRamSize
);
93 FspPlatformData
->DataPtr
= NULL
;
94 FspPlatformData
->MicrocodeRegionBase
= 0;
95 FspPlatformData
->MicrocodeRegionSize
= 0;
96 FspPlatformData
->CodeRegionBase
= 0;
97 FspPlatformData
->CodeRegionSize
= 0;
100 // Pointer to the size field
102 StackPtr
= (UINT32
*)(TopOfCar
- sizeof(UINT32
));
104 while (*StackPtr
!= 0) {
105 if (*(StackPtr
- 1) == FSP_MCUD_SIGNATURE
) {
107 // This following data was pushed onto stack after TempRamInit API
110 StackPtr
= StackPtr
- 1 - DwordSize
;
111 CopyMem (&(FspPlatformData
->MicrocodeRegionBase
), StackPtr
, (DwordSize
<< 2));
113 } else if (*(StackPtr
- 1) == FSP_PER0_SIGNATURE
) {
115 // This is the performance data for InitTempMemory API entry/exit
118 StackPtr
= StackPtr
- 1 - DwordSize
;
119 CopyMem (FspData
->PerfData
, StackPtr
, (DwordSize
<< 2));
120 ((UINT8
*)(&FspData
->PerfData
[0]))[7] = FSP_PERF_ID_API_TMPRAMINIT_ENTRY
;
121 ((UINT8
*)(&FspData
->PerfData
[1]))[7] = FSP_PERF_ID_API_TMPRAMINIT_EXIT
;
124 StackPtr
-= (*StackPtr
);
131 Initialize the FSP global data region.
132 It needs to be done as soon as possible after the stack is setup.
134 @param[in,out] PeiFspData Pointer of the FSP global data.
135 @param[in] BootLoaderStack BootLoader stack.
136 @param[in] ApiIdx The index of the FSP API.
141 IN OUT FSP_GLOBAL_DATA
*PeiFspData
,
142 IN UINT32 BootLoaderStack
,
147 FSP_INIT_PARAMS
*FspInitParams
;
152 // Init PCIE_BAR with value and set global FSP data pointer.
153 // PciExpress Base should have been programmed by platform already.
155 SetFspGlobalDataPointer (PeiFspData
);
156 ZeroMem ((VOID
*)PeiFspData
, sizeof(FSP_GLOBAL_DATA
));
158 PeiFspData
->Signature
= FSP_GLOBAL_DATA_SIGNATURE
;
159 PeiFspData
->CoreStack
= BootLoaderStack
;
160 PeiFspData
->PerfIdx
= 2;
162 SetFspMeasurePoint (FSP_PERF_ID_API_FSPINIT_ENTRY
);
165 // Get FSP Header offset
166 // It may have multiple FVs, so look into the last one for FSP header
168 PeiFspData
->FspInfoHeader
= (FSP_INFO_HEADER
*)AsmGetFspInfoHeader();
169 SecGetPlatformData (PeiFspData
);
172 // Set API calling mode
174 SetFspApiCallingMode (ApiIdx
== 1 ? 0 : 1);
177 // Initialize UPD pointer.
179 FspInitParams
= (FSP_INIT_PARAMS
*)GetFspApiParameter ();
180 UpdDataRgnPtr
= ((FSP_INIT_RT_COMMON_BUFFER
*)FspInitParams
->RtBufferPtr
)->UpdDataRgnPtr
;
181 if (UpdDataRgnPtr
== NULL
) {
182 UpdDataRgnPtr
= (VOID
*)(PeiFspData
->FspInfoHeader
->ImageBase
+ GetFspUpdRegionOffset());
184 SetFspUpdDataPointer (UpdDataRgnPtr
);
187 // Initialize serial port
188 // It might have been done in ProcessLibraryConstructorList(), however,
189 // the FSP global data is not initialized at that time. So do it again
192 SerialPortInitialize ();
195 // Ensure the golbal data pointer is valid
197 ASSERT (GetFspGlobalDataPointer () == PeiFspData
);
199 for (Idx
= 0; Idx
< 8; Idx
++) {
200 ImageId
[Idx
] = PeiFspData
->FspInfoHeader
->ImageId
[Idx
];
204 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "\n============= PEIM FSP v1.%x (%a v%x.%x.%x.%x) =============\n", \
205 PeiFspData
->FspInfoHeader
->HeaderRevision
- 1, \
207 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 24) & 0xff, \
208 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 16) & 0xff, \
209 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 8) & 0xff, \
210 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 0) & 0xff));
216 Adjust the FSP data pointers after the stack is migrated to memory.
218 @param[in] OffsetGap The offset gap between the old stack and the new stack.
222 FspDataPointerFixUp (
226 FSP_GLOBAL_DATA
*NewFspData
;
228 NewFspData
= (FSP_GLOBAL_DATA
*)((UINTN
)GetFspGlobalDataPointer() + (UINTN
)OffsetGap
);
229 SetFspGlobalDataPointer (NewFspData
);
233 This function check the FSP API calling condition.
235 @param[in] ApiIdx Internal index of the FSP API.
236 @param[in] ApiParam Parameter of the FSP API.
247 FSP_GLOBAL_DATA
*FspData
;
248 FSP_INIT_PARAMS
*FspInitParams
;
249 FSP_INIT_RT_COMMON_BUFFER
*FspRtBuffer
;
251 FspInitParams
= (FSP_INIT_PARAMS
*) ApiParam
;
252 FspRtBuffer
= ((FSP_INIT_RT_COMMON_BUFFER
*)FspInitParams
->RtBufferPtr
);
254 Status
= EFI_SUCCESS
;
255 FspData
= GetFspGlobalDataPointer ();
260 if ((UINT32
)FspData
!= 0xFFFFFFFF) {
261 Status
= EFI_UNSUPPORTED
;
262 } else if ((FspRtBuffer
== NULL
) || ((FspRtBuffer
->BootLoaderTolumSize
% EFI_PAGE_SIZE
) != 0) || (EFI_ERROR(FspUpdSignatureCheck(ApiIdx
, ApiParam
)))) {
263 Status
= EFI_INVALID_PARAMETER
;
265 } else if (ApiIdx
== 2) {
269 if ((FspData
== NULL
) || ((UINT32
)FspData
== 0xFFFFFFFF)) {
270 Status
= EFI_UNSUPPORTED
;
272 if (FspData
->Signature
!= FSP_GLOBAL_DATA_SIGNATURE
) {
273 Status
= EFI_UNSUPPORTED
;
276 } else if (ApiIdx
== 3) {
278 // FspMemoryInit check
280 if ((UINT32
)FspData
!= 0xFFFFFFFF) {
281 Status
= EFI_UNSUPPORTED
;
282 } else if ((FspRtBuffer
== NULL
) || ((FspRtBuffer
->BootLoaderTolumSize
% EFI_PAGE_SIZE
) != 0) || (EFI_ERROR(FspUpdSignatureCheck(ApiIdx
, ApiParam
)))) {
283 Status
= EFI_INVALID_PARAMETER
;
285 } else if (ApiIdx
== 4) {
289 if ((FspData
== NULL
) || ((UINT32
)FspData
== 0xFFFFFFFF)) {
290 Status
= EFI_UNSUPPORTED
;
292 if (FspData
->Signature
!= FSP_GLOBAL_DATA_SIGNATURE
) {
293 Status
= EFI_UNSUPPORTED
;
296 } else if (ApiIdx
== 5) {
298 // FspSiliconInit check
300 if ((FspData
== NULL
) || ((UINT32
)FspData
== 0xFFFFFFFF)) {
301 Status
= EFI_UNSUPPORTED
;
303 if (FspData
->Signature
!= FSP_GLOBAL_DATA_SIGNATURE
) {
304 Status
= EFI_UNSUPPORTED
;
305 } else if (EFI_ERROR(FspUpdSignatureCheck(ApiIdx
, ApiParam
))) {
306 Status
= EFI_INVALID_PARAMETER
;
310 Status
= EFI_UNSUPPORTED
;
317 This function gets the boot FV offset in FSP.
318 @return the boot firmware volumen offset inside FSP binary
323 GetBootFirmwareVolumeOffset (
327 return PcdGet32 (PcdFspBootFirmwareVolumeBase
) - PcdGet32 (PcdFspAreaBaseAddress
);