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