3 Copyright (c) 2014 - 2020, 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 interface fills platform specific data.
43 @param[in,out] FspData Pointer to the FSP global data.
49 IN OUT FSP_GLOBAL_DATA
*FspData
52 FSP_PLAT_DATA
*FspPlatformData
;
57 FspPlatformData
= &FspData
->PlatformData
;
60 // The entries of platform information, together with the number of them,
61 // reside in the bottom of stack, left untouched by normal stack operation.
64 FspPlatformData
->DataPtr
= NULL
;
65 FspPlatformData
->MicrocodeRegionBase
= 0;
66 FspPlatformData
->MicrocodeRegionSize
= 0;
67 FspPlatformData
->CodeRegionBase
= 0;
68 FspPlatformData
->CodeRegionSize
= 0;
71 // Pointer to the size field
73 TopOfCar
= PcdGet32(PcdTemporaryRamBase
) + PcdGet32(PcdTemporaryRamSize
);
74 StackPtr
= (UINT32
*)(TopOfCar
- sizeof (UINT32
));
76 if (*(StackPtr
- 1) == FSP_MCUD_SIGNATURE
) {
77 while (*StackPtr
!= 0) {
78 if (*(StackPtr
- 1) == FSP_MCUD_SIGNATURE
) {
80 // This following data was pushed onto stack after TempRamInit API
83 StackPtr
= StackPtr
- 1 - DwordSize
;
84 CopyMem (&(FspPlatformData
->MicrocodeRegionBase
), StackPtr
, (DwordSize
<< 2));
86 } else if (*(StackPtr
- 1) == FSP_PER0_SIGNATURE
) {
88 // This is the performance data for InitTempMemory API entry/exit
91 StackPtr
= StackPtr
- 1 - DwordSize
;
92 CopyMem (FspData
->PerfData
, StackPtr
, (DwordSize
<< 2));
94 ((UINT8
*)(&FspData
->PerfData
[0]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_ENTRY
;
95 ((UINT8
*)(&FspData
->PerfData
[1]))[7] = FSP_PERF_ID_API_TEMP_RAM_INIT_EXIT
;
99 StackPtr
-= (*StackPtr
);
107 Initialize the FSP global data region.
108 It needs to be done as soon as possible after the stack is setup.
110 @param[in,out] PeiFspData Pointer of the FSP global data.
111 @param[in] BootLoaderStack BootLoader stack.
112 @param[in] ApiIdx The index of the FSP API.
117 IN OUT FSP_GLOBAL_DATA
*PeiFspData
,
118 IN UINT32 BootLoaderStack
,
122 VOID
*FspmUpdDataPtr
;
127 // Set FSP Global Data pointer
129 SetFspGlobalDataPointer (PeiFspData
);
130 ZeroMem ((VOID
*)PeiFspData
, sizeof(FSP_GLOBAL_DATA
));
132 PeiFspData
->Signature
= FSP_GLOBAL_DATA_SIGNATURE
;
133 PeiFspData
->Version
= 0;
134 PeiFspData
->CoreStack
= BootLoaderStack
;
135 PeiFspData
->PerfIdx
= 2;
136 PeiFspData
->PerfSig
= FSP_PERFORMANCE_DATA_SIGNATURE
;
138 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY
);
141 // Get FSP Header offset
142 // It may have multiple FVs, so look into the last one for FSP header
144 PeiFspData
->FspInfoHeader
= (FSP_INFO_HEADER
*)AsmGetFspInfoHeader();
145 SecGetPlatformData (PeiFspData
);
148 // Set API calling mode
150 SetFspApiCallingIndex (ApiIdx
);
155 FspmUpdDataPtr
= (VOID
*) GetFspApiParameter ();
156 if (FspmUpdDataPtr
== NULL
) {
157 FspmUpdDataPtr
= (VOID
*)(PeiFspData
->FspInfoHeader
->ImageBase
+ PeiFspData
->FspInfoHeader
->CfgRegionOffset
);
159 SetFspUpdDataPointer (FspmUpdDataPtr
);
160 SetFspMemoryInitUpdDataPointer (FspmUpdDataPtr
);
161 SetFspSiliconInitUpdDataPointer (NULL
);
164 // Initialize OnSeparateStack value.
166 if (PcdGet8 (PcdFspHeapSizePercentage
) != 0) {
168 // FSP is running on its own stack and may need switching stack when calling bootloader functions.
170 GetFspGlobalDataPointer ()->OnSeparateStack
= 1;
174 // Initialize serial port
175 // It might have been done in ProcessLibraryConstructorList(), however,
176 // the FSP global data is not initialized at that time. So do it again
179 SerialPortInitialize ();
182 // Ensure the global data pointer is valid
184 ASSERT (GetFspGlobalDataPointer () == PeiFspData
);
186 for (Idx
= 0; Idx
< 8; Idx
++) {
187 ImageId
[Idx
] = PeiFspData
->FspInfoHeader
->ImageId
[Idx
];
191 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "\n============= FSP Spec v%d.%d Header Revision v%x (%a v%x.%x.%x.%x) =============\n", \
192 (PeiFspData
->FspInfoHeader
->SpecVersion
>> 4) & 0xF, \
193 PeiFspData
->FspInfoHeader
->SpecVersion
& 0xF, \
194 PeiFspData
->FspInfoHeader
->HeaderRevision
, \
196 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 24) & 0xFF, \
197 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 16) & 0xFF, \
198 (PeiFspData
->FspInfoHeader
->ImageRevision
>> 8) & 0xFF, \
199 PeiFspData
->FspInfoHeader
->ImageRevision
& 0xFF));
204 Adjust the FSP data pointers after the stack is migrated to memory.
206 @param[in] OffsetGap The offset gap between the old stack and the new stack.
210 FspDataPointerFixUp (
214 FSP_GLOBAL_DATA
*NewFspData
;
216 NewFspData
= (FSP_GLOBAL_DATA
*)((UINTN
)GetFspGlobalDataPointer() + (UINTN
)OffsetGap
);
217 SetFspGlobalDataPointer (NewFspData
);