VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c@ 108794

Last change on this file since 108794 was 108794, checked in by vboxsync, 2 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 15.4 KB
Line 
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/FspWrapperPlatformMultiPhaseLib.h>
20#include <Library/BaseMemoryLib.h>
21#include <Library/HobLib.h>
22
23/**
24 Execute 32-bit FSP API entry code.
25
26 @param[in] Function The 32bit code entry to be executed.
27 @param[in] Param1 The first parameter to pass to 32bit code.
28 @param[in] Param2 The second parameter to pass to 32bit code.
29
30 @return EFI_STATUS.
31**/
32EFI_STATUS
33Execute32BitCode (
34 IN UINT64 Function,
35 IN UINT64 Param1,
36 IN UINT64 Param2
37 );
38
39/**
40 Execute 64-bit FSP API entry code.
41
42 @param[in] Function The 64bit code entry to be executed.
43 @param[in] Param1 The first parameter to pass to 64bit code.
44 @param[in] Param2 The second parameter to pass to 64bit code.
45
46 @return EFI_STATUS.
47**/
48EFI_STATUS
49Execute64BitCode (
50 IN UINT64 Function,
51 IN UINT64 Param1,
52 IN UINT64 Param2
53 );
54
55/**
56 Call FspsMultiPhase API.
57
58 @param[in] FspsMultiPhaseParams - Parameters for MultiPhase API.
59 @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
60 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
61
62 @return EFI_UNSUPPORTED - the requested FspsMultiPhase API is not supported.
63 @return EFI_DEVICE_ERROR - the FSP header was not found.
64 @return EFI status returned by FspsMultiPhase API.
65**/
66EFI_STATUS
67EFIAPI
68CallFspMultiPhaseEntry (
69 IN VOID *FspMultiPhaseParams,
70 IN OUT VOID **FspHobListPtr,
71 IN UINT8 ComponentIndex
72 )
73{
74 FSP_INFO_HEADER *FspHeader;
75 //
76 // FSP_MULTI_PHASE_INIT and FSP_MULTI_PHASE_SI_INIT API functions having same prototype.
77 //
78 UINTN FspMultiPhaseApiEntry;
79 UINTN FspMultiPhaseApiOffset;
80 EFI_STATUS Status;
81 BOOLEAN InterruptState;
82 BOOLEAN IsVariableServiceRequest;
83 FSP_MULTI_PHASE_PARAMS *FspMultiPhaseParamsPtr;
84
85 FspMultiPhaseApiOffset = 0;
86 FspMultiPhaseParamsPtr = (FSP_MULTI_PHASE_PARAMS *)FspMultiPhaseParams;
87 IsVariableServiceRequest = FALSE;
88 if ((FspMultiPhaseParamsPtr->MultiPhaseAction == EnumMultiPhaseGetVariableRequestInfo) ||
89 (FspMultiPhaseParamsPtr->MultiPhaseAction == EnumMultiPhaseCompleteVariableRequest))
90 {
91 IsVariableServiceRequest = TRUE;
92 }
93
94 if (ComponentIndex == FspMultiPhaseMemInitApiIndex) {
95 FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));
96 if (FspHeader == NULL) {
97 return EFI_DEVICE_ERROR;
98 } else if (FspHeader->SpecVersion < 0x24) {
99 return EFI_UNSUPPORTED;
100 }
101
102 FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseMemInitEntryOffset;
103 } else if (ComponentIndex == FspMultiPhaseSiInitApiIndex) {
104 FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));
105 if (FspHeader == NULL) {
106 return EFI_DEVICE_ERROR;
107 } else if (FspHeader->SpecVersion < 0x22) {
108 return EFI_UNSUPPORTED;
109 } else if ((FspHeader->SpecVersion < 0x24) && (IsVariableServiceRequest == TRUE)) {
110 return EFI_UNSUPPORTED;
111 }
112
113 FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseSiInitEntryOffset;
114 }
115
116 if (FspMultiPhaseApiOffset == 0) {
117 return EFI_UNSUPPORTED;
118 }
119
120 FspMultiPhaseApiEntry = FspHeader->ImageBase + FspMultiPhaseApiOffset;
121 InterruptState = SaveAndDisableInterrupts ();
122 if ((FspHeader->ImageAttribute & BIT2) == 0) {
123 // BIT2: IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT
124 Status = Execute32BitCode ((UINTN)FspMultiPhaseApiEntry, (UINTN)FspMultiPhaseParams, (UINTN)NULL);
125 } else {
126 Status = Execute64BitCode ((UINTN)FspMultiPhaseApiEntry, (UINTN)FspMultiPhaseParams, (UINTN)NULL);
127 }
128
129 SetInterruptState (InterruptState);
130
131 DEBUG ((DEBUG_ERROR, "CallFspMultiPhaseEntry return Status %r \n", Status));
132
133 return Status;
134}
135
136/**
137 FSP Wrapper Variable Request Handler
138
139 @param[in, out] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
140 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
141
142 @retval EFI_UNSUPPORTED FSP Wrapper cannot support the specific variable request,
143 or FSP does not support VariableService
144 @retval EFI_STATUS Return FSP returned status
145
146**/
147EFI_STATUS
148EFIAPI
149FspWrapperVariableRequestHandler (
150 IN OUT VOID **FspHobListPtr,
151 IN UINT8 ComponentIndex
152 )
153{
154 EFI_STATUS Status;
155 FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams;
156 FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS *FspVariableRequestParams;
157 EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariablePpi;
158 EDKII_PEI_VARIABLE_PPI *VariablePpi;
159 BOOLEAN WriteVariableSupport;
160 FSP_MULTI_PHASE_COMPLETE_VARIABLE_REQUEST_PARAMS CompleteVariableRequestParams;
161 VOID *GuidHob;
162 VOID *HobData;
163
164 WriteVariableSupport = TRUE;
165 Status = PeiServicesLocatePpi (
166 &gEdkiiPeiVariablePpiGuid,
167 0,
168 NULL,
169 (VOID **)&VariablePpi
170 );
171 if (EFI_ERROR (Status)) {
172 WriteVariableSupport = FALSE;
173 Status = PeiServicesLocatePpi (
174 &gEfiPeiReadOnlyVariable2PpiGuid,
175 0,
176 NULL,
177 (VOID **)&ReadOnlyVariablePpi
178 );
179 ASSERT_EFI_ERROR (Status);
180 if (EFI_ERROR (Status)) {
181 return EFI_UNSUPPORTED;
182 }
183 }
184
185 Status = FSP_STATUS_VARIABLE_REQUEST;
186 while (Status == FSP_STATUS_VARIABLE_REQUEST) {
187 //
188 // Get the variable request information from FSP.
189 //
190 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetVariableRequestInfo;
191 FspMultiPhaseParams.PhaseIndex = 0;
192 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
193 ASSERT_EFI_ERROR (Status);
194 //
195 // FSP should output this pointer for variable request information.
196 //
197 FspVariableRequestParams = (FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS *)FspMultiPhaseParams.MultiPhaseParamPtr;
198 switch (FspVariableRequestParams->VariableRequest) {
199 case EnumFspVariableRequestGetVariable:
200 if (WriteVariableSupport) {
201 Status = VariablePpi->GetVariable (
202 VariablePpi,
203 FspVariableRequestParams->VariableName,
204 FspVariableRequestParams->VariableGuid,
205 FspVariableRequestParams->Attributes,
206 (UINTN *)FspVariableRequestParams->DataSize,
207 FspVariableRequestParams->Data
208 );
209 } else {
210 Status = ReadOnlyVariablePpi->GetVariable (
211 ReadOnlyVariablePpi,
212 FspVariableRequestParams->VariableName,
213 FspVariableRequestParams->VariableGuid,
214 FspVariableRequestParams->Attributes,
215 (UINTN *)FspVariableRequestParams->DataSize,
216 FspVariableRequestParams->Data
217 );
218 }
219
220 CompleteVariableRequestParams.VariableRequestStatus = Status;
221 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
222 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
223 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
224 break;
225
226 case EnumFspVariableRequestSetVariable:
227 if (WriteVariableSupport) {
228 Status = VariablePpi->SetVariable (
229 VariablePpi,
230 FspVariableRequestParams->VariableName,
231 FspVariableRequestParams->VariableGuid,
232 *FspVariableRequestParams->Attributes,
233 (UINTN)*FspVariableRequestParams->DataSize,
234 FspVariableRequestParams->Data
235 );
236 } else {
237 Status = EFI_UNSUPPORTED;
238 }
239
240 CompleteVariableRequestParams.VariableRequestStatus = Status;
241 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
242 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
243 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
244 break;
245
246 case EnumFspVariableRequestGetNextVariableName:
247 if (WriteVariableSupport) {
248 Status = VariablePpi->GetNextVariableName (
249 VariablePpi,
250 (UINTN *)FspVariableRequestParams->VariableNameSize,
251 FspVariableRequestParams->VariableName,
252 FspVariableRequestParams->VariableGuid
253 );
254 } else {
255 Status = ReadOnlyVariablePpi->NextVariableName (
256 ReadOnlyVariablePpi,
257 (UINTN *)FspVariableRequestParams->VariableNameSize,
258 FspVariableRequestParams->VariableName,
259 FspVariableRequestParams->VariableGuid
260 );
261 }
262
263 CompleteVariableRequestParams.VariableRequestStatus = Status;
264 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
265 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
266 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
267 break;
268
269 case EnumFspVariableRequestQueryVariableInfo:
270 if (WriteVariableSupport) {
271 Status = VariablePpi->QueryVariableInfo (
272 VariablePpi,
273 *FspVariableRequestParams->Attributes,
274 FspVariableRequestParams->MaximumVariableStorageSize,
275 FspVariableRequestParams->RemainingVariableStorageSize,
276 FspVariableRequestParams->MaximumVariableSize
277 );
278 } else {
279 Status = EFI_UNSUPPORTED;
280 }
281
282 CompleteVariableRequestParams.VariableRequestStatus = Status;
283 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
284 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
285 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
286 break;
287
288 default:
289 DEBUG ((DEBUG_ERROR, "Unknown VariableRequest type!\n"));
290 Status = EFI_UNSUPPORTED;
291 break;
292 }
293 }
294
295 //
296 // Refresh FspHobList pointer stored in HOB.
297 //
298 GuidHob = GetFirstGuidHob (&gFspHobGuid);
299 ASSERT (GuidHob != NULL);
300 if (GuidHob != NULL) {
301 HobData = GET_GUID_HOB_DATA (GuidHob);
302 CopyMem (HobData, FspHobListPtr, sizeof (*FspHobListPtr));
303 }
304
305 //
306 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
307 //
308 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {
309 DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex, Status));
310 CallFspWrapperResetSystem ((UINTN)Status);
311 }
312
313 return Status;
314}
315
316/**
317 FSP Wrapper MultiPhase Handler
318
319 @param[in, out] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
320 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
321
322 @retval EFI_UNSUPPORTED Specific MultiPhase action was not supported.
323 @retval EFI_SUCCESS MultiPhase action were completed successfully.
324
325**/
326EFI_STATUS
327EFIAPI
328FspWrapperMultiPhaseHandler (
329 IN OUT VOID **FspHobListPtr,
330 IN UINT8 ComponentIndex
331 )
332{
333 EFI_STATUS Status;
334 FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams;
335 FSP_MULTI_PHASE_GET_NUMBER_OF_PHASES_PARAMS FspMultiPhaseGetNumber;
336 UINT32 Index;
337 UINT32 NumOfPhases;
338 VOID *GuidHob;
339 VOID *HobData;
340
341 //
342 // Query FSP for the number of phases supported.
343 //
344 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetNumberOfPhases;
345 FspMultiPhaseParams.PhaseIndex = 0;
346 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&FspMultiPhaseGetNumber;
347 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
348 if (Status == EFI_UNSUPPORTED) {
349 //
350 // MultiPhase API was not supported
351 //
352 return Status;
353 } else {
354 ASSERT_EFI_ERROR (Status);
355 }
356
357 NumOfPhases = FspMultiPhaseGetNumber.NumberOfPhases;
358
359 for (Index = 1; Index <= NumOfPhases; Index++) {
360 DEBUG ((DEBUG_ERROR, "MultiPhase Index/NumOfPhases = %d of %d\n", Index, NumOfPhases));
361 //
362 // Platform actions can be added in below function for each component and phase before returning control back to FSP.
363 //
364 FspWrapperPlatformMultiPhaseHandler (FspHobListPtr, ComponentIndex, Index);
365
366 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseExecutePhase;
367 FspMultiPhaseParams.PhaseIndex = Index;
368 FspMultiPhaseParams.MultiPhaseParamPtr = NULL;
369 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
370
371 //
372 // Refresh FspHobList pointer stored in HOB.
373 //
374 GuidHob = GetFirstGuidHob (&gFspHobGuid);
375 ASSERT (GuidHob != NULL);
376 if (GuidHob != NULL) {
377 HobData = GET_GUID_HOB_DATA (GuidHob);
378 CopyMem (HobData, FspHobListPtr, sizeof (*FspHobListPtr));
379 }
380
381 if (Status == FSP_STATUS_VARIABLE_REQUEST) {
382 //
383 // call to Variable request handler
384 //
385 FspWrapperVariableRequestHandler (FspHobListPtr, ComponentIndex);
386 }
387
388 //
389 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
390 //
391 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {
392 DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex, Status));
393 CallFspWrapperResetSystem ((UINTN)Status);
394 }
395
396 ASSERT_EFI_ERROR (Status);
397 }
398
399 return EFI_SUCCESS;
400}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette