IntelFsp2Pkg: Added changes to enable FPDT performance measurements
[mirror_edk2.git] / IntelFsp2WrapperPkg / FspsWrapperPeim / FspsWrapperPeim.c
1 /** @file\r
2   This will be invoked only once. It will call FspMemoryInit API,\r
3   register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi\r
4   notify to call FspSiliconInit API.\r
5 \r
6   Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>\r
7   This program and the accompanying materials\r
8   are licensed and made available under the terms and conditions of the BSD License\r
9   which accompanies this distribution.  The full text of the license may be found at\r
10   http://opensource.org/licenses/bsd-license.php.\r
11 \r
12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14 \r
15 **/\r
16 \r
17 #include <PiPei.h>\r
18 \r
19 #include <Library/PeimEntryPoint.h>\r
20 #include <Library/PeiServicesLib.h>\r
21 #include <Library/PeiServicesTablePointerLib.h>\r
22 #include <Library/BaseLib.h>\r
23 #include <Library/DebugLib.h>\r
24 #include <Library/BaseMemoryLib.h>\r
25 #include <Library/HobLib.h>\r
26 #include <Library/PcdLib.h>\r
27 #include <Library/MemoryAllocationLib.h>\r
28 #include <Library/FspWrapperPlatformLib.h>\r
29 #include <Library/FspWrapperHobProcessLib.h>\r
30 #include <Library/TimerLib.h>\r
31 #include <Library/PerformanceLib.h>\r
32 #include <Library/FspWrapperApiLib.h>\r
33 \r
34 #include <Ppi/FspSiliconInitDone.h>\r
35 #include <Ppi/EndOfPeiPhase.h>\r
36 #include <Ppi/MemoryDiscovered.h>\r
37 #include <Ppi/TemporaryRamDone.h>\r
38 #include <Ppi/SecPlatformInformation.h>\r
39 #include <Library/FspWrapperApiTestLib.h>\r
40 #include <FspEas.h>\r
41 #include <FspStatusCode.h>\r
42 \r
43 extern EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc;\r
44 extern EFI_GUID                  gFspHobGuid;\r
45 \r
46 /**\r
47 This function handles S3 resume task at the end of PEI\r
48 \r
49 @param[in] PeiServices    Pointer to PEI Services Table.\r
50 @param[in] NotifyDesc     Pointer to the descriptor for the Notification event that\r
51 caused this function to execute.\r
52 @param[in] Ppi            Pointer to the PPI data associated with this function.\r
53 \r
54 @retval EFI_STATUS        Always return EFI_SUCCESS\r
55 **/\r
56 EFI_STATUS\r
57 EFIAPI\r
58 S3EndOfPeiNotify(\r
59   IN EFI_PEI_SERVICES          **PeiServices,\r
60   IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
61   IN VOID                      *Ppi\r
62   );\r
63 \r
64 EFI_PEI_NOTIFY_DESCRIPTOR mS3EndOfPeiNotifyDesc = {\r
65   (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
66   &gEfiEndOfPeiSignalPpiGuid,\r
67   S3EndOfPeiNotify\r
68 };\r
69 \r
70 /**\r
71 This function handles S3 resume task at the end of PEI\r
72 \r
73 @param[in] PeiServices    Pointer to PEI Services Table.\r
74 @param[in] NotifyDesc     Pointer to the descriptor for the Notification event that\r
75 caused this function to execute.\r
76 @param[in] Ppi            Pointer to the PPI data associated with this function.\r
77 \r
78 @retval EFI_STATUS        Always return EFI_SUCCESS\r
79 **/\r
80 EFI_STATUS\r
81 EFIAPI\r
82 S3EndOfPeiNotify(\r
83   IN EFI_PEI_SERVICES          **PeiServices,\r
84   IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
85   IN VOID                      *Ppi\r
86   )\r
87 {\r
88   NOTIFY_PHASE_PARAMS NotifyPhaseParams;\r
89   EFI_STATUS          Status;\r
90 \r
91   DEBUG((DEBUG_INFO, "S3EndOfPeiNotify enter\n"));\r
92 \r
93   NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration;\r
94   Status = CallFspNotifyPhase (&NotifyPhaseParams);\r
95   DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration status: 0x%x\n", Status));\r
96 \r
97   //\r
98   // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status\r
99   //\r
100   if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {\r
101     DEBUG((DEBUG_INFO, "FSP S3NotifyPhase AfterPciEnumeration requested reset 0x%x\n", Status));\r
102     CallFspWrapperResetSystem ((UINT32)Status);\r
103   }\r
104 \r
105   NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot;\r
106   Status = CallFspNotifyPhase (&NotifyPhaseParams);\r
107   DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot status: 0x%x\n", Status));\r
108 \r
109   //\r
110   // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status\r
111   //\r
112   if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {\r
113     DEBUG((DEBUG_INFO, "FSP S3NotifyPhase ReadyToBoot requested reset 0x%x\n", Status));\r
114     CallFspWrapperResetSystem ((UINT32)Status);\r
115   }\r
116 \r
117   NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware;\r
118   Status = CallFspNotifyPhase (&NotifyPhaseParams);\r
119   DEBUG((DEBUG_INFO, "FSP S3NotifyPhase EndOfFirmware status: 0x%x\n", Status));\r
120 \r
121   //\r
122   // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status\r
123   //\r
124   if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {\r
125     DEBUG((DEBUG_INFO, "FSP S3NotifyPhase EndOfFirmware requested reset 0x%x\n", Status));\r
126     CallFspWrapperResetSystem ((UINT32)Status);\r
127   }\r
128 \r
129   return EFI_SUCCESS;\r
130 }\r
131 \r
132 /**\r
133 Return Hob list produced by FSP.\r
134 \r
135 @param[in]  PeiServices  The pointer to the PEI Services Table.\r
136 @param[in]  This         The pointer to this instance of this PPI.\r
137 @param[out] FspHobList   The pointer to Hob list produced by FSP.\r
138 \r
139 @return EFI_SUCCESS FReturn Hob list produced by FSP successfully.\r
140 **/\r
141 EFI_STATUS\r
142 EFIAPI\r
143 FspSiliconInitDoneGetFspHobList (\r
144   IN  CONST EFI_PEI_SERVICES         **PeiServices,\r
145   IN  FSP_SILICON_INIT_DONE_PPI      *This,\r
146   OUT VOID                           **FspHobList\r
147   );\r
148 \r
149 FSP_SILICON_INIT_DONE_PPI mFspSiliconInitDonePpi = {\r
150   FspSiliconInitDoneGetFspHobList\r
151 };\r
152 \r
153 EFI_PEI_PPI_DESCRIPTOR            mPeiFspSiliconInitDonePpi = {\r
154   EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
155   &gFspSiliconInitDonePpiGuid,\r
156   &mFspSiliconInitDonePpi\r
157 };\r
158 \r
159 /**\r
160 Return Hob list produced by FSP.\r
161 \r
162 @param[in]  PeiServices  The pointer to the PEI Services Table.\r
163 @param[in]  This         The pointer to this instance of this PPI.\r
164 @param[out] FspHobList   The pointer to Hob list produced by FSP.\r
165 \r
166 @return EFI_SUCCESS FReturn Hob list produced by FSP successfully.\r
167 **/\r
168 EFI_STATUS\r
169 EFIAPI\r
170 FspSiliconInitDoneGetFspHobList (\r
171   IN  CONST EFI_PEI_SERVICES         **PeiServices,\r
172   IN  FSP_SILICON_INIT_DONE_PPI      *This,\r
173   OUT VOID                           **FspHobList\r
174   )\r
175 {\r
176   EFI_HOB_GUID_TYPE                  *GuidHob;\r
177 \r
178   GuidHob = GetFirstGuidHob (&gFspHobGuid);\r
179   if (GuidHob != NULL) {\r
180     *FspHobList = *(VOID **)GET_GUID_HOB_DATA(GuidHob);\r
181     return EFI_SUCCESS;\r
182   } else {\r
183     return EFI_NOT_FOUND;\r
184   }\r
185 }\r
186 \r
187 /**\r
188   This function is called after PEI core discover memory and finish migration.\r
189 \r
190   @param[in] PeiServices    Pointer to PEI Services Table.\r
191   @param[in] NotifyDesc     Pointer to the descriptor for the Notification event that\r
192                             caused this function to execute.\r
193   @param[in] Ppi            Pointer to the PPI data associated with this function.\r
194 \r
195   @retval EFI_STATUS        Always return EFI_SUCCESS\r
196 **/\r
197 EFI_STATUS\r
198 EFIAPI\r
199 PeiMemoryDiscoveredNotify (\r
200   IN EFI_PEI_SERVICES          **PeiServices,\r
201   IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
202   IN VOID                      *Ppi\r
203   );\r
204 \r
205 EFI_PEI_NOTIFY_DESCRIPTOR mPeiMemoryDiscoveredNotifyDesc = {\r
206   (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
207   &gEfiPeiMemoryDiscoveredPpiGuid,\r
208   PeiMemoryDiscoveredNotify\r
209 };\r
210 \r
211 /**\r
212 This function is called after PEI core discover memory and finish migration.\r
213 \r
214 @param[in] PeiServices    Pointer to PEI Services Table.\r
215 @param[in] NotifyDesc     Pointer to the descriptor for the Notification event that\r
216 caused this function to execute.\r
217 @param[in] Ppi            Pointer to the PPI data associated with this function.\r
218 \r
219 @retval EFI_STATUS        Always return EFI_SUCCESS\r
220 **/\r
221 EFI_STATUS\r
222 EFIAPI\r
223 PeiMemoryDiscoveredNotify (\r
224   IN EFI_PEI_SERVICES          **PeiServices,\r
225   IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
226   IN VOID                      *Ppi\r
227   )\r
228 {\r
229   FSP_INFO_HEADER           *FspsHeaderPtr;\r
230   UINT64                    TimeStampCounterStart;\r
231   EFI_STATUS                Status;\r
232   VOID                      *FspHobListPtr;\r
233   EFI_HOB_GUID_TYPE         *GuidHob;\r
234   FSPS_UPD_COMMON           *FspsUpdDataPtr;\r
235   UINTN                     *SourceData;\r
236 \r
237   \r
238   DEBUG ((DEBUG_INFO, "PeiMemoryDiscoveredNotify enter\n"));\r
239   \r
240   //\r
241   // Copy default FSP-S UPD data from Flash\r
242   //\r
243   FspsHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));\r
244   DEBUG ((DEBUG_INFO, "FspsHeaderPtr - 0x%x\n", FspsHeaderPtr));\r
245   if (FspsHeaderPtr == NULL) {\r
246     return EFI_DEVICE_ERROR;\r
247   }\r
248 \r
249   FspsUpdDataPtr = (FSPS_UPD_COMMON *)AllocateZeroPool ((UINTN)FspsHeaderPtr->CfgRegionSize);\r
250   ASSERT (FspsUpdDataPtr != NULL);\r
251   SourceData = (UINTN *)((UINTN)FspsHeaderPtr->ImageBase + (UINTN)FspsHeaderPtr->CfgRegionOffset);\r
252   CopyMem (FspsUpdDataPtr, SourceData, (UINTN)FspsHeaderPtr->CfgRegionSize);\r
253 \r
254   UpdateFspsUpdData ((VOID *)FspsUpdDataPtr);\r
255 \r
256   TimeStampCounterStart = AsmReadTsc ();\r
257   PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
258   Status = CallFspSiliconInit ((VOID *)FspsUpdDataPtr);\r
259   PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
260   DEBUG ((DEBUG_INFO, "Total time spent executing FspSiliconInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000)));\r
261 \r
262   //\r
263   // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status\r
264   //\r
265   if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {\r
266     DEBUG((DEBUG_INFO, "FspSiliconInitApi requested reset 0x%x\n", Status));\r
267     CallFspWrapperResetSystem ((UINT32)Status);\r
268   }\r
269 \r
270   if (EFI_ERROR(Status)) {\r
271     DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspSiliconInitApi(), Status = %r\n", Status));\r
272   }\r
273   DEBUG((DEBUG_INFO, "FspSiliconInit status: 0x%x\n", Status));\r
274   ASSERT_EFI_ERROR (Status);\r
275 \r
276   Status = TestFspSiliconInitApiOutput ((VOID *)NULL);\r
277   if (RETURN_ERROR (Status)) {\r
278     DEBUG ((DEBUG_ERROR, "ERROR - TestFspSiliconInitApiOutput () fail, Status = %r\n", Status));\r
279   }\r
280 \r
281   //\r
282   // Now FspHobList complete, process it\r
283   //\r
284   GuidHob = GetFirstGuidHob (&gFspHobGuid);\r
285   ASSERT (GuidHob != NULL);\r
286   FspHobListPtr = *(VOID **)GET_GUID_HOB_DATA (GuidHob);\r
287   DEBUG ((DEBUG_INFO, "FspHobListPtr - 0x%x\n", FspHobListPtr));\r
288   PostFspsHobProcess (FspHobListPtr);\r
289 \r
290   //\r
291   // Install FspSiliconInitDonePpi so that any other driver can consume this info.\r
292   //\r
293   Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi);\r
294   ASSERT_EFI_ERROR(Status);\r
295 \r
296   return Status;\r
297 }\r
298 \r
299 /**\r
300   Do FSP initialization.\r
301 \r
302   @return FSP initialization status.\r
303 **/\r
304 EFI_STATUS\r
305 FspsWrapperInit (\r
306   VOID\r
307   )\r
308 {\r
309   EFI_STATUS           Status;\r
310   EFI_BOOT_MODE        BootMode;\r
311 \r
312   //\r
313   // Register MemoryDiscovered Nofity to run FspSiliconInit\r
314   //\r
315   Status = PeiServicesNotifyPpi (&mPeiMemoryDiscoveredNotifyDesc);\r
316   ASSERT_EFI_ERROR (Status);\r
317       \r
318   //\r
319   // Register EndOfPei Notify for S3 to run FSP NotifyPhase\r
320   //\r
321   PeiServicesGetBootMode (&BootMode);\r
322   if (BootMode == BOOT_ON_S3_RESUME) {\r
323     Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);\r
324     ASSERT_EFI_ERROR (Status);\r
325   }\r
326 \r
327   return EFI_SUCCESS;\r
328 }\r
329 \r
330 /**\r
331   This is the entrypoint of PEIM\r
332 \r
333   @param[in] FileHandle  Handle of the file being invoked.\r
334   @param[in] PeiServices Describes the list of possible PEI Services.\r
335 \r
336   @retval EFI_SUCCESS if it completed successfully.\r
337 **/\r
338 EFI_STATUS\r
339 EFIAPI\r
340 FspsWrapperPeimEntryPoint (\r
341   IN       EFI_PEI_FILE_HANDLE  FileHandle,\r
342   IN CONST EFI_PEI_SERVICES     **PeiServices\r
343   )\r
344 {\r
345 \r
346   DEBUG ((DEBUG_INFO, "FspsWrapperPeimEntryPoint\n"));\r
347 \r
348   FspsWrapperInit ();\r
349 \r
350   return EFI_SUCCESS;\r
351 }\r