3 Copyright (c) 2014 - 2016, 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.
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.
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>
26 #include <FspStatusCode.h>
27 #include <Protocol/PciEnumerationComplete.h>
28 #include <Library/ReportStatusCodeLib.h>
29 #include <Library/PerformanceLib.h>
30 extern EFI_GUID gFspPerformanceDataGuid
;
32 EFI_PEI_PPI_DESCRIPTOR mPeiPostPciEnumerationPpi
= {
33 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
34 &gEfiPciEnumerationCompleteProtocolGuid
,
38 EFI_PEI_PPI_DESCRIPTOR mPeiReadyToBootPpi
= {
39 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
40 &gEfiEventReadyToBootGuid
,
44 EFI_PEI_PPI_DESCRIPTOR mPeiEndOfFirmwarePpi
= {
45 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
46 &gFspEventEndOfFirmwareGuid
,
50 UINT32 mFspNotifySequence
[] = {
51 EnumInitPhaseAfterPciEnumeration
,
52 EnumInitPhaseReadyToBoot
,
53 EnumInitPhaseEndOfFirmware
57 Install FSP notification.
59 @param[in] NotificationCode FSP notification code
61 @retval EFI_SUCCESS Notify FSP successfully
62 @retval EFI_INVALID_PARAMETER NotificationCode is invalid
67 FspNotificationHandler (
68 IN UINT32 NotificationCode
75 switch (NotificationCode
) {
76 case EnumInitPhaseAfterPciEnumeration
:
78 // Do POST PCI initialization if needed
80 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "FSP Post PCI Enumeration ...\n"));
81 PeiServicesInstallPpi (&mPeiPostPciEnumerationPpi
);
84 case EnumInitPhaseReadyToBoot
:
88 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "FSP Ready To Boot ...\n"));
89 PeiServicesInstallPpi (&mPeiReadyToBootPpi
);
92 case EnumInitPhaseEndOfFirmware
:
96 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "FSP End of Firmware ...\n"));
97 PeiServicesInstallPpi (&mPeiEndOfFirmwarePpi
);
101 Status
= EFI_INVALID_PARAMETER
;
109 This function transfer control back to BootLoader after FspSiliconInit.
111 @param[in] Status return status for the FspSiliconInit.
116 FspSiliconInitDone2 (
121 // Convert to FSP EAS defined API return codes
125 case EFI_INVALID_PARAMETER
:
126 case EFI_UNSUPPORTED
:
127 case EFI_DEVICE_ERROR
:
130 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "FspSiliconInitApi() Invalid Error - [Status: 0x%08X]\n", Status
));
131 Status
= EFI_DEVICE_ERROR
; // Force to known error.
135 // This is the end of the FspSiliconInit API
136 // Give control back to the boot loader
138 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_EXIT
);
139 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "FspSiliconInitApi() - [Status: 0x%08X] - End\n", Status
));
140 PERF_END_EX (&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_SILICON_INIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
141 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
143 SetFspApiReturnStatus (Status
);
144 Pei2LoaderSwitchStack ();
145 if (Status
!= EFI_SUCCESS
) {
146 DEBUG ((DEBUG_ERROR
, "!!!ERROR: FspSiliconInitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status
));
148 } while (Status
!= EFI_SUCCESS
);
152 This function returns control to BootLoader after MemoryInitApi.
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 ()
160 IN EFI_STATUS Status
,
161 IN OUT VOID
**HobListPtr
164 FSP_GLOBAL_DATA
*FspData
;
166 // Calling use FspMemoryInit API
167 // Update HOB and return the control directly
169 if (HobListPtr
== NULL
) {
170 HobListPtr
= (VOID
**)GetFspApiParameter2 ();
172 if (HobListPtr
!= NULL
) {
173 *HobListPtr
= (VOID
*) GetHobList ();
176 // Convert to FSP EAS defined API return codes
180 case EFI_INVALID_PARAMETER
:
181 case EFI_UNSUPPORTED
:
182 case EFI_DEVICE_ERROR
:
183 case EFI_OUT_OF_RESOURCES
:
186 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "FspMemoryInitApi() Invalid Error [Status: 0x%08X]\n", Status
));
187 Status
= EFI_DEVICE_ERROR
; // Force to known error.
191 // This is the end of the FspMemoryInit API
192 // Give control back to the boot loader
194 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "FspMemoryInitApi() - [Status: 0x%08X] - End\n", Status
));
195 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT
);
196 FspData
= GetFspGlobalDataPointer ();
197 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
);
198 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
);
199 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
);
200 PERF_END_EX(&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_MEMORY_INIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
201 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_MEMORY_INIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
203 SetFspApiReturnStatus (Status
);
204 Pei2LoaderSwitchStack ();
205 if (Status
!= EFI_SUCCESS
) {
206 DEBUG ((DEBUG_ERROR
, "!!!ERROR: FspMemoryInitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status
));
208 } while (Status
!= EFI_SUCCESS
);
211 // The TempRamExitApi is called
213 if (GetFspApiCallingIndex () == TempRamExitApiIndex
) {
214 SetPhaseStatusCode (FSP_STATUS_CODE_TEMP_RAM_EXIT
);
215 SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY
);
216 PERF_START_EX(&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
217 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_TEMP_RAM_EXIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
218 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "TempRamExitApi() - Begin\n"));
220 SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT
);
221 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY
);
222 PERF_START_EX(&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_SILICON_INIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
223 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_SILICON_INIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
224 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "FspSiliconInitApi() - Begin\n"));
229 This function returns control to BootLoader after TempRamExitApi.
231 @param[in] Status return status for the TempRamExitApi.
236 FspTempRamExitDone2 (
241 // Convert to FSP EAS defined API return codes
245 case EFI_INVALID_PARAMETER
:
246 case EFI_UNSUPPORTED
:
247 case EFI_DEVICE_ERROR
:
250 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "TempRamExitApi() Invalid Error - [Status: 0x%08X]\n", Status
));
251 Status
= EFI_DEVICE_ERROR
; // Force to known error.
255 // This is the end of the TempRamExit API
256 // Give control back to the boot loader
258 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "TempRamExitApi() - [Status: 0x%08X] - End\n", Status
));
259 SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT
);
260 PERF_END_EX(&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
261 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_TEMP_RAM_EXIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
263 SetFspApiReturnStatus (Status
);
264 Pei2LoaderSwitchStack ();
265 if (Status
!= EFI_SUCCESS
) {
266 DEBUG ((DEBUG_ERROR
, "!!!ERROR: TempRamExitApi() - [Status: 0x%08X] - Error encountered during previous API and cannot proceed further\n", Status
));
268 } while (Status
!= EFI_SUCCESS
);
269 SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT
);
270 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY
);
271 PERF_START_EX(&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_SILICON_INIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
272 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_SILICON_INIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
273 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "SiliconInitApi() - Begin\n"));
277 This function handle NotifyPhase API call from the BootLoader.
278 It gives control back to the BootLoader after it is handled. If the
279 Notification code is a ReadyToBoot event, this function will return
280 and FSP continues the remaining execution until it reaches the DxeIpl.
289 UINT32 NotificationValue
;
290 UINT32 NotificationCount
;
293 NotificationCount
= 0;
294 while (NotificationCount
< sizeof(mFspNotifySequence
) / sizeof(UINT32
)) {
296 Count
= (UINT8
)((NotificationCount
<< 1) & 0x07);
297 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY
+ Count
);
299 if (NotificationCount
== 0) {
300 SetPhaseStatusCode (FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION
);
301 PERF_START_EX (&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
302 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
303 } else if (NotificationCount
== 1) {
304 SetPhaseStatusCode (FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION
);
305 PERF_START_EX(&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
306 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
307 } else if (NotificationCount
== 2) {
308 SetPhaseStatusCode (FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION
);
309 PERF_START_EX (&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
310 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
313 NotificationValue
= ((NOTIFY_PHASE_PARAMS
*)(UINTN
)GetFspApiParameter ())->Phase
;
314 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "NotifyPhaseApi() - Begin [Phase: %08X]\n", NotificationValue
));
315 if (mFspNotifySequence
[NotificationCount
] != NotificationValue
) {
317 // Notify code does not follow the predefined order
319 DEBUG ((DEBUG_INFO
, "Unsupported FSP Notification Value\n"));
320 Status
= EFI_UNSUPPORTED
;
323 // Process Notification and Give control back to the boot loader framework caller
325 Status
= FspNotificationHandler (NotificationValue
);
326 if (!EFI_ERROR(Status
)) {
331 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "NotifyPhaseApi() - End [Status: 0x%08X]\n", Status
));
332 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_EXIT
+ Count
);
334 if ((NotificationCount
- 1) == 0) {
335 PERF_END_EX(&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
336 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
337 } else if ((NotificationCount
- 1) == 1) {
338 PERF_END_EX(&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
339 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
340 } else if ((NotificationCount
- 1) == 2) {
341 PERF_END_EX(&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
342 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
345 SetFspApiReturnStatus(Status
);
346 Pei2LoaderSwitchStack();
347 if (Status
!= EFI_SUCCESS
) {
348 DEBUG ((DEBUG_ERROR
, "!!!ERROR: NotifyPhaseApi() [Phase: %08X] - Failed - [Status: 0x%08X]\n", NotificationValue
, Status
));
350 } while (Status
!= EFI_SUCCESS
);
354 // Control goes back to the PEI Core and it dispatches further PEIMs.
355 // DXEIPL is the final one to transfer control back to the boot loader.
360 This function transfer control back to BootLoader after FspSiliconInit.
369 FspSiliconInitDone2 (EFI_SUCCESS
);
373 This function returns control to BootLoader after MemoryInitApi.
375 @param[in,out] HobListPtr The address of HobList pointer.
380 IN OUT VOID
**HobListPtr
383 FspMemoryInitDone2 (EFI_SUCCESS
, HobListPtr
);
387 This function returns control to BootLoader after TempRamExitApi.
396 FspTempRamExitDone2 (EFI_SUCCESS
);