3 Copyright (c) 2014 - 2015, 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.
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.
18 Calculate the FSP IDT gate descriptor.
20 @param[in] IdtEntryTemplate IDT gate descriptor template.
22 @return FSP specific IDT gate descriptor.
26 FspGetExceptionHandler(
27 IN UINT64 IdtEntryTemplate
31 UINT64 ExceptionHandler
;
32 IA32_IDT_GATE_DESCRIPTOR
*IdtGateDescriptor
;
33 FSP_INFO_HEADER
*FspInfoHeader
;
35 FspInfoHeader
= (FSP_INFO_HEADER
*)AsmGetFspInfoHeader();
36 ExceptionHandler
= IdtEntryTemplate
;
37 IdtGateDescriptor
= (IA32_IDT_GATE_DESCRIPTOR
*)&ExceptionHandler
;
38 Entry
= (IdtGateDescriptor
->Bits
.OffsetHigh
<< 16) | IdtGateDescriptor
->Bits
.OffsetLow
;
39 Entry
= FspInfoHeader
->ImageBase
+ FspInfoHeader
->ImageSize
- (~Entry
+ 1);
40 IdtGateDescriptor
->Bits
.OffsetHigh
= (UINT16
)(Entry
>> 16);
41 IdtGateDescriptor
->Bits
.OffsetLow
= (UINT16
)Entry
;
43 return ExceptionHandler
;
47 This function gets the FSP UPD region offset in flash.
49 @return the offset of the UPD region.
54 GetFspUpdRegionOffset (
58 FSP_GLOBAL_DATA
*FspData
;
61 FspData
= GetFspGlobalDataPointer ();
64 // It is required to put PcdUpdRegionOffset at offset 0x000C
66 // gPlatformFspPkgTokenSpaceGuid.PcdUpdRegionOffset | 0x000C | 0x12345678
68 Offset
= (UINT32
*)(FspData
->FspInfoHeader
->ImageBase
+ \
69 FspData
->FspInfoHeader
->CfgRegionOffset
+ 0x0C);
75 This interface fills platform specific data.
77 @param[in,out] FspData Pointer to the FSP global data.
83 IN OUT FSP_GLOBAL_DATA
*FspData
86 FSP_PLAT_DATA
*FspPlatformData
;
91 FspPlatformData
= &FspData
->PlatformData
;
94 // The entries of platform information, together with the number of them,
95 // reside in the bottom of stack, left untouched by normal stack operation.
97 TopOfCar
= PcdGet32 (PcdTemporaryRamBase
) + PcdGet32 (PcdTemporaryRamSize
);
99 FspPlatformData
->DataPtr
= NULL
;
100 FspPlatformData
->MicrocodeRegionBase
= 0;
101 FspPlatformData
->MicrocodeRegionSize
= 0;
102 FspPlatformData
->CodeRegionBase
= 0;
103 FspPlatformData
->CodeRegionSize
= 0;
106 // Pointer to the size field
108 StackPtr
= (UINT32
*)(TopOfCar
- sizeof(UINT32
));
110 while (*StackPtr
!= 0) {
111 if (*(StackPtr
- 1) == FSP_MCUD_SIGNATURE
) {
113 // This following data was pushed onto stack after TempRamInit API
116 StackPtr
= StackPtr
- 1 - DwordSize
;
117 CopyMem (&(FspPlatformData
->MicrocodeRegionBase
), StackPtr
, (DwordSize
<< 2));
119 } else if (*(StackPtr
- 1) == FSP_PER0_SIGNATURE
) {
121 // This is the performance data for InitTempMemory API entry/exit
124 StackPtr
= StackPtr
- 1 - DwordSize
;
125 CopyMem (FspData
->PerfData
, StackPtr
, (DwordSize
<< 2));
126 ((UINT8
*)(&FspData
->PerfData
[0]))[7] = FSP_PERF_ID_API_TMPRAMINIT_ENTRY
;
127 ((UINT8
*)(&FspData
->PerfData
[1]))[7] = FSP_PERF_ID_API_TMPRAMINIT_EXIT
;
130 StackPtr
-= (*StackPtr
);
137 Initialize the FSP global data region.
138 It needs to be done as soon as possible after the stack is setup.
140 @param[in,out] PeiFspData Pointer of the FSP global data.
141 @param[in] BootLoaderStack BootLoader stack.
142 @param[in] ApiIdx The index of the FSP API.
147 IN OUT FSP_GLOBAL_DATA
*PeiFspData
,
148 IN UINT32 BootLoaderStack
,
153 FSP_INIT_PARAMS
*FspInitParams
;
158 // Init PCIE_BAR with value and set global FSP data pointer.
159 // PciExpress Base should have been programmed by platform already.
161 SetFspGlobalDataPointer (PeiFspData
);
162 ZeroMem ((VOID
*)PeiFspData
, sizeof(FSP_GLOBAL_DATA
));
164 PeiFspData
->Signature
= FSP_GLOBAL_DATA_SIGNATURE
;
165 PeiFspData
->CoreStack
= BootLoaderStack
;
166 PeiFspData
->PerfIdx
= 2;
168 SetFspMeasurePoint (FSP_PERF_ID_API_FSPINIT_ENTRY
);
171 // Get FSP Header offset
172 // It may have multiple FVs, so look into the last one for FSP header
174 PeiFspData
->FspInfoHeader
= (FSP_INFO_HEADER
*)AsmGetFspInfoHeader();
175 SecGetPlatformData (PeiFspData
);
178 // Set API calling mode
180 SetFspApiCallingMode (ApiIdx
== 1 ? 0 : 1);
183 // Initialize UPD pointer.
185 FspInitParams
= (FSP_INIT_PARAMS
*)GetFspApiParameter ();
186 UpdDataRgnPtr
= ((FSP_INIT_RT_COMMON_BUFFER
*)FspInitParams
->RtBufferPtr
)->UpdDataRgnPtr
;
187 if (UpdDataRgnPtr
== NULL
) {
188 UpdDataRgnPtr
= (VOID
*)(PeiFspData
->FspInfoHeader
->ImageBase
+ GetFspUpdRegionOffset());
190 SetFspUpdDataPointer (UpdDataRgnPtr
);
193 // Initialize serial port
194 // It might have been done in ProcessLibraryConstructorList(), however,
195 // the FSP global data is not initialized at that time. So do it again
198 SerialPortInitialize ();
201 // Ensure the golbal data pointer is valid
203 ASSERT (GetFspGlobalDataPointer () == PeiFspData
);
205 for (Idx
= 0; Idx
< 8; Idx
++) {
206 ImageId
[Idx
] = PeiFspData
->FspInfoHeader
->ImageId
[Idx
];
210 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "\n============= PEIM FSP v1.%x (%a v%x.%x.%x.%x) =============\n", \
211 PeiFspData
->FspInfoHeader
->HeaderRevision
- 1, \
213 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 24) & 0xff, \
214 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 16) & 0xff, \
215 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 8) & 0xff, \
216 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 0) & 0xff));
222 Adjust the FSP data pointers after the stack is migrated to memory.
224 @param[in] OffsetGap The offset gap between the old stack and the new stack.
228 FspDataPointerFixUp (
232 FSP_GLOBAL_DATA
*NewFspData
;
234 NewFspData
= (FSP_GLOBAL_DATA
*)((UINTN
)GetFspGlobalDataPointer() + (UINTN
)OffsetGap
);
235 SetFspGlobalDataPointer (NewFspData
);
239 This function check the FSP API calling condition.
241 @param[in] ApiIdx Internal index of the FSP API.
242 @param[in] ApiParam Parameter of the FSP API.
253 FSP_GLOBAL_DATA
*FspData
;
254 FSP_INIT_PARAMS
*FspInitParams
;
255 FSP_INIT_RT_COMMON_BUFFER
*FspRtBuffer
;
257 FspInitParams
= (FSP_INIT_PARAMS
*) ApiParam
;
258 FspRtBuffer
= ((FSP_INIT_RT_COMMON_BUFFER
*)FspInitParams
->RtBufferPtr
);
260 Status
= EFI_SUCCESS
;
261 FspData
= GetFspGlobalDataPointer ();
266 if ((UINT32
)FspData
!= 0xFFFFFFFF) {
267 Status
= EFI_UNSUPPORTED
;
268 } else if ((FspRtBuffer
== NULL
) || ((FspRtBuffer
->BootLoaderTolumSize
% EFI_PAGE_SIZE
) != 0) || (EFI_ERROR(FspUpdSignatureCheck(ApiIdx
, ApiParam
)))) {
269 Status
= EFI_INVALID_PARAMETER
;
271 } else if (ApiIdx
== 2) {
275 if ((FspData
== NULL
) || ((UINT32
)FspData
== 0xFFFFFFFF)) {
276 Status
= EFI_UNSUPPORTED
;
278 if (FspData
->Signature
!= FSP_GLOBAL_DATA_SIGNATURE
) {
279 Status
= EFI_UNSUPPORTED
;
282 } else if (ApiIdx
== 3) {
284 // FspMemoryInit check
286 if ((UINT32
)FspData
!= 0xFFFFFFFF) {
287 Status
= EFI_UNSUPPORTED
;
288 } else if ((FspRtBuffer
== NULL
) || ((FspRtBuffer
->BootLoaderTolumSize
% EFI_PAGE_SIZE
) != 0) || (EFI_ERROR(FspUpdSignatureCheck(ApiIdx
, ApiParam
)))) {
289 Status
= EFI_INVALID_PARAMETER
;
291 } else if (ApiIdx
== 4) {
295 if ((FspData
== NULL
) || ((UINT32
)FspData
== 0xFFFFFFFF)) {
296 Status
= EFI_UNSUPPORTED
;
298 if (FspData
->Signature
!= FSP_GLOBAL_DATA_SIGNATURE
) {
299 Status
= EFI_UNSUPPORTED
;
302 } else if (ApiIdx
== 5) {
304 // FspSiliconInit check
306 if ((FspData
== NULL
) || ((UINT32
)FspData
== 0xFFFFFFFF)) {
307 Status
= EFI_UNSUPPORTED
;
309 if (FspData
->Signature
!= FSP_GLOBAL_DATA_SIGNATURE
) {
310 Status
= EFI_UNSUPPORTED
;
311 } else if (EFI_ERROR(FspUpdSignatureCheck(ApiIdx
, ApiParam
))) {
312 Status
= EFI_INVALID_PARAMETER
;
316 Status
= EFI_UNSUPPORTED
;
323 This function gets the boot FV offset in FSP.
324 @return the boot firmware volumen offset inside FSP binary
329 GetBootFirmwareVolumeOffset (
333 return PcdGet32 (PcdFspBootFirmwareVolumeBase
) - PcdGet32 (PcdFspAreaBaseAddress
);