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.
23 // Include common header file for this module.
25 #include "CommonHeader.h"
29 #define GETOCCUPIEDSIZE(ActualSize, Alignment) \
30 (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
35 IN UINT8 ErasePolarity
,
36 IN EFI_FFS_FILE_HEADER
*FfsHeader
42 Returns the highest bit set of the State field
46 ErasePolarity - Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
47 in the Attributes field.
48 FfsHeader - Pointer to FFS File Header.
51 Returns the highest bit in the State field
55 EFI_FFS_FILE_STATE FileState
;
56 EFI_FFS_FILE_STATE HighestBit
;
58 FileState
= FfsHeader
->State
;
60 if (ErasePolarity
!= 0) {
61 FileState
= (EFI_FFS_FILE_STATE
)~FileState
;
65 while (HighestBit
!= 0 && (HighestBit
& FileState
) == 0) {
74 CalculateHeaderChecksum (
75 IN EFI_FFS_FILE_HEADER
*FileHeader
81 Calculates the checksum of the header of a file.
85 FileHeader - Pointer to FFS File Header.
88 Checksum of the header.
90 The header is zero byte checksum.
91 - Zero means the header is good.
92 - Non-zero means the header is bad.
95 Bugbug: For PEI performance reason, we comments this code at this time.
103 ptr
= (UINT8
*)FileHeader
;
105 for (Index
= 0; Index
< sizeof(EFI_FFS_FILE_HEADER
) - 3; Index
+= 4) {
106 Sum
= (UINT8
)(Sum
+ ptr
[Index
]);
107 Sum
= (UINT8
)(Sum
+ ptr
[Index
+1]);
108 Sum
= (UINT8
)(Sum
+ ptr
[Index
+2]);
109 Sum
= (UINT8
)(Sum
+ ptr
[Index
+3]);
112 for (; Index
< sizeof(EFI_FFS_FILE_HEADER
); Index
++) {
113 Sum
= (UINT8
)(Sum
+ ptr
[Index
]);
117 // State field (since this indicates the different state of file).
119 Sum
= (UINT8
)(Sum
- FileHeader
->State
);
121 // Checksum field of the file is not part of the header checksum.
123 Sum
= (UINT8
)(Sum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
130 PeiFfsFindNextFileEx (
131 IN EFI_FV_FILETYPE SearchType
,
132 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
,
133 IN OUT EFI_FFS_FILE_HEADER
**FileHeader
,
139 Given the input file pointer, search for the next matching file in the
140 FFS volume as defined by SearchType. The search starts from FileHeader inside
141 the Firmware Volume defined by FwVolHeader.
144 PeiServices - Pointer to the PEI Core Services Table.
145 SearchType - Filter to find only files of this type.
146 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
147 FwVolHeader - Pointer to the FV header of the volume to search.
148 This parameter must point to a valid FFS volume.
149 FileHeader - Pointer to the current file from which to begin searching.
150 This pointer will be updated upon return to reflect the file found.
151 Flag - Indicator for if this is for PEI Dispath search
153 EFI_NOT_FOUND - No files matching the search criteria were found
158 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
160 UINT32 FileOccupiedSize
;
167 FvLength
= FwVolHeader
->FvLength
;
168 if (FwVolHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
175 // If FileHeader is not specified (NULL) start with the first file in the
176 // firmware volume. Otherwise, start from the FileHeader.
178 if (*FileHeader
== NULL
) {
179 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FwVolHeader
+ FwVolHeader
->HeaderLength
);
182 // Length is 24 bits wide so mask upper 8 bits
183 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
185 FileLength
= *(UINT32
*)(*FileHeader
)->Size
& 0x00FFFFFF;
186 FileOccupiedSize
= GETOCCUPIEDSIZE(FileLength
, 8);
187 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)*FileHeader
+ FileOccupiedSize
);
190 FileOffset
= (UINT32
) ((UINT8
*)FfsFileHeader
- (UINT8
*)FwVolHeader
);
191 ASSERT (FileOffset
<= 0xFFFFFFFF);
193 while (FileOffset
< (FvLength
- sizeof(EFI_FFS_FILE_HEADER
))) {
195 // Get FileState which is the highest bit of the State
197 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
201 case EFI_FILE_HEADER_INVALID
:
202 FileOffset
+= sizeof(EFI_FFS_FILE_HEADER
);
203 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ sizeof(EFI_FFS_FILE_HEADER
));
206 case EFI_FILE_DATA_VALID
:
207 case EFI_FILE_MARKED_FOR_UPDATE
:
208 if (CalculateHeaderChecksum (FfsFileHeader
) == 0) {
209 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
210 FileOccupiedSize
= GETOCCUPIEDSIZE(FileLength
, 8);
212 if ((FfsFileHeader
->Type
== EFI_FV_FILETYPE_PEIM
) ||
213 (FfsFileHeader
->Type
== EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
)) {
215 *FileHeader
= FfsFileHeader
;
221 if ((SearchType
== FfsFileHeader
->Type
) ||
222 (SearchType
== EFI_FV_FILETYPE_ALL
)) {
224 *FileHeader
= FfsFileHeader
;
231 FileOffset
+= FileOccupiedSize
;
232 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
235 return EFI_NOT_FOUND
;
239 case EFI_FILE_DELETED
:
240 FileLength
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
241 FileOccupiedSize
= GETOCCUPIEDSIZE(FileLength
, 8);
242 FileOffset
+= FileOccupiedSize
;
243 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*)((UINT8
*)FfsFileHeader
+ FileOccupiedSize
);
247 return EFI_NOT_FOUND
;
252 return EFI_NOT_FOUND
;
258 PeiFfsFindSectionData (
259 IN EFI_PEI_SERVICES
**PeiServices
,
260 IN EFI_SECTION_TYPE SectionType
,
261 IN EFI_FFS_FILE_HEADER
*FfsFileHeader
,
262 IN OUT VOID
**SectionData
267 Given the input file pointer, search for the next matching section in the
271 PeiServices - Pointer to the PEI Core Services Table.
272 SearchType - Filter to find only sections of this type.
273 FfsFileHeader - Pointer to the current file to search.
274 SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
275 - NULL if section not found
278 EFI_NOT_FOUND - No files matching the search criteria were found
284 EFI_COMMON_SECTION_HEADER
*Section
;
285 UINT32 SectionLength
;
290 // Size is 24 bits wide so mask upper 8 bits.
291 // Does not include FfsFileHeader header size
292 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
294 Section
= (EFI_COMMON_SECTION_HEADER
*)(FfsFileHeader
+ 1);
295 FileSize
= *(UINT32
*)(FfsFileHeader
->Size
) & 0x00FFFFFF;
296 FileSize
-= sizeof(EFI_FFS_FILE_HEADER
);
300 while (ParsedLength
< FileSize
) {
301 if (Section
->Type
== SectionType
) {
302 *SectionData
= (VOID
*)(Section
+ 1);
308 // Size is 24 bits wide so mask upper 8 bits.
309 // SectionLength is adjusted it is 4 byte aligned.
310 // Go to the next section
312 SectionLength
= *(UINT32
*)Section
->Size
& 0x00FFFFFF;
313 SectionLength
= GETOCCUPIEDSIZE (SectionLength
, 4);
314 ASSERT (SectionLength
!= 0);
315 ParsedLength
+= SectionLength
;
316 Section
= (EFI_COMMON_SECTION_HEADER
*)((UINT8
*)Section
+ SectionLength
);
319 return EFI_NOT_FOUND
;
326 IN EFI_PEI_SERVICES
**PeiServices
,
327 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
,
328 IN OUT EFI_FFS_FILE_HEADER
**PeimFileHeader
333 Given the input file pointer, search for the next matching file in the
334 FFS volume. The search starts from FileHeader inside
335 the Firmware Volume defined by FwVolHeader.
338 PeiServices - Pointer to the PEI Core Services Table.
340 FwVolHeader - Pointer to the FV header of the volume to search.
341 This parameter must point to a valid FFS volume.
343 PeimFileHeader - Pointer to the current file from which to begin searching.
344 This pointer will be updated upon return to reflect the file found.
347 EFI_NOT_FOUND - No files matching the search criteria were found
352 return PeiFfsFindNextFileEx (
363 IN EFI_PEI_SERVICES
**PeiServices
,
364 IN EFI_FV_FILETYPE SearchType
,
365 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
,
366 IN OUT EFI_FFS_FILE_HEADER
**FileHeader
371 Given the input file pointer, search for the next matching file in the
372 FFS volume as defined by SearchType. The search starts from FileHeader inside
373 the Firmware Volume defined by FwVolHeader.
376 PeiServices - Pointer to the PEI Core Services Table.
378 SearchType - Filter to find only files of this type.
379 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
381 FwVolHeader - Pointer to the FV header of the volume to search.
382 This parameter must point to a valid FFS volume.
384 FileHeader - Pointer to the current file from which to begin searching.
385 This pointer will be updated upon return to reflect the file found.
388 EFI_NOT_FOUND - No files matching the search criteria were found
393 return PeiFfsFindNextFileEx (
403 PeiFvFindNextVolume (
404 IN EFI_PEI_SERVICES
**PeiServices
,
406 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**FwVolHeader
412 Return the BFV location
414 BugBug -- Move this to the location of this code to where the
415 other FV and FFS support code lives.
416 Also, update to use FindFV for instances #'s >= 1.
420 PeiServices - The PEI core services table.
421 Instance - Instance of FV to find
422 FwVolHeader - Pointer to contain the data to return
425 Pointer to the Firmware Volume instance requested
427 EFI_INVALID_PARAMETER - FwVolHeader is NULL
429 EFI_SUCCESS - Firmware volume instance successfully found.
433 PEI_CORE_INSTANCE
*PrivateData
;
435 EFI_PEI_FIND_FV_PPI
*FindFvPpi
;
439 LocalInstance
= (UINT8
) Instance
;
441 Status
= EFI_SUCCESS
;
442 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices
);
444 if (FwVolHeader
== NULL
) {
446 return EFI_INVALID_PARAMETER
;
450 *FwVolHeader
= PrivateData
->DispatchData
.BootFvAddress
;
456 // Locate all instances of FindFV
457 // Alternately, could use FV HOBs, but the PPI is cleaner
459 Status
= PeiServicesLocatePpi (
466 if (Status
!= EFI_SUCCESS
) {
467 Status
= EFI_NOT_FOUND
;
469 Status
= FindFvPpi
->FindFv (