]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Pei/FwVol/FwVol.c
958263b522e79f4bc0ad788ab9d085a49f14358f
[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) FileHandle > (UINT64) FwVolHeader ) && \
146 ((UINT64) FileHandle <= ((UINT64) 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 >= PEI_CORE_MAX_FV_SUPPORTED) {
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 BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, (UINT64) Fv->FvInfoSize);
383 }
384
385 //
386 // Allways add to the All list
387 //
388 PrivateData->AllFv[PrivateData->AllFvCount++] = (EFI_PEI_FV_HANDLE)Fv->FvInfo;
389
390 return EFI_SUCCESS;
391 }
392
393 EFI_STATUS
394 PeiFfsProcessSection (
395 IN CONST EFI_PEI_SERVICES **PeiServices,
396 IN EFI_SECTION_TYPE SectionType,
397 IN EFI_COMMON_SECTION_HEADER *Section,
398 IN UINTN SectionSize,
399 OUT VOID **OutputBuffer,
400 OUT UINTN *OutputSize,
401 OUT UINT32 *Authentication
402 )
403 /*++
404
405 Routine Description:
406
407 Go through the file to search SectionType section,
408 when meeting an encapsuled section, search recursively.
409
410 Arguments:
411 PeiServices - Pointer to the PEI Core Services Table.
412 SearchType - Filter to find only section of this type.
413 Section - From where to search.
414 SectionSize - The file size to search.
415 OutputBuffer - Pointer to the section to search.
416 OutputSize - The size of the section to search.
417 Authentication - Authenticate the section.
418
419 Returns:
420 EFI_STATUS
421
422 --*/
423 {
424 EFI_STATUS Status;
425 UINT32 SectionLength;
426 UINT32 ParsedLength;
427 EFI_GUID_DEFINED_SECTION *GuidSection;
428 EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *GuidSectionPpi;
429 EFI_COMPRESSION_SECTION *CompressionSection;
430 EFI_PEI_DECOMPRESS_PPI *DecompressPpi;
431 VOID *PpiOutput;
432 UINTN PpiOutputSize;
433
434 *OutputBuffer = NULL;
435 ParsedLength = 0;
436 while (ParsedLength < SectionSize) {
437 if (Section->Type == SectionType) {
438 *OutputBuffer = (VOID *)(Section + 1);
439 return EFI_SUCCESS;
440 } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {
441 GuidSection = (EFI_GUID_DEFINED_SECTION *)Section;
442 Status = PeiServicesLocatePpi (&GuidSection->SectionDefinitionGuid, 0, NULL, (VOID **) &GuidSectionPpi);
443 if (!EFI_ERROR (Status)) {
444 Status = GuidSectionPpi->ExtractSection (
445 GuidSectionPpi,
446 Section,
447 &PpiOutput,
448 &PpiOutputSize,
449 Authentication
450 );
451 if (!EFI_ERROR (Status)) {
452 return PeiFfsProcessSection (
453 PeiServices,
454 SectionType,
455 PpiOutput,
456 PpiOutputSize,
457 OutputBuffer,
458 OutputSize,
459 Authentication
460 );
461 }
462 }
463 } else if (Section->Type == EFI_SECTION_COMPRESSION) {
464 CompressionSection = (EFI_COMPRESSION_SECTION *)Section;
465 Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);
466 if (!EFI_ERROR (Status)) {
467 Status = DecompressPpi->Decompress (
468 DecompressPpi,
469 CompressionSection,
470 &PpiOutput,
471 &PpiOutputSize
472 );
473 if (!EFI_ERROR (Status)) {
474 return PeiFfsProcessSection (
475 PeiServices, SectionType, PpiOutput, PpiOutputSize, OutputBuffer, OutputSize, Authentication
476 );
477 }
478 }
479 }
480
481 //
482 // Size is 24 bits wide so mask upper 8 bits.
483 // SectionLength is adjusted it is 4 byte aligned.
484 // Go to the next section
485 //
486 SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
487 SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
488 ASSERT (SectionLength != 0);
489 ParsedLength += SectionLength;
490 Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
491 }
492
493 return EFI_NOT_FOUND;
494 }
495
496
497 EFI_STATUS
498 EFIAPI
499 PeiFfsFindSectionData (
500 IN CONST EFI_PEI_SERVICES **PeiServices,
501 IN EFI_SECTION_TYPE SectionType,
502 IN EFI_PEI_FILE_HANDLE FileHandle,
503 IN OUT VOID **SectionData
504 )
505 /*++
506
507 Routine Description:
508 Given the input file pointer, search for the next matching section in the
509 FFS volume.
510
511 Arguments:
512 PeiServices - Pointer to the PEI Core Services Table.
513 SearchType - Filter to find only sections of this type.
514 FfsFileHeader - Pointer to the current file to search.
515 SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
516 - NULL if section not found
517
518 Returns:
519 EFI_NOT_FOUND - No files matching the search criteria were found
520 EFI_SUCCESS
521
522 --*/
523 {
524 EFI_FFS_FILE_HEADER *FfsFileHeader;
525 UINT32 FileSize;
526 EFI_COMMON_SECTION_HEADER *Section;
527 UINTN OutputSize;
528 UINT32 AuthenticationStatus;
529
530
531 FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);
532
533 //
534 // Size is 24 bits wide so mask upper 8 bits.
535 // Does not include FfsFileHeader header size
536 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
537 //
538 Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);
539 FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
540 FileSize -= sizeof (EFI_FFS_FILE_HEADER);
541
542 return PeiFfsProcessSection (
543 PeiServices,
544 SectionType,
545 Section,
546 FileSize,
547 SectionData,
548 &OutputSize,
549 &AuthenticationStatus
550 );
551 }
552
553
554 EFI_STATUS
555 FindNextPeim (
556 IN EFI_PEI_SERVICES **PeiServices,
557 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
558 IN OUT EFI_FFS_FILE_HEADER **PeimFileHeader
559 )
560 /*++
561
562 Routine Description:
563 Given the input file pointer, search for the next matching file in the
564 FFS volume. The search starts from FileHeader inside
565 the Firmware Volume defined by FwVolHeader.
566
567 Arguments:
568 PeiServices - Pointer to the PEI Core Services Table.
569
570 FwVolHeader - Pointer to the FV header of the volume to search.
571 This parameter must point to a valid FFS volume.
572
573 PeimFileHeader - Pointer to the current file from which to begin searching.
574 This pointer will be updated upon return to reflect the file found.
575
576 Returns:
577 EFI_NOT_FOUND - No files matching the search criteria were found
578 EFI_SUCCESS
579
580 --*/
581 {
582 return PeiFindFileEx (
583 (EFI_PEI_FV_HANDLE) FwVolHeader,
584 NULL,
585 EFI_FV_FILETYPE_PEIM,
586 (EFI_PEI_FILE_HANDLE *)PeimFileHeader,
587 NULL
588 );
589 }
590
591 EFI_STATUS
592 EFIAPI
593 PeiFfsFindNextFile (
594 IN CONST EFI_PEI_SERVICES **PeiServices,
595 IN UINT8 SearchType,
596 IN EFI_PEI_FV_HANDLE VolumeHandle,
597 IN OUT EFI_PEI_FILE_HANDLE *FileHandle
598 )
599 /*++
600
601 Routine Description:
602 Given the input file pointer, search for the next matching file in the
603 FFS volume as defined by SearchType. The search starts from FileHeader inside
604 the Firmware Volume defined by FwVolHeader.
605
606 Arguments:
607 PeiServices - Pointer to the PEI Core Services Table.
608
609 SearchType - Filter to find only files of this type.
610 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
611
612 FwVolHeader - Pointer to the FV header of the volume to search.
613 This parameter must point to a valid FFS volume.
614
615 FileHeader - Pointer to the current file from which to begin searching.
616 This pointer will be updated upon return to reflect the file found.
617
618 Returns:
619 EFI_NOT_FOUND - No files matching the search criteria were found
620 EFI_SUCCESS
621
622 --*/
623 {
624 return PeiFindFileEx (VolumeHandle, NULL, SearchType, FileHandle, NULL);
625 }
626
627
628 EFI_STATUS
629 EFIAPI
630 PeiFvFindNextVolume (
631 IN CONST EFI_PEI_SERVICES **PeiServices,
632 IN UINTN Instance,
633 IN OUT EFI_PEI_FV_HANDLE *VolumeHandle
634 )
635 /*++
636
637 Routine Description:
638
639 Return the BFV location
640
641 BugBug -- Move this to the location of this code to where the
642 other FV and FFS support code lives.
643 Also, update to use FindFV for instances #'s >= 1.
644
645 Arguments:
646
647 PeiServices - The PEI core services table.
648 Instance - Instance of FV to find
649 FwVolHeader - Pointer to contain the data to return
650
651 Returns:
652 Pointer to the Firmware Volume instance requested
653
654 EFI_INVALID_PARAMETER - FwVolHeader is NULL
655
656 EFI_SUCCESS - Firmware volume instance successfully found.
657
658 --*/
659 {
660 PEI_CORE_INSTANCE *Private;
661
662 Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
663 if (VolumeHandle == NULL) {
664 return EFI_INVALID_PARAMETER;
665 }
666
667 if (Instance >= Private->AllFvCount) {
668 VolumeHandle = NULL;
669 return EFI_NOT_FOUND;
670 }
671
672 *VolumeHandle = Private->AllFv[Instance];
673 return EFI_SUCCESS;
674 }
675
676
677 EFI_STATUS
678 EFIAPI
679 PeiFfsFindFileByName (
680 IN CONST EFI_GUID *FileName,
681 IN EFI_PEI_FV_HANDLE VolumeHandle,
682 OUT EFI_PEI_FILE_HANDLE *FileHandle
683 )
684 /*++
685
686 Routine Description:
687
688 Given the input VolumeHandle, search for the next matching name file.
689
690 Arguments:
691
692 FileName - File name to search.
693 VolumeHandle - The current FV to search.
694 FileHandle - Pointer to the file matching name in VolumeHandle.
695 - NULL if file not found
696 Returns:
697 EFI_STATUS
698
699 --*/
700 {
701 EFI_STATUS Status;
702 if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {
703 return EFI_INVALID_PARAMETER;
704 }
705 Status = PeiFindFileEx (VolumeHandle, FileName, 0, FileHandle, NULL);
706 if (Status == EFI_NOT_FOUND) {
707 *FileHandle = NULL;
708 }
709 return Status;
710 }
711
712 EFI_STATUS
713 EFIAPI
714 PeiFfsGetFileInfo (
715 IN EFI_PEI_FILE_HANDLE FileHandle,
716 OUT EFI_FV_FILE_INFO *FileInfo
717 )
718 /*++
719
720 Routine Description:
721
722 Collect information of given file.
723
724 Arguments:
725 FileHandle - The handle to file.
726 FileInfo - Pointer to the file information.
727
728 Returns:
729 EFI_STATUS
730
731 --*/
732 {
733 UINT8 FileState;
734 UINT8 ErasePolarity;
735 EFI_FFS_FILE_HEADER *FileHeader;
736 EFI_PEI_FV_HANDLE VolumeHandle;
737
738 if ((FileHandle == NULL) || (FileInfo == NULL)) {
739 return EFI_INVALID_PARAMETER;
740 }
741
742 //
743 // Retrieve the FirmwareVolume which the file resides in.
744 //
745 if (!PeiFileHandleToVolume(FileHandle, &VolumeHandle)) {
746 return EFI_INVALID_PARAMETER;
747 }
748
749 if (((EFI_FIRMWARE_VOLUME_HEADER*)VolumeHandle)->Attributes & EFI_FVB_ERASE_POLARITY) {
750 ErasePolarity = 1;
751 } else {
752 ErasePolarity = 0;
753 }
754
755 //
756 // Get FileState which is the highest bit of the State
757 //
758 FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle);
759
760 switch (FileState) {
761 case EFI_FILE_DATA_VALID:
762 case EFI_FILE_MARKED_FOR_UPDATE:
763 break;
764 default:
765 return EFI_INVALID_PARAMETER;
766 }
767
768 FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;
769 CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID));
770 FileInfo->FileType = FileHeader->Type;
771 FileInfo->FileAttributes = FileHeader->Attributes;
772 FileInfo->BufferSize = ((*(UINT32 *)FileHeader->Size) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER);
773 FileInfo->Buffer = (FileHeader + 1);
774 return EFI_SUCCESS;
775 }
776
777
778 EFI_STATUS
779 EFIAPI
780 PeiFfsGetVolumeInfo (
781 IN EFI_PEI_FV_HANDLE VolumeHandle,
782 OUT EFI_FV_INFO *VolumeInfo
783 )
784 /*++
785
786 Routine Description:
787
788 Collect information of given Fv Volume.
789
790 Arguments:
791 VolumeHandle - The handle to Fv Volume.
792 VolumeInfo - The pointer to volume information.
793
794 Returns:
795 EFI_STATUS
796
797 --*/
798 {
799 EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
800 EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
801
802 if (VolumeInfo == NULL) {
803 return EFI_INVALID_PARAMETER;
804 }
805
806 FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(VolumeHandle);
807 VolumeInfo->FvAttributes = FwVolHeader->Attributes;
808 VolumeInfo->FvStart = FwVolHeader;
809 VolumeInfo->FvSize = FwVolHeader->FvLength;
810 CopyMem (&VolumeInfo->FvFormat, &FwVolHeader->FileSystemGuid,sizeof(EFI_GUID));
811
812 if (FwVolHeader->ExtHeaderOffset != 0) {
813 FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);
814 CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));
815 }
816 return EFI_SUCCESS;
817 }
818