2 This driver will register two callbacks to call fsp's notifies.
4 Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php.
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Protocol/PciEnumerationComplete.h>
19 #include <Library/UefiDriverEntryPoint.h>
20 #include <Library/UefiBootServicesTableLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/BaseMemoryLib.h>
23 #include <Library/UefiLib.h>
24 #include <Library/FspWrapperApiLib.h>
25 #include <Library/FspWrapperPlatformLib.h>
26 #include <Library/PerformanceLib.h>
27 #include <Library/HobLib.h>
28 #include <FspStatusCode.h>
30 #define FSP_API_NOTIFY_PHASE_AFTER_PCI_ENUMERATION BIT16
34 (EFIAPI
* ADD_PERFORMANCE_RECORDS
)(
35 IN CONST VOID
*HobStart
38 struct _ADD_PERFORMANCE_RECORD_PROTOCOL
{
39 ADD_PERFORMANCE_RECORDS AddPerformanceRecords
;
42 typedef struct _ADD_PERFORMANCE_RECORD_PROTOCOL ADD_PERFORMANCE_RECORD_PROTOCOL
;
44 extern EFI_GUID gAddPerfRecordProtocolGuid
;
45 extern EFI_GUID gFspHobGuid
;
46 extern EFI_GUID gFspApiPerformanceGuid
;
48 EFI_EVENT mExitBootServicesEvent
= NULL
;
51 Relocate this image under 4G memory.
53 @param ImageHandle Handle of driver image.
54 @param SystemTable Pointer to system table.
56 @retval EFI_SUCCESS Image successfully relocated.
57 @retval EFI_ABORTED Failed to relocate image.
61 RelocateImageUnder4GIfNeeded (
62 IN EFI_HANDLE ImageHandle
,
63 IN EFI_SYSTEM_TABLE
*SystemTable
67 PciEnumerationComplete Protocol notification event handler.
69 @param[in] Event Event whose notification function is being invoked.
70 @param[in] Context Pointer to the notification function's context.
74 OnPciEnumerationComplete (
79 NOTIFY_PHASE_PARAMS NotifyPhaseParams
;
84 // Try to locate it because gEfiPciEnumerationCompleteProtocolGuid will trigger it once when registration.
85 // Just return if it is not found.
87 Status
= gBS
->LocateProtocol (
88 &gEfiPciEnumerationCompleteProtocolGuid
,
92 if (EFI_ERROR (Status
)) {
96 NotifyPhaseParams
.Phase
= EnumInitPhaseAfterPciEnumeration
;
97 PERF_START_EX(&gFspApiPerformanceGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
98 Status
= CallFspNotifyPhase (&NotifyPhaseParams
);
99 PERF_END_EX(&gFspApiPerformanceGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
102 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
104 if ((Status
>= FSP_STATUS_RESET_REQUIRED_COLD
) && (Status
<= FSP_STATUS_RESET_REQUIRED_8
)) {
105 DEBUG((DEBUG_INFO
, "FSP NotifyPhase AfterPciEnumeration requested reset 0x%x\n", Status
));
106 CallFspWrapperResetSystem ((UINT32
)Status
);
109 if (Status
!= EFI_SUCCESS
) {
110 DEBUG((DEBUG_ERROR
, "FSP NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", Status
));
112 DEBUG((DEBUG_INFO
, "FSP NotifyPhase AfterPciEnumeration Success.\n"));
117 Notification function of EVT_GROUP_READY_TO_BOOT event group.
119 This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.
120 When the Boot Manager is about to load and execute a boot option, it reclaims variable
121 storage if free size is below the threshold.
123 @param[in] Event Event whose notification function is being invoked.
124 @param[in] Context Pointer to the notification function's context.
134 NOTIFY_PHASE_PARAMS NotifyPhaseParams
;
137 gBS
->CloseEvent (Event
);
139 NotifyPhaseParams
.Phase
= EnumInitPhaseReadyToBoot
;
140 PERF_START_EX(&gFspApiPerformanceGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
141 Status
= CallFspNotifyPhase (&NotifyPhaseParams
);
142 PERF_END_EX(&gFspApiPerformanceGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
145 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
147 if ((Status
>= FSP_STATUS_RESET_REQUIRED_COLD
) && (Status
<= FSP_STATUS_RESET_REQUIRED_8
)) {
148 DEBUG((DEBUG_INFO
, "FSP NotifyPhase ReadyToBoot requested reset 0x%x\n", Status
));
149 CallFspWrapperResetSystem ((UINT32
)Status
);
152 if (Status
!= EFI_SUCCESS
) {
153 DEBUG((DEBUG_ERROR
, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", Status
));
155 DEBUG((DEBUG_INFO
, "FSP NotifyPhase ReadyToBoot Success.\n"));
160 This stage is notified just before the firmware/Preboot environment transfers
161 management of all system resources to the OS or next level execution environment.
163 @param Event Event whose notification function is being invoked.
164 @param Context Pointer to the notification function's context, which is
165 always zero in current implementation.
175 NOTIFY_PHASE_PARAMS NotifyPhaseParams
;
177 ADD_PERFORMANCE_RECORD_PROTOCOL
*AddPerfRecordInterface
;
178 EFI_PEI_HOB_POINTERS Hob
;
179 VOID
**FspHobListPtr
;
181 gBS
->CloseEvent (Event
);
183 NotifyPhaseParams
.Phase
= EnumInitPhaseEndOfFirmware
;
184 PERF_START_EX(&gFspApiPerformanceGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_ENTRY
);
185 Status
= CallFspNotifyPhase (&NotifyPhaseParams
);
186 PERF_END_EX(&gFspApiPerformanceGuid
, "EventRec", NULL
, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION
| FSP_STATUS_CODE_COMMON_CODE
| FSP_STATUS_CODE_API_EXIT
);
189 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
191 if ((Status
>= FSP_STATUS_RESET_REQUIRED_COLD
) && (Status
<= FSP_STATUS_RESET_REQUIRED_8
)) {
192 DEBUG((DEBUG_INFO
, "FSP NotifyPhase EndOfFirmware requested reset 0x%x\n", Status
));
193 CallFspWrapperResetSystem ((UINT32
)Status
);
196 if (Status
!= EFI_SUCCESS
) {
197 DEBUG((DEBUG_ERROR
, "FSP NotifyPhase EndOfFirmware failed, status: 0x%x\n", Status
));
199 DEBUG((DEBUG_INFO
, "FSP NotifyPhase EndOfFirmware Success.\n"));
201 Status
= gBS
->LocateProtocol (
202 &gAddPerfRecordProtocolGuid
,
204 (VOID
**) &AddPerfRecordInterface
206 if (EFI_ERROR (Status
)) {
207 DEBUG((DEBUG_INFO
, "gAddPerfRecordProtocolGuid - Locate protocol failed\n"));
210 Hob
.Raw
= GetFirstGuidHob (&gFspHobGuid
);
211 if (Hob
.Raw
!= NULL
) {
212 FspHobListPtr
= GET_GUID_HOB_DATA (Hob
.Raw
);
213 AddPerfRecordInterface
->AddPerformanceRecords ((VOID
*)(UINTN
)(((UINT32
)(UINTN
)*FspHobListPtr
) & 0xFFFFFFFF));
219 Main entry for the FSP DXE module.
221 This routine registers two callbacks to call fsp's notifies.
223 @param[in] ImageHandle The firmware allocated handle for the EFI image.
224 @param[in] SystemTable A pointer to the EFI System Table.
226 @retval EFI_SUCCESS The entry point is executed successfully.
227 @retval other Some error occurs when executing this entry point.
232 FspWrapperNotifyDxeEntryPoint (
233 IN EFI_HANDLE ImageHandle
,
234 IN EFI_SYSTEM_TABLE
*SystemTable
238 EFI_EVENT ReadyToBootEvent
;
240 EFI_EVENT ProtocolNotifyEvent
;
244 // Load this driver's image to memory
246 Status
= RelocateImageUnder4GIfNeeded (ImageHandle
, SystemTable
);
247 if (EFI_ERROR (Status
)) {
251 FspApiMask
= PcdGet32 (PcdSkipFspApi
);
252 if ((FspApiMask
& FSP_API_NOTIFY_PHASE_AFTER_PCI_ENUMERATION
) == 0) {
253 ProtocolNotifyEvent
= EfiCreateProtocolNotifyEvent (
254 &gEfiPciEnumerationCompleteProtocolGuid
,
256 OnPciEnumerationComplete
,
260 ASSERT (ProtocolNotifyEvent
!= NULL
);
263 Status
= EfiCreateEventReadyToBootEx (
269 ASSERT_EFI_ERROR (Status
);
271 Status
= gBS
->CreateEventEx (
276 &gEfiEventExitBootServicesGuid
,
277 &mExitBootServicesEvent
279 ASSERT_EFI_ERROR (Status
);