1 /** @file
2   In FSP API V2 mode, it will be invoked only once. It will call FspMemoryInit API,
3   register TemporaryRamDonePpi to call TempRamExit API, and register MemoryDiscoveredPpi
4   notify to call FspSiliconInit API.
5 
6   Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
7   SPDX-License-Identifier: BSD-2-Clause-Patent
8 
9 **/
10 
11 
12 #include "FspInitPei.h"
13 
14 /**
15   Return Hob list produced by FSP.
16 
17   @param[in]  PeiServices  The pointer to the PEI Services Table.
18   @param[in]  This         The pointer to this instance of this PPI.
19   @param[out] FspHobList   The pointer to Hob list produced by FSP.
20 
21   @return EFI_SUCCESS FReturn Hob list produced by FSP successfully.
22 **/
23 EFI_STATUS
24 EFIAPI
25 FspInitDoneGetFspHobListV2 (
26   IN  CONST EFI_PEI_SERVICES         **PeiServices,
27   IN  FSP_INIT_DONE_PPI              *This,
28   OUT VOID                           **FspHobList
29   );
30 
31 FSP_INIT_DONE_PPI mFspInitDonePpiV2 = {
32   FspInitDoneGetFspHobListV2
33 };
34 
35 EFI_PEI_PPI_DESCRIPTOR            mPeiFspInitDonePpiV2 = {
36   EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
37   &gFspInitDonePpiGuid,
38   &mFspInitDonePpiV2
39 };
40 
41 /**
42   This function is called after PEI core discover memory and finish migration.
43 
44   @param[in] PeiServices    Pointer to PEI Services Table.
45   @param[in] NotifyDesc     Pointer to the descriptor for the Notification event that
46                             caused this function to execute.
47   @param[in] Ppi            Pointer to the PPI data associated with this function.
48 
49   @retval EFI_STATUS        Always return EFI_SUCCESS
50 **/
51 EFI_STATUS
52 EFIAPI
53 PeiMemoryDiscoveredNotify (
54   IN EFI_PEI_SERVICES          **PeiServices,
55   IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
56   IN VOID                      *Ppi
57   );
58 
59 EFI_PEI_NOTIFY_DESCRIPTOR mPeiMemoryDiscoveredNotifyDesc = {
60   (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
61   &gEfiPeiMemoryDiscoveredPpiGuid,
62   PeiMemoryDiscoveredNotify
63 };
64 
65 /**
66   TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked
67   by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
68 
69   @retval EFI_SUCCESS           Use of Temporary RAM was disabled.
70   @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
71 
72 **/
73 EFI_STATUS
74 EFIAPI
75 PeiTemporaryRamDone (
76   VOID
77   );
78 
79 EFI_PEI_TEMPORARY_RAM_DONE_PPI mPeiTemporaryRamDonePpi = {
80   PeiTemporaryRamDone
81 };
82 
83 EFI_PEI_PPI_DESCRIPTOR         mPeiTemporaryRamDoneDesc = {
84   (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
85   &gEfiTemporaryRamDonePpiGuid,
86   &mPeiTemporaryRamDonePpi
87 };
88 
89 /**
90   Return Hob list produced by FSP.
91 
92   @param[in]  PeiServices  The pointer to the PEI Services Table.
93   @param[in]  This         The pointer to this instance of this PPI.
94   @param[out] FspHobList   The pointer to Hob list produced by FSP.
95 
96   @return EFI_SUCCESS FReturn Hob list produced by FSP successfully.
97 **/
98 EFI_STATUS
99 EFIAPI
FspInitDoneGetFspHobListV2(IN CONST EFI_PEI_SERVICES ** PeiServices,IN FSP_INIT_DONE_PPI * This,OUT VOID ** FspHobList)100 FspInitDoneGetFspHobListV2 (
101   IN  CONST EFI_PEI_SERVICES         **PeiServices,
102   IN  FSP_INIT_DONE_PPI              *This,
103   OUT VOID                           **FspHobList
104   )
105 {
106   EFI_HOB_GUID_TYPE                  *GuidHob;
107 
108   GuidHob = GetFirstGuidHob (&gFspInitDonePpiGuid);
109   if (GuidHob != NULL) {
110     *FspHobList = *(VOID **)GET_GUID_HOB_DATA (GuidHob);
111     return EFI_SUCCESS;
112   } else {
113     return EFI_NOT_FOUND;
114   }
115 }
116 
117 /**
118   Call FspMemoryInit API.
119 
120   @param[in]  FspHeader   FSP header pointer.
121 
122   @return Status returned by FspMemoryInit API.
123 **/
124 EFI_STATUS
PeiFspMemoryInit(IN FSP_INFO_HEADER * FspHeader)125 PeiFspMemoryInit (
126   IN FSP_INFO_HEADER *FspHeader
127   )
128 {
129   FSP_MEMORY_INIT_PARAMS    FspMemoryInitParams;
130   FSP_INIT_RT_COMMON_BUFFER FspRtBuffer;
131   UINT8                     FspUpdRgn[FixedPcdGet32 (PcdMaxUpdRegionSize)];
132   UINT32                    UpdRegionSize;
133   EFI_BOOT_MODE             BootMode;
134   UINT64                    StackSize;
135   EFI_PHYSICAL_ADDRESS      StackBase;
136   EFI_STATUS                Status;
137   VOID                      *FspHobList;
138   VOID                      *HobData;
139 
140   DEBUG ((DEBUG_INFO, "PeiFspMemoryInit enter\n"));
141 
142   PeiServicesGetBootMode (&BootMode);
143   DEBUG ((DEBUG_INFO, "BootMode - 0x%x\n", BootMode));
144 
145   GetStackInfo (BootMode, FALSE, &StackSize, &StackBase);
146   DEBUG ((DEBUG_INFO, "StackBase - 0x%x\n", StackBase));
147   DEBUG ((DEBUG_INFO, "StackSize - 0x%x\n", StackSize));
148 
149   ZeroMem (&FspRtBuffer, sizeof(FspRtBuffer));
150   FspRtBuffer.StackTop = (UINT32 *)(UINTN)(StackBase + StackSize);
151 
152   FspRtBuffer.BootMode = BootMode;
153 
154   /* Platform override any UPD configs */
155   UpdRegionSize = GetUpdRegionSize();
156   DEBUG ((DEBUG_INFO, "UpdRegionSize - 0x%x\n", UpdRegionSize));
157   DEBUG ((DEBUG_INFO, "sizeof(FspUpdRgn) - 0x%x\n", sizeof(FspUpdRgn)));
158   ASSERT(sizeof(FspUpdRgn) >= UpdRegionSize);
159   ZeroMem (FspUpdRgn, UpdRegionSize);
160   FspRtBuffer.UpdDataRgnPtr = UpdateFspUpdConfigs (FspUpdRgn);
161   FspRtBuffer.BootLoaderTolumSize = GetBootLoaderTolumSize ();
162 
163   ZeroMem (&FspMemoryInitParams, sizeof(FspMemoryInitParams));
164   FspMemoryInitParams.NvsBufferPtr = GetNvsBuffer ();
165   DEBUG ((DEBUG_INFO, "NvsBufferPtr - 0x%x\n", FspMemoryInitParams.NvsBufferPtr));
166   FspMemoryInitParams.RtBufferPtr  = (VOID *)&FspRtBuffer;
167   FspHobList = NULL;
168   FspMemoryInitParams.HobListPtr   = &FspHobList;
169 
170   DEBUG ((DEBUG_INFO, "FspMemoryInitParams - 0x%x\n", &FspMemoryInitParams));
171   DEBUG ((DEBUG_INFO, "  NvsBufferPtr      - 0x%x\n", FspMemoryInitParams.NvsBufferPtr));
172   DEBUG ((DEBUG_INFO, "  RtBufferPtr       - 0x%x\n", FspMemoryInitParams.RtBufferPtr));
173   DEBUG ((DEBUG_INFO, "    StackTop        - 0x%x\n", FspRtBuffer.StackTop));
174   DEBUG ((DEBUG_INFO, "    BootMode        - 0x%x\n", FspRtBuffer.BootMode));
175   DEBUG ((DEBUG_INFO, "    UpdDataRgnPtr   - 0x%x\n", FspRtBuffer.UpdDataRgnPtr));
176   DEBUG ((DEBUG_INFO, "  HobListPtr        - 0x%x\n", FspMemoryInitParams.HobListPtr));
177 
178   Status = CallFspMemoryInit (FspHeader, &FspMemoryInitParams);
179   DEBUG((DEBUG_INFO, "FspMemoryInit status: 0x%x\n", Status));
180   ASSERT_EFI_ERROR (Status);
181 
182   DEBUG ((DEBUG_INFO, "  HobListPtr (returned) - 0x%x\n", FspHobList));
183   ASSERT (FspHobList != NULL);
184 
185   FspHobProcessForMemoryResource (FspHobList);
186 
187   //
188   // FspHobList is not complete at this moment.
189   // Save FspHobList pointer to hob, so that it can be got later
190   //
191   HobData = BuildGuidHob (
192              &gFspInitDonePpiGuid,
193              sizeof (VOID *)
194              );
195   ASSERT (HobData != NULL);
196   CopyMem (HobData, &FspHobList, sizeof (FspHobList));
197 
198   return Status;
199 }
200 
201 /**
202   TemporaryRamDone() disables the use of Temporary RAM. If present, this service is invoked
203   by the PEI Foundation after the EFI_PEI_PERMANANT_MEMORY_INSTALLED_PPI is installed.
204 
205   @retval EFI_SUCCESS           Use of Temporary RAM was disabled.
206   @retval EFI_INVALID_PARAMETER Temporary RAM could not be disabled.
207 
208 **/
209 EFI_STATUS
210 EFIAPI
PeiTemporaryRamDone(VOID)211 PeiTemporaryRamDone (
212   VOID
213   )
214 {
215   EFI_STATUS                Status;
216   VOID                      *TempRamExitParam;
217   FSP_INFO_HEADER           *FspHeader;
218 
219   FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase));
220   if (FspHeader == NULL) {
221     return EFI_DEVICE_ERROR;
222   }
223 
224   DEBUG ((DEBUG_INFO, "PeiTemporaryRamDone enter\n"));
225 
226   TempRamExitParam = GetTempRamExitParam ();
227   Status = CallTempRamExit (FspHeader, TempRamExitParam);
228   DEBUG((DEBUG_INFO, "TempRamExit status: 0x%x\n", Status));
229   ASSERT_EFI_ERROR (Status);
230 
231   return EFI_SUCCESS;
232 }
233 
234 /**
235   This function is called after PEI core discover memory and finish migration.
236 
237   @param[in] PeiServices    Pointer to PEI Services Table.
238   @param[in] NotifyDesc     Pointer to the descriptor for the Notification event that
239                             caused this function to execute.
240   @param[in] Ppi            Pointer to the PPI data associated with this function.
241 
242   @retval EFI_STATUS        Always return EFI_SUCCESS
243 **/
244 EFI_STATUS
245 EFIAPI
PeiMemoryDiscoveredNotify(IN EFI_PEI_SERVICES ** PeiServices,IN EFI_PEI_NOTIFY_DESCRIPTOR * NotifyDesc,IN VOID * Ppi)246 PeiMemoryDiscoveredNotify (
247   IN EFI_PEI_SERVICES          **PeiServices,
248   IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
249   IN VOID                      *Ppi
250   )
251 {
252   EFI_STATUS                Status;
253   VOID                      *FspSiliconInitParam;
254   FSP_INFO_HEADER           *FspHeader;
255   VOID                      *FspHobList;
256   EFI_HOB_GUID_TYPE         *GuidHob;
257 
258   if (PcdGet32 (PcdFlashFvSecondFspBase) == 0) {
259     FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase));
260   } else {
261     FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvSecondFspBase));
262   }
263   if (FspHeader == NULL) {
264     return EFI_DEVICE_ERROR;
265   }
266 
267   DEBUG ((DEBUG_INFO, "PeiMemoryDiscoveredNotify enter\n"));
268 
269   FspSiliconInitParam = GetFspSiliconInitParam ();
270   Status = CallFspSiliconInit (FspHeader, FspSiliconInitParam);
271   DEBUG((DEBUG_ERROR, "FspSiliconInit status: 0x%x\n", Status));
272   ASSERT_EFI_ERROR (Status);
273 
274   //
275   // Now FspHobList complete, process it
276   //
277   GuidHob = GetFirstGuidHob (&gFspInitDonePpiGuid);
278   ASSERT (GuidHob != NULL);
279   FspHobList = *(VOID **)GET_GUID_HOB_DATA (GuidHob);
280   DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
281   FspHobProcessForOtherData (FspHobList);
282 
283   //
284   // Install FspInitDonePpi so that any other driver can consume this info.
285   //
286   Status = PeiServicesInstallPpi (&mPeiFspInitDonePpiV2);
287   ASSERT_EFI_ERROR(Status);
288 
289   return EFI_SUCCESS;
290 }
291 
292 /**
293   Do FSP initialization based on FspApi version 2.
294 
295   @param[in] FspHeader FSP header pointer.
296 
297   @return FSP initialization status.
298 **/
299 EFI_STATUS
PeiFspInitV2(IN FSP_INFO_HEADER * FspHeader)300 PeiFspInitV2 (
301   IN FSP_INFO_HEADER *FspHeader
302   )
303 {
304   EFI_STATUS           Status;
305   EFI_BOOT_MODE        BootMode;
306 
307   Status = PeiFspMemoryInit (FspHeader);
308   ASSERT_EFI_ERROR (Status);
309 
310   //
311   // Install TempramDonePpi to run TempRamExit
312   //
313   Status = PeiServicesInstallPpi (&mPeiTemporaryRamDoneDesc);
314   ASSERT_EFI_ERROR(Status);
315 
316   //
317   // Register MemoryDiscovered Nofity to run FspSiliconInit
318   //
319   Status = PeiServicesNotifyPpi (&mPeiMemoryDiscoveredNotifyDesc);
320   ASSERT_EFI_ERROR (Status);
321 
322   //
323   // Register EndOfPei Notify for S3 to run FspNotifyPhase
324   //
325   PeiServicesGetBootMode (&BootMode);
326   if (BootMode == BOOT_ON_S3_RESUME) {
327     Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc);
328     ASSERT_EFI_ERROR (Status);
329   }
330 
331   return EFI_SUCCESS;
332 }