]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
795bb28c0f71b34e2c14a4f441f9fb89c3aae5be
[mirror_edk2.git] / IntelFsp2Pkg / Library / BaseFspPlatformLib / FspPlatformNotify.c
1 /** @file
2
3 Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
5
6 **/
7
8 #include <PiPei.h>
9 #include <Library/PeiServicesLib.h>
10 #include <Library/PeiServicesTablePointerLib.h>
11 #include <Library/BaseLib.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/PcdLib.h>
14 #include <Library/DebugLib.h>
15 #include <Library/HobLib.h>
16 #include <Library/FspSwitchStackLib.h>
17 #include <Library/FspCommonLib.h>
18 #include <Guid/EventGroup.h>
19 #include <FspEas.h>
20 #include <FspStatusCode.h>
21 #include <Protocol/PciEnumerationComplete.h>
22 #include <Library/ReportStatusCodeLib.h>
23 #include <Library/PerformanceLib.h>
24 extern EFI_GUID gFspPerformanceDataGuid;
25
26 EFI_PEI_PPI_DESCRIPTOR mPeiPostPciEnumerationPpi = {
27 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
28 &gEfiPciEnumerationCompleteProtocolGuid,
29 NULL
30 };
31
32 EFI_PEI_PPI_DESCRIPTOR mPeiReadyToBootPpi = {
33 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
34 &gEfiEventReadyToBootGuid,
35 NULL
36 };
37
38 EFI_PEI_PPI_DESCRIPTOR mPeiEndOfFirmwarePpi = {
39 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
40 &gFspEventEndOfFirmwareGuid,
41 NULL
42 };
43
44 UINT32 mFspNotifySequence[] = {
45 EnumInitPhaseAfterPciEnumeration,
46 EnumInitPhaseReadyToBoot,
47 EnumInitPhaseEndOfFirmware
48 };
49
50 /**
51 Install FSP notification.
52
53 @param[in] NotificationCode FSP notification code
54
55 @retval EFI_SUCCESS Notify FSP successfully
56 @retval EFI_INVALID_PARAMETER NotificationCode is invalid
57
58 **/
59 EFI_STATUS
60 EFIAPI
61 FspNotificationHandler (
62 IN UINT32 NotificationCode
63 )
64 {
65 EFI_STATUS Status;
66
67 Status = EFI_SUCCESS;
68
69 switch (NotificationCode) {
70 case EnumInitPhaseAfterPciEnumeration:
71 //
72 // Do POST PCI initialization if needed
73 //
74 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Post PCI Enumeration ...\n"));
75 PeiServicesInstallPpi (&mPeiPostPciEnumerationPpi);
76 break;
77
78 case EnumInitPhaseReadyToBoot:
79 //
80 // Ready To Boot
81 //
82 DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP Ready To Boot ...\n"));
83 PeiServicesInstallPpi (&mPeiReadyToBootPpi);
84 break;
85
86 case EnumInitPhaseEndOfFirmware:
87 //
88 // End of Firmware
89 //
90 DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP End of Firmware ...\n"));
91 PeiServicesInstallPpi (&mPeiEndOfFirmwarePpi);
92 break;
93
94 default:
95 Status = EFI_INVALID_PARAMETER;
96 break;
97 }
98
99 return Status;
100 }
101
102 /**
103 This function transfer control back to BootLoader after FspSiliconInit.
104
105 @param[in] Status return status for the FspSiliconInit.
106
107 **/
108 VOID
109 EFIAPI
110 FspSiliconInitDone2 (
111 IN EFI_STATUS Status
112 )
113 {
114 volatile EFI_STATUS FspStatus;
115
116 FspStatus = Status;
117 //
118 // Convert to FSP EAS defined API return codes
119 //
120 switch (Status) {
121 case EFI_SUCCESS:
122 case EFI_INVALID_PARAMETER:
123 case EFI_UNSUPPORTED:
124 case EFI_DEVICE_ERROR:
125 break;
126 default:
127 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() Invalid Error - [Status: 0x%08X]\n", Status));
128 Status = EFI_DEVICE_ERROR; // Force to known error.
129 break;
130 }
131
132 //
133 // This is the end of the FspSiliconInit API
134 // Give control back to the boot loader
135 //
136 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_EXIT);
137 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - [Status: 0x%08X] - End\n", Status));
138 PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
139 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
140 if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
141 do {
142 SetFspApiReturnStatus (Status);
143 Pei2LoaderSwitchStack ();
144 if (Status != EFI_SUCCESS) {
145 DEBUG ((DEBUG_ERROR, "!!!ERROR: FspSiliconInitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status));
146 }
147 } while (FspStatus != EFI_SUCCESS);
148 }
149 }
150
151 /**
152 This function returns control to BootLoader after MemoryInitApi.
153
154 @param[in] Status return status for the MemoryInitApi.
155 @param[in,out] HobListPtr The address of HobList pointer, if NULL, will get value from GetFspApiParameter2 ()
156 **/
157 VOID
158 EFIAPI
159 FspMemoryInitDone2 (
160 IN EFI_STATUS Status,
161 IN OUT VOID **HobListPtr
162 )
163 {
164 FSP_GLOBAL_DATA *FspData;
165 volatile EFI_STATUS FspStatus;
166
167 FspStatus = Status;
168 //
169 // Calling use FspMemoryInit API
170 // Update HOB and return the control directly
171 //
172 if (HobListPtr == NULL) {
173 HobListPtr = (VOID **)GetFspApiParameter2 ();
174 }
175
176 if (HobListPtr != NULL) {
177 *HobListPtr = (VOID *)GetHobList ();
178 }
179
180 //
181 // Convert to FSP EAS defined API return codes
182 //
183 switch (Status) {
184 case EFI_SUCCESS:
185 case EFI_INVALID_PARAMETER:
186 case EFI_UNSUPPORTED:
187 case EFI_DEVICE_ERROR:
188 case EFI_OUT_OF_RESOURCES:
189 break;
190 default:
191 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() Invalid Error [Status: 0x%08X]\n", Status));
192 Status = EFI_DEVICE_ERROR; // Force to known error.
193 break;
194 }
195
196 //
197 // This is the end of the FspMemoryInit API
198 // Give control back to the boot loader
199 //
200 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() - [Status: 0x%08X] - End\n", Status));
201 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT);
202 FspData = GetFspGlobalDataPointer ();
203 PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[0] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_TEMP_RAM_INIT | FSP_STATUS_CODE_COMMON_CODE| FSP_STATUS_CODE_API_ENTRY);
204 PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[1] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_TEMP_RAM_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
205 PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[2] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
206 PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
207 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
208 if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
209 do {
210 SetFspApiReturnStatus (Status);
211 Pei2LoaderSwitchStack ();
212 if (Status != EFI_SUCCESS) {
213 DEBUG ((DEBUG_ERROR, "!!!ERROR: FspMemoryInitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status));
214 }
215 } while (FspStatus != EFI_SUCCESS);
216 }
217
218 //
219 // The TempRamExitApi is called
220 //
221 if (GetFspApiCallingIndex () == TempRamExitApiIndex) {
222 SetPhaseStatusCode (FSP_STATUS_CODE_TEMP_RAM_EXIT);
223 SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY);
224 PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
225 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
226 DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - Begin\n"));
227 } else {
228 SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
229 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
230 PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
231 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
232 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - Begin\n"));
233 }
234 }
235
236 /**
237 This function returns control to BootLoader after TempRamExitApi.
238
239 @param[in] Status return status for the TempRamExitApi.
240
241 **/
242 VOID
243 EFIAPI
244 FspTempRamExitDone2 (
245 IN EFI_STATUS Status
246 )
247 {
248 //
249 volatile EFI_STATUS FspStatus;
250
251 FspStatus = Status;
252 // Convert to FSP EAS defined API return codes
253 //
254 switch (Status) {
255 case EFI_SUCCESS:
256 case EFI_INVALID_PARAMETER:
257 case EFI_UNSUPPORTED:
258 case EFI_DEVICE_ERROR:
259 break;
260 default:
261 DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() Invalid Error - [Status: 0x%08X]\n", Status));
262 Status = EFI_DEVICE_ERROR; // Force to known error.
263 break;
264 }
265
266 //
267 // This is the end of the TempRamExit API
268 // Give control back to the boot loader
269 //
270 DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - [Status: 0x%08X] - End\n", Status));
271 SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT);
272 PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
273 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
274 if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
275 do {
276 SetFspApiReturnStatus (Status);
277 Pei2LoaderSwitchStack ();
278 if (Status != EFI_SUCCESS) {
279 DEBUG ((DEBUG_ERROR, "!!!ERROR: TempRamExitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status));
280 }
281 } while (FspStatus != EFI_SUCCESS);
282 }
283
284 SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
285 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
286 PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
287 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
288 DEBUG ((DEBUG_INFO | DEBUG_INIT, "SiliconInitApi() - Begin\n"));
289 }
290
291 /**
292 This function handle NotifyPhase API call from the BootLoader.
293 It gives control back to the BootLoader after it is handled. If the
294 Notification code is a ReadyToBoot event, this function will return
295 and FSP continues the remaining execution until it reaches the DxeIpl.
296
297 **/
298 VOID
299 FspWaitForNotify (
300 VOID
301 )
302 {
303 EFI_STATUS Status;
304 UINT32 NotificationValue;
305 UINT32 NotificationCount;
306 UINT8 Count;
307 volatile EFI_STATUS FspStatus;
308
309 NotificationCount = 0;
310 while (NotificationCount < sizeof (mFspNotifySequence) / sizeof (UINT32)) {
311 Count = (UINT8)((NotificationCount << 1) & 0x07);
312 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY + Count);
313
314 if (NotificationCount == 0) {
315 SetPhaseStatusCode (FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION);
316 PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
317 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
318 } else if (NotificationCount == 1) {
319 SetPhaseStatusCode (FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION);
320 PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
321 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
322 } else if (NotificationCount == 2) {
323 SetPhaseStatusCode (FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION);
324 PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
325 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
326 }
327
328 NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;
329 DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - Begin [Phase: %08X]\n", NotificationValue));
330 if (mFspNotifySequence[NotificationCount] != NotificationValue) {
331 //
332 // Notify code does not follow the predefined order
333 //
334 DEBUG ((DEBUG_INFO, "Unsupported FSP Notification Value\n"));
335 Status = EFI_UNSUPPORTED;
336 } else {
337 //
338 // Process Notification and Give control back to the boot loader framework caller
339 //
340 Status = FspNotificationHandler (NotificationValue);
341 if (!EFI_ERROR (Status)) {
342 NotificationCount++;
343 }
344 }
345
346 DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - End [Status: 0x%08X]\n", Status));
347 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_EXIT + Count);
348
349 if ((NotificationCount - 1) == 0) {
350 PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
351 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
352 } else if ((NotificationCount - 1) == 1) {
353 PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
354 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
355 } else if ((NotificationCount - 1) == 2) {
356 PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
357 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
358 }
359
360 if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
361 FspStatus = Status;
362 do {
363 SetFspApiReturnStatus (Status);
364 Pei2LoaderSwitchStack ();
365 if (Status != EFI_SUCCESS) {
366 DEBUG ((DEBUG_ERROR, "!!!ERROR: NotifyPhaseApi() [Phase: %08X] - Failed - [Status: 0x%08X]\n", NotificationValue, Status));
367 }
368 } while (FspStatus != EFI_SUCCESS);
369 }
370 }
371
372 //
373 // Control goes back to the PEI Core and it dispatches further PEIMs.
374 // DXEIPL is the final one to transfer control back to the boot loader.
375 //
376 }
377
378 /**
379 This function transfer control back to BootLoader after FspSiliconInit.
380
381 **/
382 VOID
383 EFIAPI
384 FspSiliconInitDone (
385 VOID
386 )
387 {
388 FspSiliconInitDone2 (EFI_SUCCESS);
389 }
390
391 /**
392 This function returns control to BootLoader after MemoryInitApi.
393
394 @param[in,out] HobListPtr The address of HobList pointer.
395 **/
396 VOID
397 EFIAPI
398 FspMemoryInitDone (
399 IN OUT VOID **HobListPtr
400 )
401 {
402 FspMemoryInitDone2 (EFI_SUCCESS, HobListPtr);
403 }
404
405 /**
406 This function returns control to BootLoader after TempRamExitApi.
407
408 **/
409 VOID
410 EFIAPI
411 FspTempRamExitDone (
412 VOID
413 )
414 {
415 FspTempRamExitDone2 (EFI_SUCCESS);
416 }