3 Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
10 A simple FV stack so the SEC can extract the SEC Core from an
17 #define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
18 (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
22 IN UINT8 ErasePolarity
,
23 IN EFI_FFS_FILE_HEADER
*FfsHeader
28 Returns the highest bit set of the State field
31 ErasePolarity - Erase Polarity as defined by EFI_FVB_ERASE_POLARITY
32 in the Attributes field.
33 FfsHeader - Pointer to FFS File Header.
36 Returns the highest bit in the State field
40 EFI_FFS_FILE_STATE FileState
;
41 EFI_FFS_FILE_STATE HighestBit
;
43 FileState
= FfsHeader
->State
;
45 if (ErasePolarity
!= 0) {
46 FileState
= (EFI_FFS_FILE_STATE
)~FileState
;
50 while (HighestBit
!= 0 && (HighestBit
& FileState
) == 0) {
58 CalculateHeaderChecksum (
59 IN EFI_FFS_FILE_HEADER
*FileHeader
64 Calculates the checksum of the header of a file.
67 FileHeader - Pointer to FFS File Header.
70 Checksum of the header.
79 ptr
= (UINT8
*) FileHeader
;
81 for (Index
= 0; Index
< sizeof (EFI_FFS_FILE_HEADER
) - 3; Index
+= 4) {
82 Sum
= (UINT8
) (Sum
+ ptr
[Index
]);
83 Sum
= (UINT8
) (Sum
+ ptr
[Index
+ 1]);
84 Sum
= (UINT8
) (Sum
+ ptr
[Index
+ 2]);
85 Sum
= (UINT8
) (Sum
+ ptr
[Index
+ 3]);
88 for (; Index
< sizeof (EFI_FFS_FILE_HEADER
); Index
++) {
89 Sum
= (UINT8
) (Sum
+ ptr
[Index
]);
92 // State field (since this indicates the different state of file).
94 Sum
= (UINT8
) (Sum
- FileHeader
->State
);
96 // Checksum field of the file is not part of the header checksum.
98 Sum
= (UINT8
) (Sum
- FileHeader
->IntegrityCheck
.Checksum
.File
);
105 IN EFI_FV_FILETYPE SearchType
,
106 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
,
107 IN OUT EFI_FFS_FILE_HEADER
**FileHeader
112 Given the input file pointer, search for the next matching file in the
113 FFS volume as defined by SearchType. The search starts from FileHeader inside
114 the Firmware Volume defined by FwVolHeader.
117 SearchType - Filter to find only files of this type.
118 Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
119 FwVolHeader - Pointer to the FV header of the volume to search.
120 This parameter must point to a valid FFS volume.
121 FileHeader - Pointer to the current file from which to begin searching.
122 This pointer will be updated upon return to reflect the file
126 EFI_NOT_FOUND - No files matching the search criteria were found
131 EFI_FFS_FILE_HEADER
*FfsFileHeader
;
133 UINT32 FileOccupiedSize
;
139 FvLength
= FwVolHeader
->FvLength
;
140 if (FwVolHeader
->Attributes
& EFI_FVB2_ERASE_POLARITY
) {
146 // If FileHeader is not specified (NULL) start with the first file in the
147 // firmware volume. Otherwise, start from the FileHeader.
149 if (*FileHeader
== NULL
) {
150 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FwVolHeader
+ FwVolHeader
->HeaderLength
);
153 // Length is 24 bits wide so mask upper 8 bits
154 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
156 FileLength
= *(UINT32
*) (*FileHeader
)->Size
& 0x00FFFFFF;
157 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
158 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) *FileHeader
+ FileOccupiedSize
);
161 FileOffset
= (UINT32
) ((UINT8
*) FfsFileHeader
- (UINT8
*) FwVolHeader
);
163 while (FileOffset
< (FvLength
- sizeof (EFI_FFS_FILE_HEADER
))) {
165 // Get FileState which is the highest bit of the State
167 FileState
= GetFileState (ErasePolarity
, FfsFileHeader
);
171 case EFI_FILE_HEADER_INVALID
:
172 FileOffset
+= sizeof (EFI_FFS_FILE_HEADER
);
173 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FfsFileHeader
+ sizeof (EFI_FFS_FILE_HEADER
));
176 case EFI_FILE_DATA_VALID
:
177 case EFI_FILE_MARKED_FOR_UPDATE
:
178 if (CalculateHeaderChecksum (FfsFileHeader
) == 0) {
179 FileLength
= *(UINT32
*) (FfsFileHeader
->Size
) & 0x00FFFFFF;
180 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
182 if ((SearchType
== FfsFileHeader
->Type
) || (SearchType
== EFI_FV_FILETYPE_ALL
)) {
184 *FileHeader
= FfsFileHeader
;
189 FileOffset
+= FileOccupiedSize
;
190 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FfsFileHeader
+ FileOccupiedSize
);
192 return EFI_NOT_FOUND
;
196 case EFI_FILE_DELETED
:
197 FileLength
= *(UINT32
*) (FfsFileHeader
->Size
) & 0x00FFFFFF;
198 FileOccupiedSize
= GET_OCCUPIED_SIZE (FileLength
, 8);
199 FileOffset
+= FileOccupiedSize
;
200 FfsFileHeader
= (EFI_FFS_FILE_HEADER
*) ((UINT8
*) FfsFileHeader
+ FileOccupiedSize
);
204 return EFI_NOT_FOUND
;
209 return EFI_NOT_FOUND
;
213 SecFfsFindSectionData (
214 IN EFI_SECTION_TYPE SectionType
,
215 IN EFI_FFS_FILE_HEADER
*FfsFileHeader
,
216 IN OUT VOID
**SectionData
221 Given the input file pointer, search for the next matching section in the
225 SearchType - Filter to find only sections of this type.
226 FfsFileHeader - Pointer to the current file to search.
227 SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
228 NULL if section not found
231 EFI_NOT_FOUND - No files matching the search criteria were found
237 EFI_COMMON_SECTION_HEADER
*Section
;
238 UINT32 SectionLength
;
242 // Size is 24 bits wide so mask upper 8 bits.
243 // Does not include FfsFileHeader header size
244 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
246 Section
= (EFI_COMMON_SECTION_HEADER
*) (FfsFileHeader
+ 1);
247 FileSize
= *(UINT32
*) (FfsFileHeader
->Size
) & 0x00FFFFFF;
248 FileSize
-= sizeof (EFI_FFS_FILE_HEADER
);
252 while (ParsedLength
< FileSize
) {
253 if (Section
->Type
== SectionType
) {
254 *SectionData
= (VOID
*) (Section
+ 1);
258 // Size is 24 bits wide so mask upper 8 bits.
259 // SectionLength is adjusted it is 4 byte aligned.
260 // Go to the next section
262 SectionLength
= *(UINT32
*) Section
->Size
& 0x00FFFFFF;
263 SectionLength
= GET_OCCUPIED_SIZE (SectionLength
, 4);
265 ParsedLength
+= SectionLength
;
266 Section
= (EFI_COMMON_SECTION_HEADER
*) ((UINT8
*) Section
+ SectionLength
);
269 return EFI_NOT_FOUND
;
274 IN EFI_FIRMWARE_VOLUME_HEADER
*FwVolHeader
,
280 Given the pointer to the Firmware Volume Header find the SEC
281 core and return it's PE32 image.
284 FwVolHeader - Pointer to memory mapped FV
285 Pe32Data - Pointer to SEC PE32 iamge.
288 EFI_SUCCESS - Pe32Data is valid
294 EFI_FFS_FILE_HEADER
*FileHeader
;
295 EFI_FV_FILETYPE SearchType
;
297 SearchType
= EFI_FV_FILETYPE_PEI_CORE
;
300 Status
= SecFfsFindNextFile (SearchType
, FwVolHeader
, &FileHeader
);
301 if (!EFI_ERROR (Status
)) {
302 Status
= SecFfsFindSectionData (EFI_SECTION_PE32
, FileHeader
, Pe32Data
);
305 } while (!EFI_ERROR (Status
));