2 Support FSP Wrapper MultiPhase process.
4 Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
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>
15 #include <FspGlobalData.h>
16 #include <Ppi/ReadOnlyVariable2.h>
17 #include <Ppi/Variable.h>
18 #include <Library/PeiServicesLib.h>
19 #include <Library/FspWrapperMultiPhaseProcessLib.h>
22 Execute 32-bit FSP API entry code.
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.
38 Execute 64-bit FSP API entry code.
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.
54 Call FspsMultiPhase API.
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.
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.
66 CallFspMultiPhaseEntry (
67 IN VOID
*FspMultiPhaseParams
,
68 IN OUT VOID
**FspHobListPtr
,
69 IN UINT8 ComponentIndex
72 FSP_INFO_HEADER
*FspHeader
;
74 // FSP_MULTI_PHASE_INIT and FSP_MULTI_PHASE_SI_INIT API functions having same prototype.
76 UINTN FspMultiPhaseApiEntry
;
77 UINTN FspMultiPhaseApiOffset
;
79 BOOLEAN InterruptState
;
81 if (ComponentIndex
== FspMultiPhaseMemInitApiIndex
) {
82 FspHeader
= (FSP_INFO_HEADER
*)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress
));
83 if (FspHeader
== NULL
) {
84 return EFI_DEVICE_ERROR
;
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
;
94 FspMultiPhaseApiOffset
= FspHeader
->FspMultiPhaseSiInitEntryOffset
;
97 if (FspMultiPhaseApiOffset
== 0) {
98 return EFI_UNSUPPORTED
;
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
);
107 Status
= Execute64BitCode ((UINTN
)FspMultiPhaseApiEntry
, (UINTN
)FspMultiPhaseParams
, (UINTN
)NULL
);
110 SetInterruptState (InterruptState
);
112 DEBUG ((DEBUG_ERROR
, "CallFspMultiPhaseEntry return Status %r \n", Status
));
118 FSP Wrapper Variable Request Handler
120 @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
121 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
123 @retval EFI_UNSUPPORTED FSP Wrapper cannot support the specific variable request
124 @retval EFI_STATUS Return FSP returned status
129 FspWrapperVariableRequestHandler (
130 IN OUT VOID
**FspHobListPtr
,
131 IN UINT8 ComponentIndex
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
;
142 WriteVariableSupport
= TRUE
;
143 Status
= PeiServicesLocatePpi (
144 &gEdkiiPeiVariablePpiGuid
,
147 (VOID
**)&VariablePpi
149 if (EFI_ERROR (Status
)) {
150 WriteVariableSupport
= FALSE
;
151 Status
= PeiServicesLocatePpi (
152 &gEfiPeiReadOnlyVariable2PpiGuid
,
155 (VOID
**)&ReadOnlyVariablePpi
157 ASSERT_EFI_ERROR (Status
);
158 if (EFI_ERROR (Status
)) {
159 return EFI_UNSUPPORTED
;
163 Status
= FSP_STATUS_VARIABLE_REQUEST
;
164 while (Status
== FSP_STATUS_VARIABLE_REQUEST
) {
166 // Get the variable request information from FSP.
168 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseGetVariableRequestInfo
;
169 FspMultiPhaseParams
.PhaseIndex
= 0;
170 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
171 ASSERT_EFI_ERROR (Status
);
173 // FSP should output this pointer for variable request information.
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 (
181 FspVariableRequestParams
->VariableName
,
182 FspVariableRequestParams
->VariableGuid
,
183 FspVariableRequestParams
->Attributes
,
184 (UINTN
*)FspVariableRequestParams
->DataSize
,
185 FspVariableRequestParams
->Data
188 Status
= ReadOnlyVariablePpi
->GetVariable (
190 FspVariableRequestParams
->VariableName
,
191 FspVariableRequestParams
->VariableGuid
,
192 FspVariableRequestParams
->Attributes
,
193 (UINTN
*)FspVariableRequestParams
->DataSize
,
194 FspVariableRequestParams
->Data
198 CompleteVariableRequestParams
.VariableRequestStatus
= Status
;
199 FspMultiPhaseParams
.MultiPhaseParamPtr
= (VOID
*)&CompleteVariableRequestParams
;
200 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseCompleteVariableRequest
;
201 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
204 case EnumFspVariableRequestSetVariable
:
205 if (WriteVariableSupport
) {
206 Status
= VariablePpi
->SetVariable (
208 FspVariableRequestParams
->VariableName
,
209 FspVariableRequestParams
->VariableGuid
,
210 *FspVariableRequestParams
->Attributes
,
211 (UINTN
)*FspVariableRequestParams
->DataSize
,
212 FspVariableRequestParams
->Data
215 Status
= EFI_UNSUPPORTED
;
218 CompleteVariableRequestParams
.VariableRequestStatus
= Status
;
219 FspMultiPhaseParams
.MultiPhaseParamPtr
= (VOID
*)&CompleteVariableRequestParams
;
220 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseCompleteVariableRequest
;
221 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
224 case EnumFspVariableRequestGetNextVariableName
:
225 if (WriteVariableSupport
) {
226 Status
= VariablePpi
->GetNextVariableName (
228 (UINTN
*)FspVariableRequestParams
->VariableNameSize
,
229 FspVariableRequestParams
->VariableName
,
230 FspVariableRequestParams
->VariableGuid
233 Status
= ReadOnlyVariablePpi
->NextVariableName (
235 (UINTN
*)FspVariableRequestParams
->VariableNameSize
,
236 FspVariableRequestParams
->VariableName
,
237 FspVariableRequestParams
->VariableGuid
241 CompleteVariableRequestParams
.VariableRequestStatus
= Status
;
242 FspMultiPhaseParams
.MultiPhaseParamPtr
= (VOID
*)&CompleteVariableRequestParams
;
243 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseCompleteVariableRequest
;
244 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
247 case EnumFspVariableRequestQueryVariableInfo
:
248 if (WriteVariableSupport
) {
249 Status
= VariablePpi
->QueryVariableInfo (
251 *FspVariableRequestParams
->Attributes
,
252 FspVariableRequestParams
->MaximumVariableStorageSize
,
253 FspVariableRequestParams
->RemainingVariableStorageSize
,
254 FspVariableRequestParams
->MaximumVariableSize
257 Status
= EFI_UNSUPPORTED
;
260 CompleteVariableRequestParams
.VariableRequestStatus
= Status
;
261 FspMultiPhaseParams
.MultiPhaseParamPtr
= (VOID
*)&CompleteVariableRequestParams
;
262 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseCompleteVariableRequest
;
263 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
267 DEBUG ((DEBUG_ERROR
, "Unknown VariableRequest type!\n"));
268 Status
= EFI_UNSUPPORTED
;
274 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
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
);
285 FSP Wrapper MultiPhase Handler
287 @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
288 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
290 @retval EFI_STATUS Always return EFI_SUCCESS
295 FspWrapperMultiPhaseHandler (
296 IN OUT VOID
**FspHobListPtr
,
297 IN UINT8 ComponentIndex
301 FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams
;
302 FSP_MULTI_PHASE_GET_NUMBER_OF_PHASES_PARAMS FspMultiPhaseGetNumber
;
307 // Query FSP for the number of phases supported.
309 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseGetNumberOfPhases
;
310 FspMultiPhaseParams
.PhaseIndex
= 0;
311 FspMultiPhaseParams
.MultiPhaseParamPtr
= (VOID
*)&FspMultiPhaseGetNumber
;
312 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
313 if (Status
== EFI_UNSUPPORTED
) {
315 // MultiPhase API was not supported
319 ASSERT_EFI_ERROR (Status
);
322 NumOfPhases
= FspMultiPhaseGetNumber
.NumberOfPhases
;
324 for (Index
= 1; Index
<= NumOfPhases
; Index
++) {
325 DEBUG ((DEBUG_ERROR
, "MultiPhase Index/NumOfPhases = %d of %d\n", Index
, NumOfPhases
));
327 // Platform actions can be added in below function for each component and phase before returning control back to FSP.
329 FspWrapperPlatformMultiPhaseHandler (FspHobListPtr
, ComponentIndex
, Index
);
331 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseExecutePhase
;
332 FspMultiPhaseParams
.PhaseIndex
= Index
;
333 FspMultiPhaseParams
.MultiPhaseParamPtr
= NULL
;
334 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
336 if (Status
== FSP_STATUS_VARIABLE_REQUEST
) {
338 // call to Variable request handler
340 FspWrapperVariableRequestHandler (FspHobListPtr
, ComponentIndex
);
344 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
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
);
351 ASSERT_EFI_ERROR (Status
);