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