TianoCore EDK2 master
Loading...
Searching...
No Matches
PeiFspWrapperMultiPhaseProcessLib.c
Go to the documentation of this file.
1
9#include <Library/BaseLib.h>
10#include <Library/DebugLib.h>
11#include <Library/PcdLib.h>
14#include <FspEas.h>
15#include <FspGlobalData.h>
17#include <Ppi/Variable.h>
20
32 IN UINT64 Function,
33 IN UINT64 Param1,
34 IN UINT64 Param2
35 );
36
48 IN UINT64 Function,
49 IN UINT64 Param1,
50 IN UINT64 Param2
51 );
52
65EFIAPI
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 BOOLEAN IsVariableServiceRequest;
81 FSP_MULTI_PHASE_PARAMS *FspMultiPhaseParamsPtr;
82
83 FspMultiPhaseApiOffset = 0;
84 FspMultiPhaseParamsPtr = (FSP_MULTI_PHASE_PARAMS *)FspMultiPhaseParams;
85 IsVariableServiceRequest = FALSE;
86 if ((FspMultiPhaseParamsPtr->MultiPhaseAction == EnumMultiPhaseGetVariableRequestInfo) ||
87 (FspMultiPhaseParamsPtr->MultiPhaseAction == EnumMultiPhaseCompleteVariableRequest))
88 {
89 IsVariableServiceRequest = TRUE;
90 }
91
92 if (ComponentIndex == FspMultiPhaseMemInitApiIndex) {
93 FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));
94 if (FspHeader == NULL) {
95 return EFI_DEVICE_ERROR;
96 } else if (FspHeader->SpecVersion < 0x24) {
97 return EFI_UNSUPPORTED;
98 }
99
100 FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseMemInitEntryOffset;
101 } else if (ComponentIndex == FspMultiPhaseSiInitApiIndex) {
102 FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));
103 if (FspHeader == NULL) {
104 return EFI_DEVICE_ERROR;
105 } else if (FspHeader->SpecVersion < 0x22) {
106 return EFI_UNSUPPORTED;
107 } else if ((FspHeader->SpecVersion < 0x24) && (IsVariableServiceRequest == TRUE)) {
108 return EFI_UNSUPPORTED;
109 }
110
111 FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseSiInitEntryOffset;
112 }
113
114 if (FspMultiPhaseApiOffset == 0) {
115 return EFI_UNSUPPORTED;
116 }
117
118 FspMultiPhaseApiEntry = FspHeader->ImageBase + FspMultiPhaseApiOffset;
119 InterruptState = SaveAndDisableInterrupts ();
120 if ((FspHeader->ImageAttribute & BIT2) == 0) {
121 // BIT2: IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT
122 Status = Execute32BitCode ((UINTN)FspMultiPhaseApiEntry, (UINTN)FspMultiPhaseParams, (UINTN)NULL);
123 } else {
124 Status = Execute64BitCode ((UINTN)FspMultiPhaseApiEntry, (UINTN)FspMultiPhaseParams, (UINTN)NULL);
125 }
126
127 SetInterruptState (InterruptState);
128
129 DEBUG ((DEBUG_ERROR, "CallFspMultiPhaseEntry return Status %r \n", Status));
130
131 return Status;
132}
133
146EFIAPI
148 IN OUT VOID **FspHobListPtr,
149 IN UINT8 ComponentIndex
150 )
151{
152 EFI_STATUS Status;
153 FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams;
154 FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS *FspVariableRequestParams;
155 EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariablePpi;
156 EDKII_PEI_VARIABLE_PPI *VariablePpi;
157 BOOLEAN WriteVariableSupport;
158 FSP_MULTI_PHASE_COMPLETE_VARIABLE_REQUEST_PARAMS CompleteVariableRequestParams;
159
160 WriteVariableSupport = TRUE;
161 Status = PeiServicesLocatePpi (
162 &gEdkiiPeiVariablePpiGuid,
163 0,
164 NULL,
165 (VOID **)&VariablePpi
166 );
167 if (EFI_ERROR (Status)) {
168 WriteVariableSupport = FALSE;
169 Status = PeiServicesLocatePpi (
170 &gEfiPeiReadOnlyVariable2PpiGuid,
171 0,
172 NULL,
173 (VOID **)&ReadOnlyVariablePpi
174 );
175 ASSERT_EFI_ERROR (Status);
176 if (EFI_ERROR (Status)) {
177 return EFI_UNSUPPORTED;
178 }
179 }
180
181 Status = FSP_STATUS_VARIABLE_REQUEST;
182 while (Status == FSP_STATUS_VARIABLE_REQUEST) {
183 //
184 // Get the variable request information from FSP.
185 //
186 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetVariableRequestInfo;
187 FspMultiPhaseParams.PhaseIndex = 0;
188 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
189 ASSERT_EFI_ERROR (Status);
190 //
191 // FSP should output this pointer for variable request information.
192 //
193 FspVariableRequestParams = (FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS *)FspMultiPhaseParams.MultiPhaseParamPtr;
194 switch (FspVariableRequestParams->VariableRequest) {
195 case EnumFspVariableRequestGetVariable:
196 if (WriteVariableSupport) {
197 Status = VariablePpi->GetVariable (
198 VariablePpi,
199 FspVariableRequestParams->VariableName,
200 FspVariableRequestParams->VariableGuid,
201 FspVariableRequestParams->Attributes,
202 (UINTN *)FspVariableRequestParams->DataSize,
203 FspVariableRequestParams->Data
204 );
205 } else {
206 Status = ReadOnlyVariablePpi->GetVariable (
207 ReadOnlyVariablePpi,
208 FspVariableRequestParams->VariableName,
209 FspVariableRequestParams->VariableGuid,
210 FspVariableRequestParams->Attributes,
211 (UINTN *)FspVariableRequestParams->DataSize,
212 FspVariableRequestParams->Data
213 );
214 }
215
216 CompleteVariableRequestParams.VariableRequestStatus = Status;
217 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
218 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
219 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
220 break;
221
222 case EnumFspVariableRequestSetVariable:
223 if (WriteVariableSupport) {
224 Status = VariablePpi->SetVariable (
225 VariablePpi,
226 FspVariableRequestParams->VariableName,
227 FspVariableRequestParams->VariableGuid,
228 *FspVariableRequestParams->Attributes,
229 (UINTN)*FspVariableRequestParams->DataSize,
230 FspVariableRequestParams->Data
231 );
232 } else {
233 Status = EFI_UNSUPPORTED;
234 }
235
236 CompleteVariableRequestParams.VariableRequestStatus = Status;
237 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
238 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
239 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
240 break;
241
242 case EnumFspVariableRequestGetNextVariableName:
243 if (WriteVariableSupport) {
244 Status = VariablePpi->GetNextVariableName (
245 VariablePpi,
246 (UINTN *)FspVariableRequestParams->VariableNameSize,
247 FspVariableRequestParams->VariableName,
248 FspVariableRequestParams->VariableGuid
249 );
250 } else {
251 Status = ReadOnlyVariablePpi->NextVariableName (
252 ReadOnlyVariablePpi,
253 (UINTN *)FspVariableRequestParams->VariableNameSize,
254 FspVariableRequestParams->VariableName,
255 FspVariableRequestParams->VariableGuid
256 );
257 }
258
259 CompleteVariableRequestParams.VariableRequestStatus = Status;
260 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
261 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
262 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
263 break;
264
265 case EnumFspVariableRequestQueryVariableInfo:
266 if (WriteVariableSupport) {
267 Status = VariablePpi->QueryVariableInfo (
268 VariablePpi,
269 *FspVariableRequestParams->Attributes,
270 FspVariableRequestParams->MaximumVariableStorageSize,
271 FspVariableRequestParams->RemainingVariableStorageSize,
272 FspVariableRequestParams->MaximumVariableSize
273 );
274 } else {
275 Status = EFI_UNSUPPORTED;
276 }
277
278 CompleteVariableRequestParams.VariableRequestStatus = Status;
279 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
280 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
281 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
282 break;
283
284 default:
285 DEBUG ((DEBUG_ERROR, "Unknown VariableRequest type!\n"));
286 Status = EFI_UNSUPPORTED;
287 break;
288 }
289 }
290
291 //
292 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
293 //
294 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {
295 DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex, Status));
297 }
298
299 return Status;
300}
301
313EFIAPI
315 IN OUT VOID **FspHobListPtr,
316 IN UINT8 ComponentIndex
317 )
318{
319 EFI_STATUS Status;
320 FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams;
321 FSP_MULTI_PHASE_GET_NUMBER_OF_PHASES_PARAMS FspMultiPhaseGetNumber;
322 UINT32 Index;
323 UINT32 NumOfPhases;
324
325 //
326 // Query FSP for the number of phases supported.
327 //
328 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetNumberOfPhases;
329 FspMultiPhaseParams.PhaseIndex = 0;
330 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&FspMultiPhaseGetNumber;
331 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
332 if (Status == EFI_UNSUPPORTED) {
333 //
334 // MultiPhase API was not supported
335 //
336 return Status;
337 } else {
338 ASSERT_EFI_ERROR (Status);
339 }
340
341 NumOfPhases = FspMultiPhaseGetNumber.NumberOfPhases;
342
343 for (Index = 1; Index <= NumOfPhases; Index++) {
344 DEBUG ((DEBUG_ERROR, "MultiPhase Index/NumOfPhases = %d of %d\n", Index, NumOfPhases));
345 //
346 // Platform actions can be added in below function for each component and phase before returning control back to FSP.
347 //
348 FspWrapperPlatformMultiPhaseHandler (FspHobListPtr, ComponentIndex, Index);
349
350 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseExecutePhase;
351 FspMultiPhaseParams.PhaseIndex = Index;
352 FspMultiPhaseParams.MultiPhaseParamPtr = NULL;
353 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
354
355 if (Status == FSP_STATUS_VARIABLE_REQUEST) {
356 //
357 // call to Variable request handler
358 //
359 FspWrapperVariableRequestHandler (FspHobListPtr, ComponentIndex);
360 }
361
362 //
363 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
364 //
365 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {
366 DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex, Status));
368 }
369
370 ASSERT_EFI_ERROR (Status);
371 }
372
373 return EFI_SUCCESS;
374}
UINT64 UINTN
BOOLEAN EFIAPI SetInterruptState(IN BOOLEAN InterruptState)
Definition: Cpu.c:48
BOOLEAN EFIAPI SaveAndDisableInterrupts(VOID)
Definition: Cpu.c:21
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
FSP_INFO_HEADER *EFIAPI FspFindFspHeader(IN EFI_PHYSICAL_ADDRESS FlashFvFspBase)
VOID EFIAPI CallFspWrapperResetSystem(IN EFI_STATUS FspStatusResetType)
VOID EFIAPI FspWrapperPlatformMultiPhaseHandler(IN OUT VOID **FspHobListPtr, IN UINT8 ComponentIndex, IN UINT32 PhaseIndex)
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
EFI_STATUS Execute32BitCode(IN UINT64 Function, IN UINT64 Param1, IN UINT64 Param2)
EFI_STATUS EFIAPI FspWrapperVariableRequestHandler(IN OUT VOID **FspHobListPtr, IN UINT8 ComponentIndex)
EFI_STATUS EFIAPI CallFspMultiPhaseEntry(IN VOID *FspMultiPhaseParams, IN OUT VOID **FspHobListPtr, IN UINT8 ComponentIndex)
EFI_STATUS Execute64BitCode(IN UINT64 Function, IN UINT64 Param1, IN UINT64 Param2)
EFI_STATUS EFIAPI FspWrapperMultiPhaseHandler(IN OUT VOID **FspHobListPtr, IN UINT8 ComponentIndex)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
UINT32 FspMultiPhaseSiInitEntryOffset
UINT32 FspMultiPhaseMemInitEntryOffset
UINT16 ImageAttribute
Definition: FspHeaderFile.h:99