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