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