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/FspWrapperPlatformMultiPhaseLib.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
;
80 BOOLEAN IsVariableServiceRequest
;
81 FSP_MULTI_PHASE_PARAMS
*FspMultiPhaseParamsPtr
;
83 FspMultiPhaseParamsPtr
= (FSP_MULTI_PHASE_PARAMS
*)FspMultiPhaseParams
;
84 IsVariableServiceRequest
= FALSE
;
85 if ((FspMultiPhaseParamsPtr
->MultiPhaseAction
== EnumMultiPhaseGetVariableRequestInfo
) ||
86 (FspMultiPhaseParamsPtr
->MultiPhaseAction
== EnumMultiPhaseCompleteVariableRequest
))
88 IsVariableServiceRequest
= TRUE
;
91 if (ComponentIndex
== FspMultiPhaseMemInitApiIndex
) {
92 FspHeader
= (FSP_INFO_HEADER
*)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress
));
93 if (FspHeader
== NULL
) {
94 return EFI_DEVICE_ERROR
;
95 } else if (FspHeader
->SpecVersion
< 0x24) {
96 return EFI_UNSUPPORTED
;
99 FspMultiPhaseApiOffset
= FspHeader
->FspMultiPhaseMemInitEntryOffset
;
100 } else if (ComponentIndex
== FspMultiPhaseSiInitApiIndex
) {
101 FspHeader
= (FSP_INFO_HEADER
*)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress
));
102 if (FspHeader
== NULL
) {
103 return EFI_DEVICE_ERROR
;
104 } else if (FspHeader
->SpecVersion
< 0x22) {
105 return EFI_UNSUPPORTED
;
106 } else if ((FspHeader
->SpecVersion
< 0x24) && (IsVariableServiceRequest
== TRUE
)) {
107 return EFI_UNSUPPORTED
;
110 FspMultiPhaseApiOffset
= FspHeader
->FspMultiPhaseSiInitEntryOffset
;
113 if (FspMultiPhaseApiOffset
== 0) {
114 return EFI_UNSUPPORTED
;
117 FspMultiPhaseApiEntry
= FspHeader
->ImageBase
+ FspMultiPhaseApiOffset
;
118 InterruptState
= SaveAndDisableInterrupts ();
119 if ((FspHeader
->ImageAttribute
& BIT2
) == 0) {
120 // BIT2: IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT
121 Status
= Execute32BitCode ((UINTN
)FspMultiPhaseApiEntry
, (UINTN
)FspMultiPhaseParams
, (UINTN
)NULL
);
123 Status
= Execute64BitCode ((UINTN
)FspMultiPhaseApiEntry
, (UINTN
)FspMultiPhaseParams
, (UINTN
)NULL
);
126 SetInterruptState (InterruptState
);
128 DEBUG ((DEBUG_ERROR
, "CallFspMultiPhaseEntry return Status %r \n", Status
));
134 FSP Wrapper Variable Request Handler
136 @param[in, out] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
137 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
139 @retval EFI_UNSUPPORTED FSP Wrapper cannot support the specific variable request,
140 or FSP does not support VariableService
141 @retval EFI_STATUS Return FSP returned status
146 FspWrapperVariableRequestHandler (
147 IN OUT VOID
**FspHobListPtr
,
148 IN UINT8 ComponentIndex
152 FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams
;
153 FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS
*FspVariableRequestParams
;
154 EFI_PEI_READ_ONLY_VARIABLE2_PPI
*ReadOnlyVariablePpi
;
155 EDKII_PEI_VARIABLE_PPI
*VariablePpi
;
156 BOOLEAN WriteVariableSupport
;
157 FSP_MULTI_PHASE_COMPLETE_VARIABLE_REQUEST_PARAMS CompleteVariableRequestParams
;
159 WriteVariableSupport
= TRUE
;
160 Status
= PeiServicesLocatePpi (
161 &gEdkiiPeiVariablePpiGuid
,
164 (VOID
**)&VariablePpi
166 if (EFI_ERROR (Status
)) {
167 WriteVariableSupport
= FALSE
;
168 Status
= PeiServicesLocatePpi (
169 &gEfiPeiReadOnlyVariable2PpiGuid
,
172 (VOID
**)&ReadOnlyVariablePpi
174 ASSERT_EFI_ERROR (Status
);
175 if (EFI_ERROR (Status
)) {
176 return EFI_UNSUPPORTED
;
180 Status
= FSP_STATUS_VARIABLE_REQUEST
;
181 while (Status
== FSP_STATUS_VARIABLE_REQUEST
) {
183 // Get the variable request information from FSP.
185 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseGetVariableRequestInfo
;
186 FspMultiPhaseParams
.PhaseIndex
= 0;
187 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
188 ASSERT_EFI_ERROR (Status
);
190 // FSP should output this pointer for variable request information.
192 FspVariableRequestParams
= (FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS
*)FspMultiPhaseParams
.MultiPhaseParamPtr
;
193 switch (FspVariableRequestParams
->VariableRequest
) {
194 case EnumFspVariableRequestGetVariable
:
195 if (WriteVariableSupport
) {
196 Status
= VariablePpi
->GetVariable (
198 FspVariableRequestParams
->VariableName
,
199 FspVariableRequestParams
->VariableGuid
,
200 FspVariableRequestParams
->Attributes
,
201 (UINTN
*)FspVariableRequestParams
->DataSize
,
202 FspVariableRequestParams
->Data
205 Status
= ReadOnlyVariablePpi
->GetVariable (
207 FspVariableRequestParams
->VariableName
,
208 FspVariableRequestParams
->VariableGuid
,
209 FspVariableRequestParams
->Attributes
,
210 (UINTN
*)FspVariableRequestParams
->DataSize
,
211 FspVariableRequestParams
->Data
215 CompleteVariableRequestParams
.VariableRequestStatus
= Status
;
216 FspMultiPhaseParams
.MultiPhaseParamPtr
= (VOID
*)&CompleteVariableRequestParams
;
217 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseCompleteVariableRequest
;
218 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
221 case EnumFspVariableRequestSetVariable
:
222 if (WriteVariableSupport
) {
223 Status
= VariablePpi
->SetVariable (
225 FspVariableRequestParams
->VariableName
,
226 FspVariableRequestParams
->VariableGuid
,
227 *FspVariableRequestParams
->Attributes
,
228 (UINTN
)*FspVariableRequestParams
->DataSize
,
229 FspVariableRequestParams
->Data
232 Status
= EFI_UNSUPPORTED
;
235 CompleteVariableRequestParams
.VariableRequestStatus
= Status
;
236 FspMultiPhaseParams
.MultiPhaseParamPtr
= (VOID
*)&CompleteVariableRequestParams
;
237 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseCompleteVariableRequest
;
238 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
241 case EnumFspVariableRequestGetNextVariableName
:
242 if (WriteVariableSupport
) {
243 Status
= VariablePpi
->GetNextVariableName (
245 (UINTN
*)FspVariableRequestParams
->VariableNameSize
,
246 FspVariableRequestParams
->VariableName
,
247 FspVariableRequestParams
->VariableGuid
250 Status
= ReadOnlyVariablePpi
->NextVariableName (
252 (UINTN
*)FspVariableRequestParams
->VariableNameSize
,
253 FspVariableRequestParams
->VariableName
,
254 FspVariableRequestParams
->VariableGuid
258 CompleteVariableRequestParams
.VariableRequestStatus
= Status
;
259 FspMultiPhaseParams
.MultiPhaseParamPtr
= (VOID
*)&CompleteVariableRequestParams
;
260 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseCompleteVariableRequest
;
261 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
264 case EnumFspVariableRequestQueryVariableInfo
:
265 if (WriteVariableSupport
) {
266 Status
= VariablePpi
->QueryVariableInfo (
268 *FspVariableRequestParams
->Attributes
,
269 FspVariableRequestParams
->MaximumVariableStorageSize
,
270 FspVariableRequestParams
->RemainingVariableStorageSize
,
271 FspVariableRequestParams
->MaximumVariableSize
274 Status
= EFI_UNSUPPORTED
;
277 CompleteVariableRequestParams
.VariableRequestStatus
= Status
;
278 FspMultiPhaseParams
.MultiPhaseParamPtr
= (VOID
*)&CompleteVariableRequestParams
;
279 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseCompleteVariableRequest
;
280 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
284 DEBUG ((DEBUG_ERROR
, "Unknown VariableRequest type!\n"));
285 Status
= EFI_UNSUPPORTED
;
291 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
293 if ((Status
>= FSP_STATUS_RESET_REQUIRED_COLD
) && (Status
<= FSP_STATUS_RESET_REQUIRED_8
)) {
294 DEBUG ((DEBUG_INFO
, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex
, Status
));
295 CallFspWrapperResetSystem ((UINTN
)Status
);
302 FSP Wrapper MultiPhase Handler
304 @param[in, out] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
305 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
307 @retval EFI_UNSUPPORTED Specific MultiPhase action was not supported.
308 @retval EFI_SUCCESS MultiPhase action were completed successfully.
313 FspWrapperMultiPhaseHandler (
314 IN OUT VOID
**FspHobListPtr
,
315 IN UINT8 ComponentIndex
319 FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams
;
320 FSP_MULTI_PHASE_GET_NUMBER_OF_PHASES_PARAMS FspMultiPhaseGetNumber
;
325 // Query FSP for the number of phases supported.
327 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseGetNumberOfPhases
;
328 FspMultiPhaseParams
.PhaseIndex
= 0;
329 FspMultiPhaseParams
.MultiPhaseParamPtr
= (VOID
*)&FspMultiPhaseGetNumber
;
330 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
331 if (Status
== EFI_UNSUPPORTED
) {
333 // MultiPhase API was not supported
337 ASSERT_EFI_ERROR (Status
);
340 NumOfPhases
= FspMultiPhaseGetNumber
.NumberOfPhases
;
342 for (Index
= 1; Index
<= NumOfPhases
; Index
++) {
343 DEBUG ((DEBUG_ERROR
, "MultiPhase Index/NumOfPhases = %d of %d\n", Index
, NumOfPhases
));
345 // Platform actions can be added in below function for each component and phase before returning control back to FSP.
347 FspWrapperPlatformMultiPhaseHandler (FspHobListPtr
, ComponentIndex
, Index
);
349 FspMultiPhaseParams
.MultiPhaseAction
= EnumMultiPhaseExecutePhase
;
350 FspMultiPhaseParams
.PhaseIndex
= Index
;
351 FspMultiPhaseParams
.MultiPhaseParamPtr
= NULL
;
352 Status
= CallFspMultiPhaseEntry (&FspMultiPhaseParams
, FspHobListPtr
, ComponentIndex
);
354 if (Status
== FSP_STATUS_VARIABLE_REQUEST
) {
356 // call to Variable request handler
358 FspWrapperVariableRequestHandler (FspHobListPtr
, ComponentIndex
);
362 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
364 if ((Status
>= FSP_STATUS_RESET_REQUIRED_COLD
) && (Status
<= FSP_STATUS_RESET_REQUIRED_8
)) {
365 DEBUG ((DEBUG_INFO
, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex
, Status
));
366 CallFspWrapperResetSystem ((UINTN
)Status
);
369 ASSERT_EFI_ERROR (Status
);