]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[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
9ed8c3a8 4 Copyright (c) 2014 - 2019, 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
7c7184e2 24#define FSP_API_NOTIFY_PHASE_AFTER_PCI_ENUMERATION BIT16\r
4d4b8169 25\r
cf1d4549
JY
26typedef\r
27EFI_STATUS\r
7c7184e2 28(EFIAPI *ADD_PERFORMANCE_RECORDS)(\r
cf1d4549
JY
29 IN CONST VOID *HobStart\r
30 );\r
31\r
32struct _ADD_PERFORMANCE_RECORD_PROTOCOL {\r
7c7184e2 33 ADD_PERFORMANCE_RECORDS AddPerformanceRecords;\r
cf1d4549
JY
34};\r
35\r
36typedef struct _ADD_PERFORMANCE_RECORD_PROTOCOL ADD_PERFORMANCE_RECORD_PROTOCOL;\r
37\r
7c7184e2
MK
38extern EFI_GUID gAddPerfRecordProtocolGuid;\r
39extern EFI_GUID gFspHobGuid;\r
40extern EFI_GUID gFspApiPerformanceGuid;\r
cf1d4549 41\r
7c7184e2 42static EFI_EVENT mExitBootServicesEvent = NULL;\r
cf1d4549
JY
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
7c7184e2
MK
56 IN EFI_HANDLE ImageHandle,\r
57 IN EFI_SYSTEM_TABLE *SystemTable\r
cf1d4549
JY
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
7c7184e2
MK
73 NOTIFY_PHASE_PARAMS NotifyPhaseParams;\r
74 EFI_STATUS Status;\r
75 VOID *Interface;\r
cf1d4549
JY
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
7c7184e2 87 return;\r
cf1d4549
JY
88 }\r
89\r
90 NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration;\r
7c7184e2 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
7c7184e2 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
7c7184e2 99 DEBUG ((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration requested reset 0x%x\n", Status));\r
24eac4ca 100 CallFspWrapperResetSystem (Status);\r
f862a3b6
JY
101 }\r
102\r
cf1d4549 103 if (Status != EFI_SUCCESS) {\r
7c7184e2 104 DEBUG ((DEBUG_ERROR, "FSP NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", Status));\r
cf1d4549 105 } else {\r
7c7184e2 106 DEBUG ((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration Success.\n"));\r
cf1d4549
JY
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
7c7184e2
MK
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
7c7184e2 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
7c7184e2 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
7c7184e2 142 DEBUG ((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot requested reset 0x%x\n", Status));\r
24eac4ca 143 CallFspWrapperResetSystem (Status);\r
f862a3b6
JY
144 }\r
145\r
cf1d4549 146 if (Status != EFI_SUCCESS) {\r
7c7184e2 147 DEBUG ((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", Status));\r
cf1d4549 148 } else {\r
7c7184e2 149 DEBUG ((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot Success.\n"));\r
cf1d4549 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
7c7184e2
MK
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
7c7184e2 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
7c7184e2 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
7c7184e2 186 DEBUG ((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware requested reset 0x%x\n", Status));\r
24eac4ca 187 CallFspWrapperResetSystem (Status);\r
f862a3b6
JY
188 }\r
189\r
cf1d4549 190 if (Status != EFI_SUCCESS) {\r
7c7184e2 191 DEBUG ((DEBUG_ERROR, "FSP NotifyPhase EndOfFirmware failed, status: 0x%x\n", Status));\r
cf1d4549 192 } else {\r
7c7184e2 193 DEBUG ((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware Success.\n"));\r
cf1d4549 194 }\r
7c7184e2 195\r
19d29d35
YS
196 Status = gBS->LocateProtocol (\r
197 &gAddPerfRecordProtocolGuid,\r
198 NULL,\r
7c7184e2 199 (VOID **)&AddPerfRecordInterface\r
19d29d35
YS
200 );\r
201 if (EFI_ERROR (Status)) {\r
7c7184e2 202 DEBUG ((DEBUG_INFO, "gAddPerfRecordProtocolGuid - Locate protocol failed\n"));\r
19d29d35
YS
203 return;\r
204 } else {\r
205 Hob.Raw = GetFirstGuidHob (&gFspHobGuid);\r
206 if (Hob.Raw != NULL) {\r
207 FspHobListPtr = GET_GUID_HOB_DATA (Hob.Raw);\r
208 AddPerfRecordInterface->AddPerformanceRecords ((VOID *)(UINTN)(((UINT32)(UINTN)*FspHobListPtr) & 0xFFFFFFFF));\r
209 }\r
210 }\r
cf1d4549
JY
211}\r
212\r
213/**\r
214 Main entry for the FSP DXE module.\r
215\r
216 This routine registers two callbacks to call fsp's notifies.\r
217\r
218 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
219 @param[in] SystemTable A pointer to the EFI System Table.\r
220\r
221 @retval EFI_SUCCESS The entry point is executed successfully.\r
222 @retval other Some error occurs when executing this entry point.\r
223\r
224**/\r
225EFI_STATUS\r
226EFIAPI\r
227FspWrapperNotifyDxeEntryPoint (\r
7c7184e2
MK
228 IN EFI_HANDLE ImageHandle,\r
229 IN EFI_SYSTEM_TABLE *SystemTable\r
cf1d4549
JY
230 )\r
231{\r
7c7184e2
MK
232 EFI_STATUS Status;\r
233 EFI_EVENT ReadyToBootEvent;\r
234 VOID *Registration;\r
235 EFI_EVENT ProtocolNotifyEvent;\r
236 UINT32 FspApiMask;\r
cf1d4549
JY
237\r
238 //\r
239 // Load this driver's image to memory\r
240 //\r
241 Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable);\r
242 if (EFI_ERROR (Status)) {\r
243 return EFI_SUCCESS;\r
244 }\r
245\r
4d4b8169
DG
246 FspApiMask = PcdGet32 (PcdSkipFspApi);\r
247 if ((FspApiMask & FSP_API_NOTIFY_PHASE_AFTER_PCI_ENUMERATION) == 0) {\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
cf1d4549
JY
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