]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Pei/FwVol/FwVol.c
Eliminate the variable.
[mirror_edk2.git] / MdeModulePkg / Core / Pei / FwVol / FwVol.c
CommitLineData
615c6dd0 1/** @file\r
b1f6a7c6 2 Pei Core Firmware File System service routines.\r
3 \r
387208ab 4Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
cd5ebaa0 5This program and the accompanying materials \r
192f6d4c 6are licensed and made available under the terms and conditions of the BSD License \r
7which accompanies this distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php \r
9 \r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
12\r
615c6dd0 13**/\r
192f6d4c 14\r
3b428ade 15#include "FwVol.h"\r
192f6d4c 16\r
c7935105
SZ
17EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList[] = {\r
18 {\r
19 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
20 &gEfiPeiFirmwareVolumeInfoPpiGuid,\r
21 FirmwareVolmeInfoPpiNotifyCallback \r
22 },\r
23 {\r
24 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
25 &gEfiPeiFirmwareVolumeInfo2PpiGuid,\r
26 FirmwareVolmeInfoPpiNotifyCallback \r
27 }\r
b0d803fe 28};\r
29\r
890e5417
SZ
30PEI_FW_VOL_INSTANCE mPeiFfs2FwVol = {\r
31 PEI_FW_VOL_SIGNATURE,\r
32 FALSE,\r
33 {\r
34 PeiFfsFvPpiProcessVolume,\r
35 PeiFfsFvPpiFindFileByType,\r
36 PeiFfsFvPpiFindFileByName,\r
37 PeiFfsFvPpiGetFileInfo,\r
38 PeiFfsFvPpiGetVolumeInfo,\r
c7935105
SZ
39 PeiFfsFvPpiFindSectionByType,\r
40 PeiFfsFvPpiGetFileInfo2,\r
41 PeiFfsFvPpiFindSectionByType2,\r
42 EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE,\r
43 EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION\r
890e5417
SZ
44 }\r
45};\r
46\r
47PEI_FW_VOL_INSTANCE mPeiFfs3FwVol = {\r
48 PEI_FW_VOL_SIGNATURE,\r
49 TRUE,\r
50 {\r
51 PeiFfsFvPpiProcessVolume,\r
52 PeiFfsFvPpiFindFileByType,\r
53 PeiFfsFvPpiFindFileByName,\r
54 PeiFfsFvPpiGetFileInfo,\r
55 PeiFfsFvPpiGetVolumeInfo,\r
c7935105
SZ
56 PeiFfsFvPpiFindSectionByType,\r
57 PeiFfsFvPpiGetFileInfo2,\r
58 PeiFfsFvPpiFindSectionByType2,\r
59 EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE,\r
60 EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION\r
890e5417 61 }\r
3b428ade 62};\r
63 \r
64EFI_PEI_PPI_DESCRIPTOR mPeiFfs2FvPpiList = {\r
65 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
66 &gEfiFirmwareFileSystem2Guid,\r
890e5417
SZ
67 &mPeiFfs2FwVol.Fv\r
68};\r
69\r
70EFI_PEI_PPI_DESCRIPTOR mPeiFfs3FvPpiList = {\r
71 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
72 &gEfiFirmwareFileSystem3Guid,\r
73 &mPeiFfs3FwVol.Fv\r
3b428ade 74};\r
795bb9b6
SZ
75\r
76/**\r
77Required Alignment Alignment Value in FFS Alignment Value in\r
78(bytes) Attributes Field Firmware Volume Interfaces\r
791 0 0\r
8016 1 4\r
81128 2 7\r
82512 3 9\r
831 KB 4 10\r
844 KB 5 12\r
8532 KB 6 15\r
8664 KB 7 16\r
87**/\r
88UINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16};\r
89\r
90/**\r
91 Convert the FFS File Attributes to FV File Attributes\r
92\r
93 @param FfsAttributes The attributes of UINT8 type.\r
94\r
95 @return The attributes of EFI_FV_FILE_ATTRIBUTES\r
96\r
97**/\r
98EFI_FV_FILE_ATTRIBUTES\r
99FfsAttributes2FvFileAttributes (\r
100 IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes\r
101 )\r
102{\r
103 UINT8 DataAlignment;\r
104 EFI_FV_FILE_ATTRIBUTES FileAttribute;\r
105\r
106 DataAlignment = (UINT8) ((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);\r
107 ASSERT (DataAlignment < 8);\r
108\r
109 FileAttribute = (EFI_FV_FILE_ATTRIBUTES) mFvAttributes[DataAlignment];\r
110\r
111 if ((FfsAttributes & FFS_ATTRIB_FIXED) == FFS_ATTRIB_FIXED) {\r
112 FileAttribute |= EFI_FV_FILE_ATTRIB_FIXED;\r
113 }\r
114\r
115 return FileAttribute;\r
116}\r
117\r
b1f6a7c6 118/**\r
ed299e3c 119 Returns the file state set by the highest zero bit in the State field\r
192f6d4c 120\r
b1f6a7c6 121 @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY\r
122 in the Attributes field.\r
123 @param FfsHeader Pointer to FFS File Header.\r
192f6d4c 124\r
ed299e3c
LG
125 @retval EFI_FFS_FILE_STATE File state is set by the highest none zero bit \r
126 in the header State field.\r
b1f6a7c6 127**/\r
128EFI_FFS_FILE_STATE\r
129GetFileState(\r
130 IN UINT8 ErasePolarity,\r
131 IN EFI_FFS_FILE_HEADER *FfsHeader\r
132 )\r
192f6d4c 133{\r
134 EFI_FFS_FILE_STATE FileState;\r
135 EFI_FFS_FILE_STATE HighestBit;\r
136\r
137 FileState = FfsHeader->State;\r
138\r
139 if (ErasePolarity != 0) {\r
140 FileState = (EFI_FFS_FILE_STATE)~FileState;\r
141 }\r
ed299e3c
LG
142 \r
143 //\r
144 // Get file state set by its highest none zero bit.\r
145 //\r
192f6d4c 146 HighestBit = 0x80;\r
147 while (HighestBit != 0 && (HighestBit & FileState) == 0) {\r
148 HighestBit >>= 1;\r
149 }\r
150\r
151 return HighestBit;\r
152} \r
153\r
b1f6a7c6 154/**\r
155 Calculates the checksum of the header of a file.\r
156\r
157 @param FileHeader Pointer to FFS File Header.\r
158\r
159 @return Checksum of the header.\r
b1f6a7c6 160 Zero means the header is good.\r
161 Non-zero means the header is bad.\r
162**/\r
192f6d4c 163UINT8\r
164CalculateHeaderChecksum (\r
165 IN EFI_FFS_FILE_HEADER *FileHeader\r
166 )\r
192f6d4c 167{\r
890e5417 168 EFI_FFS_FILE_HEADER2 TestFileHeader;\r
192f6d4c 169\r
890e5417
SZ
170 if (IS_FFS_FILE2 (FileHeader)) {\r
171 CopyMem (&TestFileHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER2));\r
172 //\r
173 // Ingore State and File field in FFS header.\r
174 //\r
175 TestFileHeader.State = 0;\r
176 TestFileHeader.IntegrityCheck.Checksum.File = 0;\r
177\r
178 return CalculateSum8 ((CONST UINT8 *) &TestFileHeader, sizeof (EFI_FFS_FILE_HEADER2));\r
179 } else {\r
180 CopyMem (&TestFileHeader, FileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
181 //\r
182 // Ingore State and File field in FFS header.\r
183 //\r
184 TestFileHeader.State = 0;\r
185 TestFileHeader.IntegrityCheck.Checksum.File = 0;\r
186\r
187 return CalculateSum8 ((CONST UINT8 *) &TestFileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
188 }\r
192f6d4c 189}\r
190\r
b1f6a7c6 191/**\r
3b428ade 192 Find FV handler according to FileHandle in that FV.\r
b1f6a7c6 193\r
194 @param FileHandle Handle of file image\r
3b428ade 195 \r
196 @return Pointer to instance of PEI_CORE_FV_HANDLE.\r
b1f6a7c6 197**/\r
3b428ade 198PEI_CORE_FV_HANDLE*\r
199FileHandleToVolume (\r
200 IN EFI_PEI_FILE_HANDLE FileHandle\r
b0d803fe 201 )\r
202{\r
203 UINTN Index;\r
204 PEI_CORE_INSTANCE *PrivateData;\r
205 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
206\r
207 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());\r
3b428ade 208 \r
b0d803fe 209 for (Index = 0; Index < PrivateData->FvCount; Index++) {\r
210 FwVolHeader = PrivateData->Fv[Index].FvHeader;\r
67a58d0f 211 if (((UINT64) (UINTN) FileHandle > (UINT64) (UINTN) FwVolHeader ) && \\r
212 ((UINT64) (UINTN) FileHandle <= ((UINT64) (UINTN) FwVolHeader + FwVolHeader->FvLength - 1))) {\r
3b428ade 213 return &PrivateData->Fv[Index];\r
b0d803fe 214 }\r
215 }\r
3b428ade 216 return NULL;\r
b0d803fe 217}\r
218\r
b1f6a7c6 219/**\r
ed299e3c 220 Given the input file pointer, search for the first matching file in the\r
b1f6a7c6 221 FFS volume as defined by SearchType. The search starts from FileHeader inside\r
222 the Firmware Volume defined by FwVolHeader.\r
ed299e3c
LG
223 If SearchType is EFI_FV_FILETYPE_ALL, the first FFS file will return without check its file type.\r
224 If SearchType is PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE, \r
225 the first PEIM, or COMBINED PEIM or FV file type FFS file will return. \r
b1f6a7c6 226\r
227 @param FvHandle Pointer to the FV header of the volume to search\r
228 @param FileName File name\r
229 @param SearchType Filter to find only files of this type.\r
230 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r
231 @param FileHandle This parameter must point to a valid FFS volume.\r
232 @param AprioriFile Pointer to AprioriFile image in this FV if has\r
b0d803fe 233\r
b1f6a7c6 234 @return EFI_NOT_FOUND No files matching the search criteria were found\r
235 @retval EFI_SUCCESS Success to search given file\r
236\r
237**/\r
192f6d4c 238EFI_STATUS\r
3b428ade 239FindFileEx (\r
b0d803fe 240 IN CONST EFI_PEI_FV_HANDLE FvHandle,\r
241 IN CONST EFI_GUID *FileName, OPTIONAL\r
242 IN EFI_FV_FILETYPE SearchType,\r
243 IN OUT EFI_PEI_FILE_HANDLE *FileHandle,\r
3837e91c 244 IN OUT EFI_PEI_FILE_HANDLE *AprioriFile OPTIONAL\r
192f6d4c 245 )\r
192f6d4c 246{\r
f95f107c
SZ
247 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
248 EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExtHeader;\r
b0d803fe 249 EFI_FFS_FILE_HEADER **FileHeader;\r
250 EFI_FFS_FILE_HEADER *FfsFileHeader;\r
b0d803fe 251 UINT32 FileLength;\r
252 UINT32 FileOccupiedSize;\r
253 UINT32 FileOffset;\r
254 UINT64 FvLength;\r
255 UINT8 ErasePolarity;\r
256 UINT8 FileState;\r
89cd8129 257 UINT8 DataCheckSum;\r
890e5417 258 BOOLEAN IsFfs3Fv;\r
3b428ade 259 \r
260 //\r
261 // Convert the handle of FV to FV header for memory-mapped firmware volume\r
262 //\r
263 FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvHandle;\r
b0d803fe 264 FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle;\r
192f6d4c 265\r
890e5417
SZ
266 IsFfs3Fv = CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem3Guid);\r
267\r
192f6d4c 268 FvLength = FwVolHeader->FvLength;\r
d976bf31 269 if ((FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) != 0) {\r
192f6d4c 270 ErasePolarity = 1;\r
271 } else {\r
272 ErasePolarity = 0;\r
273 }\r
274 \r
275 //\r
b0d803fe 276 // If FileHeader is not specified (NULL) or FileName is not NULL,\r
277 // start with the first file in the firmware volume. Otherwise,\r
278 // start from the FileHeader.\r
192f6d4c 279 //\r
b0d803fe 280 if ((*FileHeader == NULL) || (FileName != NULL)) {\r
f95f107c
SZ
281 if (FwVolHeader->ExtHeaderOffset != 0) {\r
282 //\r
283 // Searching for files starts on an 8 byte aligned boundary after the end of the Extended Header if it exists.\r
284 //\r
285 FwVolExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *) ((UINT8 *) FwVolHeader + FwVolHeader->ExtHeaderOffset);\r
286 FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FwVolExtHeader + FwVolExtHeader->ExtHeaderSize);\r
287 FfsFileHeader = (EFI_FFS_FILE_HEADER *) ALIGN_POINTER (FfsFileHeader, 8);\r
288 } else {\r
289 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *) FwVolHeader + FwVolHeader->HeaderLength);\r
290 }\r
192f6d4c 291 } else {\r
890e5417
SZ
292 if (IS_FFS_FILE2 (*FileHeader)) {\r
293 if (!IsFfs3Fv) {\r
294 DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &(*FileHeader)->Name));\r
295 }\r
296 FileLength = FFS_FILE2_SIZE (*FileHeader);\r
297 ASSERT (FileLength > 0x00FFFFFF);\r
298 } else {\r
299 FileLength = FFS_FILE_SIZE (*FileHeader);\r
300 }\r
192f6d4c 301 //\r
192f6d4c 302 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.\r
303 //\r
b0d803fe 304 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r
192f6d4c 305 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);\r
306 }\r
e98cd821 307 \r
192f6d4c 308 FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);\r
309 ASSERT (FileOffset <= 0xFFFFFFFF);\r
e98cd821 310\r
b0d803fe 311 while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {\r
192f6d4c 312 //\r
313 // Get FileState which is the highest bit of the State \r
314 //\r
315 FileState = GetFileState (ErasePolarity, FfsFileHeader);\r
192f6d4c 316 switch (FileState) {\r
317\r
890e5417 318 case EFI_FILE_HEADER_CONSTRUCTION:\r
192f6d4c 319 case EFI_FILE_HEADER_INVALID:\r
890e5417
SZ
320 if (IS_FFS_FILE2 (FfsFileHeader)) {\r
321 if (!IsFfs3Fv) {\r
322 DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r
323 }\r
324 FileOffset += sizeof (EFI_FFS_FILE_HEADER2);\r
325 FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));\r
326 } else {\r
327 FileOffset += sizeof (EFI_FFS_FILE_HEADER);\r
328 FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));\r
329 }\r
192f6d4c 330 break;\r
331 \r
332 case EFI_FILE_DATA_VALID:\r
333 case EFI_FILE_MARKED_FOR_UPDATE:\r
b0d803fe 334 if (CalculateHeaderChecksum (FfsFileHeader) != 0) {\r
192f6d4c 335 ASSERT (FALSE);\r
e98cd821 336 *FileHeader = NULL;\r
192f6d4c 337 return EFI_NOT_FOUND;\r
338 }\r
b0d803fe 339\r
890e5417
SZ
340 if (IS_FFS_FILE2 (FfsFileHeader)) {\r
341 FileLength = FFS_FILE2_SIZE (FfsFileHeader);\r
342 ASSERT (FileLength > 0x00FFFFFF);\r
343 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r
344 if (!IsFfs3Fv) {\r
345 DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r
346 FileOffset += FileOccupiedSize;\r
347 FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize);\r
348 break;\r
349 }\r
350 } else {\r
351 FileLength = FFS_FILE_SIZE (FfsFileHeader);\r
352 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r
353 }\r
b0d803fe 354\r
89cd8129
LG
355 DataCheckSum = FFS_FIXED_CHECKSUM;\r
356 if ((FfsFileHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {\r
890e5417
SZ
357 if (IS_FFS_FILE2 (FfsFileHeader)) {\r
358 DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2), FileLength - sizeof(EFI_FFS_FILE_HEADER2));\r
359 } else {\r
360 DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER), FileLength - sizeof(EFI_FFS_FILE_HEADER));\r
361 }\r
89cd8129
LG
362 }\r
363 if (FfsFileHeader->IntegrityCheck.Checksum.File != DataCheckSum) {\r
364 ASSERT (FALSE);\r
365 *FileHeader = NULL;\r
366 return EFI_NOT_FOUND;\r
367 }\r
368\r
b0d803fe 369 if (FileName != NULL) {\r
370 if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) {\r
371 *FileHeader = FfsFileHeader;\r
372 return EFI_SUCCESS;\r
373 }\r
374 } else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) {\r
375 if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) || \r
288f9b38
LG
376 (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER) ||\r
377 (FfsFileHeader->Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE)) { \r
b0d803fe 378 \r
379 *FileHeader = FfsFileHeader;\r
380 return EFI_SUCCESS;\r
381 } else if (AprioriFile != NULL) {\r
382 if (FfsFileHeader->Type == EFI_FV_FILETYPE_FREEFORM) {\r
383 if (CompareGuid (&FfsFileHeader->Name, &gPeiAprioriFileNameGuid)) {\r
384 *AprioriFile = FfsFileHeader;\r
385 } \r
386 } \r
387 }\r
7e181f2f 388 } else if (((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) && \r
389 (FfsFileHeader->Type != EFI_FV_FILETYPE_FFS_PAD)) { \r
b0d803fe 390 *FileHeader = FfsFileHeader;\r
391 return EFI_SUCCESS;\r
392 }\r
393\r
40f26b8f 394 FileOffset += FileOccupiedSize; \r
395 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
192f6d4c 396 break;\r
397 \r
398 case EFI_FILE_DELETED:\r
890e5417
SZ
399 if (IS_FFS_FILE2 (FfsFileHeader)) {\r
400 if (!IsFfs3Fv) {\r
401 DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r
402 }\r
403 FileLength = FFS_FILE2_SIZE (FfsFileHeader);\r
404 ASSERT (FileLength > 0x00FFFFFF);\r
405 } else {\r
406 FileLength = FFS_FILE_SIZE (FfsFileHeader);\r
407 }\r
40f26b8f 408 FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);\r
409 FileOffset += FileOccupiedSize;\r
410 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
192f6d4c 411 break;\r
412\r
413 default:\r
e98cd821 414 *FileHeader = NULL;\r
192f6d4c 415 return EFI_NOT_FOUND;\r
192f6d4c 416 } \r
417 }\r
e98cd821
LG
418 \r
419 *FileHeader = NULL;\r
192f6d4c 420 return EFI_NOT_FOUND; \r
421}\r
422\r
b1f6a7c6 423/**\r
b1f6a7c6 424 Initialize PeiCore Fv List.\r
425\r
b1f6a7c6 426 @param PrivateData - Pointer to PEI_CORE_INSTANCE.\r
427 @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.\r
b1f6a7c6 428**/\r
b0d803fe 429VOID \r
430PeiInitializeFv (\r
431 IN PEI_CORE_INSTANCE *PrivateData,\r
432 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData\r
433 )\r
b0d803fe 434{\r
3b428ade 435 EFI_STATUS Status;\r
436 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r
437 EFI_PEI_FV_HANDLE FvHandle;\r
438 EFI_FIRMWARE_VOLUME_HEADER *BfvHeader;\r
439 \r
b0d803fe 440 //\r
3b428ade 441 // Install FV_PPI for FFS2 file system.\r
b0d803fe 442 //\r
3b428ade 443 PeiServicesInstallPpi (&mPeiFfs2FvPpiList);\r
890e5417
SZ
444\r
445 //\r
446 // Install FV_PPI for FFS3 file system.\r
447 //\r
448 PeiServicesInstallPpi (&mPeiFfs3FvPpiList);\r
449\r
3b428ade 450 BfvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;\r
451 \r
452 //\r
453 // The FV_PPI in BFV's format should be installed.\r
454 //\r
455 Status = PeiServicesLocatePpi (\r
456 &BfvHeader->FileSystemGuid,\r
457 0,\r
458 NULL,\r
459 (VOID**)&FvPpi\r
460 );\r
461 ASSERT_EFI_ERROR (Status);\r
462 \r
463 //\r
464 // Get handle of BFV\r
465 //\r
466 FvPpi->ProcessVolume (\r
467 FvPpi, \r
468 SecCoreData->BootFirmwareVolumeBase,\r
469 (UINTN)BfvHeader->FvLength,\r
470 &FvHandle\r
471 );\r
dc6f9b35 472\r
473 //\r
474 // Update internal PEI_CORE_FV array.\r
475 //\r
476 PrivateData->Fv[PrivateData->FvCount].FvHeader = BfvHeader;\r
477 PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi;\r
478 PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;\r
c7935105 479 PrivateData->Fv[PrivateData->FvCount].AuthenticationStatus = 0;\r
dc6f9b35 480 DEBUG ((\r
481 EFI_D_INFO, \r
482 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n", \r
483 (UINT32) PrivateData->FvCount, \r
484 (VOID *) BfvHeader, \r
485 BfvHeader->FvLength,\r
486 FvHandle\r
487 )); \r
488 PrivateData->FvCount ++;\r
489 \r
b0d803fe 490 //\r
c7935105 491 // Post a call-back for the FvInfoPPI and FvInfo2PPI services to expose\r
b0d803fe 492 // additional Fvs to PeiCore.\r
493 //\r
c7935105 494 Status = PeiServicesNotifyPpi (mNotifyOnFvInfoList);\r
b0d803fe 495 ASSERT_EFI_ERROR (Status);\r
496\r
497}\r
3b428ade 498 \r
b1f6a7c6 499/**\r
c7935105 500 Process Firmware Volum Information once FvInfoPPI or FvInfo2PPI install.\r
ed299e3c 501 The FV Info will be registered into PeiCore private data structure.\r
c7935105 502 And search the inside FV image, if found, the new FV INFO(2) PPI will be installed.\r
b1f6a7c6 503\r
ed299e3c 504 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
731bd38e 505 @param NotifyDescriptor Address of the notification descriptor data structure.\r
506 @param Ppi Address of the PPI that was installed.\r
b1f6a7c6 507\r
ed299e3c 508 @retval EFI_SUCCESS The FV Info is registered into PeiCore private data structure.\r
6a1ae84a 509 @return if not EFI_SUCESS, fail to verify FV.\r
b1f6a7c6 510\r
511**/\r
b0d803fe 512EFI_STATUS\r
513EFIAPI\r
514FirmwareVolmeInfoPpiNotifyCallback (\r
515 IN EFI_PEI_SERVICES **PeiServices,\r
516 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
517 IN VOID *Ppi\r
518 )\r
b0d803fe 519{\r
c7935105 520 EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI FvInfo2Ppi;\r
3b428ade 521 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r
b0d803fe 522 PEI_CORE_INSTANCE *PrivateData;\r
288f9b38 523 EFI_STATUS Status;\r
3b428ade 524 EFI_PEI_FV_HANDLE FvHandle;\r
525 UINTN FvIndex;\r
dc6f9b35 526 EFI_PEI_FILE_HANDLE FileHandle;\r
527 VOID *DepexData;\r
387208ab 528 BOOLEAN IsFvInfo2;\r
b0d803fe 529 \r
288f9b38
LG
530 Status = EFI_SUCCESS;\r
531 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
b0d803fe 532\r
fe781940
SZ
533 if (PrivateData->FvCount >= PcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
534 DEBUG ((EFI_D_ERROR, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData->FvCount + 1, PcdGet32 (PcdPeiCoreMaxFvSupported)));\r
97b2c9b5 535 DEBUG ((EFI_D_ERROR, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));\r
b0d803fe 536 ASSERT (FALSE);\r
537 }\r
538\r
c7935105
SZ
539 if (CompareGuid (NotifyDescriptor->Guid, &gEfiPeiFirmwareVolumeInfo2PpiGuid)) {\r
540 //\r
541 // It is FvInfo2PPI.\r
542 //\r
543 CopyMem (&FvInfo2Ppi, Ppi, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI));\r
387208ab 544 IsFvInfo2 = TRUE;\r
c7935105
SZ
545 } else {\r
546 //\r
547 // It is FvInfoPPI.\r
548 //\r
549 CopyMem (&FvInfo2Ppi, Ppi, sizeof (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI));\r
550 FvInfo2Ppi.AuthenticationStatus = 0;\r
387208ab 551 IsFvInfo2 = FALSE;\r
c7935105 552 }\r
b0d803fe 553\r
97b2c9b5 554 //\r
3b428ade 555 // Locate the corresponding FV_PPI according to founded FV's format guid\r
97b2c9b5 556 //\r
3b428ade 557 Status = PeiServicesLocatePpi (\r
c7935105
SZ
558 &FvInfo2Ppi.FvFormat,\r
559 0,\r
3b428ade 560 NULL,\r
561 (VOID**)&FvPpi\r
562 );\r
563 if (!EFI_ERROR (Status)) {\r
564 //\r
565 // Process new found FV and get FV handle.\r
566 //\r
c7935105 567 Status = FvPpi->ProcessVolume (FvPpi, FvInfo2Ppi.FvInfo, FvInfo2Ppi.FvInfoSize, &FvHandle);\r
3b428ade 568 if (EFI_ERROR (Status)) {\r
dc6f9b35 569 DEBUG ((EFI_D_ERROR, "Fail to process new found FV, FV may be corrupted!\n"));\r
6a1ae84a 570 return Status;\r
571 }\r
dc6f9b35 572\r
573 //\r
574 // Check whether the FV has already been processed.\r
575 //\r
576 for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex ++) {\r
577 if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) {\r
387208ab
SZ
578 if (IsFvInfo2 && (FvInfo2Ppi.AuthenticationStatus != PrivateData->Fv[FvIndex].AuthenticationStatus)) {\r
579 PrivateData->Fv[FvIndex].AuthenticationStatus = FvInfo2Ppi.AuthenticationStatus;\r
580 DEBUG ((EFI_D_INFO, "Update AuthenticationStatus of the %dth FV to 0x%x!\n", FvIndex, FvInfo2Ppi.AuthenticationStatus)); \r
581 }\r
c7935105 582 DEBUG ((EFI_D_INFO, "The Fv %p has already been processed!\n", FvInfo2Ppi.FvInfo));\r
dc6f9b35 583 return EFI_SUCCESS;\r
584 }\r
585 }\r
586\r
587 //\r
588 // Update internal PEI_CORE_FV array.\r
589 //\r
c7935105 590 PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) FvInfo2Ppi.FvInfo;\r
dc6f9b35 591 PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi;\r
592 PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;\r
c7935105 593 PrivateData->Fv[PrivateData->FvCount].AuthenticationStatus = FvInfo2Ppi.AuthenticationStatus;\r
dc6f9b35 594 DEBUG ((\r
595 EFI_D_INFO, \r
596 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n", \r
597 (UINT32) PrivateData->FvCount, \r
c7935105
SZ
598 (VOID *) FvInfo2Ppi.FvInfo, \r
599 FvInfo2Ppi.FvInfoSize,\r
dc6f9b35 600 FvHandle\r
601 )); \r
602 PrivateData->FvCount ++;\r
603\r
604 //\r
605 // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE \r
606 //\r
607 FileHandle = NULL;\r
608 do {\r
609 Status = FvPpi->FindFileByType (\r
610 FvPpi,\r
611 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r
612 FvHandle,\r
613 &FileHandle\r
614 );\r
615 if (!EFI_ERROR (Status)) {\r
616 Status = FvPpi->FindSectionByType (\r
617 FvPpi,\r
618 EFI_SECTION_PEI_DEPEX,\r
619 FileHandle,\r
620 (VOID**)&DepexData\r
621 );\r
622 if (!EFI_ERROR (Status)) {\r
623 if (!PeimDispatchReadiness (PeiServices, DepexData)) {\r
624 //\r
625 // Dependency is not satisfied.\r
626 //\r
627 continue;\r
628 }\r
629 }\r
630 \r
631 DEBUG ((EFI_D_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, PrivateData->FvCount - 1, FvHandle));\r
c7935105 632 ProcessFvFile (PrivateData, &PrivateData->Fv[PrivateData->FvCount - 1], FileHandle);\r
dc6f9b35 633 }\r
634 } while (FileHandle != NULL);\r
3b428ade 635 } else {\r
c7935105 636 DEBUG ((EFI_D_ERROR, "Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found!\n", FvInfo2Ppi.FvInfo));\r
6a1ae84a 637 \r
c7935105 638 AddUnknownFormatFvInfo (PrivateData, &FvInfo2Ppi);\r
288f9b38 639 }\r
3b428ade 640 \r
b0d803fe 641 return EFI_SUCCESS;\r
642}\r
643\r
8472f1f5
SZ
644/**\r
645 Verify the Guided Section GUID by checking if there is the Guided Section GUID HOB recorded the GUID itself.\r
646\r
647 @param GuidedSectionGuid The Guided Section GUID.\r
648 @param GuidedSectionExtraction A pointer to the pointer to the supported Guided Section Extraction Ppi\r
649 for the Guided Section.\r
650\r
651 @return TRUE The GuidedSectionGuid could be identified, and the pointer to\r
652 the Guided Section Extraction Ppi will be returned to *GuidedSectionExtraction.\r
653 @return FALSE The GuidedSectionGuid could not be identified, or \r
654 the Guided Section Extraction Ppi has not been installed yet.\r
655\r
656**/\r
657BOOLEAN\r
658VerifyGuidedSectionGuid (\r
659 IN EFI_GUID *GuidedSectionGuid,\r
660 OUT EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI **GuidedSectionExtraction\r
661 )\r
662{\r
663 EFI_PEI_HOB_POINTERS Hob;\r
664 EFI_GUID *GuidRecorded;\r
665 VOID *Interface;\r
666 EFI_STATUS Status;\r
667\r
668 //\r
669 // Check if there is the Guided Section GUID HOB recorded the GUID itself.\r
670 //\r
671 Hob.Raw = GetFirstGuidHob (GuidedSectionGuid);\r
672 if (Hob.Raw != NULL) {\r
673 GuidRecorded = (EFI_GUID *) GET_GUID_HOB_DATA (Hob);\r
674 if (CompareGuid (GuidRecorded, GuidedSectionGuid)) {\r
675 //\r
676 // Found the recorded GuidedSectionGuid.\r
677 //\r
678 Status = PeiServicesLocatePpi (GuidedSectionGuid, 0, NULL, (VOID **) &Interface);\r
679 if (!EFI_ERROR (Status) && Interface != NULL) {\r
680 //\r
681 // Found the supported Guided Section Extraction Ppi for the Guided Section.\r
682 //\r
683 *GuidedSectionExtraction = (EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *) Interface;\r
684 return TRUE;\r
685 }\r
686 return FALSE;\r
687 }\r
688 }\r
689\r
690 return FALSE;\r
691}\r
692\r
b1f6a7c6 693/**\r
ed299e3c
LG
694 Go through the file to search SectionType section. \r
695 Search within encapsulation sections (compression and GUIDed) recursively, \r
696 until the match section is found.\r
697 \r
3b428ade 698 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
699 @param SectionType Filter to find only section of this type.\r
c7935105 700 @param SectionInstance Pointer to the filter to find the specific instance of section.\r
3b428ade 701 @param Section From where to search.\r
702 @param SectionSize The file size to search.\r
703 @param OutputBuffer A pointer to the discovered section, if successful.\r
ed299e3c 704 NULL if section not found\r
c7935105 705 @param AuthenticationStatus Updated upon return to point to the authentication status for this section.\r
890e5417 706 @param IsFfs3Fv Indicates the FV format.\r
b1f6a7c6 707\r
ed299e3c
LG
708 @return EFI_NOT_FOUND The match section is not found.\r
709 @return EFI_SUCCESS The match section is found.\r
b1f6a7c6 710\r
711**/\r
b0d803fe 712EFI_STATUS\r
3b428ade 713ProcessSection (\r
b0d803fe 714 IN CONST EFI_PEI_SERVICES **PeiServices,\r
715 IN EFI_SECTION_TYPE SectionType,\r
c7935105 716 IN OUT UINTN *SectionInstance,\r
b0d803fe 717 IN EFI_COMMON_SECTION_HEADER *Section,\r
718 IN UINTN SectionSize,\r
890e5417 719 OUT VOID **OutputBuffer,\r
c7935105 720 OUT UINT32 *AuthenticationStatus,\r
890e5417 721 IN BOOLEAN IsFfs3Fv\r
b0d803fe 722 )\r
b0d803fe 723{\r
724 EFI_STATUS Status;\r
725 UINT32 SectionLength;\r
726 UINT32 ParsedLength;\r
b0d803fe 727 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *GuidSectionPpi;\r
b0d803fe 728 EFI_PEI_DECOMPRESS_PPI *DecompressPpi;\r
729 VOID *PpiOutput;\r
730 UINTN PpiOutputSize;\r
288f9b38
LG
731 UINTN Index;\r
732 UINT32 Authentication;\r
733 PEI_CORE_INSTANCE *PrivateData;\r
8472f1f5 734 EFI_GUID *SectionDefinitionGuid;\r
c7935105
SZ
735 BOOLEAN SectionCached;\r
736 VOID *TempOutputBuffer;\r
737 UINT32 TempAuthenticationStatus;\r
9d8de12c 738 UINT16 GuidedSectionAttributes;\r
b0d803fe 739\r
288f9b38 740 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
b0d803fe 741 *OutputBuffer = NULL;\r
288f9b38
LG
742 ParsedLength = 0;\r
743 Index = 0;\r
744 Status = EFI_NOT_FOUND;\r
745 PpiOutput = NULL;\r
746 PpiOutputSize = 0;\r
b0d803fe 747 while (ParsedLength < SectionSize) {\r
890e5417
SZ
748\r
749 if (IS_SECTION2 (Section)) {\r
750 ASSERT (SECTION2_SIZE (Section) > 0x00FFFFFF);\r
751 if (!IsFfs3Fv) {\r
752 DEBUG ((EFI_D_ERROR, "Found a FFS3 formatted section in a non-FFS3 formatted FV.\n"));\r
753 SectionLength = SECTION2_SIZE (Section);\r
754 //\r
755 // SectionLength is adjusted it is 4 byte aligned.\r
756 // Go to the next section\r
757 //\r
758 SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
759 ASSERT (SectionLength != 0);\r
760 ParsedLength += SectionLength;\r
761 Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength);\r
762 continue;\r
763 }\r
764 }\r
765\r
b0d803fe 766 if (Section->Type == SectionType) {\r
c7935105
SZ
767 //\r
768 // The type matches, so check the instance count to see if it's the one we want.\r
769 //\r
770 (*SectionInstance)--;\r
771 if (*SectionInstance == 0) {\r
772 //\r
773 // Got it!\r
774 //\r
775 if (IS_SECTION2 (Section)) {\r
776 *OutputBuffer = (VOID *)((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER2));\r
777 } else {\r
778 *OutputBuffer = (VOID *)((UINT8 *) Section + sizeof (EFI_COMMON_SECTION_HEADER));\r
779 }\r
780 return EFI_SUCCESS;\r
890e5417 781 } else {\r
c7935105
SZ
782 if (IS_SECTION2 (Section)) {\r
783 SectionLength = SECTION2_SIZE (Section);\r
784 } else {\r
785 SectionLength = SECTION_SIZE (Section);\r
786 }\r
787 //\r
788 // SectionLength is adjusted it is 4 byte aligned.\r
789 // Go to the next section\r
790 //\r
791 SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
792 ASSERT (SectionLength != 0);\r
793 ParsedLength += SectionLength;\r
794 Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);\r
795 continue;\r
890e5417 796 }\r
288f9b38
LG
797 } else if ((Section->Type == EFI_SECTION_GUID_DEFINED) || (Section->Type == EFI_SECTION_COMPRESSION)) {\r
798 //\r
799 // Check the encapsulated section is extracted into the cache data.\r
800 //\r
c7935105 801 SectionCached = FALSE;\r
288f9b38
LG
802 for (Index = 0; Index < PrivateData->CacheSection.AllSectionCount; Index ++) {\r
803 if (Section == PrivateData->CacheSection.Section[Index]) {\r
c7935105 804 SectionCached = TRUE;\r
288f9b38
LG
805 PpiOutput = PrivateData->CacheSection.SectionData[Index];\r
806 PpiOutputSize = PrivateData->CacheSection.SectionSize[Index];\r
c7935105 807 Authentication = PrivateData->CacheSection.AuthenticationStatus[Index];\r
288f9b38
LG
808 //\r
809 // Search section directly from the cache data.\r
810 //\r
c7935105
SZ
811 TempAuthenticationStatus = 0;\r
812 Status = ProcessSection (\r
813 PeiServices,\r
814 SectionType,\r
815 SectionInstance,\r
816 PpiOutput, \r
817 PpiOutputSize, \r
818 &TempOutputBuffer,\r
819 &TempAuthenticationStatus,\r
820 IsFfs3Fv\r
3b428ade 821 );\r
c7935105
SZ
822 if (!EFI_ERROR (Status)) {\r
823 *OutputBuffer = TempOutputBuffer;\r
824 *AuthenticationStatus = TempAuthenticationStatus | Authentication;\r
825 return EFI_SUCCESS;\r
826 }\r
b0d803fe 827 }\r
828 }\r
c7935105
SZ
829\r
830 //\r
831 // If SectionCached is TRUE, the section data has been cached and scanned.\r
832 //\r
833 if (!SectionCached) {\r
834 Status = EFI_NOT_FOUND;\r
835 Authentication = 0;\r
836 if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
837 if (IS_SECTION2 (Section)) {\r
9d8de12c
LG
838 SectionDefinitionGuid = &((EFI_GUID_DEFINED_SECTION2 *)Section)->SectionDefinitionGuid;\r
839 GuidedSectionAttributes = ((EFI_GUID_DEFINED_SECTION2 *)Section)->Attributes;\r
c7935105 840 } else {\r
9d8de12c
LG
841 SectionDefinitionGuid = &((EFI_GUID_DEFINED_SECTION *)Section)->SectionDefinitionGuid;\r
842 GuidedSectionAttributes = ((EFI_GUID_DEFINED_SECTION *)Section)->Attributes;\r
c7935105
SZ
843 }\r
844 if (VerifyGuidedSectionGuid (SectionDefinitionGuid, &GuidSectionPpi)) {\r
845 Status = GuidSectionPpi->ExtractSection (\r
846 GuidSectionPpi,\r
847 Section,\r
848 &PpiOutput,\r
849 &PpiOutputSize,\r
850 &Authentication\r
851 );\r
9d8de12c
LG
852 } else if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) == 0) {\r
853 //\r
854 // Figure out the proper authentication status for GUIDED section without processing required\r
855 //\r
856 Status = EFI_SUCCESS;\r
857 if ((GuidedSectionAttributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) == EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {\r
858 Authentication |= EFI_AUTH_STATUS_IMAGE_SIGNED | EFI_AUTH_STATUS_NOT_TESTED;\r
859 }\r
860 if (IS_SECTION2 (Section)) {\r
861 PpiOutputSize = SECTION2_SIZE (Section) - ((EFI_GUID_DEFINED_SECTION2 *) Section)->DataOffset;\r
862 PpiOutput = (UINT8 *) Section + ((EFI_GUID_DEFINED_SECTION2 *) Section)->DataOffset;\r
863 } else {\r
864 PpiOutputSize = SECTION_SIZE (Section) - ((EFI_GUID_DEFINED_SECTION *) Section)->DataOffset;\r
865 PpiOutput = (UINT8 *) Section + ((EFI_GUID_DEFINED_SECTION *) Section)->DataOffset;\r
866 }\r
c7935105
SZ
867 }\r
868 } else if (Section->Type == EFI_SECTION_COMPRESSION) {\r
869 Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);\r
870 if (!EFI_ERROR (Status)) {\r
871 Status = DecompressPpi->Decompress (\r
872 DecompressPpi,\r
873 (CONST EFI_COMPRESSION_SECTION*) Section,\r
874 &PpiOutput,\r
875 &PpiOutputSize\r
876 );\r
877 }\r
288f9b38 878 }\r
c7935105 879\r
288f9b38 880 if (!EFI_ERROR (Status)) {\r
c7935105
SZ
881 //\r
882 // Update cache section data.\r
883 //\r
884 if (PrivateData->CacheSection.AllSectionCount < CACHE_SETION_MAX_NUMBER) {\r
885 PrivateData->CacheSection.AllSectionCount ++;\r
886 }\r
887 PrivateData->CacheSection.Section [PrivateData->CacheSection.SectionIndex] = Section;\r
888 PrivateData->CacheSection.SectionData [PrivateData->CacheSection.SectionIndex] = PpiOutput;\r
889 PrivateData->CacheSection.SectionSize [PrivateData->CacheSection.SectionIndex] = PpiOutputSize;\r
890 PrivateData->CacheSection.AuthenticationStatus [PrivateData->CacheSection.SectionIndex] = Authentication;\r
891 PrivateData->CacheSection.SectionIndex = (PrivateData->CacheSection.SectionIndex + 1)%CACHE_SETION_MAX_NUMBER;\r
892\r
893 TempAuthenticationStatus = 0;\r
894 Status = ProcessSection (\r
895 PeiServices,\r
896 SectionType,\r
897 SectionInstance,\r
898 PpiOutput, \r
899 PpiOutputSize, \r
900 &TempOutputBuffer,\r
901 &TempAuthenticationStatus,\r
902 IsFfs3Fv\r
903 );\r
904 if (!EFI_ERROR (Status)) {\r
905 *OutputBuffer = TempOutputBuffer;\r
906 *AuthenticationStatus = TempAuthenticationStatus | Authentication;\r
907 return EFI_SUCCESS;\r
908 }\r
288f9b38 909 }\r
288f9b38 910 }\r
b0d803fe 911 }\r
912\r
890e5417
SZ
913 if (IS_SECTION2 (Section)) {\r
914 SectionLength = SECTION2_SIZE (Section);\r
915 } else {\r
916 SectionLength = SECTION_SIZE (Section);\r
917 }\r
b0d803fe 918 //\r
b0d803fe 919 // SectionLength is adjusted it is 4 byte aligned.\r
920 // Go to the next section\r
921 //\r
b0d803fe 922 SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
923 ASSERT (SectionLength != 0);\r
924 ParsedLength += SectionLength;\r
925 Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);\r
926 }\r
927 \r
928 return EFI_NOT_FOUND;\r
929}\r
930\r
192f6d4c 931\r
b1f6a7c6 932/**\r
3b428ade 933 Searches for the next matching section within the specified file.\r
b1f6a7c6 934\r
ed299e3c 935 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
b1f6a7c6 936 @param SectionType Filter to find only sections of this type.\r
937 @param FileHandle Pointer to the current file to search.\r
ed299e3c 938 @param SectionData A pointer to the discovered section, if successful.\r
b1f6a7c6 939 NULL if section not found\r
940\r
3b428ade 941 @retval EFI_NOT_FOUND The section was not found.\r
942 @retval EFI_SUCCESS The section was found.\r
b1f6a7c6 943\r
944**/\r
192f6d4c 945EFI_STATUS\r
946EFIAPI\r
947PeiFfsFindSectionData (\r
3b428ade 948 IN CONST EFI_PEI_SERVICES **PeiServices,\r
192f6d4c 949 IN EFI_SECTION_TYPE SectionType,\r
0c2b5da8 950 IN EFI_PEI_FILE_HANDLE FileHandle,\r
3b428ade 951 OUT VOID **SectionData\r
192f6d4c 952 )\r
192f6d4c 953{\r
3b428ade 954 PEI_CORE_FV_HANDLE *CoreFvHandle;\r
955 \r
956 CoreFvHandle = FileHandleToVolume (FileHandle);\r
957 if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {\r
958 return EFI_NOT_FOUND;\r
959 }\r
960 \r
961 return CoreFvHandle->FvPpi->FindSectionByType (CoreFvHandle->FvPpi, SectionType, FileHandle, SectionData);\r
192f6d4c 962}\r
963\r
c7935105
SZ
964/**\r
965 Searches for the next matching section within the specified file.\r
966\r
967 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
968 @param SectionType The value of the section type to find.\r
969 @param SectionInstance Section instance to find.\r
970 @param FileHandle Handle of the firmware file to search.\r
971 @param SectionData A pointer to the discovered section, if successful.\r
972 @param AuthenticationStatus A pointer to the authentication status for this section.\r
973\r
974 @retval EFI_SUCCESS The section was found.\r
975 @retval EFI_NOT_FOUND The section was not found.\r
976\r
977**/\r
978EFI_STATUS\r
979EFIAPI\r
980PeiFfsFindSectionData3 (\r
981 IN CONST EFI_PEI_SERVICES **PeiServices,\r
982 IN EFI_SECTION_TYPE SectionType,\r
983 IN UINTN SectionInstance,\r
984 IN EFI_PEI_FILE_HANDLE FileHandle,\r
985 OUT VOID **SectionData,\r
986 OUT UINT32 *AuthenticationStatus\r
987 )\r
988{\r
989 PEI_CORE_FV_HANDLE *CoreFvHandle;\r
990 \r
991 CoreFvHandle = FileHandleToVolume (FileHandle);\r
992 if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {\r
993 return EFI_NOT_FOUND;\r
994 }\r
995\r
996 if ((CoreFvHandle->FvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) &&\r
997 (CoreFvHandle->FvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION)) {\r
998 return CoreFvHandle->FvPpi->FindSectionByType2 (CoreFvHandle->FvPpi, SectionType, SectionInstance, FileHandle, SectionData, AuthenticationStatus);\r
999 }\r
1000 //\r
1001 // The old FvPpi doesn't support to find section by section instance\r
1002 // and return authentication status, so return EFI_UNSUPPORTED.\r
1003 //\r
1004 return EFI_UNSUPPORTED;\r
1005}\r
1006\r
b1f6a7c6 1007/**\r
3b428ade 1008 Searches for the next matching file in the firmware volume.\r
b1f6a7c6 1009\r
d73d93c3 1010 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
b1f6a7c6 1011 @param SearchType Filter to find only files of this type.\r
1012 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r
aa75dfec 1013 @param FvHandle Handle of firmware volume in which to search.\r
3b428ade 1014 @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start\r
1015 at the beginning of the firmware volume. On exit, points the file handle of the next file\r
1016 in the volume or NULL if there are no more files.\r
1017\r
1018 @retval EFI_NOT_FOUND The file was not found.\r
1019 @retval EFI_NOT_FOUND The header checksum was not zero.\r
1020 @retval EFI_SUCCESS The file was found.\r
b1f6a7c6 1021\r
1022**/\r
192f6d4c 1023EFI_STATUS\r
1024EFIAPI\r
1025PeiFfsFindNextFile (\r
0c2b5da8 1026 IN CONST EFI_PEI_SERVICES **PeiServices,\r
1027 IN UINT8 SearchType,\r
3b428ade 1028 IN EFI_PEI_FV_HANDLE FvHandle,\r
0c2b5da8 1029 IN OUT EFI_PEI_FILE_HANDLE *FileHandle\r
192f6d4c 1030 )\r
192f6d4c 1031{\r
3b428ade 1032 PEI_CORE_FV_HANDLE *CoreFvHandle;\r
1033 \r
1034 CoreFvHandle = FvHandleToCoreHandle (FvHandle);\r
1035 \r
2f016ba8 1036 //\r
1037 // To make backward compatiblity, if can not find corresponding the handle of FV\r
890e5417 1038 // then treat FV as build-in FFS2/FFS3 format and memory mapped FV that FV handle is pointed\r
2f016ba8 1039 // to the address of first byte of FV.\r
1040 //\r
1041 if ((CoreFvHandle == NULL) && FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r
1042 return FindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL);\r
1043 } \r
1044 \r
3b428ade 1045 if ((CoreFvHandle == NULL) || CoreFvHandle->FvPpi == NULL) {\r
1046 return EFI_NOT_FOUND;\r
1047 }\r
1048 \r
1049 return CoreFvHandle->FvPpi->FindFileByType (CoreFvHandle->FvPpi, SearchType, FvHandle, FileHandle);\r
192f6d4c 1050}\r
1051\r
b0d803fe 1052\r
b1f6a7c6 1053/**\r
ed299e3c 1054 Search the firmware volumes by index\r
b1f6a7c6 1055\r
ed299e3c 1056 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
3b428ade 1057 @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware\r
1058 Volume (BFV).\r
1059 @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist.\r
b1f6a7c6 1060\r
3b428ade 1061 @retval EFI_INVALID_PARAMETER VolumeHandle is NULL\r
1062 @retval EFI_NOT_FOUND The volume was not found.\r
1063 @retval EFI_SUCCESS The volume was found.\r
b1f6a7c6 1064\r
1065**/\r
192f6d4c 1066EFI_STATUS \r
1067EFIAPI\r
3b428ade 1068PeiFfsFindNextVolume (\r
2a00326e 1069 IN CONST EFI_PEI_SERVICES **PeiServices,\r
192f6d4c 1070 IN UINTN Instance,\r
0c2b5da8 1071 IN OUT EFI_PEI_FV_HANDLE *VolumeHandle\r
192f6d4c 1072 )\r
192f6d4c 1073{\r
3b428ade 1074 PEI_CORE_INSTANCE *Private;\r
1075 PEI_CORE_FV_HANDLE *CoreFvHandle;\r
1076 \r
3e4c5b49 1077 if (VolumeHandle == NULL) {\r
1078 return EFI_INVALID_PARAMETER;\r
1079 }\r
1080 \r
b0d803fe 1081 Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
2a00326e 1082 \r
3b428ade 1083 CoreFvHandle = FindNextCoreFvHandle (Private, Instance);\r
1084 if (CoreFvHandle == NULL) {\r
1085 *VolumeHandle = NULL;\r
1086 return EFI_NOT_FOUND;\r
2a00326e 1087 }\r
3b428ade 1088 \r
1089 *VolumeHandle = CoreFvHandle->FvHandle;\r
1090 \r
b0d803fe 1091 return EFI_SUCCESS;\r
1092}\r
192f6d4c 1093\r
192f6d4c 1094\r
b1f6a7c6 1095/**\r
ed299e3c 1096 Find a file within a volume by its name.\r
b1f6a7c6 1097\r
ed299e3c
LG
1098 @param FileName A pointer to the name of the file to find within the firmware volume.\r
1099 @param VolumeHandle The firmware volume to search\r
1100 @param FileHandle Upon exit, points to the found file's handle \r
1101 or NULL if it could not be found.\r
b1f6a7c6 1102\r
ed299e3c
LG
1103 @retval EFI_SUCCESS File was found.\r
1104 @retval EFI_NOT_FOUND File was not found.\r
1105 @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL.\r
b1f6a7c6 1106\r
b1f6a7c6 1107**/\r
b0d803fe 1108EFI_STATUS\r
1109EFIAPI \r
1110PeiFfsFindFileByName (\r
1111 IN CONST EFI_GUID *FileName,\r
1112 IN EFI_PEI_FV_HANDLE VolumeHandle,\r
1113 OUT EFI_PEI_FILE_HANDLE *FileHandle\r
1114 )\r
b0d803fe 1115{\r
3b428ade 1116 PEI_CORE_FV_HANDLE *CoreFvHandle;\r
1117 \r
b0d803fe 1118 if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {\r
192f6d4c 1119 return EFI_INVALID_PARAMETER;\r
1120 }\r
3b428ade 1121 \r
1122 CoreFvHandle = FvHandleToCoreHandle (VolumeHandle);\r
1123 if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {\r
1124 return EFI_NOT_FOUND;\r
b0d803fe 1125 }\r
3b428ade 1126 \r
1127 return CoreFvHandle->FvPpi->FindFileByName (CoreFvHandle->FvPpi, FileName, &VolumeHandle, FileHandle);\r
b0d803fe 1128}\r
1129\r
b1f6a7c6 1130/**\r
b1f6a7c6 1131 Returns information about a specific file.\r
1132\r
3b428ade 1133 @param FileHandle Handle of the file.\r
4237d40b 1134 @param FileInfo Upon exit, points to the file's information.\r
b1f6a7c6 1135\r
3b428ade 1136 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.\r
1137 @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.\r
1138 @retval EFI_SUCCESS File information returned.\r
b1f6a7c6 1139\r
1140**/\r
b0d803fe 1141EFI_STATUS\r
1142EFIAPI \r
1143PeiFfsGetFileInfo (\r
1144 IN EFI_PEI_FILE_HANDLE FileHandle,\r
1145 OUT EFI_FV_FILE_INFO *FileInfo\r
1146 )\r
b0d803fe 1147{\r
3b428ade 1148 PEI_CORE_FV_HANDLE *CoreFvHandle;\r
1149 \r
b0d803fe 1150 if ((FileHandle == NULL) || (FileInfo == NULL)) {\r
1151 return EFI_INVALID_PARAMETER;\r
1152 }\r
1153\r
1154 //\r
1155 // Retrieve the FirmwareVolume which the file resides in.\r
1156 //\r
3b428ade 1157 CoreFvHandle = FileHandleToVolume (FileHandle);\r
1158 if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {\r
b0d803fe 1159 return EFI_INVALID_PARAMETER;\r
1160 }\r
1161\r
3b428ade 1162 return CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, FileHandle, FileInfo);\r
b0d803fe 1163}\r
1164\r
c7935105
SZ
1165/**\r
1166 Returns information about a specific file.\r
1167\r
1168 @param FileHandle Handle of the file.\r
1169 @param FileInfo Upon exit, points to the file's information.\r
1170\r
1171 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.\r
1172 @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.\r
1173 @retval EFI_SUCCESS File information returned.\r
1174\r
1175**/\r
1176EFI_STATUS\r
1177EFIAPI \r
1178PeiFfsGetFileInfo2 (\r
1179 IN EFI_PEI_FILE_HANDLE FileHandle,\r
1180 OUT EFI_FV_FILE_INFO2 *FileInfo\r
1181 )\r
1182{\r
1183 PEI_CORE_FV_HANDLE *CoreFvHandle;\r
1184 \r
1185 if ((FileHandle == NULL) || (FileInfo == NULL)) {\r
1186 return EFI_INVALID_PARAMETER;\r
1187 }\r
1188\r
1189 //\r
1190 // Retrieve the FirmwareVolume which the file resides in.\r
1191 //\r
1192 CoreFvHandle = FileHandleToVolume (FileHandle);\r
1193 if ((CoreFvHandle == NULL) || (CoreFvHandle->FvPpi == NULL)) {\r
1194 return EFI_INVALID_PARAMETER;\r
1195 }\r
1196\r
1197 if ((CoreFvHandle->FvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) &&\r
1198 (CoreFvHandle->FvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION)) {\r
1199 return CoreFvHandle->FvPpi->GetFileInfo2 (CoreFvHandle->FvPpi, FileHandle, FileInfo);\r
1200 }\r
1201 //\r
1202 // The old FvPpi doesn't support to return file info with authentication status,\r
1203 // so return EFI_UNSUPPORTED.\r
1204 //\r
1205 return EFI_UNSUPPORTED;\r
1206}\r
b0d803fe 1207\r
b1f6a7c6 1208/**\r
3b428ade 1209 Returns information about the specified volume.\r
b1f6a7c6 1210\r
5a9403b8 1211 This function returns information about a specific firmware\r
1212 volume, including its name, type, attributes, starting address\r
1213 and size.\r
1214\r
1215 @param VolumeHandle Handle of the volume.\r
1216 @param VolumeInfo Upon exit, points to the volume's information.\r
1217\r
1218 @retval EFI_SUCCESS Volume information returned.\r
1219 @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume.\r
1220 @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL.\r
1221 @retval EFI_SUCCESS Information successfully returned.\r
1222 @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available.\r
b1f6a7c6 1223\r
b1f6a7c6 1224**/\r
b0d803fe 1225EFI_STATUS\r
1226EFIAPI \r
1227PeiFfsGetVolumeInfo (\r
1228 IN EFI_PEI_FV_HANDLE VolumeHandle,\r
1229 OUT EFI_FV_INFO *VolumeInfo\r
1230 )\r
b0d803fe 1231{\r
3b428ade 1232 PEI_CORE_FV_HANDLE *CoreHandle;\r
1233 \r
8fdcc412 1234 if ((VolumeInfo == NULL) || (VolumeHandle == NULL)) {\r
b0d803fe 1235 return EFI_INVALID_PARAMETER;\r
192f6d4c 1236 }\r
288f9b38 1237 \r
3b428ade 1238 CoreHandle = FvHandleToCoreHandle (VolumeHandle);\r
1239 \r
1240 if ((CoreHandle == NULL) || (CoreHandle->FvPpi == NULL)) {\r
288f9b38
LG
1241 return EFI_INVALID_PARAMETER;\r
1242 }\r
3b428ade 1243 \r
1244 return CoreHandle->FvPpi->GetVolumeInfo (CoreHandle->FvPpi, VolumeHandle, VolumeInfo);\r
192f6d4c 1245}\r
b0d803fe 1246\r
4c6486b9 1247/**\r
c7935105 1248 Get Fv image from the FV type file, then install FV INFO(2) ppi, Build FV hob.\r
4c6486b9 1249\r
c7935105 1250 @param PrivateData PeiCore's private data structure\r
3b428ade 1251 @param ParentFvCoreHandle Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image.\r
97b2c9b5 1252 @param ParentFvFileHandle File handle of a Fv type file that contain this Fv image.\r
4c6486b9 1253\r
1254 @retval EFI_NOT_FOUND FV image can't be found.\r
1255 @retval EFI_SUCCESS Successfully to process it.\r
1256 @retval EFI_OUT_OF_RESOURCES Can not allocate page when aligning FV image\r
c7935105 1257 @retval EFI_SECURITY_VIOLATION Image is illegal\r
4c6486b9 1258 @retval Others Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section\r
1259 \r
1260**/\r
1261EFI_STATUS\r
1262ProcessFvFile (\r
c7935105 1263 IN PEI_CORE_INSTANCE *PrivateData,\r
3b428ade 1264 IN PEI_CORE_FV_HANDLE *ParentFvCoreHandle,\r
1265 IN EFI_PEI_FILE_HANDLE ParentFvFileHandle\r
4c6486b9 1266 )\r
1267{\r
3b428ade 1268 EFI_STATUS Status;\r
1269 EFI_FV_INFO ParentFvImageInfo;\r
1270 UINT32 FvAlignment;\r
1271 VOID *NewFvBuffer;\r
1272 EFI_PEI_HOB_POINTERS HobPtr;\r
1273 EFI_PEI_FIRMWARE_VOLUME_PPI *ParentFvPpi;\r
1274 EFI_PEI_FV_HANDLE ParentFvHandle;\r
1275 EFI_FIRMWARE_VOLUME_HEADER *FvHeader;\r
1276 EFI_FV_FILE_INFO FileInfo;\r
b4d856a6 1277 UINT64 FvLength;\r
c7935105 1278 UINT32 AuthenticationStatus;\r
3b428ade 1279 \r
4c6486b9 1280 //\r
1281 // Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already\r
1282 // been extracted.\r
1283 //\r
1284 HobPtr.Raw = GetHobList ();\r
1285 while ((HobPtr.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobPtr.Raw)) != NULL) {\r
97b2c9b5 1286 if (CompareGuid (&(((EFI_FFS_FILE_HEADER *)ParentFvFileHandle)->Name), &HobPtr.FirmwareVolume2->FileName)) {\r
4c6486b9 1287 //\r
1288 // this FILE has been dispatched, it will not be dispatched again.\r
1289 //\r
3b428ade 1290 DEBUG ((EFI_D_INFO, "FV file %p has been dispatched!\r\n", ParentFvFileHandle));\r
4c6486b9 1291 return EFI_SUCCESS;\r
1292 }\r
1293 HobPtr.Raw = GET_NEXT_HOB (HobPtr);\r
1294 }\r
1295\r
3b428ade 1296 ParentFvHandle = ParentFvCoreHandle->FvHandle;\r
1297 ParentFvPpi = ParentFvCoreHandle->FvPpi;\r
1298 \r
4c6486b9 1299 //\r
1300 // Find FvImage in FvFile\r
1301 //\r
c7935105
SZ
1302 AuthenticationStatus = 0;\r
1303 if ((ParentFvPpi->Signature == EFI_PEI_FIRMWARE_VOLUME_PPI_SIGNATURE) &&\r
1304 (ParentFvPpi->Revision == EFI_PEI_FIRMWARE_VOLUME_PPI_REVISION)) {\r
1305 Status = ParentFvPpi->FindSectionByType2 (\r
1306 ParentFvPpi,\r
1307 EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
1308 0,\r
1309 ParentFvFileHandle,\r
1310 (VOID **)&FvHeader,\r
1311 &AuthenticationStatus\r
1312 );\r
1313 } else {\r
1314 Status = ParentFvPpi->FindSectionByType (\r
1315 ParentFvPpi,\r
1316 EFI_SECTION_FIRMWARE_VOLUME_IMAGE,\r
1317 ParentFvFileHandle,\r
1318 (VOID **)&FvHeader\r
1319 );\r
1320 }\r
4c6486b9 1321 if (EFI_ERROR (Status)) {\r
1322 return Status;\r
1323 }\r
97b2c9b5 1324\r
c7935105
SZ
1325 Status = VerifyPeim (PrivateData, ParentFvHandle, ParentFvFileHandle, AuthenticationStatus);\r
1326 if (Status == EFI_SECURITY_VIOLATION) {\r
1327 return Status;\r
1328 }\r
1329\r
97b2c9b5 1330 //\r
3837e91c
SZ
1331 // If EFI_FVB2_WEAK_ALIGNMENT is set in the volume header then the first byte of the volume\r
1332 // can be aligned on any power-of-two boundary. A weakly aligned volume can not be moved from\r
1333 // its initial linked location and maintain its alignment.\r
4c6486b9 1334 //\r
3837e91c
SZ
1335 if ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_WEAK_ALIGNMENT) != EFI_FVB2_WEAK_ALIGNMENT) {\r
1336 //\r
1337 // FvAlignment must be greater than or equal to 8 bytes of the minimum FFS alignment value.\r
1338 //\r
1339 FvAlignment = 1 << ((ReadUnaligned32 (&FvHeader->Attributes) & EFI_FVB2_ALIGNMENT) >> 16);\r
1340 if (FvAlignment < 8) {\r
1341 FvAlignment = 8;\r
1342 }\r
1343\r
1344 //\r
1345 // Check FvImage\r
1346 //\r
1347 if ((UINTN) FvHeader % FvAlignment != 0) {\r
1348 FvLength = ReadUnaligned64 (&FvHeader->FvLength);\r
1349 NewFvBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINT32) FvLength), FvAlignment);\r
1350 if (NewFvBuffer == NULL) {\r
1351 return EFI_OUT_OF_RESOURCES;\r
1352 }\r
1353 CopyMem (NewFvBuffer, FvHeader, (UINTN) FvLength);\r
1354 FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) NewFvBuffer;\r
4c6486b9 1355 }\r
4c6486b9 1356 }\r
3837e91c 1357\r
3b428ade 1358 Status = ParentFvPpi->GetVolumeInfo (ParentFvPpi, ParentFvHandle, &ParentFvImageInfo);\r
1359 ASSERT_EFI_ERROR (Status);\r
1360 \r
1361 Status = ParentFvPpi->GetFileInfo (ParentFvPpi, ParentFvFileHandle, &FileInfo);\r
1362 ASSERT_EFI_ERROR (Status);\r
1363 \r
4c6486b9 1364 //\r
387208ab 1365 // Install FvInfo(2) Ppi\r
4c6486b9 1366 //\r
387208ab
SZ
1367 PeiServicesInstallFvInfoPpi (\r
1368 &FvHeader->FileSystemGuid,\r
1369 (VOID**) FvHeader,\r
1370 (UINT32) FvHeader->FvLength,\r
1371 &ParentFvImageInfo.FvName,\r
1372 &FileInfo.FileName\r
1373 );\r
1374\r
c7935105 1375 PeiServicesInstallFvInfo2Ppi (\r
3b428ade 1376 &FvHeader->FileSystemGuid,\r
1377 (VOID**) FvHeader,\r
1378 (UINT32) FvHeader->FvLength,\r
97b2c9b5 1379 &ParentFvImageInfo.FvName,\r
c7935105
SZ
1380 &FileInfo.FileName,\r
1381 AuthenticationStatus\r
4c6486b9 1382 );\r
1383\r
1384 //\r
1385 // Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase\r
4c6486b9 1386 //\r
223c22d8 1387 BuildFvHob (\r
3b428ade 1388 (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
1389 FvHeader->FvLength\r
18fcd6a7 1390 );\r
4c6486b9 1391\r
1392 //\r
1393 // Makes the encapsulated volume show up in DXE phase to skip processing of\r
1394 // encapsulated file again.\r
1395 //\r
1396 BuildFv2Hob (\r
3b428ade 1397 (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,\r
1398 FvHeader->FvLength,\r
97b2c9b5 1399 &ParentFvImageInfo.FvName,\r
3b428ade 1400 &FileInfo.FileName\r
4c6486b9 1401 );\r
1402\r
1403 return EFI_SUCCESS;\r
1404}\r
1405\r
3b428ade 1406/**\r
1407 Process a firmware volume and create a volume handle.\r
1408\r
1409 Create a volume handle from the information in the buffer. For\r
1410 memory-mapped firmware volumes, Buffer and BufferSize refer to\r
1411 the start of the firmware volume and the firmware volume size.\r
1412 For non memory-mapped firmware volumes, this points to a\r
1413 buffer which contains the necessary information for creating\r
1414 the firmware volume handle. Normally, these values are derived\r
1415 from the EFI_FIRMWARE_VOLUME_INFO_PPI.\r
1416 \r
1417 \r
1418 @param This Points to this instance of the\r
1419 EFI_PEI_FIRMWARE_VOLUME_PPI.\r
1420 @param Buffer Points to the start of the buffer.\r
1421 @param BufferSize Size of the buffer.\r
1422 @param FvHandle Points to the returned firmware volume\r
1423 handle. The firmware volume handle must\r
1424 be unique within the system. \r
1425\r
1426 @retval EFI_SUCCESS Firmware volume handle created.\r
1427 @retval EFI_VOLUME_CORRUPTED Volume was corrupt.\r
1428\r
1429**/\r
1430EFI_STATUS\r
1431EFIAPI\r
890e5417 1432PeiFfsFvPpiProcessVolume (\r
3b428ade 1433 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,\r
1434 IN VOID *Buffer,\r
1435 IN UINTN BufferSize,\r
1436 OUT EFI_PEI_FV_HANDLE *FvHandle\r
1437 )\r
1438{\r
1439 EFI_STATUS Status;\r
3b428ade 1440 \r
dc6f9b35 1441 ASSERT (FvHandle != NULL);\r
1442 \r
1443 if (Buffer == NULL) {\r
1444 return EFI_VOLUME_CORRUPTED;\r
1445 }\r
3b428ade 1446 \r
1447 //\r
890e5417 1448 // The build-in EFI_PEI_FIRMWARE_VOLUME_PPI for FFS2/FFS3 support memory-mapped\r
3b428ade 1449 // FV image and the handle is pointed to Fv image's buffer.\r
1450 //\r
1451 *FvHandle = (EFI_PEI_FV_HANDLE) Buffer;\r
1452 \r
1453 //\r
1454 // Do verify for given FV buffer.\r
1455 //\r
1456 Status = VerifyFv ((EFI_FIRMWARE_VOLUME_HEADER*) Buffer);\r
1457 if (EFI_ERROR(Status)) {\r
1458 DEBUG ((EFI_D_ERROR, "Fail to verify FV which address is 0x%11p", Buffer));\r
1459 return EFI_VOLUME_CORRUPTED;\r
1460 }\r
1461\r
3b428ade 1462 return EFI_SUCCESS;\r
1463} \r
1464\r
1465/**\r
1466 Finds the next file of the specified type.\r
1467\r
1468 This service enables PEI modules to discover additional firmware files. \r
1469 The FileHandle must be unique within the system.\r
1470\r
1471 @param This Points to this instance of the\r
1472 EFI_PEI_FIRMWARE_VOLUME_PPI.\r
1473 @param SearchType A filter to find only files of this type. Type\r
1474 EFI_FV_FILETYPE_ALL causes no filtering to be\r
1475 done.\r
1476 @param FvHandle Handle of firmware volume in which to\r
1477 search.\r
1478 @param FileHandle Points to the current handle from which to\r
1479 begin searching or NULL to start at the\r
1480 beginning of the firmware volume. Updated\r
1481 upon return to reflect the file found.\r
1482\r
1483 @retval EFI_SUCCESS The file was found.\r
1484 @retval EFI_NOT_FOUND The file was not found. FileHandle contains NULL.\r
1485\r
1486**/\r
1487EFI_STATUS\r
1488EFIAPI\r
890e5417 1489PeiFfsFvPpiFindFileByType (\r
3b428ade 1490 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,\r
1491 IN EFI_FV_FILETYPE SearchType,\r
1492 IN EFI_PEI_FV_HANDLE FvHandle,\r
1493 IN OUT EFI_PEI_FILE_HANDLE *FileHandle\r
1494 )\r
1495{ \r
1496 return FindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL);\r
1497}\r
1498\r
1499/**\r
1500 Find a file within a volume by its name. \r
1501 \r
1502 This service searches for files with a specific name, within\r
1503 either the specified firmware volume or all firmware volumes.\r
1504\r
1505 @param This Points to this instance of the\r
1506 EFI_PEI_FIRMWARE_VOLUME_PPI.\r
1507 @param FileName A pointer to the name of the file to find\r
1508 within the firmware volume.\r
1509 @param FvHandle Upon entry, the pointer to the firmware\r
1510 volume to search or NULL if all firmware\r
1511 volumes should be searched. Upon exit, the\r
1512 actual firmware volume in which the file was\r
1513 found.\r
1514 @param FileHandle Upon exit, points to the found file's\r
1515 handle or NULL if it could not be found.\r
1516\r
1517 @retval EFI_SUCCESS File was found.\r
1518 @retval EFI_NOT_FOUND File was not found.\r
1519 @retval EFI_INVALID_PARAMETER FvHandle or FileHandle or\r
1520 FileName was NULL.\r
1521\r
1522\r
1523**/\r
1524EFI_STATUS\r
1525EFIAPI\r
890e5417 1526PeiFfsFvPpiFindFileByName (\r
3b428ade 1527 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,\r
1528 IN CONST EFI_GUID *FileName,\r
1529 IN EFI_PEI_FV_HANDLE *FvHandle,\r
1530 OUT EFI_PEI_FILE_HANDLE *FileHandle \r
1531 )\r
1532{\r
1533 EFI_STATUS Status;\r
1534 PEI_CORE_INSTANCE *PrivateData;\r
1535 UINTN Index;\r
1536 \r
1537 if ((FvHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {\r
1538 return EFI_INVALID_PARAMETER;\r
1539 }\r
1540 \r
1541 if (*FvHandle != NULL) {\r
1542 Status = FindFileEx (*FvHandle, FileName, 0, FileHandle, NULL);\r
1543 if (Status == EFI_NOT_FOUND) {\r
1544 *FileHandle = NULL;\r
1545 }\r
1546 } else { \r
1547 //\r
1548 // If *FvHandle = NULL, so search all FV for given filename\r
1549 //\r
1550 Status = EFI_NOT_FOUND;\r
1551 \r
1552 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer());\r
1553 for (Index = 0; Index < PrivateData->FvCount; Index ++) {\r
1554 //\r
1555 // Only search the FV which is associated with a EFI_PEI_FIRMWARE_VOLUME_PPI instance.\r
1556 //\r
1557 if (PrivateData->Fv[Index].FvPpi != NULL) {\r
1558 Status = FindFileEx (PrivateData->Fv[Index].FvHandle, FileName, 0, FileHandle, NULL);\r
1559 if (!EFI_ERROR (Status)) {\r
1560 *FvHandle = PrivateData->Fv[Index].FvHandle;\r
1c738c8f 1561 break;\r
3b428ade 1562 }\r
1563 }\r
1564 }\r
1565 }\r
1566 \r
1567 return Status; \r
1568} \r
1569\r
1570/**\r
1571 Returns information about a specific file.\r
1572\r
1573 This function returns information about a specific\r
1574 file, including its file name, type, attributes, starting\r
1575 address and size. \r
1576 \r
1577 @param This Points to this instance of the\r
1578 EFI_PEI_FIRMWARE_VOLUME_PPI.\r
1579 @param FileHandle Handle of the file.\r
1580 @param FileInfo Upon exit, points to the file's\r
1581 information.\r
1582\r
1583 @retval EFI_SUCCESS File information returned.\r
1584 @retval EFI_INVALID_PARAMETER If FileHandle does not\r
1585 represent a valid file.\r
1586 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.\r
1587 \r
1588**/ \r
1589EFI_STATUS\r
1590EFIAPI\r
890e5417 1591PeiFfsFvPpiGetFileInfo (\r
3b428ade 1592 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, \r
1593 IN EFI_PEI_FILE_HANDLE FileHandle, \r
1594 OUT EFI_FV_FILE_INFO *FileInfo\r
1595 )\r
1596{\r
1597 UINT8 FileState;\r
1598 UINT8 ErasePolarity;\r
1599 EFI_FFS_FILE_HEADER *FileHeader;\r
1600 PEI_CORE_FV_HANDLE *CoreFvHandle;\r
890e5417
SZ
1601 PEI_FW_VOL_INSTANCE *FwVolInstance;\r
1602\r
3b428ade 1603 if ((FileHandle == NULL) || (FileInfo == NULL)) {\r
1604 return EFI_INVALID_PARAMETER;\r
1605 }\r
1606\r
1607 //\r
1608 // Retrieve the FirmwareVolume which the file resides in.\r
1609 //\r
1610 CoreFvHandle = FileHandleToVolume (FileHandle);\r
1611 if (CoreFvHandle == NULL) {\r
1612 return EFI_INVALID_PARAMETER;\r
1613 }\r
1614\r
890e5417
SZ
1615 FwVolInstance = PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This);\r
1616\r
4140a663 1617 if ((CoreFvHandle->FvHeader->Attributes & EFI_FVB2_ERASE_POLARITY) != 0) {\r
3b428ade 1618 ErasePolarity = 1;\r
1619 } else {\r
1620 ErasePolarity = 0;\r
1621 }\r
1622\r
1623 //\r
1624 // Get FileState which is the highest bit of the State \r
1625 //\r
1626 FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle);\r
1627\r
1628 switch (FileState) {\r
1629 case EFI_FILE_DATA_VALID:\r
1630 case EFI_FILE_MARKED_FOR_UPDATE:\r
1631 break; \r
1632 default:\r
1633 return EFI_INVALID_PARAMETER;\r
1634 }\r
1635\r
1636 FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;\r
890e5417
SZ
1637 if (IS_FFS_FILE2 (FileHeader)) {\r
1638 ASSERT (FFS_FILE2_SIZE (FileHeader) > 0x00FFFFFF);\r
1639 if (!FwVolInstance->IsFfs3Fv) {\r
1640 DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FileHeader->Name));\r
1641 return EFI_INVALID_PARAMETER;\r
1642 }\r
1643 FileInfo->BufferSize = FFS_FILE2_SIZE (FileHeader) - sizeof (EFI_FFS_FILE_HEADER2);\r
1644 FileInfo->Buffer = (UINT8 *) FileHeader + sizeof (EFI_FFS_FILE_HEADER2);\r
1645 } else {\r
1646 FileInfo->BufferSize = FFS_FILE_SIZE (FileHeader) - sizeof (EFI_FFS_FILE_HEADER);\r
1647 FileInfo->Buffer = (UINT8 *) FileHeader + sizeof (EFI_FFS_FILE_HEADER);\r
1648 }\r
c7935105
SZ
1649 CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID));\r
1650 FileInfo->FileType = FileHeader->Type;\r
1651 FileInfo->FileAttributes = FfsAttributes2FvFileAttributes (FileHeader->Attributes);\r
1652 if ((CoreFvHandle->FvHeader->Attributes & EFI_FVB2_MEMORY_MAPPED) == EFI_FVB2_MEMORY_MAPPED) {\r
1653 FileInfo->FileAttributes |= EFI_FV_FILE_ATTRIB_MEMORY_MAPPED;\r
1654 }\r
1655 return EFI_SUCCESS;\r
1656}\r
1657\r
1658/**\r
1659 Returns information about a specific file.\r
1660\r
1661 This function returns information about a specific\r
1662 file, including its file name, type, attributes, starting\r
1663 address, size and authentication status.\r
1664\r
1665 @param This Points to this instance of the\r
1666 EFI_PEI_FIRMWARE_VOLUME_PPI.\r
1667 @param FileHandle Handle of the file.\r
1668 @param FileInfo Upon exit, points to the file's\r
1669 information.\r
1670\r
1671 @retval EFI_SUCCESS File information returned.\r
1672 @retval EFI_INVALID_PARAMETER If FileHandle does not\r
1673 represent a valid file.\r
1674 @retval EFI_INVALID_PARAMETER If FileInfo is NULL.\r
1675\r
1676**/\r
1677EFI_STATUS\r
1678EFIAPI\r
1679PeiFfsFvPpiGetFileInfo2 (\r
1680 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, \r
1681 IN EFI_PEI_FILE_HANDLE FileHandle, \r
1682 OUT EFI_FV_FILE_INFO2 *FileInfo\r
1683 )\r
1684{\r
1685 EFI_STATUS Status;\r
1686 PEI_CORE_FV_HANDLE *CoreFvHandle;\r
1687\r
1688 if ((FileHandle == NULL) || (FileInfo == NULL)) {\r
1689 return EFI_INVALID_PARAMETER;\r
1690 }\r
1691\r
1692 //\r
1693 // Retrieve the FirmwareVolume which the file resides in.\r
1694 //\r
1695 CoreFvHandle = FileHandleToVolume (FileHandle);\r
1696 if (CoreFvHandle == NULL) {\r
1697 return EFI_INVALID_PARAMETER;\r
1698 }\r
1699\r
1700 Status = PeiFfsFvPpiGetFileInfo (This, FileHandle, (EFI_FV_FILE_INFO *) FileInfo);\r
1701 if (!EFI_ERROR (Status)) {\r
1702 FileInfo->AuthenticationStatus = CoreFvHandle->AuthenticationStatus;\r
1703 }\r
1704\r
1705 return Status;\r
1706}\r
1707\r
3b428ade 1708/**\r
1709 This function returns information about the firmware volume.\r
1710 \r
1711 @param This Points to this instance of the\r
1712 EFI_PEI_FIRMWARE_VOLUME_PPI.\r
1713 @param FvHandle Handle to the firmware handle.\r
1714 @param VolumeInfo Points to the returned firmware volume\r
1715 information.\r
1716\r
1717 @retval EFI_SUCCESS Information returned successfully.\r
1718 @retval EFI_INVALID_PARAMETER FvHandle does not indicate a valid\r
1719 firmware volume or VolumeInfo is NULL.\r
1720\r
1721**/ \r
1722EFI_STATUS\r
1723EFIAPI\r
890e5417 1724PeiFfsFvPpiGetVolumeInfo (\r
3b428ade 1725 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This, \r
1726 IN EFI_PEI_FV_HANDLE FvHandle, \r
1727 OUT EFI_FV_INFO *VolumeInfo\r
1728 )\r
1729{\r
1730 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader;\r
1731 EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;\r
1732\r
8fdcc412 1733 if ((VolumeInfo == NULL) || (FvHandle == NULL)) {\r
3b428ade 1734 return EFI_INVALID_PARAMETER;\r
1735 }\r
1736 \r
1737 //\r
1738 // VolumeHandle may not align at 8 byte, \r
1739 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte. \r
1740 // So, Copy FvHeader into the local FvHeader structure.\r
1741 //\r
1742 CopyMem (&FwVolHeader, FvHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
1743\r
1744 //\r
1745 // Check Fv Image Signature\r
1746 //\r
1747 if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) {\r
1748 return EFI_INVALID_PARAMETER;\r
1749 }\r
1750\r
1751 ZeroMem (VolumeInfo, sizeof (EFI_FV_INFO));\r
1752 VolumeInfo->FvAttributes = FwVolHeader.Attributes;\r
1753 VolumeInfo->FvStart = (VOID *) FvHandle;\r
1754 VolumeInfo->FvSize = FwVolHeader.FvLength;\r
1755 CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof(EFI_GUID));\r
1756\r
1757 if (FwVolHeader.ExtHeaderOffset != 0) {\r
1758 FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FvHandle) + FwVolHeader.ExtHeaderOffset);\r
1759 CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));\r
1760 }\r
1761 \r
1762 return EFI_SUCCESS; \r
1763} \r
1764\r
1765/**\r
1766 Find the next matching section in the firmware file.\r
1767 \r
1768 This service enables PEI modules to discover sections\r
1769 of a given type within a valid file.\r
1770 \r
1771 @param This Points to this instance of the\r
1772 EFI_PEI_FIRMWARE_VOLUME_PPI.\r
1773 @param SearchType A filter to find only sections of this\r
1774 type.\r
1775 @param FileHandle Handle of firmware file in which to\r
1776 search.\r
890e5417 1777 @param SectionData Updated upon return to point to the\r
3b428ade 1778 section found.\r
1779 \r
1780 @retval EFI_SUCCESS Section was found.\r
1781 @retval EFI_NOT_FOUND Section of the specified type was not\r
1782 found. SectionData contains NULL.\r
1783**/\r
1784EFI_STATUS\r
1785EFIAPI\r
890e5417 1786PeiFfsFvPpiFindSectionByType (\r
3b428ade 1787 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,\r
1788 IN EFI_SECTION_TYPE SearchType,\r
1789 IN EFI_PEI_FILE_HANDLE FileHandle,\r
1790 OUT VOID **SectionData\r
1791 )\r
1792{\r
c7935105
SZ
1793 UINT32 AuthenticationStatus;\r
1794 return PeiFfsFvPpiFindSectionByType2 (This, SearchType, 0, FileHandle, SectionData, &AuthenticationStatus);\r
1795}\r
1796\r
1797/**\r
1798 Find the next matching section in the firmware file.\r
1799\r
1800 This service enables PEI modules to discover sections\r
1801 of a given instance and type within a valid file.\r
1802\r
1803 @param This Points to this instance of the\r
1804 EFI_PEI_FIRMWARE_VOLUME_PPI.\r
1805 @param SearchType A filter to find only sections of this\r
1806 type.\r
1807 @param SearchInstance A filter to find the specific instance\r
1808 of sections.\r
1809 @param FileHandle Handle of firmware file in which to\r
1810 search.\r
1811 @param SectionData Updated upon return to point to the\r
1812 section found.\r
1813 @param AuthenticationStatus Updated upon return to point to the\r
1814 authentication status for this section.\r
1815\r
1816 @retval EFI_SUCCESS Section was found.\r
1817 @retval EFI_NOT_FOUND Section of the specified type was not\r
1818 found. SectionData contains NULL.\r
1819**/\r
1820EFI_STATUS\r
1821EFIAPI\r
1822PeiFfsFvPpiFindSectionByType2 (\r
1823 IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,\r
1824 IN EFI_SECTION_TYPE SearchType,\r
1825 IN UINTN SearchInstance,\r
1826 IN EFI_PEI_FILE_HANDLE FileHandle,\r
1827 OUT VOID **SectionData,\r
1828 OUT UINT32 *AuthenticationStatus\r
1829 )\r
1830{\r
1831 EFI_STATUS Status;\r
3b428ade 1832 EFI_FFS_FILE_HEADER *FfsFileHeader;\r
1833 UINT32 FileSize;\r
1834 EFI_COMMON_SECTION_HEADER *Section;\r
890e5417 1835 PEI_FW_VOL_INSTANCE *FwVolInstance;\r
c7935105
SZ
1836 PEI_CORE_FV_HANDLE *CoreFvHandle;\r
1837 UINTN Instance;\r
1838 UINT32 ExtractedAuthenticationStatus;\r
1839\r
1840 if (SectionData == NULL) {\r
1841 return EFI_NOT_FOUND;\r
1842 }\r
890e5417
SZ
1843\r
1844 FwVolInstance = PEI_FW_VOL_INSTANCE_FROM_FV_THIS (This);\r
1845\r
c7935105
SZ
1846 //\r
1847 // Retrieve the FirmwareVolume which the file resides in.\r
1848 //\r
1849 CoreFvHandle = FileHandleToVolume (FileHandle);\r
1850 if (CoreFvHandle == NULL) {\r
1851 return EFI_NOT_FOUND;\r
1852 }\r
1853\r
3b428ade 1854 FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);\r
1855\r
890e5417
SZ
1856 if (IS_FFS_FILE2 (FfsFileHeader)) {\r
1857 ASSERT (FFS_FILE2_SIZE (FfsFileHeader) > 0x00FFFFFF);\r
1858 if (!FwVolInstance->IsFfs3Fv) {\r
1859 DEBUG ((EFI_D_ERROR, "It is a FFS3 formatted file: %g in a non-FFS3 formatted FV.\n", &FfsFileHeader->Name));\r
1860 return EFI_NOT_FOUND;\r
1861 }\r
1862 Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));\r
1863 FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);\r
1864 } else {\r
1865 Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));\r
1866 FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);\r
1867 }\r
3b428ade 1868\r
c7935105
SZ
1869 Instance = SearchInstance + 1;\r
1870 ExtractedAuthenticationStatus = 0;\r
1871 Status = ProcessSection (\r
1872 GetPeiServicesTablePointer (),\r
1873 SearchType,\r
1874 &Instance,\r
1875 Section, \r
1876 FileSize, \r
1877 SectionData,\r
1878 &ExtractedAuthenticationStatus,\r
1879 FwVolInstance->IsFfs3Fv\r
1880 );\r
1881 if (!EFI_ERROR (Status)) {\r
1882 //\r
1883 // Inherit the authentication status.\r
1884 //\r
1885 *AuthenticationStatus = ExtractedAuthenticationStatus | CoreFvHandle->AuthenticationStatus;\r
1886 }\r
1887 return Status;\r
1888}\r
3b428ade 1889\r
1890/**\r
1891 Convert the handle of FV to pointer of corresponding PEI_CORE_FV_HANDLE.\r
1892 \r
1893 @param FvHandle The handle of a FV.\r
1894 \r
1895 @retval NULL if can not find.\r
1896 @return Pointer of corresponding PEI_CORE_FV_HANDLE. \r
1897**/\r
1898PEI_CORE_FV_HANDLE *\r
1899FvHandleToCoreHandle (\r
1900 IN EFI_PEI_FV_HANDLE FvHandle\r
1901 )\r
1902{\r
1903 UINTN Index;\r
1904 PEI_CORE_INSTANCE *PrivateData;\r
1905 \r
1906 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer()); \r
1907 for (Index = 0; Index < PrivateData->FvCount; Index ++) {\r
1908 if (FvHandle == PrivateData->Fv[Index].FvHandle) {\r
1909 return &PrivateData->Fv[Index];\r
1910 }\r
1911 }\r
1912 \r
1913 return NULL;\r
1914} \r
1915\r
1916/**\r
1917 Get instance of PEI_CORE_FV_HANDLE for next volume according to given index.\r
1918 \r
1919 This routine also will install FvInfo ppi for FV hob in PI ways.\r
1920 \r
1921 @param Private Pointer of PEI_CORE_INSTANCE\r
1922 @param Instance The index of FV want to be searched.\r
1923 \r
1924 @return Instance of PEI_CORE_FV_HANDLE.\r
1925**/\r
1926PEI_CORE_FV_HANDLE *\r
1927FindNextCoreFvHandle (\r
1928 IN PEI_CORE_INSTANCE *Private,\r
1929 IN UINTN Instance\r
1930 )\r
1931{\r
1932 UINTN Index;\r
1933 BOOLEAN Match;\r
1934 EFI_HOB_FIRMWARE_VOLUME *FvHob;\r
1935 \r
1936 //\r
1937 // Handle Framework FvHob and Install FvInfo Ppi for it.\r
1938 //\r
1939 if (FeaturePcdGet (PcdFrameworkCompatibilitySupport)) {\r
1940 //\r
1941 // Loop to search the wanted FirmwareVolume which supports FFS\r
1942 //\r
1943 FvHob = (EFI_HOB_FIRMWARE_VOLUME *)GetFirstHob (EFI_HOB_TYPE_FV);\r
1944 while (FvHob != NULL) {\r
20ead725 1945 //\r
1946 // Search whether FvHob has been installed into PeiCore's FV database.\r
1947 // If found, no need install new FvInfoPpi for it.\r
1948 //\r
3b428ade 1949 for (Index = 0, Match = FALSE; Index < Private->FvCount; Index++) {\r
1950 if ((EFI_PEI_FV_HANDLE)(UINTN)FvHob->BaseAddress == Private->Fv[Index].FvHeader) {\r
1951 Match = TRUE;\r
1952 break;\r
1953 }\r
1954 }\r
20ead725 1955 \r
3b428ade 1956 //\r
20ead725 1957 // Search whether FvHob has been cached into PeiCore's Unknown FV database.\r
1958 // If found, no need install new FvInfoPpi for it.\r
1959 //\r
1960 if (!Match) {\r
1961 for (Index = 0; Index < Private->UnknownFvInfoCount; Index ++) {\r
1962 if ((UINTN)FvHob->BaseAddress == (UINTN)Private->UnknownFvInfo[Index].FvInfo) {\r
1963 Match = TRUE;\r
1964 break;\r
1965 }\r
1966 }\r
1967 }\r
1968\r
1969 //\r
1970 // If the Fv in FvHob has not been installed into PeiCore's FV database and has\r
1971 // not been cached into PeiCore's Unknown FV database, install a new FvInfoPpi\r
1972 // for it then PeiCore will dispatch it in callback of FvInfoPpi.\r
3b428ade 1973 //\r
1974 if (!Match) {\r
1975 PeiServicesInstallFvInfoPpi (\r
1976 &(((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHob->BaseAddress)->FileSystemGuid),\r
1977 (VOID *)(UINTN)FvHob->BaseAddress,\r
1978 (UINT32)FvHob->Length,\r
1979 NULL,\r
1980 NULL\r
1981 );\r
1982 }\r
20ead725 1983 \r
3b428ade 1984 FvHob = (EFI_HOB_FIRMWARE_VOLUME *)GetNextHob (EFI_HOB_TYPE_FV, (VOID *)((UINTN)FvHob + FvHob->Header.HobLength)); \r
1985 }\r
1986 }\r
1987\r
fe781940 1988 ASSERT (Private->FvCount <= PcdGet32 (PcdPeiCoreMaxFvSupported));\r
3b428ade 1989 if (Instance >= Private->FvCount) {\r
1990 return NULL;\r
1991 }\r
4c6486b9 1992\r
3b428ade 1993 return &Private->Fv[Instance];\r
1994} \r
8e0e40ed 1995\r
1996/**\r
1997 After PeiCore image is shadowed into permanent memory, all build-in FvPpi should\r
1998 be re-installed with the instance in permanent memory and all cached FvPpi pointers in \r
1999 PrivateData->Fv[] array should be fixed up to be pointed to the one in permenant\r
2000 memory.\r
2001 \r
2002 @param PrivateData Pointer to PEI_CORE_INSTANCE.\r
2003**/ \r
2004VOID\r
2005PeiReinitializeFv (\r
2006 IN PEI_CORE_INSTANCE *PrivateData\r
2007 )\r
2008{\r
890e5417 2009 VOID *OldFfsFvPpi;\r
7ec93917 2010 EFI_PEI_PPI_DESCRIPTOR *OldDescriptor;\r
2011 UINTN Index;\r
2012 EFI_STATUS Status;\r
2013\r
2014 //\r
2015 // Locate old build-in Ffs2 EFI_PEI_FIRMWARE_VOLUME_PPI which\r
2016 // in flash.\r
2017 //\r
2018 Status = PeiServicesLocatePpi (\r
2019 &gEfiFirmwareFileSystem2Guid,\r
2020 0,\r
2021 &OldDescriptor,\r
890e5417 2022 &OldFfsFvPpi\r
7ec93917 2023 );\r
2024 ASSERT_EFI_ERROR (Status);\r
2025\r
2026 //\r
2027 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs2\r
2028 // which is shadowed from flash to permanent memory within PeiCore image.\r
2029 //\r
2030 Status = PeiServicesReInstallPpi (OldDescriptor, &mPeiFfs2FvPpiList);\r
2031 ASSERT_EFI_ERROR (Status);\r
890e5417 2032\r
7ec93917 2033 //\r
2034 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.\r
2035 //\r
fe781940 2036 for (Index = 0; Index < PcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) {\r
890e5417
SZ
2037 if (PrivateData->Fv[Index].FvPpi == OldFfsFvPpi) {\r
2038 PrivateData->Fv[Index].FvPpi = &mPeiFfs2FwVol.Fv;\r
7ec93917 2039 }\r
2040 }\r
890e5417
SZ
2041\r
2042 //\r
2043 // Locate old build-in Ffs3 EFI_PEI_FIRMWARE_VOLUME_PPI which\r
2044 // in flash.\r
2045 //\r
2046 Status = PeiServicesLocatePpi (\r
2047 &gEfiFirmwareFileSystem3Guid,\r
2048 0,\r
2049 &OldDescriptor,\r
2050 &OldFfsFvPpi\r
2051 );\r
2052 ASSERT_EFI_ERROR (Status);\r
2053\r
2054 //\r
2055 // Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs3\r
2056 // which is shadowed from flash to permanent memory within PeiCore image.\r
2057 //\r
2058 Status = PeiServicesReInstallPpi (OldDescriptor, &mPeiFfs3FvPpiList);\r
2059 ASSERT_EFI_ERROR (Status);\r
2060\r
2061 //\r
2062 // Fixup all FvPpi pointers for the implementation in flash to permanent memory.\r
2063 //\r
fe781940 2064 for (Index = 0; Index < PcdGet32 (PcdPeiCoreMaxFvSupported); Index ++) {\r
890e5417
SZ
2065 if (PrivateData->Fv[Index].FvPpi == OldFfsFvPpi) {\r
2066 PrivateData->Fv[Index].FvPpi = &mPeiFfs3FwVol.Fv;\r
2067 }\r
2068 }\r
2069}\r
8e0e40ed 2070\r
f3358329 2071/**\r
2072 Report the information for a new discoveried FV in unknown third-party format.\r
2073 \r
2074 If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for third-party FV format, but\r
c7935105 2075 the FV in this format has been discoveried, then this FV's information will be cached into\r
f3358329 2076 PEI_CORE_INSTANCE's UnknownFvInfo array.\r
2077 Also a notification would be installed for unknown third-party FV format guid, if EFI_PEI_FIRMWARE_VOLUME_PPI\r
2078 is installed later by platform's PEIM, the original unknown third-party FV will be processed by\r
2079 using new installed EFI_PEI_FIRMWARE_VOLUME_PPI.\r
2080 \r
2081 @param PrivateData Point to instance of PEI_CORE_INSTANCE\r
c7935105 2082 @param FvInfo2Ppi Point to FvInfo2 PPI.\r
f3358329 2083 \r
2084 @retval EFI_OUT_OF_RESOURCES The FV info array in PEI_CORE_INSTANCE has no more spaces.\r
2085 @retval EFI_SUCCESS Success to add the information for unknown FV.\r
2086**/\r
2087EFI_STATUS\r
2088AddUnknownFormatFvInfo (\r
c7935105
SZ
2089 IN PEI_CORE_INSTANCE *PrivateData,\r
2090 IN EFI_PEI_FIRMWARE_VOLUME_INFO2_PPI *FvInfo2Ppi\r
f3358329 2091 )\r
2092{\r
2093 PEI_CORE_UNKNOW_FORMAT_FV_INFO *NewUnknownFv;\r
2094 \r
fe781940 2095 if (PrivateData->UnknownFvInfoCount + 1 >= PcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
f3358329 2096 return EFI_OUT_OF_RESOURCES;\r
2097 }\r
2098 \r
2099 NewUnknownFv = &PrivateData->UnknownFvInfo[PrivateData->UnknownFvInfoCount];\r
2100 PrivateData->UnknownFvInfoCount ++;\r
2101 \r
c7935105
SZ
2102 CopyGuid (&NewUnknownFv->FvFormat, &FvInfo2Ppi->FvFormat);\r
2103 NewUnknownFv->FvInfo = FvInfo2Ppi->FvInfo;\r
2104 NewUnknownFv->FvInfoSize = FvInfo2Ppi->FvInfoSize;\r
2105 NewUnknownFv->AuthenticationStatus = FvInfo2Ppi->AuthenticationStatus;\r
f3358329 2106 NewUnknownFv->NotifyDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);\r
2107 NewUnknownFv->NotifyDescriptor.Guid = &NewUnknownFv->FvFormat;\r
2108 NewUnknownFv->NotifyDescriptor.Notify = ThirdPartyFvPpiNotifyCallback;\r
2109 \r
2110 PeiServicesNotifyPpi (&NewUnknownFv->NotifyDescriptor);\r
2111 return EFI_SUCCESS;\r
2112}\r
2113\r
2114/**\r
2115 Find the FV information according to third-party FV format guid.\r
2116 \r
2117 This routine also will remove the FV information found by given FV format guid from\r
2118 PrivateData->UnknownFvInfo[].\r
2119 \r
2120 @param PrivateData Point to instance of PEI_CORE_INSTANCE\r
2121 @param Format Point to given FV format guid\r
2122 @param FvInfo On return, the pointer of FV information buffer\r
2123 @param FvInfoSize On return, the size of FV information buffer.\r
c7935105 2124 @param AuthenticationStatus On return, the authentication status of FV information buffer.\r
f3358329 2125 \r
2126 @retval EFI_NOT_FOUND The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI\r
2127 @retval EFI_SUCCESS Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI.\r
2128**/\r
2129EFI_STATUS\r
2130FindUnknownFormatFvInfo (\r
2131 IN PEI_CORE_INSTANCE *PrivateData,\r
2132 IN EFI_GUID *Format,\r
2133 OUT VOID **FvInfo,\r
c7935105
SZ
2134 OUT UINT32 *FvInfoSize,\r
2135 OUT UINT32 *AuthenticationStatus\r
f3358329 2136 )\r
2137{\r
2138 UINTN Index;\r
2139 UINTN Index2;\r
2140\r
2141 Index = 0;\r
2142 for (; Index < PrivateData->UnknownFvInfoCount; Index ++) {\r
2143 if (CompareGuid (Format, &PrivateData->UnknownFvInfo[Index].FvFormat)) {\r
2144 break;\r
2145 }\r
2146 }\r
2147 \r
2148 if (Index == PrivateData->UnknownFvInfoCount) {\r
2149 return EFI_NOT_FOUND;\r
2150 }\r
2151 \r
2152 *FvInfo = PrivateData->UnknownFvInfo[Index].FvInfo;\r
2153 *FvInfoSize = PrivateData->UnknownFvInfo[Index].FvInfoSize;\r
c7935105 2154 *AuthenticationStatus = PrivateData->UnknownFvInfo[Index].AuthenticationStatus;\r
f3358329 2155 \r
2156 //\r
2157 // Remove an entry from UnknownFvInfo array.\r
2158 //\r
2159 Index2 = Index + 1;\r
2160 for (;Index2 < PrivateData->UnknownFvInfoCount; Index2 ++, Index ++) {\r
2161 CopyMem (&PrivateData->UnknownFvInfo[Index], &PrivateData->UnknownFvInfo[Index2], sizeof (PEI_CORE_UNKNOW_FORMAT_FV_INFO));\r
2162 }\r
2163 PrivateData->UnknownFvInfoCount --;\r
2164 return EFI_SUCCESS;\r
2165} \r
2166\r
2167/**\r
2168 Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI.\r
2169 \r
2170 When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format, this \r
2171 routine is called to process all discoveried FVs in this format.\r
2172 \r
2173 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
2174 @param NotifyDescriptor Address of the notification descriptor data structure.\r
2175 @param Ppi Address of the PPI that was installed.\r
2176 \r
2177 @retval EFI_SUCCESS The notification callback is processed correctly.\r
2178**/\r
2179EFI_STATUS\r
2180EFIAPI\r
2181ThirdPartyFvPpiNotifyCallback (\r
2182 IN EFI_PEI_SERVICES **PeiServices,\r
2183 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
2184 IN VOID *Ppi\r
2185 )\r
2186{\r
2187 PEI_CORE_INSTANCE *PrivateData;\r
2188 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r
2189 VOID *FvInfo;\r
2190 UINT32 FvInfoSize;\r
c7935105 2191 UINT32 AuthenticationStatus;\r
f3358329 2192 EFI_STATUS Status;\r
2193 EFI_PEI_FV_HANDLE FvHandle;\r
2194 BOOLEAN IsProcessed;\r
2195 UINTN FvIndex;\r
2196 EFI_PEI_FILE_HANDLE FileHandle;\r
2197 VOID *DepexData; \r
2198 \r
2199 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
2200 FvPpi = (EFI_PEI_FIRMWARE_VOLUME_PPI*) Ppi;\r
2201 \r
2202 do {\r
c7935105 2203 Status = FindUnknownFormatFvInfo (PrivateData, NotifyDescriptor->Guid, &FvInfo, &FvInfoSize, &AuthenticationStatus);\r
f3358329 2204 if (EFI_ERROR (Status)) {\r
2205 return EFI_SUCCESS;\r
2206 }\r
2207 \r
2208 //\r
2209 // Process new found FV and get FV handle.\r
2210 //\r
2211 Status = FvPpi->ProcessVolume (FvPpi, FvInfo, FvInfoSize, &FvHandle);\r
2212 if (EFI_ERROR (Status)) {\r
2213 DEBUG ((EFI_D_ERROR, "Fail to process the FV 0x%p, FV may be corrupted!\n", FvInfo));\r
2214 continue;\r
2215 }\r
2216\r
2217 //\r
2218 // Check whether the FV has already been processed.\r
2219 //\r
2220 IsProcessed = FALSE;\r
2221 for (FvIndex = 0; FvIndex < PrivateData->FvCount; FvIndex ++) {\r
2222 if (PrivateData->Fv[FvIndex].FvHandle == FvHandle) {\r
2223 DEBUG ((EFI_D_INFO, "The Fv %p has already been processed!\n", FvInfo));\r
2224 IsProcessed = TRUE;\r
2225 break;\r
2226 }\r
2227 }\r
2228 \r
2229 if (IsProcessed) {\r
2230 continue;\r
2231 }\r
2232 \r
fe781940
SZ
2233 if (PrivateData->FvCount >= PcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
2234 DEBUG ((EFI_D_ERROR, "The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei", PrivateData->FvCount + 1, PcdGet32 (PcdPeiCoreMaxFvSupported)));\r
ccf0f68d 2235 DEBUG ((EFI_D_ERROR, "PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC"));\r
2236 ASSERT (FALSE);\r
2237 }\r
2238 \r
f3358329 2239 //\r
2240 // Update internal PEI_CORE_FV array.\r
2241 //\r
2242 PrivateData->Fv[PrivateData->FvCount].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*) FvInfo;\r
2243 PrivateData->Fv[PrivateData->FvCount].FvPpi = FvPpi;\r
2244 PrivateData->Fv[PrivateData->FvCount].FvHandle = FvHandle;\r
c7935105 2245 PrivateData->Fv[PrivateData->FvCount].AuthenticationStatus = AuthenticationStatus;\r
f3358329 2246 DEBUG ((\r
2247 EFI_D_INFO, \r
2248 "The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p\n", \r
2249 (UINT32) PrivateData->FvCount, \r
2250 (VOID *) FvInfo, \r
2251 FvInfoSize,\r
2252 FvHandle\r
2253 )); \r
2254 PrivateData->FvCount ++;\r
2255\r
2256 //\r
2257 // Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE \r
2258 //\r
2259 FileHandle = NULL;\r
2260 do {\r
2261 Status = FvPpi->FindFileByType (\r
2262 FvPpi,\r
2263 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,\r
2264 FvHandle,\r
2265 &FileHandle\r
2266 );\r
2267 if (!EFI_ERROR (Status)) {\r
2268 Status = FvPpi->FindSectionByType (\r
2269 FvPpi,\r
2270 EFI_SECTION_PEI_DEPEX,\r
2271 FileHandle,\r
2272 (VOID**)&DepexData\r
2273 );\r
2274 if (!EFI_ERROR (Status)) {\r
2275 if (!PeimDispatchReadiness (PeiServices, DepexData)) {\r
2276 //\r
2277 // Dependency is not satisfied.\r
2278 //\r
2279 continue;\r
2280 }\r
2281 }\r
2282 \r
2283 DEBUG ((EFI_D_INFO, "Found firmware volume Image File %p in FV[%d] %p\n", FileHandle, PrivateData->FvCount - 1, FvHandle));\r
c7935105 2284 ProcessFvFile (PrivateData, &PrivateData->Fv[PrivateData->FvCount - 1], FileHandle);\r
f3358329 2285 }\r
2286 } while (FileHandle != NULL);\r
2287 } while (TRUE);\r
f3358329 2288}\r