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