]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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
26638d2a
CC
76 UINTN FspMultiPhaseApiEntry;\r
77 UINTN FspMultiPhaseApiOffset;\r
78 EFI_STATUS Status;\r
79 BOOLEAN InterruptState;\r
80 BOOLEAN IsVariableServiceRequest;\r
81 FSP_MULTI_PHASE_PARAMS *FspMultiPhaseParamsPtr;\r
82\r
83 FspMultiPhaseParamsPtr = (FSP_MULTI_PHASE_PARAMS *)FspMultiPhaseParams;\r
84 IsVariableServiceRequest = FALSE;\r
85 if ((FspMultiPhaseParamsPtr->MultiPhaseAction == EnumMultiPhaseGetVariableRequestInfo) ||\r
86 (FspMultiPhaseParamsPtr->MultiPhaseAction == EnumMultiPhaseCompleteVariableRequest))\r
87 {\r
88 IsVariableServiceRequest = TRUE;\r
89 }\r
31a94f7f
CC
90\r
91 if (ComponentIndex == FspMultiPhaseMemInitApiIndex) {\r
92 FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));\r
93 if (FspHeader == NULL) {\r
94 return EFI_DEVICE_ERROR;\r
26638d2a
CC
95 } else if (FspHeader->SpecVersion < 0x24) {\r
96 return EFI_UNSUPPORTED;\r
31a94f7f
CC
97 }\r
98\r
99 FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseMemInitEntryOffset;\r
100 } else if (ComponentIndex == FspMultiPhaseSiInitApiIndex) {\r
101 FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));\r
102 if (FspHeader == NULL) {\r
103 return EFI_DEVICE_ERROR;\r
26638d2a
CC
104 } else if (FspHeader->SpecVersion < 0x22) {\r
105 return EFI_UNSUPPORTED;\r
106 } else if ((FspHeader->SpecVersion < 0x24) && (IsVariableServiceRequest == TRUE)) {\r
107 return EFI_UNSUPPORTED;\r
31a94f7f
CC
108 }\r
109\r
110 FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseSiInitEntryOffset;\r
111 }\r
112\r
113 if (FspMultiPhaseApiOffset == 0) {\r
114 return EFI_UNSUPPORTED;\r
115 }\r
116\r
117 FspMultiPhaseApiEntry = FspHeader->ImageBase + FspMultiPhaseApiOffset;\r
118 InterruptState = SaveAndDisableInterrupts ();\r
119 if ((FspHeader->ImageAttribute & BIT2) == 0) {\r
120 // BIT2: IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT\r
121 Status = Execute32BitCode ((UINTN)FspMultiPhaseApiEntry, (UINTN)FspMultiPhaseParams, (UINTN)NULL);\r
122 } else {\r
123 Status = Execute64BitCode ((UINTN)FspMultiPhaseApiEntry, (UINTN)FspMultiPhaseParams, (UINTN)NULL);\r
124 }\r
125\r
126 SetInterruptState (InterruptState);\r
127\r
128 DEBUG ((DEBUG_ERROR, "CallFspMultiPhaseEntry return Status %r \n", Status));\r
129\r
130 return Status;\r
131}\r
132\r
133/**\r
134 FSP Wrapper Variable Request Handler\r
135\r
26638d2a
CC
136 @param[in, out] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)\r
137 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.\r
31a94f7f 138\r
26638d2a
CC
139 @retval EFI_UNSUPPORTED FSP Wrapper cannot support the specific variable request,\r
140 or FSP does not support VariableService\r
31a94f7f
CC
141 @retval EFI_STATUS Return FSP returned status\r
142\r
143**/\r
144EFI_STATUS\r
145EFIAPI\r
146FspWrapperVariableRequestHandler (\r
147 IN OUT VOID **FspHobListPtr,\r
148 IN UINT8 ComponentIndex\r
149 )\r
150{\r
151 EFI_STATUS Status;\r
152 FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams;\r
153 FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS *FspVariableRequestParams;\r
154 EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariablePpi;\r
155 EDKII_PEI_VARIABLE_PPI *VariablePpi;\r
156 BOOLEAN WriteVariableSupport;\r
157 FSP_MULTI_PHASE_COMPLETE_VARIABLE_REQUEST_PARAMS CompleteVariableRequestParams;\r
158\r
159 WriteVariableSupport = TRUE;\r
160 Status = PeiServicesLocatePpi (\r
161 &gEdkiiPeiVariablePpiGuid,\r
162 0,\r
163 NULL,\r
164 (VOID **)&VariablePpi\r
165 );\r
166 if (EFI_ERROR (Status)) {\r
167 WriteVariableSupport = FALSE;\r
168 Status = PeiServicesLocatePpi (\r
169 &gEfiPeiReadOnlyVariable2PpiGuid,\r
170 0,\r
171 NULL,\r
172 (VOID **)&ReadOnlyVariablePpi\r
173 );\r
174 ASSERT_EFI_ERROR (Status);\r
175 if (EFI_ERROR (Status)) {\r
176 return EFI_UNSUPPORTED;\r
177 }\r
178 }\r
179\r
180 Status = FSP_STATUS_VARIABLE_REQUEST;\r
181 while (Status == FSP_STATUS_VARIABLE_REQUEST) {\r
182 //\r
183 // Get the variable request information from FSP.\r
184 //\r
185 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetVariableRequestInfo;\r
186 FspMultiPhaseParams.PhaseIndex = 0;\r
187 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);\r
188 ASSERT_EFI_ERROR (Status);\r
189 //\r
190 // FSP should output this pointer for variable request information.\r
191 //\r
192 FspVariableRequestParams = (FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS *)FspMultiPhaseParams.MultiPhaseParamPtr;\r
193 switch (FspVariableRequestParams->VariableRequest) {\r
194 case EnumFspVariableRequestGetVariable:\r
195 if (WriteVariableSupport) {\r
196 Status = VariablePpi->GetVariable (\r
197 VariablePpi,\r
198 FspVariableRequestParams->VariableName,\r
199 FspVariableRequestParams->VariableGuid,\r
200 FspVariableRequestParams->Attributes,\r
201 (UINTN *)FspVariableRequestParams->DataSize,\r
202 FspVariableRequestParams->Data\r
203 );\r
204 } else {\r
205 Status = ReadOnlyVariablePpi->GetVariable (\r
206 ReadOnlyVariablePpi,\r
207 FspVariableRequestParams->VariableName,\r
208 FspVariableRequestParams->VariableGuid,\r
209 FspVariableRequestParams->Attributes,\r
210 (UINTN *)FspVariableRequestParams->DataSize,\r
211 FspVariableRequestParams->Data\r
212 );\r
213 }\r
214\r
215 CompleteVariableRequestParams.VariableRequestStatus = Status;\r
216 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;\r
217 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;\r
218 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);\r
219 break;\r
220\r
221 case EnumFspVariableRequestSetVariable:\r
222 if (WriteVariableSupport) {\r
223 Status = VariablePpi->SetVariable (\r
224 VariablePpi,\r
225 FspVariableRequestParams->VariableName,\r
226 FspVariableRequestParams->VariableGuid,\r
227 *FspVariableRequestParams->Attributes,\r
228 (UINTN)*FspVariableRequestParams->DataSize,\r
229 FspVariableRequestParams->Data\r
230 );\r
231 } else {\r
232 Status = EFI_UNSUPPORTED;\r
233 }\r
234\r
235 CompleteVariableRequestParams.VariableRequestStatus = Status;\r
236 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;\r
237 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;\r
238 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);\r
239 break;\r
240\r
241 case EnumFspVariableRequestGetNextVariableName:\r
242 if (WriteVariableSupport) {\r
243 Status = VariablePpi->GetNextVariableName (\r
244 VariablePpi,\r
245 (UINTN *)FspVariableRequestParams->VariableNameSize,\r
246 FspVariableRequestParams->VariableName,\r
247 FspVariableRequestParams->VariableGuid\r
248 );\r
249 } else {\r
250 Status = ReadOnlyVariablePpi->NextVariableName (\r
251 ReadOnlyVariablePpi,\r
252 (UINTN *)FspVariableRequestParams->VariableNameSize,\r
253 FspVariableRequestParams->VariableName,\r
254 FspVariableRequestParams->VariableGuid\r
255 );\r
256 }\r
257\r
258 CompleteVariableRequestParams.VariableRequestStatus = Status;\r
259 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;\r
260 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;\r
261 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);\r
262 break;\r
263\r
264 case EnumFspVariableRequestQueryVariableInfo:\r
265 if (WriteVariableSupport) {\r
266 Status = VariablePpi->QueryVariableInfo (\r
267 VariablePpi,\r
268 *FspVariableRequestParams->Attributes,\r
269 FspVariableRequestParams->MaximumVariableStorageSize,\r
270 FspVariableRequestParams->RemainingVariableStorageSize,\r
271 FspVariableRequestParams->MaximumVariableSize\r
272 );\r
273 } else {\r
274 Status = EFI_UNSUPPORTED;\r
275 }\r
276\r
277 CompleteVariableRequestParams.VariableRequestStatus = Status;\r
278 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;\r
279 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;\r
280 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);\r
281 break;\r
282\r
283 default:\r
284 DEBUG ((DEBUG_ERROR, "Unknown VariableRequest type!\n"));\r
285 Status = EFI_UNSUPPORTED;\r
286 break;\r
287 }\r
288 }\r
289\r
290 //\r
291 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status\r
292 //\r
293 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {\r
294 DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex, Status));\r
295 CallFspWrapperResetSystem ((UINTN)Status);\r
296 }\r
297\r
298 return Status;\r
299}\r
300\r
301/**\r
302 FSP Wrapper MultiPhase Handler\r
303\r
26638d2a
CC
304 @param[in, out] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)\r
305 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.\r
31a94f7f 306\r
26638d2a
CC
307 @retval EFI_UNSUPPORTED Specific MultiPhase action was not supported.\r
308 @retval EFI_SUCCESS MultiPhase action were completed successfully.\r
31a94f7f
CC
309\r
310**/\r
311EFI_STATUS\r
312EFIAPI\r
313FspWrapperMultiPhaseHandler (\r
314 IN OUT VOID **FspHobListPtr,\r
315 IN UINT8 ComponentIndex\r
316 )\r
317{\r
318 EFI_STATUS Status;\r
319 FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams;\r
320 FSP_MULTI_PHASE_GET_NUMBER_OF_PHASES_PARAMS FspMultiPhaseGetNumber;\r
321 UINT32 Index;\r
322 UINT32 NumOfPhases;\r
323\r
324 //\r
325 // Query FSP for the number of phases supported.\r
326 //\r
327 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetNumberOfPhases;\r
328 FspMultiPhaseParams.PhaseIndex = 0;\r
329 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&FspMultiPhaseGetNumber;\r
330 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);\r
331 if (Status == EFI_UNSUPPORTED) {\r
332 //\r
333 // MultiPhase API was not supported\r
334 //\r
335 return Status;\r
336 } else {\r
337 ASSERT_EFI_ERROR (Status);\r
338 }\r
339\r
340 NumOfPhases = FspMultiPhaseGetNumber.NumberOfPhases;\r
341\r
342 for (Index = 1; Index <= NumOfPhases; Index++) {\r
343 DEBUG ((DEBUG_ERROR, "MultiPhase Index/NumOfPhases = %d of %d\n", Index, NumOfPhases));\r
344 //\r
345 // Platform actions can be added in below function for each component and phase before returning control back to FSP.\r
346 //\r
347 FspWrapperPlatformMultiPhaseHandler (FspHobListPtr, ComponentIndex, Index);\r
348\r
349 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseExecutePhase;\r
350 FspMultiPhaseParams.PhaseIndex = Index;\r
351 FspMultiPhaseParams.MultiPhaseParamPtr = NULL;\r
352 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);\r
353\r
354 if (Status == FSP_STATUS_VARIABLE_REQUEST) {\r
355 //\r
356 // call to Variable request handler\r
357 //\r
358 FspWrapperVariableRequestHandler (FspHobListPtr, ComponentIndex);\r
359 }\r
360\r
361 //\r
362 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status\r
363 //\r
364 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {\r
365 DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex, Status));\r
366 CallFspWrapperResetSystem ((UINTN)Status);\r
367 }\r
368\r
369 ASSERT_EFI_ERROR (Status);\r
370 }\r
371\r
372 return EFI_SUCCESS;\r
373}\r