]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/FspSecCore/SecFsp.c
IntelFsp2Pkg: Adopt FSP 2.4 MultiPhase functions.
[mirror_edk2.git] / IntelFsp2Pkg / FspSecCore / SecFsp.c
1 /** @file
2
3 Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
5
6 **/
7
8 #include "SecFsp.h"
9
10 /**
11
12 Calculate the FSP IDT gate descriptor.
13
14 @param[in] IdtEntryTemplate IDT gate descriptor template.
15
16 @return FSP specific IDT gate descriptor.
17
18 **/
19 IA32_IDT_GATE_DESCRIPTOR
20 FspGetExceptionHandler (
21 IN UINT64 IdtEntryTemplate
22 )
23 {
24 UINT32 Entry;
25 IA32_IDT_GATE_DESCRIPTOR ExceptionHandler;
26 IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor;
27 FSP_INFO_HEADER *FspInfoHeader;
28
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;
37
38 return ExceptionHandler;
39 }
40
41 /**
42 This interface fills platform specific data.
43
44 @param[in,out] FspData Pointer to the FSP global data.
45
46 **/
47 VOID
48 EFIAPI
49 SecGetPlatformData (
50 IN OUT FSP_GLOBAL_DATA *FspData
51 )
52 {
53 FSP_PLAT_DATA *FspPlatformData;
54 UINT32 TopOfCar;
55 UINT32 *StackPtr;
56 UINT32 DwordSize;
57
58 FspPlatformData = &FspData->PlatformData;
59
60 //
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.
63 //
64
65 FspPlatformData->DataPtr = NULL;
66 FspPlatformData->MicrocodeRegionBase = 0;
67 FspPlatformData->MicrocodeRegionSize = 0;
68 FspPlatformData->CodeRegionBase = 0;
69 FspPlatformData->CodeRegionSize = 0;
70
71 //
72 // Pointer to the size field
73 //
74 TopOfCar = PcdGet32 (PcdTemporaryRamBase) + PcdGet32 (PcdTemporaryRamSize);
75 StackPtr = (UINT32 *)(TopOfCar - sizeof (UINT32));
76
77 if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {
78 while (*StackPtr != 0) {
79 if (*(StackPtr - 1) == FSP_MCUD_SIGNATURE) {
80 //
81 // This following data was pushed onto stack after TempRamInit API
82 //
83 DwordSize = 4;
84 StackPtr = StackPtr - 1 - DwordSize;
85 CopyMem (&(FspPlatformData->MicrocodeRegionBase), StackPtr, (DwordSize << 2));
86 StackPtr--;
87 } else if (*(StackPtr - 1) == FSP_PER0_SIGNATURE) {
88 //
89 // This is the performance data for InitTempMemory API entry/exit
90 //
91 DwordSize = 4;
92 StackPtr = StackPtr - 1 - DwordSize;
93 CopyMem (FspData->PerfData, StackPtr, (DwordSize << 2));
94
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;
97
98 StackPtr--;
99 } else {
100 StackPtr -= (*StackPtr);
101 }
102 }
103 }
104 }
105
106 /**
107
108 Initialize the FSP global data region.
109 It needs to be done as soon as possible after the stack is setup.
110
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.
114
115 **/
116 VOID
117 FspGlobalDataInit (
118 IN OUT FSP_GLOBAL_DATA *PeiFspData,
119 IN UINTN BootLoaderStack,
120 IN UINT8 ApiIdx
121 )
122 {
123 VOID *FspmUpdDataPtr;
124 CHAR8 ImageId[9];
125 UINTN Idx;
126
127 //
128 // Set FSP Global Data pointer
129 //
130 SetFspGlobalDataPointer (PeiFspData);
131 ZeroMem ((VOID *)PeiFspData, sizeof (FSP_GLOBAL_DATA));
132
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;
138 //
139 // Cache FspHobList pointer passed by bootloader via ApiParameter2
140 //
141 PeiFspData->FspHobListPtr = (VOID **)GetFspApiParameter2 ();
142
143 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_ENTRY);
144
145 //
146 // Get FSP Header offset
147 // It may have multiple FVs, so look into the last one for FSP header
148 //
149 PeiFspData->FspInfoHeader = (FSP_INFO_HEADER *)(UINTN)AsmGetFspInfoHeader ();
150 SecGetPlatformData (PeiFspData);
151
152 //
153 // Set API calling mode
154 //
155 SetFspApiCallingIndex (ApiIdx);
156
157 //
158 // Set UPD pointer
159 //
160 FspmUpdDataPtr = (VOID *)GetFspApiParameter ();
161 if (FspmUpdDataPtr == NULL) {
162 FspmUpdDataPtr = (VOID *)(UINTN)(PeiFspData->FspInfoHeader->ImageBase + PeiFspData->FspInfoHeader->CfgRegionOffset);
163 }
164
165 SetFspUpdDataPointer (FspmUpdDataPtr);
166 SetFspMemoryInitUpdDataPointer (FspmUpdDataPtr);
167 SetFspSiliconInitUpdDataPointer (NULL);
168
169 //
170 // Initialize OnSeparateStack value.
171 //
172 if (PcdGet8 (PcdFspHeapSizePercentage) != 0) {
173 //
174 // FSP is running on its own stack and may need switching stack when calling bootloader functions.
175 //
176 GetFspGlobalDataPointer ()->OnSeparateStack = 1;
177 }
178
179 //
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
183 // for safe.
184 //
185 SerialPortInitialize ();
186
187 //
188 // Ensure the global data pointer is valid
189 //
190 ASSERT (GetFspGlobalDataPointer () == PeiFspData);
191
192 for (Idx = 0; Idx < 8; Idx++) {
193 ImageId[Idx] = PeiFspData->FspInfoHeader->ImageId[Idx];
194 }
195
196 ImageId[Idx] = 0;
197
198 DEBUG ((
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, \
204 ImageId, \
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)
213 ));
214 }
215
216 /**
217
218 Adjust the FSP data pointers after the stack is migrated to memory.
219
220 @param[in] OffsetGap The offset gap between the old stack and the new stack.
221
222 **/
223 VOID
224 FspDataPointerFixUp (
225 IN UINTN OffsetGap
226 )
227 {
228 FSP_GLOBAL_DATA *NewFspData;
229
230 NewFspData = (FSP_GLOBAL_DATA *)((UINTN)GetFspGlobalDataPointer () + (UINTN)OffsetGap);
231 SetFspGlobalDataPointer (NewFspData);
232 }