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