]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c
IntelFsp2WrapperPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / IntelFsp2WrapperPkg / FspWrapperNotifyDxe / FspWrapperNotifyDxe.c
CommitLineData
cf1d4549
JY
1/** @file\r
2 This driver will register two callbacks to call fsp's notifies.\r
3\r
4 Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>\r
512e23a3 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
cf1d4549
JY
6\r
7**/\r
8\r
9#include <PiDxe.h>\r
10\r
11#include <Protocol/PciEnumerationComplete.h>\r
12\r
13#include <Library/UefiDriverEntryPoint.h>\r
14#include <Library/UefiBootServicesTableLib.h>\r
15#include <Library/DebugLib.h>\r
16#include <Library/BaseMemoryLib.h>\r
17#include <Library/UefiLib.h>\r
18#include <Library/FspWrapperApiLib.h>\r
f862a3b6 19#include <Library/FspWrapperPlatformLib.h>\r
cf1d4549
JY
20#include <Library/PerformanceLib.h>\r
21#include <Library/HobLib.h>\r
19d29d35 22#include <FspStatusCode.h>\r
cf1d4549 23\r
4d4b8169
DG
24#define FSP_API_NOTIFY_PHASE_AFTER_PCI_ENUMERATION BIT16\r
25\r
cf1d4549
JY
26typedef\r
27EFI_STATUS\r
28(EFIAPI * ADD_PERFORMANCE_RECORDS)(\r
29 IN CONST VOID *HobStart\r
30 );\r
31\r
32struct _ADD_PERFORMANCE_RECORD_PROTOCOL {\r
33 ADD_PERFORMANCE_RECORDS AddPerformanceRecords;\r
34};\r
35\r
36typedef struct _ADD_PERFORMANCE_RECORD_PROTOCOL ADD_PERFORMANCE_RECORD_PROTOCOL;\r
37\r
38extern EFI_GUID gAddPerfRecordProtocolGuid;\r
39extern EFI_GUID gFspHobGuid;\r
40extern EFI_GUID gFspApiPerformanceGuid;\r
41\r
42EFI_EVENT mExitBootServicesEvent = NULL;\r
43\r
44/**\r
45 Relocate this image under 4G memory.\r
46\r
47 @param ImageHandle Handle of driver image.\r
48 @param SystemTable Pointer to system table.\r
49\r
50 @retval EFI_SUCCESS Image successfully relocated.\r
51 @retval EFI_ABORTED Failed to relocate image.\r
52\r
53**/\r
54EFI_STATUS\r
55RelocateImageUnder4GIfNeeded (\r
56 IN EFI_HANDLE ImageHandle,\r
57 IN EFI_SYSTEM_TABLE *SystemTable\r
58 );\r
59\r
60/**\r
61 PciEnumerationComplete Protocol notification event handler.\r
62\r
63 @param[in] Event Event whose notification function is being invoked.\r
64 @param[in] Context Pointer to the notification function's context.\r
65**/\r
66VOID\r
67EFIAPI\r
68OnPciEnumerationComplete (\r
69 IN EFI_EVENT Event,\r
70 IN VOID *Context\r
71 )\r
72{\r
73 NOTIFY_PHASE_PARAMS NotifyPhaseParams;\r
74 EFI_STATUS Status;\r
75 VOID *Interface;\r
76\r
77 //\r
78 // Try to locate it because gEfiPciEnumerationCompleteProtocolGuid will trigger it once when registration.\r
79 // Just return if it is not found.\r
80 //\r
81 Status = gBS->LocateProtocol (\r
82 &gEfiPciEnumerationCompleteProtocolGuid,\r
83 NULL,\r
84 &Interface\r
85 );\r
86 if (EFI_ERROR (Status)) {\r
87 return ;\r
88 }\r
89\r
90 NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration;\r
19d29d35 91 PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
cf1d4549 92 Status = CallFspNotifyPhase (&NotifyPhaseParams);\r
19d29d35 93 PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
f862a3b6
JY
94\r
95 //\r
96 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status\r
97 //\r
98 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {\r
99 DEBUG((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration requested reset 0x%x\n", Status));\r
100 CallFspWrapperResetSystem ((UINT32)Status);\r
101 }\r
102\r
cf1d4549
JY
103 if (Status != EFI_SUCCESS) {\r
104 DEBUG((DEBUG_ERROR, "FSP NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", Status));\r
105 } else {\r
106 DEBUG((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration Success.\n"));\r
107 }\r
108}\r
109\r
110/**\r
111 Notification function of EVT_GROUP_READY_TO_BOOT event group.\r
112\r
113 This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.\r
114 When the Boot Manager is about to load and execute a boot option, it reclaims variable\r
115 storage if free size is below the threshold.\r
116\r
117 @param[in] Event Event whose notification function is being invoked.\r
118 @param[in] Context Pointer to the notification function's context.\r
119\r
120**/\r
121VOID\r
122EFIAPI\r
123OnReadyToBoot (\r
124 IN EFI_EVENT Event,\r
125 IN VOID *Context\r
126 )\r
127{\r
128 NOTIFY_PHASE_PARAMS NotifyPhaseParams;\r
129 EFI_STATUS Status;\r
cf1d4549
JY
130\r
131 gBS->CloseEvent (Event);\r
132\r
133 NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot;\r
19d29d35 134 PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
cf1d4549 135 Status = CallFspNotifyPhase (&NotifyPhaseParams);\r
19d29d35 136 PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
f862a3b6
JY
137\r
138 //\r
139 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status\r
140 //\r
141 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {\r
142 DEBUG((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot requested reset 0x%x\n", Status));\r
143 CallFspWrapperResetSystem ((UINT32)Status);\r
144 }\r
145\r
cf1d4549
JY
146 if (Status != EFI_SUCCESS) {\r
147 DEBUG((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", Status));\r
148 } else {\r
149 DEBUG((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot Success.\n"));\r
150 }\r
cf1d4549
JY
151}\r
152\r
153/**\r
154 This stage is notified just before the firmware/Preboot environment transfers\r
155 management of all system resources to the OS or next level execution environment.\r
156\r
157 @param Event Event whose notification function is being invoked.\r
158 @param Context Pointer to the notification function's context, which is\r
159 always zero in current implementation.\r
160\r
161**/\r
162VOID\r
163EFIAPI\r
164OnEndOfFirmware (\r
165 IN EFI_EVENT Event,\r
166 IN VOID *Context\r
167 )\r
168{\r
19d29d35
YS
169 NOTIFY_PHASE_PARAMS NotifyPhaseParams;\r
170 EFI_STATUS Status;\r
171 ADD_PERFORMANCE_RECORD_PROTOCOL *AddPerfRecordInterface;\r
172 EFI_PEI_HOB_POINTERS Hob;\r
173 VOID **FspHobListPtr;\r
cf1d4549
JY
174\r
175 gBS->CloseEvent (Event);\r
176\r
177 NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware;\r
19d29d35 178 PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
cf1d4549 179 Status = CallFspNotifyPhase (&NotifyPhaseParams);\r
19d29d35 180 PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
f862a3b6
JY
181\r
182 //\r
183 // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status\r
184 //\r
185 if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {\r
186 DEBUG((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware requested reset 0x%x\n", Status));\r
187 CallFspWrapperResetSystem ((UINT32)Status);\r
188 }\r
189\r
cf1d4549
JY
190 if (Status != EFI_SUCCESS) {\r
191 DEBUG((DEBUG_ERROR, "FSP NotifyPhase EndOfFirmware failed, status: 0x%x\n", Status));\r
192 } else {\r
193 DEBUG((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware Success.\n"));\r
194 }\r
19d29d35
YS
195 Status = gBS->LocateProtocol (\r
196 &gAddPerfRecordProtocolGuid,\r
197 NULL,\r
198 (VOID**) &AddPerfRecordInterface\r
199 );\r
200 if (EFI_ERROR (Status)) {\r
201 DEBUG((DEBUG_INFO, "gAddPerfRecordProtocolGuid - Locate protocol failed\n"));\r
202 return;\r
203 } else {\r
204 Hob.Raw = GetFirstGuidHob (&gFspHobGuid);\r
205 if (Hob.Raw != NULL) {\r
206 FspHobListPtr = GET_GUID_HOB_DATA (Hob.Raw);\r
207 AddPerfRecordInterface->AddPerformanceRecords ((VOID *)(UINTN)(((UINT32)(UINTN)*FspHobListPtr) & 0xFFFFFFFF));\r
208 }\r
209 }\r
cf1d4549
JY
210}\r
211\r
212/**\r
213 Main entry for the FSP DXE module.\r
214\r
215 This routine registers two callbacks to call fsp's notifies.\r
216\r
217 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
218 @param[in] SystemTable A pointer to the EFI System Table.\r
219\r
220 @retval EFI_SUCCESS The entry point is executed successfully.\r
221 @retval other Some error occurs when executing this entry point.\r
222\r
223**/\r
224EFI_STATUS\r
225EFIAPI\r
226FspWrapperNotifyDxeEntryPoint (\r
227 IN EFI_HANDLE ImageHandle,\r
228 IN EFI_SYSTEM_TABLE *SystemTable\r
229 )\r
230{\r
231 EFI_STATUS Status;\r
232 EFI_EVENT ReadyToBootEvent;\r
233 VOID *Registration;\r
234 EFI_EVENT ProtocolNotifyEvent;\r
4d4b8169 235 UINT32 FspApiMask;\r
cf1d4549
JY
236\r
237 //\r
238 // Load this driver's image to memory\r
239 //\r
240 Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable);\r
241 if (EFI_ERROR (Status)) {\r
242 return EFI_SUCCESS;\r
243 }\r
244\r
4d4b8169
DG
245 FspApiMask = PcdGet32 (PcdSkipFspApi);\r
246 if ((FspApiMask & FSP_API_NOTIFY_PHASE_AFTER_PCI_ENUMERATION) == 0) {\r
247 ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent (\r
248 &gEfiPciEnumerationCompleteProtocolGuid,\r
249 TPL_CALLBACK,\r
250 OnPciEnumerationComplete,\r
251 NULL,\r
252 &Registration\r
253 );\r
254 ASSERT (ProtocolNotifyEvent != NULL);\r
255 }\r
cf1d4549
JY
256\r
257 Status = EfiCreateEventReadyToBootEx (\r
258 TPL_CALLBACK,\r
259 OnReadyToBoot,\r
260 NULL,\r
261 &ReadyToBootEvent\r
262 );\r
263 ASSERT_EFI_ERROR (Status);\r
264\r
265 Status = gBS->CreateEventEx (\r
266 EVT_NOTIFY_SIGNAL,\r
267 TPL_NOTIFY,\r
268 OnEndOfFirmware,\r
269 NULL,\r
270 &gEfiEventExitBootServicesGuid,\r
271 &mExitBootServicesEvent\r
272 );\r
273 ASSERT_EFI_ERROR (Status);\r
274\r
275 return EFI_SUCCESS;\r
276}\r
277\r