IntelFsp2Pkg: Added changes to enable FPDT performance measurements
[mirror_edk2.git] / IntelFsp2Pkg / Library / BaseFspPlatformLib / FspPlatformNotify.c
1 /** @file
2
3 Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php.
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 **/
13
14 #include <PiPei.h>
15 #include <Library/PeiServicesLib.h>
16 #include <Library/PeiServicesTablePointerLib.h>
17 #include <Library/BaseLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/PcdLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/HobLib.h>
22 #include <Library/FspSwitchStackLib.h>
23 #include <Library/FspCommonLib.h>
24 #include <Guid/EventGroup.h>
25 #include <FspEas.h>
26 #include <FspStatusCode.h>
27 #include <Protocol/PciEnumerationComplete.h>
28 #include <Library/ReportStatusCodeLib.h>
29 #include <Library/PerformanceLib.h>
30 extern EFI_GUID gFspPerformanceDataGuid;
31
32 EFI_PEI_PPI_DESCRIPTOR mPeiPostPciEnumerationPpi = {
33 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
34 &gEfiPciEnumerationCompleteProtocolGuid,
35 NULL
36 };
37
38 EFI_PEI_PPI_DESCRIPTOR mPeiReadyToBootPpi = {
39 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
40 &gEfiEventReadyToBootGuid,
41 NULL
42 };
43
44 EFI_PEI_PPI_DESCRIPTOR mPeiEndOfFirmwarePpi = {
45 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
46 &gFspEventEndOfFirmwareGuid,
47 NULL
48 };
49
50 UINT32 mFspNotifySequence[] = {
51 EnumInitPhaseAfterPciEnumeration,
52 EnumInitPhaseReadyToBoot,
53 EnumInitPhaseEndOfFirmware
54 };
55
56 /**
57 Install FSP notification.
58
59 @param[in] NotificationCode FSP notification code
60
61 @retval EFI_SUCCESS Notify FSP successfully
62 @retval EFI_INVALID_PARAMETER NotificationCode is invalid
63
64 **/
65 EFI_STATUS
66 EFIAPI
67 FspNotificationHandler (
68 IN UINT32 NotificationCode
69 )
70 {
71 EFI_STATUS Status;
72
73 Status = EFI_SUCCESS;
74
75 switch (NotificationCode) {
76 case EnumInitPhaseAfterPciEnumeration:
77 //
78 // Do POST PCI initialization if needed
79 //
80 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP Post PCI Enumeration ...\n"));
81 PeiServicesInstallPpi (&mPeiPostPciEnumerationPpi);
82 break;
83
84 case EnumInitPhaseReadyToBoot:
85 //
86 // Ready To Boot
87 //
88 DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP Ready To Boot ...\n"));
89 PeiServicesInstallPpi (&mPeiReadyToBootPpi);
90 break;
91
92 case EnumInitPhaseEndOfFirmware:
93 //
94 // End of Firmware
95 //
96 DEBUG ((DEBUG_INFO| DEBUG_INIT, "FSP End of Firmware ...\n"));
97 PeiServicesInstallPpi (&mPeiEndOfFirmwarePpi);
98 break;
99
100 default:
101 Status = EFI_INVALID_PARAMETER;
102 break;
103 }
104
105 return Status;
106 }
107
108 /**
109 This function transfer control back to BootLoader after FspSiliconInit.
110
111 **/
112 VOID
113 EFIAPI
114 FspSiliconInitDone (
115 VOID
116 )
117 {
118 //
119 // This is the end of the FspSiliconInit API
120 // Give control back to the boot loader
121 //
122 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_EXIT);
123 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - End\n"));
124 PERF_END_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
125 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
126 SetFspApiReturnStatus (EFI_SUCCESS);
127
128 Pei2LoaderSwitchStack();
129
130 }
131
132 /**
133 This function returns control to BootLoader after MemoryInitApi.
134
135 @param[in,out] HobListPtr The address of HobList pointer.
136 **/
137 VOID
138 EFIAPI
139 FspMemoryInitDone (
140 IN OUT VOID **HobListPtr
141 )
142 {
143 FSP_GLOBAL_DATA *FspData;
144 //
145 // Calling use FspMemoryInit API
146 // Update HOB and return the control directly
147 //
148 if (HobListPtr != NULL) {
149 *HobListPtr = (VOID *) GetHobList ();
150 }
151
152 //
153 // This is the end of the FspMemoryInit API
154 // Give control back to the boot loader
155 //
156 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspMemoryInitApi() - End\n"));
157 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_MEMORY_INIT_EXIT);
158 FspData = GetFspGlobalDataPointer ();
159 PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[0] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_TEMP_RAM_INIT | FSP_STATUS_CODE_COMMON_CODE| FSP_STATUS_CODE_API_ENTRY);
160 PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[1] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_TEMP_RAM_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
161 PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, (FspData->PerfData[2] & FSP_PERFORMANCE_DATA_TIMER_MASK), FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
162 PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
163 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_MEMORY_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
164 SetFspApiReturnStatus (EFI_SUCCESS);
165 Pei2LoaderSwitchStack ();
166
167 //
168 // The TempRamExitApi is called
169 //
170 if (GetFspApiCallingIndex () == TempRamExitApiIndex) {
171 SetPhaseStatusCode (FSP_STATUS_CODE_TEMP_RAM_EXIT);
172 SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_ENTRY);
173 PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
174 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
175 DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - Begin\n"));
176 } else {
177 SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
178 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
179 PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
180 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
181 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FspSiliconInitApi() - Begin\n"));
182 }
183 }
184
185 /**
186 This function returns control to BootLoader after TempRamExitApi.
187
188 **/
189 VOID
190 EFIAPI
191 FspTempRamExitDone (
192 VOID
193 )
194 {
195
196 //
197 // This is the end of the TempRamExit API
198 // Give control back to the boot loader
199 //
200 DEBUG ((DEBUG_INFO | DEBUG_INIT, "TempRamExitApi() - End\n"));
201 SetFspMeasurePoint (FSP_PERF_ID_API_TEMP_RAM_EXIT_EXIT);
202 PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
203 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_TEMP_RAM_EXIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
204 SetFspApiReturnStatus (EFI_SUCCESS);
205 Pei2LoaderSwitchStack ();
206
207 SetPhaseStatusCode (FSP_STATUS_CODE_SILICON_INIT);
208 SetFspMeasurePoint (FSP_PERF_ID_API_FSP_SILICON_INIT_ENTRY);
209 PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
210 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
211 DEBUG ((DEBUG_INFO | DEBUG_INIT, "SiliconInitApi() - Begin\n"));
212 }
213
214 /**
215 This function handle NotifyPhase API call from the BootLoader.
216 It gives control back to the BootLoader after it is handled. If the
217 Notification code is a ReadyToBoot event, this function will return
218 and FSP continues the remaining execution until it reaches the DxeIpl.
219
220 **/
221 VOID
222 FspWaitForNotify (
223 VOID
224 )
225 {
226 EFI_STATUS Status;
227 UINT32 NotificationValue;
228 UINT32 NotificationCount;
229 UINT8 Count;
230
231 NotificationCount = 0;
232 while (NotificationCount < sizeof(mFspNotifySequence) / sizeof(UINT32)) {
233
234 Count = (UINT8)((NotificationCount << 1) & 0x07);
235 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_ENTRY + Count);
236
237 if (NotificationCount == 0) {
238 SetPhaseStatusCode (FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION);
239 PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
240 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
241 } else if (NotificationCount == 1) {
242 SetPhaseStatusCode (FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION);
243 PERF_START_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
244 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
245 } else if (NotificationCount == 2) {
246 SetPhaseStatusCode (FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION);
247 PERF_START_EX (&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
248 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);
249 }
250
251 NotificationValue = ((NOTIFY_PHASE_PARAMS *)(UINTN)GetFspApiParameter ())->Phase;
252 DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - Begin [Phase: %08X]\n", NotificationValue));
253 if (mFspNotifySequence[NotificationCount] != NotificationValue) {
254 //
255 // Notify code does not follow the predefined order
256 //
257 DEBUG ((DEBUG_INFO, "Unsupported FSP Notification Value\n"));
258 Status = EFI_UNSUPPORTED;
259 } else {
260 //
261 // Process Notification and Give control back to the boot loader framework caller
262 //
263 Status = FspNotificationHandler (NotificationValue);
264 if (!EFI_ERROR(Status)) {
265 NotificationCount++;
266 }
267 }
268
269 SetFspApiReturnStatus(Status);
270 DEBUG ((DEBUG_INFO | DEBUG_INIT, "NotifyPhaseApi() - End [Status: 0x%08X]\n", Status));
271
272 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_POST_PCI_EXIT + Count);
273
274 if ((NotificationCount - 1) == 0) {
275 PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
276 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_POST_PCIE_ENUM_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
277 } else if ((NotificationCount - 1) == 1) {
278 PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
279 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_READY_TO_BOOT_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
280 } else if ((NotificationCount - 1) == 2) {
281 PERF_END_EX(&gFspPerformanceDataGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
282 REPORT_STATUS_CODE (EFI_PROGRESS_CODE, FSP_STATUS_CODE_END_OF_FIRMWARE_NOTIFICATION | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);
283 }
284 Pei2LoaderSwitchStack();
285 }
286
287 //
288 // Control goes back to the PEI Core and it dispatches further PEIMs.
289 // DXEIPL is the final one to transfer control back to the boot loader.
290 //
291 }
292