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