]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Pei/FwVol/FwVol.c
remove a redefinition to pass ICC build
[mirror_edk2.git] / MdeModulePkg / Core / Pei / FwVol / FwVol.c
CommitLineData
615c6dd0 1/** @file\r
b1f6a7c6 2 Pei Core Firmware File System service routines.\r
3 \r
b0d803fe 4Copyright (c) 2006 - 2007, Intel Corporation \r
192f6d4c 5All rights reserved. This program and the accompanying materials \r
6are licensed and made available under the terms and conditions of the BSD License \r
7which accompanies this distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php \r
9 \r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
12\r
13Module Name:\r
14\r
15 FwVol.c\r
16\r
17Abstract:\r
18\r
b1f6a7c6 19 \r
192f6d4c 20\r
615c6dd0 21**/\r
192f6d4c 22\r
192f6d4c 23#include <PeiMain.h>\r
24\r
b0d803fe 25STATIC EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList = {\r
26 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
27 &gEfiPeiFirmwareVolumeInfoPpiGuid,\r
28 FirmwareVolmeInfoPpiNotifyCallback \r
29};\r
30\r
31\r
32#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \\r
192f6d4c 33 (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))\r
34\r
b1f6a7c6 35/**\r
192f6d4c 36 Returns the highest bit set of the State field\r
37\r
192f6d4c 38\r
b1f6a7c6 39 @param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY\r
40 in the Attributes field.\r
41 @param FfsHeader Pointer to FFS File Header.\r
192f6d4c 42\r
b1f6a7c6 43 @return Returns the highest bit in the State field\r
192f6d4c 44\r
b1f6a7c6 45**/\r
46EFI_FFS_FILE_STATE\r
47GetFileState(\r
48 IN UINT8 ErasePolarity,\r
49 IN EFI_FFS_FILE_HEADER *FfsHeader\r
50 )\r
192f6d4c 51{\r
52 EFI_FFS_FILE_STATE FileState;\r
53 EFI_FFS_FILE_STATE HighestBit;\r
54\r
55 FileState = FfsHeader->State;\r
56\r
57 if (ErasePolarity != 0) {\r
58 FileState = (EFI_FFS_FILE_STATE)~FileState;\r
59 }\r
60\r
61 HighestBit = 0x80;\r
62 while (HighestBit != 0 && (HighestBit & FileState) == 0) {\r
63 HighestBit >>= 1;\r
64 }\r
65\r
66 return HighestBit;\r
67} \r
68\r
b1f6a7c6 69/**\r
70 Calculates the checksum of the header of a file.\r
71\r
72 @param FileHeader Pointer to FFS File Header.\r
73\r
74 @return Checksum of the header.\r
75 The header is zero byte checksum.\r
76 Zero means the header is good.\r
77 Non-zero means the header is bad.\r
78**/\r
192f6d4c 79UINT8\r
80CalculateHeaderChecksum (\r
81 IN EFI_FFS_FILE_HEADER *FileHeader\r
82 )\r
192f6d4c 83{\r
b1f6a7c6 84 UINT8 *Ptr;\r
192f6d4c 85 UINTN Index;\r
86 UINT8 Sum;\r
87 \r
88 Sum = 0;\r
b1f6a7c6 89 Ptr = (UINT8 *)FileHeader;\r
192f6d4c 90\r
91 for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) {\r
b1f6a7c6 92 Sum = (UINT8)(Sum + Ptr[Index]);\r
93 Sum = (UINT8)(Sum + Ptr[Index+1]);\r
94 Sum = (UINT8)(Sum + Ptr[Index+2]);\r
95 Sum = (UINT8)(Sum + Ptr[Index+3]);\r
192f6d4c 96 }\r
97\r
98 for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {\r
b1f6a7c6 99 Sum = (UINT8)(Sum + Ptr[Index]);\r
192f6d4c 100 }\r
101 \r
102 //\r
103 // State field (since this indicates the different state of file). \r
104 //\r
105 Sum = (UINT8)(Sum - FileHeader->State);\r
106 //\r
107 // Checksum field of the file is not part of the header checksum.\r
108 //\r
109 Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);\r
110\r
111 return Sum;\r
112}\r
113\r
b1f6a7c6 114/**\r
115 Find FV handler according some FileHandle in that FV.\r
116\r
117 @param FileHandle Handle of file image\r
118 @param VolumeHandle Handle of FV\r
119\r
120 @return EDES_TODO: Add description for return value\r
121\r
122**/\r
b0d803fe 123BOOLEAN\r
124EFIAPI\r
125PeiFileHandleToVolume (\r
126 IN EFI_PEI_FILE_HANDLE FileHandle,\r
127 OUT EFI_PEI_FV_HANDLE *VolumeHandle\r
128 )\r
129{\r
130 UINTN Index;\r
131 PEI_CORE_INSTANCE *PrivateData;\r
132 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
133\r
134 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());\r
135 for (Index = 0; Index < PrivateData->FvCount; Index++) {\r
136 FwVolHeader = PrivateData->Fv[Index].FvHeader;\r
67a58d0f 137 if (((UINT64) (UINTN) FileHandle > (UINT64) (UINTN) FwVolHeader ) && \\r
138 ((UINT64) (UINTN) FileHandle <= ((UINT64) (UINTN) FwVolHeader + FwVolHeader->FvLength - 1))) {\r
b0d803fe 139 *VolumeHandle = (EFI_PEI_FV_HANDLE)FwVolHeader;\r
140 return TRUE;\r
141 }\r
142 }\r
143 return FALSE;\r
144}\r
145\r
b1f6a7c6 146/**\r
147 Given the input file pointer, search for the next matching file in the\r
148 FFS volume as defined by SearchType. The search starts from FileHeader inside\r
149 the Firmware Volume defined by FwVolHeader.\r
150\r
151\r
152 @param FvHandle Pointer to the FV header of the volume to search\r
153 @param FileName File name\r
154 @param SearchType Filter to find only files of this type.\r
155 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r
156 @param FileHandle This parameter must point to a valid FFS volume.\r
157 @param AprioriFile Pointer to AprioriFile image in this FV if has\r
b0d803fe 158\r
b1f6a7c6 159 @return EFI_NOT_FOUND No files matching the search criteria were found\r
160 @retval EFI_SUCCESS Success to search given file\r
161\r
162**/\r
192f6d4c 163EFI_STATUS\r
b0d803fe 164PeiFindFileEx (\r
165 IN CONST EFI_PEI_FV_HANDLE FvHandle,\r
166 IN CONST EFI_GUID *FileName, OPTIONAL\r
167 IN EFI_FV_FILETYPE SearchType,\r
168 IN OUT EFI_PEI_FILE_HANDLE *FileHandle,\r
169 IN OUT EFI_PEI_FV_HANDLE *AprioriFile OPTIONAL\r
192f6d4c 170 )\r
192f6d4c 171{\r
b0d803fe 172 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;\r
173 EFI_FFS_FILE_HEADER **FileHeader;\r
174 EFI_FFS_FILE_HEADER *FfsFileHeader;\r
175 EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;\r
176 UINT32 FileLength;\r
177 UINT32 FileOccupiedSize;\r
178 UINT32 FileOffset;\r
179 UINT64 FvLength;\r
180 UINT8 ErasePolarity;\r
181 UINT8 FileState;\r
182\r
183 FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvHandle;\r
184 FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle;\r
192f6d4c 185\r
186 FvLength = FwVolHeader->FvLength;\r
797a9d67 187 if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {\r
192f6d4c 188 ErasePolarity = 1;\r
189 } else {\r
190 ErasePolarity = 0;\r
191 }\r
192 \r
193 //\r
b0d803fe 194 // If FileHeader is not specified (NULL) or FileName is not NULL,\r
195 // start with the first file in the firmware volume. Otherwise,\r
196 // start from the FileHeader.\r
192f6d4c 197 //\r
b0d803fe 198 if ((*FileHeader == NULL) || (FileName != NULL)) {\r
192f6d4c 199 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);\r
b0d803fe 200 if (FwVolHeader->ExtHeaderOffset != 0) {\r
201 FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);\r
202 FfsFileHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FwVolExHeaderInfo) + FwVolExHeaderInfo->ExtHeaderSize);\r
203 }\r
192f6d4c 204 } else {\r
205 //\r
206 // Length is 24 bits wide so mask upper 8 bits\r
207 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.\r
208 //\r
209 FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;\r
b0d803fe 210 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);\r
192f6d4c 211 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);\r
212 }\r
e98cd821 213 \r
192f6d4c 214 FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);\r
215 ASSERT (FileOffset <= 0xFFFFFFFF);\r
e98cd821 216\r
b0d803fe 217 while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {\r
192f6d4c 218 //\r
219 // Get FileState which is the highest bit of the State \r
220 //\r
221 FileState = GetFileState (ErasePolarity, FfsFileHeader);\r
192f6d4c 222 switch (FileState) {\r
223\r
224 case EFI_FILE_HEADER_INVALID:\r
225 FileOffset += sizeof(EFI_FFS_FILE_HEADER);\r
226 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));\r
227 break;\r
228 \r
229 case EFI_FILE_DATA_VALID:\r
230 case EFI_FILE_MARKED_FOR_UPDATE:\r
b0d803fe 231 if (CalculateHeaderChecksum (FfsFileHeader) != 0) {\r
192f6d4c 232 ASSERT (FALSE);\r
e98cd821 233 *FileHeader = NULL;\r
192f6d4c 234 return EFI_NOT_FOUND;\r
235 }\r
b0d803fe 236\r
237 FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
238 FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);\r
239\r
240 if (FileName != NULL) {\r
241 if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) {\r
242 *FileHeader = FfsFileHeader;\r
243 return EFI_SUCCESS;\r
244 }\r
245 } else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) {\r
246 if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) || \r
288f9b38
LG
247 (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER) ||\r
248 (FfsFileHeader->Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE)) { \r
b0d803fe 249 \r
250 *FileHeader = FfsFileHeader;\r
251 return EFI_SUCCESS;\r
252 } else if (AprioriFile != NULL) {\r
253 if (FfsFileHeader->Type == EFI_FV_FILETYPE_FREEFORM) {\r
254 if (CompareGuid (&FfsFileHeader->Name, &gPeiAprioriFileNameGuid)) {\r
255 *AprioriFile = FfsFileHeader;\r
256 } \r
257 } \r
258 }\r
7e181f2f 259 } else if (((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) && \r
260 (FfsFileHeader->Type != EFI_FV_FILETYPE_FFS_PAD)) { \r
b0d803fe 261 *FileHeader = FfsFileHeader;\r
262 return EFI_SUCCESS;\r
263 }\r
264\r
265 FileOffset += FileOccupiedSize; \r
266 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
192f6d4c 267 break;\r
268 \r
269 case EFI_FILE_DELETED:\r
270 FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
b0d803fe 271 FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);\r
192f6d4c 272 FileOffset += FileOccupiedSize;\r
273 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);\r
274 break;\r
275\r
276 default:\r
e98cd821 277 *FileHeader = NULL;\r
192f6d4c 278 return EFI_NOT_FOUND;\r
192f6d4c 279 } \r
280 }\r
e98cd821
LG
281 \r
282 *FileHeader = NULL;\r
192f6d4c 283 return EFI_NOT_FOUND; \r
284}\r
285\r
b1f6a7c6 286/**\r
287\r
288 Initialize PeiCore Fv List.\r
289\r
290\r
291 @param PrivateData - Pointer to PEI_CORE_INSTANCE.\r
292 @param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.\r
293\r
294 @return NONE\r
295\r
296**/\r
b0d803fe 297VOID \r
298PeiInitializeFv (\r
299 IN PEI_CORE_INSTANCE *PrivateData,\r
300 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData\r
301 )\r
b0d803fe 302{\r
303 EFI_STATUS Status;\r
304 //\r
305 // The BFV must be the first entry. The Core FV support is stateless \r
306 // The AllFV list has a single entry per FV in PEI. \r
307 // The Fv list only includes FV that PEIMs will be dispatched from and\r
308 // its File System Format is PI 1.0 definition.\r
309 //\r
310 PrivateData->FvCount = 1;\r
311 PrivateData->Fv[0].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;\r
312\r
313 PrivateData->AllFvCount = 1;\r
314 PrivateData->AllFv[0] = (EFI_PEI_FV_HANDLE)PrivateData->Fv[0].FvHeader;\r
315\r
316\r
317 //\r
318 // Post a call-back for the FvInfoPPI services to expose\r
319 // additional Fvs to PeiCore.\r
320 //\r
321 Status = PeiServicesNotifyPpi (&mNotifyOnFvInfoList);\r
322 ASSERT_EFI_ERROR (Status);\r
323\r
324}\r
325\r
b1f6a7c6 326/**\r
327 Process Firmware Volum Information once FvInfoPPI install.\r
328\r
329\r
330 @param PeiServices - General purpose services available to every PEIM.\r
331 @param NotifyDescriptor EDES_TODO: Add parameter description\r
332 @param Ppi EDES_TODO: Add parameter description\r
333\r
334 @retval EFI_SUCCESS if the interface could be successfully installed\r
335\r
336**/\r
b0d803fe 337EFI_STATUS\r
338EFIAPI\r
339FirmwareVolmeInfoPpiNotifyCallback (\r
340 IN EFI_PEI_SERVICES **PeiServices,\r
341 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
342 IN VOID *Ppi\r
343 )\r
b0d803fe 344{\r
345 UINT8 FvCount;\r
346 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;\r
347 PEI_CORE_INSTANCE *PrivateData;\r
288f9b38
LG
348 EFI_PEI_FILE_HANDLE FileHandle;\r
349 VOID *DepexData;\r
350 UINT32 AuthenticationStatus;\r
351 EFI_STATUS Status;\r
b0d803fe 352 \r
288f9b38
LG
353 FileHandle = NULL;\r
354 DepexData = NULL;\r
355 Status = EFI_SUCCESS;\r
356 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
b0d803fe 357\r
177aabe6 358 if (PrivateData->FvCount >= FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
b0d803fe 359 ASSERT (FALSE);\r
360 }\r
361\r
362 Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;\r
363\r
288f9b38
LG
364 if (CompareGuid (&Fv->FvFormat, &gEfiFirmwareFileSystem2Guid)) {\r
365 for (FvCount = 0; FvCount < PrivateData->FvCount; FvCount ++) {\r
366 if ((UINTN)PrivateData->Fv[FvCount].FvHeader == (UINTN)Fv->FvInfo) {\r
367 return EFI_SUCCESS;\r
368 }\r
369 }\r
b0d803fe 370 PrivateData->Fv[PrivateData->FvCount++].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Fv->FvInfo;\r
b0d803fe 371\r
288f9b38
LG
372 //\r
373 // Only add FileSystem2 Fv to the All list\r
374 //\r
375 PrivateData->AllFv[PrivateData->AllFvCount++] = (EFI_PEI_FV_HANDLE)Fv->FvInfo;\r
376 \r
377 DEBUG ((EFI_D_INFO, "The %dth FvImage start address is 0x%10p and size is 0x%08x\n", PrivateData->AllFvCount, (VOID *) Fv->FvInfo, Fv->FvInfoSize));\r
378 //\r
379 // Preprocess all FV type files in this new FileSystem2 Fv image\r
380 //\r
381 do {\r
382 Status = PeiFindFileEx (\r
383 (EFI_PEI_FV_HANDLE)Fv->FvInfo, \r
384 NULL, \r
385 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, \r
386 &FileHandle, \r
387 NULL\r
388 );\r
389 if (!EFI_ERROR (Status)) {\r
390 Status = PeiFfsFindSectionData (\r
391 (CONST EFI_PEI_SERVICES **) PeiServices,\r
392 EFI_SECTION_PEI_DEPEX,\r
393 FileHandle, \r
394 (VOID **)&DepexData\r
395 );\r
396 if (!EFI_ERROR (Status)) {\r
397 if (!PeimDispatchReadiness (PeiServices, DepexData)) {\r
398 //\r
399 // Dependency is not satisfied.\r
400 //\r
401 continue;\r
402 }\r
403 }\r
404 //\r
405 // Process FvFile to install FvInfo ppi and build FvHob\r
406 // \r
407 ProcessFvFile (PeiServices, FileHandle, &AuthenticationStatus);\r
408 }\r
409 } while (FileHandle != NULL);\r
410 }\r
b0d803fe 411\r
412 return EFI_SUCCESS;\r
413}\r
414\r
b1f6a7c6 415/**\r
416\r
417 Go through the file to search SectionType section,\r
418 when meeting an encapsuled section.\r
419\r
420\r
421 @param PeiServices - General purpose services available to every PEIM.\r
422 SearchType - Filter to find only section of this type.\r
423 @param SectionType EDES_TODO: Add parameter description\r
424 @param Section - From where to search.\r
425 @param SectionSize - The file size to search.\r
426 @param OutputBuffer - Pointer to the section to search.\r
427\r
428 @return EFI_STATUS\r
429\r
430**/\r
b0d803fe 431EFI_STATUS\r
432PeiFfsProcessSection (\r
433 IN CONST EFI_PEI_SERVICES **PeiServices,\r
434 IN EFI_SECTION_TYPE SectionType,\r
435 IN EFI_COMMON_SECTION_HEADER *Section,\r
436 IN UINTN SectionSize,\r
288f9b38 437 OUT VOID **OutputBuffer\r
b0d803fe 438 )\r
b0d803fe 439{\r
440 EFI_STATUS Status;\r
441 UINT32 SectionLength;\r
442 UINT32 ParsedLength;\r
b0d803fe 443 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *GuidSectionPpi;\r
b0d803fe 444 EFI_PEI_DECOMPRESS_PPI *DecompressPpi;\r
445 VOID *PpiOutput;\r
446 UINTN PpiOutputSize;\r
288f9b38
LG
447 UINTN Index;\r
448 UINT32 Authentication;\r
449 PEI_CORE_INSTANCE *PrivateData;\r
b0d803fe 450\r
288f9b38 451 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
b0d803fe 452 *OutputBuffer = NULL;\r
288f9b38
LG
453 ParsedLength = 0;\r
454 Index = 0;\r
455 Status = EFI_NOT_FOUND;\r
456 PpiOutput = NULL;\r
457 PpiOutputSize = 0;\r
b0d803fe 458 while (ParsedLength < SectionSize) {\r
459 if (Section->Type == SectionType) {\r
460 *OutputBuffer = (VOID *)(Section + 1);\r
461 return EFI_SUCCESS;\r
288f9b38
LG
462 } else if ((Section->Type == EFI_SECTION_GUID_DEFINED) || (Section->Type == EFI_SECTION_COMPRESSION)) {\r
463 //\r
464 // Check the encapsulated section is extracted into the cache data.\r
465 //\r
466 for (Index = 0; Index < PrivateData->CacheSection.AllSectionCount; Index ++) {\r
467 if (Section == PrivateData->CacheSection.Section[Index]) {\r
468 PpiOutput = PrivateData->CacheSection.SectionData[Index];\r
469 PpiOutputSize = PrivateData->CacheSection.SectionSize[Index];\r
470 //\r
471 // Search section directly from the cache data.\r
472 //\r
b0d803fe 473 return PeiFfsProcessSection (\r
474 PeiServices,\r
475 SectionType, \r
476 PpiOutput, \r
477 PpiOutputSize, \r
288f9b38 478 OutputBuffer \r
b0d803fe 479 );\r
480 }\r
481 }\r
288f9b38
LG
482 \r
483 Status = EFI_NOT_FOUND;\r
484 if (Section->Type == EFI_SECTION_GUID_DEFINED) {\r
485 Status = PeiServicesLocatePpi (\r
486 &((EFI_GUID_DEFINED_SECTION *)Section)->SectionDefinitionGuid, \r
487 0, \r
488 NULL, \r
489 (VOID **) &GuidSectionPpi\r
490 );\r
b0d803fe 491 if (!EFI_ERROR (Status)) {\r
288f9b38
LG
492 Status = GuidSectionPpi->ExtractSection (\r
493 GuidSectionPpi,\r
494 Section,\r
495 &PpiOutput,\r
496 &PpiOutputSize,\r
497 &Authentication\r
498 );\r
499 }\r
500 } else if (Section->Type == EFI_SECTION_COMPRESSION) {\r
501 Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);\r
502 if (!EFI_ERROR (Status)) {\r
503 Status = DecompressPpi->Decompress (\r
504 DecompressPpi,\r
505 (CONST EFI_COMPRESSION_SECTION*) Section,\r
506 &PpiOutput,\r
507 &PpiOutputSize\r
508 );\r
b0d803fe 509 }\r
510 }\r
288f9b38
LG
511 \r
512 if (!EFI_ERROR (Status)) {\r
513 //\r
514 // Update cache section data.\r
515 //\r
516 if (PrivateData->CacheSection.AllSectionCount < CACHE_SETION_MAX_NUMBER) {\r
517 PrivateData->CacheSection.AllSectionCount ++;\r
518 }\r
519 PrivateData->CacheSection.Section [PrivateData->CacheSection.SectionIndex] = Section;\r
520 PrivateData->CacheSection.SectionData [PrivateData->CacheSection.SectionIndex] = PpiOutput;\r
521 PrivateData->CacheSection.SectionSize [PrivateData->CacheSection.SectionIndex] = PpiOutputSize;\r
522 PrivateData->CacheSection.SectionIndex = (PrivateData->CacheSection.SectionIndex + 1)%CACHE_SETION_MAX_NUMBER;\r
523 \r
524 return PeiFfsProcessSection (\r
525 PeiServices,\r
526 SectionType, \r
527 PpiOutput, \r
528 PpiOutputSize, \r
529 OutputBuffer \r
530 );\r
531 }\r
b0d803fe 532 }\r
533\r
534 //\r
535 // Size is 24 bits wide so mask upper 8 bits. \r
536 // SectionLength is adjusted it is 4 byte aligned.\r
537 // Go to the next section\r
538 //\r
539 SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;\r
540 SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);\r
541 ASSERT (SectionLength != 0);\r
542 ParsedLength += SectionLength;\r
543 Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);\r
544 }\r
545 \r
546 return EFI_NOT_FOUND;\r
547}\r
548\r
192f6d4c 549\r
b1f6a7c6 550/**\r
551 Given the input file pointer, search for the next matching section in the\r
552 FFS volume.\r
553\r
554\r
555 @param PeiServices Pointer to the PEI Core Services Table.\r
556 @param SectionType Filter to find only sections of this type.\r
557 @param FileHandle Pointer to the current file to search.\r
558 @param SectionData Pointer to the Section matching SectionType in FfsFileHeader.\r
559 NULL if section not found\r
560\r
561 @retval EFI_NOT_FOUND No files matching the search criteria were found\r
562 @retval EFI_SUCCESS Success to find section data in given file\r
563\r
564**/\r
192f6d4c 565EFI_STATUS\r
566EFIAPI\r
567PeiFfsFindSectionData (\r
0c2b5da8 568 IN CONST EFI_PEI_SERVICES **PeiServices,\r
192f6d4c 569 IN EFI_SECTION_TYPE SectionType,\r
0c2b5da8 570 IN EFI_PEI_FILE_HANDLE FileHandle,\r
192f6d4c 571 IN OUT VOID **SectionData\r
572 )\r
192f6d4c 573{\r
b0d803fe 574 EFI_FFS_FILE_HEADER *FfsFileHeader;\r
575 UINT32 FileSize;\r
576 EFI_COMMON_SECTION_HEADER *Section;\r
b0d803fe 577\r
578 FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);\r
192f6d4c 579\r
580 //\r
581 // Size is 24 bits wide so mask upper 8 bits. \r
b0d803fe 582 // Does not include FfsFileHeader header size\r
192f6d4c 583 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.\r
584 //\r
585 Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);\r
586 FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;\r
b0d803fe 587 FileSize -= sizeof (EFI_FFS_FILE_HEADER);\r
588\r
589 return PeiFfsProcessSection (\r
288f9b38 590 PeiServices,\r
b0d803fe 591 SectionType, \r
592 Section, \r
593 FileSize, \r
288f9b38 594 SectionData\r
b0d803fe 595 );\r
192f6d4c 596}\r
597\r
b1f6a7c6 598/**\r
599 Given the input file pointer, search for the next matching file in the\r
600 FFS volume as defined by SearchType. The search starts from FileHeader inside\r
601 the Firmware Volume defined by FwVolHeader.\r
192f6d4c 602\r
b1f6a7c6 603\r
604 @param PeiServices Pointer to the PEI Core Services Table.\r
605 @param SearchType Filter to find only files of this type.\r
606 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.\r
607 @param VolumeHandle Pointer to the FV header of the volume to search.\r
608 @param FileHandle Pointer to the current file from which to begin searching.\r
609 This pointer will be updated upon return to reflect the file found.\r
610 @retval EFI_NOT_FOUND No files matching the search criteria were found\r
611 @retval EFI_SUCCESS Success to find next file in given volume\r
612\r
613**/\r
192f6d4c 614EFI_STATUS\r
615EFIAPI\r
616PeiFfsFindNextFile (\r
0c2b5da8 617 IN CONST EFI_PEI_SERVICES **PeiServices,\r
618 IN UINT8 SearchType,\r
619 IN EFI_PEI_FV_HANDLE VolumeHandle,\r
620 IN OUT EFI_PEI_FILE_HANDLE *FileHandle\r
192f6d4c 621 )\r
192f6d4c 622{\r
b0d803fe 623 return PeiFindFileEx (VolumeHandle, NULL, SearchType, FileHandle, NULL);\r
192f6d4c 624}\r
625\r
b0d803fe 626\r
b1f6a7c6 627/**\r
628 search the firmware volumes by index\r
629\r
630 @param PeiServices The PEI core services table.\r
631 @param Instance Instance of FV to find\r
632 @param VolumeHandle Pointer to found Volume.\r
633\r
634 @retval EFI_INVALID_PARAMETER FwVolHeader is NULL\r
635 @retval EFI_SUCCESS Firmware volume instance successfully found.\r
636\r
637**/\r
192f6d4c 638EFI_STATUS \r
639EFIAPI\r
640PeiFvFindNextVolume (\r
0c2b5da8 641 IN CONST EFI_PEI_SERVICES **PeiServices,\r
192f6d4c 642 IN UINTN Instance,\r
0c2b5da8 643 IN OUT EFI_PEI_FV_HANDLE *VolumeHandle\r
192f6d4c 644 )\r
192f6d4c 645{\r
b0d803fe 646 PEI_CORE_INSTANCE *Private;\r
192f6d4c 647\r
b0d803fe 648 Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
649 if (VolumeHandle == NULL) {\r
650 return EFI_INVALID_PARAMETER;\r
651 } \r
192f6d4c 652\r
b0d803fe 653 if (Instance >= Private->AllFvCount) {\r
654 VolumeHandle = NULL;\r
655 return EFI_NOT_FOUND;\r
656 }\r
192f6d4c 657\r
b0d803fe 658 *VolumeHandle = Private->AllFv[Instance];\r
659 return EFI_SUCCESS;\r
660}\r
192f6d4c 661\r
192f6d4c 662\r
b1f6a7c6 663/**\r
664\r
665 Given the input VolumeHandle, search for the next matching name file.\r
666\r
667\r
668 @param FileName - File name to search.\r
669 @param VolumeHandle - The current FV to search.\r
670 @param FileHandle - Pointer to the file matching name in VolumeHandle.\r
671 - NULL if file not found\r
672\r
673 @return EFI_STATUS\r
674\r
675**/\r
b0d803fe 676EFI_STATUS\r
677EFIAPI \r
678PeiFfsFindFileByName (\r
679 IN CONST EFI_GUID *FileName,\r
680 IN EFI_PEI_FV_HANDLE VolumeHandle,\r
681 OUT EFI_PEI_FILE_HANDLE *FileHandle\r
682 )\r
b0d803fe 683{\r
684 EFI_STATUS Status;\r
685 if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {\r
192f6d4c 686 return EFI_INVALID_PARAMETER;\r
687 }\r
b0d803fe 688 Status = PeiFindFileEx (VolumeHandle, FileName, 0, FileHandle, NULL);\r
689 if (Status == EFI_NOT_FOUND) {\r
690 *FileHandle = NULL;\r
691 }\r
692 return Status;\r
693}\r
694\r
b1f6a7c6 695/**\r
696\r
697 Returns information about a specific file.\r
698\r
699\r
700 @param FileHandle - The handle to file.\r
701 @param FileInfo - Pointer to the file information.\r
702\r
703 @retval EFI_INVALID_PARAMETER Invalid FileHandle or FileInfo.\r
704 @retval EFI_SUCCESS Success to collect file info.\r
705\r
706**/\r
b0d803fe 707EFI_STATUS\r
708EFIAPI \r
709PeiFfsGetFileInfo (\r
710 IN EFI_PEI_FILE_HANDLE FileHandle,\r
711 OUT EFI_FV_FILE_INFO *FileInfo\r
712 )\r
b0d803fe 713{\r
714 UINT8 FileState;\r
715 UINT8 ErasePolarity;\r
716 EFI_FFS_FILE_HEADER *FileHeader;\r
717 EFI_PEI_FV_HANDLE VolumeHandle;\r
718\r
719 if ((FileHandle == NULL) || (FileInfo == NULL)) {\r
720 return EFI_INVALID_PARAMETER;\r
721 }\r
722\r
173b35e4 723 VolumeHandle = 0;\r
b0d803fe 724 //\r
725 // Retrieve the FirmwareVolume which the file resides in.\r
726 //\r
727 if (!PeiFileHandleToVolume(FileHandle, &VolumeHandle)) {\r
728 return EFI_INVALID_PARAMETER;\r
729 }\r
730\r
797a9d67 731 if (((EFI_FIRMWARE_VOLUME_HEADER*)VolumeHandle)->Attributes & EFI_FVB2_ERASE_POLARITY) {\r
b0d803fe 732 ErasePolarity = 1;\r
192f6d4c 733 } else {\r
b0d803fe 734 ErasePolarity = 0;\r
735 }\r
736\r
737 //\r
738 // Get FileState which is the highest bit of the State \r
739 //\r
740 FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle);\r
192f6d4c 741\r
b0d803fe 742 switch (FileState) {\r
743 case EFI_FILE_DATA_VALID:\r
744 case EFI_FILE_MARKED_FOR_UPDATE:\r
745 break; \r
746 default:\r
747 return EFI_INVALID_PARAMETER;\r
192f6d4c 748 }\r
b0d803fe 749\r
750 FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;\r
751 CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID));\r
752 FileInfo->FileType = FileHeader->Type;\r
753 FileInfo->FileAttributes = FileHeader->Attributes;\r
754 FileInfo->BufferSize = ((*(UINT32 *)FileHeader->Size) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER);\r
755 FileInfo->Buffer = (FileHeader + 1);\r
756 return EFI_SUCCESS;\r
757}\r
758\r
759\r
b1f6a7c6 760/**\r
761\r
762 Collect information of given Fv Volume.\r
763\r
764 @param VolumeHandle - The handle to Fv Volume.\r
765 @param VolumeInfo - The pointer to volume information.\r
766\r
767 @retval EFI_INVALID_PARAMETER VolumeInfo is NULL\r
768 @retval EFI_SUCCESS Success to collect fv info.\r
769**/\r
b0d803fe 770EFI_STATUS\r
771EFIAPI \r
772PeiFfsGetVolumeInfo (\r
773 IN EFI_PEI_FV_HANDLE VolumeHandle,\r
774 OUT EFI_FV_INFO *VolumeInfo\r
775 )\r
b0d803fe 776{\r
288f9b38 777 EFI_FIRMWARE_VOLUME_HEADER FwVolHeader;\r
b0d803fe 778 EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;\r
779\r
780 if (VolumeInfo == NULL) {\r
781 return EFI_INVALID_PARAMETER;\r
192f6d4c 782 }\r
288f9b38
LG
783 \r
784 //\r
785 // VolumeHandle may not align at 8 byte, \r
786 // but FvLength is UINT64 type, which requires FvHeader align at least 8 byte. \r
787 // So, Copy FvHeader into the local FvHeader structure.\r
788 //\r
789 CopyMem (&FwVolHeader, VolumeHandle, sizeof (EFI_FIRMWARE_VOLUME_HEADER));\r
790 //\r
791 // Check Fv Image Signature\r
792 //\r
793 if (FwVolHeader.Signature != EFI_FVH_SIGNATURE) {\r
794 return EFI_INVALID_PARAMETER;\r
795 }\r
796 VolumeInfo->FvAttributes = FwVolHeader.Attributes;\r
797 VolumeInfo->FvStart = (VOID *) VolumeHandle;\r
798 VolumeInfo->FvSize = FwVolHeader.FvLength;\r
799 CopyMem (&VolumeInfo->FvFormat, &FwVolHeader.FileSystemGuid, sizeof(EFI_GUID));\r
b0d803fe 800\r
288f9b38
LG
801 if (FwVolHeader.ExtHeaderOffset != 0) {\r
802 FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)VolumeHandle) + FwVolHeader.ExtHeaderOffset);\r
b0d803fe 803 CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));\r
804 }\r
805 return EFI_SUCCESS;\r
192f6d4c 806}\r
b0d803fe 807\r