VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c@ 94368

Last change on this file since 94368 was 80721, checked in by vboxsync, 5 years ago

Devices/EFI/FirmwareNew: Start upgrade process to edk2-stable201908 (compiles on Windows and works to some extent), bugref:4643

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette