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