BaseTools/BinToPcd: Fix Python 2.7.x compatibility issue
[mirror_edk2.git] / IntelFspPkg / FspDxeIpl / DxeIpl.c
CommitLineData
c8ec22a2
JY
1/** @file\r
2\r
9da59186 3 Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
c8ec22a2
JY
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 "DxeIpl.h"\r
15\r
16\r
17//\r
18// Module Globals used in the DXE to PEI hand off\r
19// These must be module globals, so the stack can be switched\r
20//\r
21CONST EFI_DXE_IPL_PPI mDxeIplPpi = {\r
22 DxeLoadCore\r
23};\r
24\r
25CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomGuidedSectionExtractionPpi = {\r
26 CustomGuidedSectionExtract\r
27};\r
28\r
29CONST EFI_PEI_DECOMPRESS_PPI mDecompressPpi = {\r
30 Decompress\r
31};\r
32\r
33CONST EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {\r
34 {\r
35 EFI_PEI_PPI_DESCRIPTOR_PPI,\r
36 &gEfiDxeIplPpiGuid,\r
37 (VOID *) &mDxeIplPpi\r
38 },\r
39 {\r
40 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
41 &gEfiPeiDecompressPpiGuid,\r
42 (VOID *) &mDecompressPpi\r
43 }\r
44};\r
45\r
46CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {\r
47 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
48 &gEfiEndOfPeiSignalPpiGuid,\r
49 NULL\r
50};\r
51\r
52/**\r
53 Entry point of DXE IPL PEIM.\r
54\r
55 This function installs DXE IPL PPI and Decompress PPI. It also reloads\r
56 itself to memory on non-S3 resume boot path.\r
57\r
58 @param[in] FileHandle Handle of the file being invoked.\r
59 @param[in] PeiServices Describes the list of possible PEI Services.\r
60\r
61 @retval EFI_SUCESS The entry point of DXE IPL PEIM executes successfully.\r
62 @retval Others Some error occurs during the execution of this function.\r
63\r
64**/\r
65EFI_STATUS\r
66EFIAPI\r
67PeimInitializeDxeIpl (\r
68 IN EFI_PEI_FILE_HANDLE FileHandle,\r
69 IN CONST EFI_PEI_SERVICES **PeiServices\r
70 )\r
71{\r
72 EFI_STATUS Status;\r
73 EFI_GUID *ExtractHandlerGuidTable;\r
74 UINTN ExtractHandlerNumber;\r
75 EFI_PEI_PPI_DESCRIPTOR *GuidPpi;\r
76\r
77 //\r
78 // Get custom extract guided section method guid list\r
79 //\r
80 ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable);\r
81\r
82 //\r
83 // Install custom extraction guid PPI\r
84 //\r
85 if (ExtractHandlerNumber > 0) {\r
86 GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR));\r
87 ASSERT (GuidPpi != NULL);\r
88 while (ExtractHandlerNumber-- > 0) {\r
89 GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;\r
90 GuidPpi->Ppi = (VOID *) &mCustomGuidedSectionExtractionPpi;\r
91 GuidPpi->Guid = &ExtractHandlerGuidTable[ExtractHandlerNumber];\r
92 Status = PeiServicesInstallPpi (GuidPpi++);\r
93 ASSERT_EFI_ERROR(Status);\r
94 }\r
95 }\r
96\r
97 //\r
98 // Install DxeIpl and Decompress PPIs.\r
99 //\r
100 Status = PeiServicesInstallPpi (mPpiList);\r
101 ASSERT_EFI_ERROR(Status);\r
102\r
103 return Status;\r
104}\r
105\r
106/**\r
107 The ExtractSection() function processes the input section and\r
108 returns a pointer to the section contents. If the section being\r
109 extracted does not require processing (if the section\r
110 GuidedSectionHeader.Attributes has the\r
111 EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then\r
112 OutputBuffer is just updated to point to the start of the\r
113 section's contents. Otherwise, *Buffer must be allocated\r
114 from PEI permanent memory.\r
115\r
116 @param[in] This Indicates the\r
117 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.\r
118 Buffer containing the input GUIDed section to be\r
119 processed. OutputBuffer OutputBuffer is\r
120 allocated from PEI permanent memory and contains\r
121 the new section stream.\r
122 @param[in] InputSection A pointer to the input buffer, which contains\r
123 the input section to be processed.\r
124 @param[out] OutputBuffer A pointer to a caller-allocated buffer, whose\r
125 size is specified by the contents of OutputSize.\r
126 @param[out] OutputSize A pointer to a caller-allocated\r
127 UINTN in which the size of *OutputBuffer\r
128 allocation is stored. If the function\r
129 returns anything other than EFI_SUCCESS,\r
130 the value of OutputSize is undefined.\r
131 @param[out] AuthenticationStatus A pointer to a caller-allocated\r
132 UINT32 that indicates the\r
133 authentication status of the\r
134 output buffer. If the input\r
135 section's GuidedSectionHeader.\r
136 Attributes field has the\r
137 EFI_GUIDED_SECTION_AUTH_STATUS_VALID\r
138 bit as clear,\r
139 AuthenticationStatus must return\r
140 zero. These bits reflect the\r
141 status of the extraction\r
142 operation. If the function\r
143 returns anything other than\r
144 EFI_SUCCESS, the value of\r
145 AuthenticationStatus is\r
146 undefined.\r
147\r
148 @retval EFI_SUCCESS The InputSection was\r
149 successfully processed and the\r
150 section contents were returned.\r
151\r
152 @retval EFI_OUT_OF_RESOURCES The system has insufficient\r
153 resources to process the request.\r
154\r
155 @retval EFI_INVALID_PARAMETER The GUID in InputSection does\r
156 not match this instance of the\r
157 GUIDed Section Extraction PPI.\r
158\r
159**/\r
160EFI_STATUS\r
161EFIAPI\r
162CustomGuidedSectionExtract (\r
163 IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,\r
164 IN CONST VOID *InputSection,\r
165 OUT VOID **OutputBuffer,\r
166 OUT UINTN *OutputSize,\r
167 OUT UINT32 *AuthenticationStatus\r
168)\r
169{\r
170 EFI_STATUS Status;\r
171 UINT8 *ScratchBuffer;\r
172 UINT32 ScratchBufferSize;\r
173 UINT32 OutputBufferSize;\r
174 UINT16 SectionAttribute;\r
175\r
176 //\r
177 // Init local variable\r
178 //\r
179 ScratchBuffer = NULL;\r
180\r
181 //\r
182 // Call GetInfo to get the size and attribute of input guided section data.\r
183 //\r
184 Status = ExtractGuidedSectionGetInfo (\r
185 InputSection,\r
186 &OutputBufferSize,\r
187 &ScratchBufferSize,\r
188 &SectionAttribute\r
189 );\r
190\r
191 if (EFI_ERROR (Status)) {\r
192 DEBUG ((DEBUG_ERROR, "GetInfo from guided section Failed - %r\n", Status));\r
193 return Status;\r
194 }\r
195\r
196 if (ScratchBufferSize != 0) {\r
197 //\r
198 // Allocate scratch buffer\r
199 //\r
200 ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
201 if (ScratchBuffer == NULL) {\r
202 return EFI_OUT_OF_RESOURCES;\r
203 }\r
204 }\r
205\r
206 if (((SectionAttribute & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) && OutputBufferSize > 0) {\r
207 //\r
208 // Allocate output buffer\r
209 //\r
210 *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (OutputBufferSize) + 1);\r
211 if (*OutputBuffer == NULL) {\r
212 return EFI_OUT_OF_RESOURCES;\r
213 }\r
214 DEBUG ((DEBUG_INFO, "Customized Guided section Memory Size required is 0x%x and address is 0x%p\n", OutputBufferSize, *OutputBuffer));\r
215 //\r
216 // *OutputBuffer still is one section. Adjust *OutputBuffer offset,\r
217 // skip EFI section header to make section data at page alignment.\r
218 //\r
219 *OutputBuffer = (VOID *)((UINT8 *) *OutputBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER));\r
220 }\r
221\r
222 Status = ExtractGuidedSectionDecode (\r
223 InputSection,\r
224 OutputBuffer,\r
225 ScratchBuffer,\r
226 AuthenticationStatus\r
227 );\r
228 if (EFI_ERROR (Status)) {\r
229 //\r
230 // Decode failed\r
231 //\r
232 DEBUG ((DEBUG_ERROR, "Extract guided section Failed - %r\n", Status));\r
233 return Status;\r
234 }\r
235\r
236 *OutputSize = (UINTN) OutputBufferSize;\r
237\r
238 return EFI_SUCCESS;\r
239}\r
240\r
241\r
242\r
243/**\r
244 Decompresses a section to the output buffer.\r
245\r
246 This function looks up the compression type field in the input section and\r
247 applies the appropriate compression algorithm to compress the section to a\r
248 callee allocated buffer.\r
249\r
250 @param[in] This Points to this instance of the\r
251 EFI_PEI_DECOMPRESS_PEI PPI.\r
252 @param[in] CompressionSection Points to the compressed section.\r
253 @param[out] OutputBuffer Holds the returned pointer to the decompressed\r
254 sections.\r
255 @param[out] OutputSize Holds the returned size of the decompress\r
256 section streams.\r
257\r
258 @retval EFI_SUCCESS The section was decompressed successfully.\r
259 OutputBuffer contains the resulting data and\r
260 OutputSize contains the resulting size.\r
261\r
262**/\r
263EFI_STATUS\r
264EFIAPI\r
265Decompress (\r
266 IN CONST EFI_PEI_DECOMPRESS_PPI *This,\r
267 IN CONST EFI_COMPRESSION_SECTION *CompressionSection,\r
268 OUT VOID **OutputBuffer,\r
269 OUT UINTN *OutputSize\r
270 )\r
271{\r
272 EFI_STATUS Status;\r
273 UINT8 *DstBuffer;\r
274 UINT8 *ScratchBuffer;\r
275 UINT32 DstBufferSize;\r
276 UINT32 ScratchBufferSize;\r
277 VOID *CompressionSource;\r
278 UINT32 CompressionSourceSize;\r
279 UINT32 UncompressedLength;\r
280 UINT8 CompressionType;\r
281\r
282 if (CompressionSection->CommonHeader.Type != EFI_SECTION_COMPRESSION) {\r
283 ASSERT (FALSE);\r
284 return EFI_INVALID_PARAMETER;\r
285 }\r
286\r
287 if (IS_SECTION2 (CompressionSection)) {\r
288 CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION2));\r
289 CompressionSourceSize = (UINT32) (SECTION2_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION2));\r
290 UncompressedLength = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->UncompressedLength;\r
291 CompressionType = ((EFI_COMPRESSION_SECTION2 *) CompressionSection)->CompressionType;\r
292 } else {\r
293 CompressionSource = (VOID *) ((UINT8 *) CompressionSection + sizeof (EFI_COMPRESSION_SECTION));\r
294 CompressionSourceSize = (UINT32) (SECTION_SIZE (CompressionSection) - sizeof (EFI_COMPRESSION_SECTION));\r
295 UncompressedLength = CompressionSection->UncompressedLength;\r
296 CompressionType = CompressionSection->CompressionType;\r
297 }\r
298\r
299 //\r
300 // This is a compression set, expand it\r
301 //\r
302 switch (CompressionType) {\r
303 case EFI_STANDARD_COMPRESSION:\r
496b0dd0
QS
304 //\r
305 // Load EFI standard compression.\r
306 // For compressed data, decompress them to destination buffer.\r
307 //\r
308 Status = UefiDecompressGetInfo (\r
309 CompressionSource,\r
310 CompressionSourceSize,\r
311 &DstBufferSize,\r
312 &ScratchBufferSize\r
313 );\r
314 if (EFI_ERROR (Status)) {\r
c8ec22a2 315 //\r
496b0dd0 316 // GetInfo failed\r
c8ec22a2 317 //\r
496b0dd0
QS
318 DEBUG ((DEBUG_ERROR, "Decompress GetInfo Failed - %r\n", Status));\r
319 return EFI_NOT_FOUND;\r
320 }\r
321 //\r
322 // Allocate scratch buffer\r
323 //\r
324 ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));\r
325 if (ScratchBuffer == NULL) {\r
326 return EFI_OUT_OF_RESOURCES;\r
327 }\r
328 //\r
329 // Allocate destination buffer, extra one page for adjustment\r
330 //\r
331 DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
332 if (DstBuffer == NULL) {\r
333 return EFI_OUT_OF_RESOURCES;\r
334 }\r
335 //\r
336 // DstBuffer still is one section. Adjust DstBuffer offset, skip EFI section header\r
337 // to make section data at page alignment.\r
338 //\r
339 DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
340 //\r
341 // Call decompress function\r
342 //\r
343 Status = UefiDecompress (\r
344 CompressionSource,\r
345 DstBuffer,\r
346 ScratchBuffer\r
347 );\r
348 if (EFI_ERROR (Status)) {\r
c8ec22a2 349 //\r
496b0dd0 350 // Decompress failed\r
c8ec22a2 351 //\r
496b0dd0 352 DEBUG ((DEBUG_ERROR, "Decompress Failed - %r\n", Status));\r
c8ec22a2
JY
353 return EFI_NOT_FOUND;\r
354 }\r
496b0dd0 355 break;\r
c8ec22a2
JY
356\r
357 case EFI_NOT_COMPRESSED:\r
358 //\r
359 // Allocate destination buffer\r
360 //\r
361 DstBufferSize = UncompressedLength;\r
362 DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize) + 1);\r
363 if (DstBuffer == NULL) {\r
364 return EFI_OUT_OF_RESOURCES;\r
365 }\r
366 //\r
367 // Adjust DstBuffer offset, skip EFI section header\r
368 // to make section data at page alignment.\r
369 //\r
370 DstBuffer = DstBuffer + EFI_PAGE_SIZE - sizeof (EFI_COMMON_SECTION_HEADER);\r
371 //\r
372 // stream is not actually compressed, just encapsulated. So just copy it.\r
373 //\r
374 CopyMem (DstBuffer, CompressionSource, DstBufferSize);\r
375 break;\r
376\r
377 default:\r
378 //\r
379 // Don't support other unknown compression type.\r
380 //\r
381 ASSERT (FALSE);\r
382 return EFI_NOT_FOUND;\r
383 }\r
384\r
385 *OutputSize = DstBufferSize;\r
386 *OutputBuffer = DstBuffer;\r
387\r
388 return EFI_SUCCESS;\r
389}\r
390\r
391/**\r
392 Main entry point to last PEIM.\r
393\r
394 This function finds DXE Core in the firmware volume and transfer the control to\r
395 DXE core.\r
396\r
397 @param[in] This Entry point for DXE IPL PPI.\r
398 @param[in] PeiServices General purpose services available to every PEIM.\r
399 @param[in] HobList Address to the Pei HOB list.\r
400\r
401 @return EFI_SUCCESS DXE core was successfully loaded.\r
402 @return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core.\r
403\r
404**/\r
405EFI_STATUS\r
406EFIAPI\r
407DxeLoadCore (\r
408 IN CONST EFI_DXE_IPL_PPI *This,\r
409 IN EFI_PEI_SERVICES **PeiServices,\r
410 IN EFI_PEI_HOB_POINTERS HobList\r
411 )\r
412{\r
413 EFI_STATUS Status;\r
414\r
415 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP HOB is located at 0x%08X\n", HobList));\r
416\r
baaacdc8
JY
417 //\r
418 // End of PEI phase signal\r
419 //\r
420 Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);\r
421 ASSERT_EFI_ERROR (Status);\r
422\r
c8ec22a2 423 //\r
9da59186 424 // Give control back to BootLoader after FspInit\r
c8ec22a2
JY
425 //\r
426 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP is waiting for NOTIFY\n"));\r
427 FspInitDone ();\r
428\r
429 //\r
9da59186 430 // BootLoader called FSP again through NotifyPhase\r
c8ec22a2
JY
431 //\r
432 FspWaitForNotify ();\r
433\r
c8ec22a2
JY
434\r
435 //\r
436 // Give control back to the boot loader framework caller\r
437 //\r
438 DEBUG ((DEBUG_INFO | DEBUG_INIT, "============= PEIM FSP is Completed =============\n\n"));\r
439\r
440 SetFspApiReturnStatus(EFI_SUCCESS);\r
441\r
442 SetFspMeasurePoint (FSP_PERF_ID_API_NOTIFY_RDYBOOT_EXIT);\r
443\r
444 Pei2LoaderSwitchStack();\r
445\r
446 //\r
447 // Should not come here\r
448 //\r
449 while (TRUE) {\r
450 DEBUG ((DEBUG_ERROR, "No FSP API should be called after FSP is DONE!\n"));\r
451 SetFspApiReturnStatus(EFI_UNSUPPORTED);\r
452 Pei2LoaderSwitchStack();\r
453 }\r
454\r
455 return EFI_SUCCESS;\r
456}\r