3 Copyright (c) 2006, 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
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.
18 Pei Core Firmware File System service routines.
24 #define GETOCCUPIEDSIZE(ActualSize, Alignment) \
25 (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
30 IN UINT8 ErasePolarity
,
31 IN EFI_FFS_FILE_HEADER
*FfsHeader
37 Returns the highest bit set of the State field
41 ErasePolarity - Erase Polarity as defined by EFI_FVB_ERASE_POLARITY
42 in the Attributes field.
43 FfsHeader - Pointer to FFS File Header.
46 Returns the highest bit in the State field
50 EFI_FFS_FILE_STATE FileState
;
51 EFI_FFS_FILE_STATE HighestBit
;
53 FileState
= FfsHeader
->State
;
55 if (ErasePolarity
!= 0) {
56 FileState
= (EFI_FFS_FILE_STATE
)~FileState
;
60 while (HighestBit
!= 0 && (HighestBit
& FileState
) == 0) {
69 CalculateHeaderChecksum (
70 IN EFI_FFS_FILE_HEADER
*FileHeader
76 Calculates the checksum of the header of a file.
80 FileHeader - Pointer to FFS File Header.
83 Checksum of the header.
85 The header is zero byte checksum.
86 - Zero means the header is good.
87 - Non-zero means the header is bad.
90 Bugbug: For PEI performance reason, we comments this code at this time.
98 ptr
= (UINT8
*)FileHeader
;
100 for (Index
= 0; Index
< sizeof(EFI_FFS_FILE_HEADER
) - 3; Index
+= 4) {
101 Sum
= (UINT8
)(Sum
+ ptr
[Index
]);
102 Sum
= (UINT8
)(Sum
+ ptr
[Index
+1]);
103 Sum
= (UINT8
)(Sum
+ ptr
[Index
+2]);
104 Sum
= (UINT8
)(Sum
+ ptr
[Index
+3]);
107 for (; Index
< sizeof(EFI_FFS_FILE_HEADER
); Index
++) {
108 Sum
= (UINT8
)(Sum
+ ptr
[Index
]);
112 // State field (since this indicates the different state of file).
114 Sum
= (UINT8
)(Sum
- FileHeader
->State
);
116 // Checksum field of the file is not part of the header checksum.
118 Sum
= (UINT8
)(Sum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
125 PeiFfsFindNextFileEx (
126 IN EFI_FV_FILETYPE SearchType
,
127 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
,
128 IN OUT EFI_FFS_FILE_HEADER
**FileHeader
,
134 Given the input file pointer, search for the next matching file in the
135 FFS volume as defined by SearchType. The search starts from FileHeader inside
136 the Firmware Volume defined by FwVolHeader.
139 PeiServices - Pointer to the PEI Core Services Table.
140 SearchType - Filter to find only files of this type.
141 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
142 FwVolHeader - Pointer to the FV header of the volume to search.
143 This parameter must point to a valid FFS volume.
144 FileHeader - Pointer to the current file from which to begin searching.
145 This pointer will be updated upon return to reflect the file found.
146 Flag - Indicator for if this is for PEI Dispath search
148 EFI_NOT_FOUND - No files matching the search criteria were found
153 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
155 UINT32 FileOccupiedSize
;
162 FvLength
= FwVolHeader
->FvLength
;
163 if (FwVolHeader
->Attributes
& EFI_FVB_ERASE_POLARITY
) {
170 // If FileHeader is not specified (NULL) start with the first file in the
171 // firmware volume. Otherwise, start from the FileHeader.
173 if (*FileHeader
== NULL
) {
174 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FwVolHeader
+ FwVolHeader
->HeaderLength
);
177 // Length is 24 bits wide so mask upper 8 bits
178 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
180 FileLength
= *(UINT32
*)(*FileHeader
)->Size
& 0x00FFFFFF;
181 FileOccupiedSize
= GETOCCUPIEDSIZE(FileLength
, 8);
182 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)*FileHeader
+ FileOccupiedSize
);
185 FileOffset
= (UINT32
) ((UINT8
*)FfsFileHeader
- (UINT8
*)FwVolHeader
);
186 ASSERT (FileOffset
<= 0xFFFFFFFF);
188 while (FileOffset
< (FvLength
- sizeof(EFI_FFS_FILE_HEADER
))) {
190 // Get FileState which is the highest bit of the State
192 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
196 case EFI_FILE_HEADER_INVALID
:
197 FileOffset
+= sizeof(EFI_FFS_FILE_HEADER
);
198 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ sizeof(EFI_FFS_FILE_HEADER
));
201 case EFI_FILE_DATA_VALID
:
202 case EFI_FILE_MARKED_FOR_UPDATE
:
203 if (CalculateHeaderChecksum (FfsFileHeader
) == 0) {
204 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
205 FileOccupiedSize
= GETOCCUPIEDSIZE(FileLength
, 8);
207 if ((FfsFileHeader
->Type
== EFI_FV_FILETYPE_PEIM
) ||
208 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
)) {
210 *FileHeader
= FfsFileHeader
;
216 if ((SearchType
== FfsFileHeader
->Type
) ||
217 (SearchType
== EFI_FV_FILETYPE_ALL
)) {
219 *FileHeader
= FfsFileHeader
;
226 FileOffset
+= FileOccupiedSize
;
227 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
230 return EFI_NOT_FOUND
;
234 case EFI_FILE_DELETED
:
235 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
236 FileOccupiedSize
= GETOCCUPIEDSIZE(FileLength
, 8);
237 FileOffset
+= FileOccupiedSize
;
238 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
242 return EFI_NOT_FOUND
;
247 return EFI_NOT_FOUND
;
253 PeiFfsFindSectionData (
254 IN EFI_PEI_SERVICES
**PeiServices
,
255 IN EFI_SECTION_TYPE SectionType
,
256 IN EFI_FFS_FILE_HEADER
*FfsFileHeader
,
257 IN OUT VOID
**SectionData
262 Given the input file pointer, search for the next matching section in the
266 PeiServices - Pointer to the PEI Core Services Table.
267 SearchType - Filter to find only sections of this type.
268 FfsFileHeader - Pointer to the current file to search.
269 SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
270 - NULL if section not found
273 EFI_NOT_FOUND - No files matching the search criteria were found
279 EFI_COMMON_SECTION_HEADER
*Section
;
280 UINT32 SectionLength
;
285 // Size is 24 bits wide so mask upper 8 bits.
286 // Does not include FfsFileHeader header size
287 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
289 Section
= (EFI_COMMON_SECTION_HEADER
*)(FfsFileHeader
+ 1);
290 FileSize
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
291 FileSize
-= sizeof(EFI_FFS_FILE_HEADER
);
295 while (ParsedLength
< FileSize
) {
296 if (Section
->Type
== SectionType
) {
297 *SectionData
= (VOID
*)(Section
+ 1);
303 // Size is 24 bits wide so mask upper 8 bits.
304 // SectionLength is adjusted it is 4 byte aligned.
305 // Go to the next section
307 SectionLength
= *(UINT32
*)Section
->Size
& 0x00FFFFFF;
308 SectionLength
= GETOCCUPIEDSIZE (SectionLength
, 4);
309 ASSERT (SectionLength
!= 0);
310 ParsedLength
+= SectionLength
;
311 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
314 return EFI_NOT_FOUND
;
321 IN EFI_PEI_SERVICES
**PeiServices
,
322 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
,
323 IN OUT EFI_FFS_FILE_HEADER
**PeimFileHeader
328 Given the input file pointer, search for the next matching file in the
329 FFS volume. The search starts from FileHeader inside
330 the Firmware Volume defined by FwVolHeader.
333 PeiServices - Pointer to the PEI Core Services Table.
335 FwVolHeader - Pointer to the FV header of the volume to search.
336 This parameter must point to a valid FFS volume.
338 PeimFileHeader - Pointer to the current file from which to begin searching.
339 This pointer will be updated upon return to reflect the file found.
342 EFI_NOT_FOUND - No files matching the search criteria were found
347 return PeiFfsFindNextFileEx (
358 IN EFI_PEI_SERVICES
**PeiServices
,
359 IN EFI_FV_FILETYPE SearchType
,
360 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
,
361 IN OUT EFI_FFS_FILE_HEADER
**FileHeader
366 Given the input file pointer, search for the next matching file in the
367 FFS volume as defined by SearchType. The search starts from FileHeader inside
368 the Firmware Volume defined by FwVolHeader.
371 PeiServices - Pointer to the PEI Core Services Table.
373 SearchType - Filter to find only files of this type.
374 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
376 FwVolHeader - Pointer to the FV header of the volume to search.
377 This parameter must point to a valid FFS volume.
379 FileHeader - Pointer to the current file from which to begin searching.
380 This pointer will be updated upon return to reflect the file found.
383 EFI_NOT_FOUND - No files matching the search criteria were found
388 return PeiFfsFindNextFileEx (
398 PeiFvFindNextVolume (
399 IN EFI_PEI_SERVICES
**PeiServices
,
401 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**FwVolHeader
407 Return the BFV location
409 BugBug -- Move this to the location of this code to where the
410 other FV and FFS support code lives.
411 Also, update to use FindFV for instances #'s >= 1.
415 PeiServices - The PEI core services table.
416 Instance - Instance of FV to find
417 FwVolHeader - Pointer to contain the data to return
420 Pointer to the Firmware Volume instance requested
422 EFI_INVALID_PARAMETER - FwVolHeader is NULL
424 EFI_SUCCESS - Firmware volume instance successfully found.
428 PEI_CORE_INSTANCE
*PrivateData
;
430 EFI_PEI_FIND_FV_PPI
*FindFvPpi
;
434 LocalInstance
= (UINT8
) Instance
;
436 Status
= EFI_SUCCESS
;
437 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices
);
439 if (FwVolHeader
== NULL
) {
441 return EFI_INVALID_PARAMETER
;
445 *FwVolHeader
= PrivateData
->DispatchData
.BootFvAddress
;
451 // Locate all instances of FindFV
452 // Alternately, could use FV HOBs, but the PPI is cleaner
454 Status
= PeiServicesLocatePpi (
461 if (Status
!= EFI_SUCCESS
) {
462 Status
= EFI_NOT_FOUND
;
464 Status
= FindFvPpi
->FindFv (