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