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