IntelFsp2WrapperPkg: Fix line ending format issue
[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 - 2018, 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   DEBUG ((DEBUG_INFO, "PeiMemoryDiscoveredNotify enter\n"));\r
238   FspsUpdDataPtr = NULL;\r
239 \r
240   FspsHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));\r
241   DEBUG ((DEBUG_INFO, "FspsHeaderPtr - 0x%x\n", FspsHeaderPtr));\r
242   if (FspsHeaderPtr == NULL) {\r
243     return EFI_DEVICE_ERROR;\r
244   }\r
245 \r
246   if (PcdGet32 (PcdFspsUpdDataAddress) == 0 && (FspsHeaderPtr->CfgRegionSize != 0) && (FspsHeaderPtr->CfgRegionOffset != 0)) {\r
247     //\r
248     // Copy default FSP-S UPD data from Flash\r
249     //\r
250     FspsUpdDataPtr = (FSPS_UPD_COMMON *)AllocateZeroPool ((UINTN)FspsHeaderPtr->CfgRegionSize);\r
251     ASSERT (FspsUpdDataPtr != NULL);\r
252     SourceData = (UINTN *)((UINTN)FspsHeaderPtr->ImageBase + (UINTN)FspsHeaderPtr->CfgRegionOffset);\r
253     CopyMem (FspsUpdDataPtr, SourceData, (UINTN)FspsHeaderPtr->CfgRegionSize);\r
254   } else {\r
255     FspsUpdDataPtr = (FSPS_UPD_COMMON *)PcdGet32 (PcdFspsUpdDataAddress);\r
256     ASSERT (FspsUpdDataPtr != NULL);\r
257   }\r
258 \r
259   UpdateFspsUpdData ((VOID *)FspsUpdDataPtr);\r
260 \r
261   TimeStampCounterStart = AsmReadTsc ();\r
262   PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_ENTRY);\r
263   Status = CallFspSiliconInit ((VOID *)FspsUpdDataPtr);\r
264   PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, FSP_STATUS_CODE_SILICON_INIT | FSP_STATUS_CODE_COMMON_CODE | FSP_STATUS_CODE_API_EXIT);\r
265   DEBUG ((DEBUG_INFO, "Total time spent executing FspSiliconInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000)));\r
266 \r
267   //\r
268   // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status\r
269   //\r
270   if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {\r
271     DEBUG((DEBUG_INFO, "FspSiliconInitApi requested reset 0x%x\n", Status));\r
272     CallFspWrapperResetSystem ((UINT32)Status);\r
273   }\r
274 \r
275   if (EFI_ERROR(Status)) {\r
276     DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspSiliconInitApi(), Status = %r\n", Status));\r
277   }\r
278   DEBUG((DEBUG_INFO, "FspSiliconInit status: 0x%x\n", Status));\r
279   ASSERT_EFI_ERROR (Status);\r
280 \r
281   Status = TestFspSiliconInitApiOutput ((VOID *)NULL);\r
282   if (RETURN_ERROR (Status)) {\r
283     DEBUG ((DEBUG_ERROR, "ERROR - TestFspSiliconInitApiOutput () fail, Status = %r\n", Status));\r
284   }\r
285 \r
286   //\r
287   // Now FspHobList complete, process it\r
288   //\r
289   GuidHob = GetFirstGuidHob (&gFspHobGuid);\r
290   ASSERT (GuidHob != NULL);\r
291   FspHobListPtr = *(VOID **)GET_GUID_HOB_DATA (GuidHob);\r
292   DEBUG ((DEBUG_INFO, "FspHobListPtr - 0x%x\n", FspHobListPtr));\r
293   PostFspsHobProcess (FspHobListPtr);\r
294 \r
295   //\r
296   // Install FspSiliconInitDonePpi so that any other driver can consume this info.\r
297   //\r
298   Status = PeiServicesInstallPpi (&mPeiFspSiliconInitDonePpi);\r
299   ASSERT_EFI_ERROR(Status);\r
300 \r
301   return Status;\r
302 }\r
303 \r
304 /**\r
305   Do FSP initialization.\r
306 \r
307   @return FSP initialization status.\r
308 **/\r
309 EFI_STATUS\r
310 FspsWrapperInit (\r
311   VOID\r
312   )\r
313 {\r
314   EFI_STATUS           Status;\r
315   EFI_BOOT_MODE        BootMode;\r
316 \r
317   //\r
318   // Register MemoryDiscovered Nofity to run FspSiliconInit\r
319   //\r
320   Status = PeiServicesNotifyPpi (&mPeiMemoryDiscoveredNotifyDesc);\r
321   ASSERT_EFI_ERROR (Status);\r
322 \r
323   //\r
324   // Register EndOfPei Notify for S3 to run FSP NotifyPhase\r
325   //\r
326   PeiServicesGetBootMode (&BootMode);\r
327   if (BootMode == BOOT_ON_S3_RESUME) {\r
328     Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);\r
329     ASSERT_EFI_ERROR (Status);\r
330   }\r
331 \r
332   return EFI_SUCCESS;\r
333 }\r
334 \r
335 /**\r
336   This is the entrypoint of PEIM\r
337 \r
338   @param[in] FileHandle  Handle of the file being invoked.\r
339   @param[in] PeiServices Describes the list of possible PEI Services.\r
340 \r
341   @retval EFI_SUCCESS if it completed successfully.\r
342 **/\r
343 EFI_STATUS\r
344 EFIAPI\r
345 FspsWrapperPeimEntryPoint (\r
346   IN       EFI_PEI_FILE_HANDLE  FileHandle,\r
347   IN CONST EFI_PEI_SERVICES     **PeiServices\r
348   )\r
349 {\r
350   DEBUG ((DEBUG_INFO, "FspsWrapperPeimEntryPoint\n"));\r
351 \r
352   if (FixedPcdGet8 (PcdFspModeSelection) == 1) {\r
353     FspsWrapperInit ();\r
354   } else {\r
355     PeiServicesInstallFvInfoPpi (\r
356       NULL,\r
357       (VOID *)(UINTN) PcdGet32 (PcdFspsBaseAddress),\r
358       (UINT32)((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PcdGet32 (PcdFspsBaseAddress))->FvLength,\r
359       NULL,\r
360       NULL\r
361       );\r
362   }\r
363 \r
364   return EFI_SUCCESS;\r
365 }\r