]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c
IntelFsp2WrapperPkg: Add FSP 2.4 MultiPhase interface.
[mirror_edk2.git] / IntelFsp2WrapperPkg / Library / FspWrapperMultiPhaseProcessLib / PeiFspWrapperMultiPhaseProcessLib.c
1 /** @file
2 Support FSP Wrapper MultiPhase process.
3
4 Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <Library/BaseLib.h>
10 #include <Library/DebugLib.h>
11 #include <Library/PcdLib.h>
12 #include <Library/FspWrapperApiLib.h>
13 #include <Library/FspWrapperPlatformLib.h>
14 #include <FspEas.h>
15 #include <FspGlobalData.h>
16 #include <Ppi/ReadOnlyVariable2.h>
17 #include <Ppi/Variable.h>
18 #include <Library/PeiServicesLib.h>
19 #include <Library/FspWrapperMultiPhaseProcessLib.h>
20
21 /**
22 Execute 32-bit FSP API entry code.
23
24 @param[in] Function The 32bit code entry to be executed.
25 @param[in] Param1 The first parameter to pass to 32bit code.
26 @param[in] Param2 The second parameter to pass to 32bit code.
27
28 @return EFI_STATUS.
29 **/
30 EFI_STATUS
31 Execute32BitCode (
32 IN UINT64 Function,
33 IN UINT64 Param1,
34 IN UINT64 Param2
35 );
36
37 /**
38 Execute 64-bit FSP API entry code.
39
40 @param[in] Function The 64bit code entry to be executed.
41 @param[in] Param1 The first parameter to pass to 64bit code.
42 @param[in] Param2 The second parameter to pass to 64bit code.
43
44 @return EFI_STATUS.
45 **/
46 EFI_STATUS
47 Execute64BitCode (
48 IN UINT64 Function,
49 IN UINT64 Param1,
50 IN UINT64 Param2
51 );
52
53 /**
54 Call FspsMultiPhase API.
55
56 @param[in] FspsMultiPhaseParams - Parameters for MultiPhase API.
57 @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
58 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
59
60 @return EFI_UNSUPPORTED - the requested FspsMultiPhase API is not supported.
61 @return EFI_DEVICE_ERROR - the FSP header was not found.
62 @return EFI status returned by FspsMultiPhase API.
63 **/
64 EFI_STATUS
65 EFIAPI
66 CallFspMultiPhaseEntry (
67 IN VOID *FspMultiPhaseParams,
68 IN OUT VOID **FspHobListPtr,
69 IN UINT8 ComponentIndex
70 )
71 {
72 FSP_INFO_HEADER *FspHeader;
73 //
74 // FSP_MULTI_PHASE_INIT and FSP_MULTI_PHASE_SI_INIT API functions having same prototype.
75 //
76 UINTN FspMultiPhaseApiEntry;
77 UINTN FspMultiPhaseApiOffset;
78 EFI_STATUS Status;
79 BOOLEAN InterruptState;
80
81 if (ComponentIndex == FspMultiPhaseMemInitApiIndex) {
82 FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));
83 if (FspHeader == NULL) {
84 return EFI_DEVICE_ERROR;
85 }
86
87 FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseMemInitEntryOffset;
88 } else if (ComponentIndex == FspMultiPhaseSiInitApiIndex) {
89 FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));
90 if (FspHeader == NULL) {
91 return EFI_DEVICE_ERROR;
92 }
93
94 FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseSiInitEntryOffset;
95 }
96
97 if (FspMultiPhaseApiOffset == 0) {
98 return EFI_UNSUPPORTED;
99 }
100
101 FspMultiPhaseApiEntry = FspHeader->ImageBase + FspMultiPhaseApiOffset;
102 InterruptState = SaveAndDisableInterrupts ();
103 if ((FspHeader->ImageAttribute & BIT2) == 0) {
104 // BIT2: IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT
105 Status = Execute32BitCode ((UINTN)FspMultiPhaseApiEntry, (UINTN)FspMultiPhaseParams, (UINTN)NULL);
106 } else {
107 Status = Execute64BitCode ((UINTN)FspMultiPhaseApiEntry, (UINTN)FspMultiPhaseParams, (UINTN)NULL);
108 }
109
110 SetInterruptState (InterruptState);
111
112 DEBUG ((DEBUG_ERROR, "CallFspMultiPhaseEntry return Status %r \n", Status));
113
114 return Status;
115 }
116
117 /**
118 FSP Wrapper Variable Request Handler
119
120 @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
121 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
122
123 @retval EFI_UNSUPPORTED FSP Wrapper cannot support the specific variable request
124 @retval EFI_STATUS Return FSP returned status
125
126 **/
127 EFI_STATUS
128 EFIAPI
129 FspWrapperVariableRequestHandler (
130 IN OUT VOID **FspHobListPtr,
131 IN UINT8 ComponentIndex
132 )
133 {
134 EFI_STATUS Status;
135 FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams;
136 FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS *FspVariableRequestParams;
137 EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariablePpi;
138 EDKII_PEI_VARIABLE_PPI *VariablePpi;
139 BOOLEAN WriteVariableSupport;
140 FSP_MULTI_PHASE_COMPLETE_VARIABLE_REQUEST_PARAMS CompleteVariableRequestParams;
141
142 WriteVariableSupport = TRUE;
143 Status = PeiServicesLocatePpi (
144 &gEdkiiPeiVariablePpiGuid,
145 0,
146 NULL,
147 (VOID **)&VariablePpi
148 );
149 if (EFI_ERROR (Status)) {
150 WriteVariableSupport = FALSE;
151 Status = PeiServicesLocatePpi (
152 &gEfiPeiReadOnlyVariable2PpiGuid,
153 0,
154 NULL,
155 (VOID **)&ReadOnlyVariablePpi
156 );
157 ASSERT_EFI_ERROR (Status);
158 if (EFI_ERROR (Status)) {
159 return EFI_UNSUPPORTED;
160 }
161 }
162
163 Status = FSP_STATUS_VARIABLE_REQUEST;
164 while (Status == FSP_STATUS_VARIABLE_REQUEST) {
165 //
166 // Get the variable request information from FSP.
167 //
168 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetVariableRequestInfo;
169 FspMultiPhaseParams.PhaseIndex = 0;
170 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
171 ASSERT_EFI_ERROR (Status);
172 //
173 // FSP should output this pointer for variable request information.
174 //
175 FspVariableRequestParams = (FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS *)FspMultiPhaseParams.MultiPhaseParamPtr;
176 switch (FspVariableRequestParams->VariableRequest) {
177 case EnumFspVariableRequestGetVariable:
178 if (WriteVariableSupport) {
179 Status = VariablePpi->GetVariable (
180 VariablePpi,
181 FspVariableRequestParams->VariableName,
182 FspVariableRequestParams->VariableGuid,
183 FspVariableRequestParams->Attributes,
184 (UINTN *)FspVariableRequestParams->DataSize,
185 FspVariableRequestParams->Data
186 );
187 } else {
188 Status = ReadOnlyVariablePpi->GetVariable (
189 ReadOnlyVariablePpi,
190 FspVariableRequestParams->VariableName,
191 FspVariableRequestParams->VariableGuid,
192 FspVariableRequestParams->Attributes,
193 (UINTN *)FspVariableRequestParams->DataSize,
194 FspVariableRequestParams->Data
195 );
196 }
197
198 CompleteVariableRequestParams.VariableRequestStatus = Status;
199 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
200 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
201 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
202 break;
203
204 case EnumFspVariableRequestSetVariable:
205 if (WriteVariableSupport) {
206 Status = VariablePpi->SetVariable (
207 VariablePpi,
208 FspVariableRequestParams->VariableName,
209 FspVariableRequestParams->VariableGuid,
210 *FspVariableRequestParams->Attributes,
211 (UINTN)*FspVariableRequestParams->DataSize,
212 FspVariableRequestParams->Data
213 );
214 } else {
215 Status = EFI_UNSUPPORTED;
216 }
217
218 CompleteVariableRequestParams.VariableRequestStatus = Status;
219 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
220 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
221 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
222 break;
223
224 case EnumFspVariableRequestGetNextVariableName:
225 if (WriteVariableSupport) {
226 Status = VariablePpi->GetNextVariableName (
227 VariablePpi,
228 (UINTN *)FspVariableRequestParams->VariableNameSize,
229 FspVariableRequestParams->VariableName,
230 FspVariableRequestParams->VariableGuid
231 );
232 } else {
233 Status = ReadOnlyVariablePpi->NextVariableName (
234 ReadOnlyVariablePpi,
235 (UINTN *)FspVariableRequestParams->VariableNameSize,
236 FspVariableRequestParams->VariableName,
237 FspVariableRequestParams->VariableGuid
238 );
239 }
240
241 CompleteVariableRequestParams.VariableRequestStatus = Status;
242 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
243 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
244 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
245 break;
246
247 case EnumFspVariableRequestQueryVariableInfo:
248 if (WriteVariableSupport) {
249 Status = VariablePpi->QueryVariableInfo (
250 VariablePpi,
251 *FspVariableRequestParams->Attributes,
252 FspVariableRequestParams->MaximumVariableStorageSize,
253 FspVariableRequestParams->RemainingVariableStorageSize,
254 FspVariableRequestParams->MaximumVariableSize
255 );
256 } else {
257 Status = EFI_UNSUPPORTED;
258 }
259
260 CompleteVariableRequestParams.VariableRequestStatus = Status;
261 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
262 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
263 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
264 break;
265
266 default:
267 DEBUG ((DEBUG_ERROR, "Unknown VariableRequest type!\n"));
268 Status = EFI_UNSUPPORTED;
269 break;
270 }
271 }
272
273 //
274 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
275 //
276 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {
277 DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex, Status));
278 CallFspWrapperResetSystem ((UINTN)Status);
279 }
280
281 return Status;
282 }
283
284 /**
285 FSP Wrapper MultiPhase Handler
286
287 @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
288 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
289
290 @retval EFI_STATUS Always return EFI_SUCCESS
291
292 **/
293 EFI_STATUS
294 EFIAPI
295 FspWrapperMultiPhaseHandler (
296 IN OUT VOID **FspHobListPtr,
297 IN UINT8 ComponentIndex
298 )
299 {
300 EFI_STATUS Status;
301 FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams;
302 FSP_MULTI_PHASE_GET_NUMBER_OF_PHASES_PARAMS FspMultiPhaseGetNumber;
303 UINT32 Index;
304 UINT32 NumOfPhases;
305
306 //
307 // Query FSP for the number of phases supported.
308 //
309 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetNumberOfPhases;
310 FspMultiPhaseParams.PhaseIndex = 0;
311 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&FspMultiPhaseGetNumber;
312 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
313 if (Status == EFI_UNSUPPORTED) {
314 //
315 // MultiPhase API was not supported
316 //
317 return Status;
318 } else {
319 ASSERT_EFI_ERROR (Status);
320 }
321
322 NumOfPhases = FspMultiPhaseGetNumber.NumberOfPhases;
323
324 for (Index = 1; Index <= NumOfPhases; Index++) {
325 DEBUG ((DEBUG_ERROR, "MultiPhase Index/NumOfPhases = %d of %d\n", Index, NumOfPhases));
326 //
327 // Platform actions can be added in below function for each component and phase before returning control back to FSP.
328 //
329 FspWrapperPlatformMultiPhaseHandler (FspHobListPtr, ComponentIndex, Index);
330
331 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseExecutePhase;
332 FspMultiPhaseParams.PhaseIndex = Index;
333 FspMultiPhaseParams.MultiPhaseParamPtr = NULL;
334 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
335
336 if (Status == FSP_STATUS_VARIABLE_REQUEST) {
337 //
338 // call to Variable request handler
339 //
340 FspWrapperVariableRequestHandler (FspHobListPtr, ComponentIndex);
341 }
342
343 //
344 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
345 //
346 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {
347 DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex, Status));
348 CallFspWrapperResetSystem ((UINTN)Status);
349 }
350
351 ASSERT_EFI_ERROR (Status);
352 }
353
354 return EFI_SUCCESS;
355 }