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