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