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