]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFsp2Pkg/Library/BaseFspPlatformLib/FspPlatformNotify.c
IntelFsp2Pkg: Replace BSD License with BSD+Patent License
[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 // This is the end of the FspSiliconInit API
133 // Give control back to the boot loader
134 //
135 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_EXIT);
136 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - [Status: 0x%08X] - End\n", Status));
137 PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
138 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
139 if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
140 do {
141 SetFspApiReturnStatus (Status);
142 Pei2LoaderSwitchStack ();
143 if (Status != EFI_SUCCESS) {
144 DEBUG ((DEBUG_ERROR, "!!!ERROR: FspSiliconInitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status));
145 }
146 } while (FspStatus != EFI_SUCCESS);
147 }
148 }
149
150 /**
151 This function returns control to BootLoader after MemoryInitApi.
152
153 @param[in] Status return status for the MemoryInitApi.
154 @param[in,out] HobListPtr The address of HobList pointer, if NULL, will get value from GetFspApiParameter2 ()
155 **/
156 VOID
157 EFIAPI
158 FspMemoryInitDone2 (
159 IN EFI_STATUS Status,
160 IN OUT VOID **HobListPtr
161 )
162 {
163 FSP_GLOBAL_DATA *FspData;
164 volatile EFI_STATUS FspStatus;
165
166 FspStatus = Status;
167 //
168 // Calling use FspMemoryInit API
169 // Update HOB and return the control directly
170 //
171 if (HobListPtr == NULL) {
172 HobListPtr = (VOID **)GetFspApiParameter2 ();
173 }
174 if (HobListPtr != NULL) {
175 *HobListPtr = (VOID *) GetHobList ();
176 }
177 //
178 // Convert to FSP EAS defined API return codes
179 //
180 switch (Status) {
181 case EFI_SUCCESS:
182 case EFI_INVALID_PARAMETER:
183 case EFI_UNSUPPORTED:
184 case EFI_DEVICE_ERROR:
185 case EFI_OUT_OF_RESOURCES:
186 break;
187 default:
188 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() Invalid Error [Status: 0x%08X]\n", Status));
189 Status = EFI_DEVICE_ERROR; // Force to known error.
190 break;
191 }
192 //
193 // This is the end of the FspMemoryInit API
194 // Give control back to the boot loader
195 //
196 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() - [Status: 0x%08X] - End\n", Status));
197 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT);
198 FspData = GetFspGlobalDataPointer ();
199 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);
200 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);
201 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);
202 PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
203 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
204 if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
205 do {
206 SetFspApiReturnStatus (Status);
207 Pei2LoaderSwitchStack ();
208 if (Status != EFI_SUCCESS) {
209 DEBUG ((DEBUG_ERROR, "!!!ERROR: FspMemoryInitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status));
210 }
211 } while (FspStatus != EFI_SUCCESS);
212 }
213
214 //
215 // The TempRamExitApi is called
216 //
217 if (GetFspApiCallingIndex () == TempRamExitApiIndex) {
218 SetPhaseStatusCode (FSP_STATUS_CODE_TEMP_RAM_EXIT);
219 SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY);
220 PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
221 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
222 DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - Begin\n"));
223 } else {
224 SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
225 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
226 PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
227 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
228 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - Begin\n"));
229 }
230 }
231
232 /**
233 This function returns control to BootLoader after TempRamExitApi.
234
235 @param[in] Status return status for the TempRamExitApi.
236
237 **/
238 VOID
239 EFIAPI
240 FspTempRamExitDone2 (
241 IN EFI_STATUS Status
242 )
243 {
244 //
245 volatile EFI_STATUS FspStatus;
246
247 FspStatus = Status;
248 // Convert to FSP EAS defined API return codes
249 //
250 switch (Status) {
251 case EFI_SUCCESS:
252 case EFI_INVALID_PARAMETER:
253 case EFI_UNSUPPORTED:
254 case EFI_DEVICE_ERROR:
255 break;
256 default:
257 DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() Invalid Error - [Status: 0x%08X]\n", Status));
258 Status = EFI_DEVICE_ERROR; // Force to known error.
259 break;
260 }
261 //
262 // This is the end of the TempRamExit API
263 // Give control back to the boot loader
264 //
265 DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - [Status: 0x%08X] - End\n", Status));
266 SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT);
267 PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
268 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
269 if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
270 do {
271 SetFspApiReturnStatus (Status);
272 Pei2LoaderSwitchStack ();
273 if (Status != EFI_SUCCESS) {
274 DEBUG ((DEBUG_ERROR, "!!!ERROR: TempRamExitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status));
275 }
276 } while (FspStatus != EFI_SUCCESS);
277 }
278 SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
279 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
280 PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
281 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
282 DEBUG ((DEBUG_INFO | DEBUG_INIT, "SiliconInitApi() - Begin\n"));
283 }
284
285 /**
286 This function handle NotifyPhase API call from the BootLoader.
287 It gives control back to the BootLoader after it is handled. If the
288 Notification code is a ReadyToBoot event, this function will return
289 and FSP continues the remaining execution until it reaches the DxeIpl.
290
291 **/
292 VOID
293 FspWaitForNotify (
294 VOID
295 )
296 {
297 EFI_STATUS Status;
298 UINT32 NotificationValue;
299 UINT32 NotificationCount;
300 UINT8 Count;
301 volatile EFI_STATUS FspStatus;
302
303 NotificationCount = 0;
304 while (NotificationCount < sizeof(mFspNotifySequence) / sizeof(UINT32)) {
305
306 Count = (UINT8)((NotificationCount << 1) & 0x07);
307 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY + Count);
308
309 if (NotificationCount == 0) {
310 SetPhaseStatusCode (FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION);
311 PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
312 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
313 } else if (NotificationCount == 1) {
314 SetPhaseStatusCode (FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION);
315 PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
316 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
317 } else if (NotificationCount == 2) {
318 SetPhaseStatusCode (FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION);
319 PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
320 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
321 }
322
323 NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;
324 DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - Begin [Phase: %08X]\n", NotificationValue));
325 if (mFspNotifySequence[NotificationCount] != NotificationValue) {
326 //
327 // Notify code does not follow the predefined order
328 //
329 DEBUG ((DEBUG_INFO, "Unsupported FSP Notification Value\n"));
330 Status = EFI_UNSUPPORTED;
331 } else {
332 //
333 // Process Notification and Give control back to the boot loader framework caller
334 //
335 Status = FspNotificationHandler (NotificationValue);
336 if (!EFI_ERROR(Status)) {
337 NotificationCount++;
338 }
339 }
340
341 DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - End [Status: 0x%08X]\n", Status));
342 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_EXIT + Count);
343
344 if ((NotificationCount - 1) == 0) {
345 PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
346 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
347 } else if ((NotificationCount - 1) == 1) {
348 PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
349 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
350 } else if ((NotificationCount - 1) == 2) {
351 PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
352 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
353 }
354 if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
355 FspStatus = Status;
356 do {
357 SetFspApiReturnStatus(Status);
358 Pei2LoaderSwitchStack();
359 if (Status != EFI_SUCCESS) {
360 DEBUG ((DEBUG_ERROR, "!!!ERROR: NotifyPhaseApi() [Phase: %08X] - Failed - [Status: 0x%08X]\n", NotificationValue, Status));
361 }
362 } while (FspStatus != EFI_SUCCESS);
363 }
364 }
365 //
366 // Control goes back to the PEI Core and it dispatches further PEIMs.
367 // DXEIPL is the final one to transfer control back to the boot loader.
368 //
369 }
370
371 /**
372 This function transfer control back to BootLoader after FspSiliconInit.
373
374 **/
375 VOID
376 EFIAPI
377 FspSiliconInitDone (
378 VOID
379 )
380 {
381 FspSiliconInitDone2 (EFI_SUCCESS);
382 }
383
384 /**
385 This function returns control to BootLoader after MemoryInitApi.
386
387 @param[in,out] HobListPtr The address of HobList pointer.
388 **/
389 VOID
390 EFIAPI
391 FspMemoryInitDone (
392 IN OUT VOID **HobListPtr
393 )
394 {
395 FspMemoryInitDone2 (EFI_SUCCESS, HobListPtr);
396 }
397
398 /**
399 This function returns control to BootLoader after TempRamExitApi.
400
401 **/
402 VOID
403 EFIAPI
404 FspTempRamExitDone (
405 VOID
406 )
407 {
408 FspTempRamExitDone2 (EFI_SUCCESS);
409 }