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.
119 // This is the end of the FspSiliconInit API
120 // Give control back to the boot loader
122 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_EXIT
);
123 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "FspSiliconInitApi() - End\n"));
125 PERF_END_EX (&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, 0x907F);
127 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
128 SetFspApiReturnStatus (EFI_SUCCESS
);
130 Pei2LoaderSwitchStack();
132 PERF_START_EX (&gFspPerformanceDataGuid
, "EventRec", NULL
, 0, 0x6000);
136 This function returns control to BootLoader after MemoryInitApi.
138 @param[in,out] HobListPtr The address of HobList pointer.
143 IN OUT VOID
**HobListPtr
147 // Calling use FspMemoryInit API
148 // Update HOB and return the control directly
150 if (HobListPtr
!= NULL
) {
151 *HobListPtr
= (VOID
*) GetHobList ();
155 // This is the end of the FspMemoryInit API
156 // Give control back to the boot loader
158 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT
);
159 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "FspMemoryInitApi() - End\n"));
160 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_MEMORY_INIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
161 SetFspApiReturnStatus (EFI_SUCCESS
);
162 Pei2LoaderSwitchStack ();
165 // The TempRamExitApi is called
167 if (GetFspApiCallingIndex () == TempRamExitApiIndex
) {
168 SetPhaseStatusCode (FSP_STATUS_CODE_TEMP_RAM_EXIT
);
169 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_TEMP_RAM_EXIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
170 SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY
);
171 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "TempRamExitApi() - Begin\n"));
173 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY
);
174 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "FspSiliconInitApi() - Begin\n"));
175 SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT
);
176 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_SILICON_INIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
181 This function returns control to BootLoader after TempRamExitApi.
192 // This is the end of the TempRamExit API
193 // Give control back to the boot loader
195 SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT
);
196 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "TempRamExitApi() - End\n"));
197 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_TEMP_RAM_EXIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
198 SetFspApiReturnStatus (EFI_SUCCESS
);
199 Pei2LoaderSwitchStack ();
201 SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT
);
202 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY
);
203 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "SiliconInitApi() - Begin\n"));
204 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_SILICON_INIT
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
208 This function handle NotifyPhase API call from the BootLoader.
209 It gives control back to the BootLoader after it is handled. If the
210 Notification code is a ReadyToBoot event, this function will return
211 and FSP continues the remaining execution until it reaches the DxeIpl.
220 UINT32 NotificationValue
;
221 UINT32 NotificationCount
;
224 NotificationCount
= 0;
225 while (NotificationCount
< sizeof(mFspNotifySequence
) / sizeof(UINT32
)) {
227 Count
= (UINT8
)((NotificationCount
<< 1) & 0x07);
228 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY
+ Count
);
230 if (NotificationCount
== 0) {
231 SetPhaseStatusCode (FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION
);
232 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
233 } else if (NotificationCount
== 1) {
234 SetPhaseStatusCode (FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION
);
235 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
236 } else if (NotificationCount
== 2) {
237 SetPhaseStatusCode (FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION
);
238 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
241 NotificationValue
= ((NOTIFY_PHASE_PARAMS
*)(UINTN
)GetFspApiParameter ())->Phase
;
242 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "NotifyPhaseApi() - Begin [Phase: %08X]\n", NotificationValue
));
243 if (mFspNotifySequence
[NotificationCount
] != NotificationValue
) {
245 // Notify code does not follow the predefined order
247 DEBUG ((DEBUG_INFO
, "Unsupported FSP Notification Value\n"));
248 Status
= EFI_UNSUPPORTED
;
251 // Process Notification and Give control back to the boot loader framework caller
253 Status
= FspNotificationHandler (NotificationValue
);
254 if (!EFI_ERROR(Status
)) {
259 SetFspApiReturnStatus(Status
);
260 DEBUG ((DEBUG_INFO
| DEBUG_INIT
, "NotifyPhaseApi() - End [Status: 0x%08X]\n", Status
));
262 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_EXIT
+ Count
);
264 if ((NotificationCount
- 1) == 0) {
265 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
266 } else if ((NotificationCount
- 1) == 1) {
267 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
268 } else if ((NotificationCount
- 1) == 2) {
269 REPORT_STATUS_CODE (EFI_PROGRESS_CODE
, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
271 Pei2LoaderSwitchStack();
275 // Control goes back to the PEI Core and it dispatches further PEIMs.
276 // DXEIPL is the final one to transfer control back to the boot loader.