]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / IntelFsp2WrapperPkg / Library / FspWrapperMultiPhaseProcessLib / PeiFspWrapperMultiPhaseProcessLib.c
1 /** @file
2 Support FSP Wrapper MultiPhase process.
3
4 Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
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>
14 #include <FspEas.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>
20
21 /**
22 Execute 32-bit FSP API entry code.
23
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.
27
28 @return EFI_STATUS.
29 **/
30 EFI_STATUS
31 Execute32BitCode (
32 IN UINT64 Function,
33 IN UINT64 Param1,
34 IN UINT64 Param2
35 );
36
37 /**
38 Execute 64-bit FSP API entry code.
39
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.
43
44 @return EFI_STATUS.
45 **/
46 EFI_STATUS
47 Execute64BitCode (
48 IN UINT64 Function,
49 IN UINT64 Param1,
50 IN UINT64 Param2
51 );
52
53 /**
54 Call FspsMultiPhase API.
55
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.
59
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.
63 **/
64 EFI_STATUS
65 EFIAPI
66 CallFspMultiPhaseEntry (
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 FspMultiPhaseParamsPtr = (FSP_MULTI_PHASE_PARAMS *)FspMultiPhaseParams;
84 IsVariableServiceRequest = FALSE;
85 if ((FspMultiPhaseParamsPtr->MultiPhaseAction == EnumMultiPhaseGetVariableRequestInfo) ||
86 (FspMultiPhaseParamsPtr->MultiPhaseAction == EnumMultiPhaseCompleteVariableRequest))
87 {
88 IsVariableServiceRequest = TRUE;
89 }
90
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;
97 }
98
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;
108 }
109
110 FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseSiInitEntryOffset;
111 }
112
113 if (FspMultiPhaseApiOffset == 0) {
114 return EFI_UNSUPPORTED;
115 }
116
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);
122 } else {
123 Status = Execute64BitCode ((UINTN)FspMultiPhaseApiEntry, (UINTN)FspMultiPhaseParams, (UINTN)NULL);
124 }
125
126 SetInterruptState (InterruptState);
127
128 DEBUG ((DEBUG_ERROR, "CallFspMultiPhaseEntry return Status %r \n", Status));
129
130 return Status;
131 }
132
133 /**
134 FSP Wrapper Variable Request Handler
135
136 @param[in, out] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
137 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
138
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
142
143 **/
144 EFI_STATUS
145 EFIAPI
146 FspWrapperVariableRequestHandler (
147 IN OUT VOID **FspHobListPtr,
148 IN UINT8 ComponentIndex
149 )
150 {
151 EFI_STATUS Status;
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;
158
159 WriteVariableSupport = TRUE;
160 Status = PeiServicesLocatePpi (
161 &gEdkiiPeiVariablePpiGuid,
162 0,
163 NULL,
164 (VOID **)&VariablePpi
165 );
166 if (EFI_ERROR (Status)) {
167 WriteVariableSupport = FALSE;
168 Status = PeiServicesLocatePpi (
169 &gEfiPeiReadOnlyVariable2PpiGuid,
170 0,
171 NULL,
172 (VOID **)&ReadOnlyVariablePpi
173 );
174 ASSERT_EFI_ERROR (Status);
175 if (EFI_ERROR (Status)) {
176 return EFI_UNSUPPORTED;
177 }
178 }
179
180 Status = FSP_STATUS_VARIABLE_REQUEST;
181 while (Status == FSP_STATUS_VARIABLE_REQUEST) {
182 //
183 // Get the variable request information from FSP.
184 //
185 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetVariableRequestInfo;
186 FspMultiPhaseParams.PhaseIndex = 0;
187 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
188 ASSERT_EFI_ERROR (Status);
189 //
190 // FSP should output this pointer for variable request information.
191 //
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 (
197 VariablePpi,
198 FspVariableRequestParams->VariableName,
199 FspVariableRequestParams->VariableGuid,
200 FspVariableRequestParams->Attributes,
201 (UINTN *)FspVariableRequestParams->DataSize,
202 FspVariableRequestParams->Data
203 );
204 } else {
205 Status = ReadOnlyVariablePpi->GetVariable (
206 ReadOnlyVariablePpi,
207 FspVariableRequestParams->VariableName,
208 FspVariableRequestParams->VariableGuid,
209 FspVariableRequestParams->Attributes,
210 (UINTN *)FspVariableRequestParams->DataSize,
211 FspVariableRequestParams->Data
212 );
213 }
214
215 CompleteVariableRequestParams.VariableRequestStatus = Status;
216 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
217 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
218 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
219 break;
220
221 case EnumFspVariableRequestSetVariable:
222 if (WriteVariableSupport) {
223 Status = VariablePpi->SetVariable (
224 VariablePpi,
225 FspVariableRequestParams->VariableName,
226 FspVariableRequestParams->VariableGuid,
227 *FspVariableRequestParams->Attributes,
228 (UINTN)*FspVariableRequestParams->DataSize,
229 FspVariableRequestParams->Data
230 );
231 } else {
232 Status = EFI_UNSUPPORTED;
233 }
234
235 CompleteVariableRequestParams.VariableRequestStatus = Status;
236 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
237 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
238 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
239 break;
240
241 case EnumFspVariableRequestGetNextVariableName:
242 if (WriteVariableSupport) {
243 Status = VariablePpi->GetNextVariableName (
244 VariablePpi,
245 (UINTN *)FspVariableRequestParams->VariableNameSize,
246 FspVariableRequestParams->VariableName,
247 FspVariableRequestParams->VariableGuid
248 );
249 } else {
250 Status = ReadOnlyVariablePpi->NextVariableName (
251 ReadOnlyVariablePpi,
252 (UINTN *)FspVariableRequestParams->VariableNameSize,
253 FspVariableRequestParams->VariableName,
254 FspVariableRequestParams->VariableGuid
255 );
256 }
257
258 CompleteVariableRequestParams.VariableRequestStatus = Status;
259 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
260 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
261 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
262 break;
263
264 case EnumFspVariableRequestQueryVariableInfo:
265 if (WriteVariableSupport) {
266 Status = VariablePpi->QueryVariableInfo (
267 VariablePpi,
268 *FspVariableRequestParams->Attributes,
269 FspVariableRequestParams->MaximumVariableStorageSize,
270 FspVariableRequestParams->RemainingVariableStorageSize,
271 FspVariableRequestParams->MaximumVariableSize
272 );
273 } else {
274 Status = EFI_UNSUPPORTED;
275 }
276
277 CompleteVariableRequestParams.VariableRequestStatus = Status;
278 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
279 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
280 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
281 break;
282
283 default:
284 DEBUG ((DEBUG_ERROR, "Unknown VariableRequest type!\n"));
285 Status = EFI_UNSUPPORTED;
286 break;
287 }
288 }
289
290 //
291 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
292 //
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);
296 }
297
298 return Status;
299 }
300
301 /**
302 FSP Wrapper MultiPhase Handler
303
304 @param[in, out] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
305 @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
306
307 @retval EFI_UNSUPPORTED Specific MultiPhase action was not supported.
308 @retval EFI_SUCCESS MultiPhase action were completed successfully.
309
310 **/
311 EFI_STATUS
312 EFIAPI
313 FspWrapperMultiPhaseHandler (
314 IN OUT VOID **FspHobListPtr,
315 IN UINT8 ComponentIndex
316 )
317 {
318 EFI_STATUS Status;
319 FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams;
320 FSP_MULTI_PHASE_GET_NUMBER_OF_PHASES_PARAMS FspMultiPhaseGetNumber;
321 UINT32 Index;
322 UINT32 NumOfPhases;
323
324 //
325 // Query FSP for the number of phases supported.
326 //
327 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetNumberOfPhases;
328 FspMultiPhaseParams.PhaseIndex = 0;
329 FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&FspMultiPhaseGetNumber;
330 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
331 if (Status == EFI_UNSUPPORTED) {
332 //
333 // MultiPhase API was not supported
334 //
335 return Status;
336 } else {
337 ASSERT_EFI_ERROR (Status);
338 }
339
340 NumOfPhases = FspMultiPhaseGetNumber.NumberOfPhases;
341
342 for (Index = 1; Index <= NumOfPhases; Index++) {
343 DEBUG ((DEBUG_ERROR, "MultiPhase Index/NumOfPhases = %d of %d\n", Index, NumOfPhases));
344 //
345 // Platform actions can be added in below function for each component and phase before returning control back to FSP.
346 //
347 FspWrapperPlatformMultiPhaseHandler (FspHobListPtr, ComponentIndex, Index);
348
349 FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseExecutePhase;
350 FspMultiPhaseParams.PhaseIndex = Index;
351 FspMultiPhaseParams.MultiPhaseParamPtr = NULL;
352 Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
353
354 if (Status == FSP_STATUS_VARIABLE_REQUEST) {
355 //
356 // call to Variable request handler
357 //
358 FspWrapperVariableRequestHandler (FspHobListPtr, ComponentIndex);
359 }
360
361 //
362 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
363 //
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);
367 }
368
369 ASSERT_EFI_ERROR (Status);
370 }
371
372 return EFI_SUCCESS;
373 }