TianoCore EDK2 master
Loading...
Searching...
No Matches
FvLib.c
Go to the documentation of this file.
1
10#include <Library/FvLib.h>
11
12#include <Library/BaseLib.h>
14#include <Library/DebugLib.h>
15
16#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
17 (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
18
28EFI_FFS_FILE_STATE
30 IN UINT8 ErasePolarity,
31 IN EFI_FFS_FILE_HEADER *FfsHeader
32 )
33{
34 EFI_FFS_FILE_STATE FileState;
35 EFI_FFS_FILE_STATE HighestBit;
36
37 FileState = FfsHeader->State;
38
39 if (ErasePolarity != 0) {
40 FileState = (EFI_FFS_FILE_STATE) ~FileState;
41 }
42
43 HighestBit = 0x80;
44 while (HighestBit != 0 && (HighestBit & FileState) == 0) {
45 HighestBit >>= 1;
46 }
47
48 return HighestBit;
49}
50
58UINT8
60 IN EFI_FFS_FILE_HEADER *FileHeader
61 )
62{
63 UINT8 *ptr;
64 UINTN Index;
65 UINT8 Sum;
66 UINTN Size;
67
68 Sum = 0;
69 ptr = (UINT8 *)FileHeader;
70 Size = IS_FFS_FILE2 (FileHeader) ? sizeof (EFI_FFS_FILE_HEADER2) : sizeof (EFI_FFS_FILE_HEADER);
71
72 for (Index = 0; Index < Size - 3; Index += 4) {
73 Sum = (UINT8)(Sum + ptr[Index]);
74 Sum = (UINT8)(Sum + ptr[Index + 1]);
75 Sum = (UINT8)(Sum + ptr[Index + 2]);
76 Sum = (UINT8)(Sum + ptr[Index + 3]);
77 }
78
79 for ( ; Index < Size; Index++) {
80 Sum = (UINT8)(Sum + ptr[Index]);
81 }
82
83 //
84 // State field (since this indicates the different state of file).
85 //
86 Sum = (UINT8)(Sum - FileHeader->State);
87 //
88 // Checksum field of the file is not part of the header checksum.
89 //
90 Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);
91
92 return Sum;
93}
94
111EFIAPI
113 IN EFI_FV_FILETYPE SearchType,
114 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
115 IN OUT EFI_FFS_FILE_HEADER **FileHeader
116 )
117{
119
120 EFI_FFS_FILE_HEADER *FfsFileHeader;
121 UINT32 FileLength;
122 UINT32 FileOccupiedSize;
123 UINT32 FileOffset;
124 UINT64 FvLength;
125 UINT8 ErasePolarity;
126 UINT8 FileState;
127
128 FvLength = FwVolHeader->FvLength;
129 if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
130 ErasePolarity = 1;
131 } else {
132 ErasePolarity = 0;
133 }
134
135 //
136 // If FileHeader is not specified (NULL) start with the first file in the
137 // firmware volume. Otherwise, start from the FileHeader.
138 //
139 if (*FileHeader == NULL) {
140 if (FwVolHeader->ExtHeaderOffset != 0) {
141 FvExtHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)((UINT8 *)FwVolHeader +
142 FwVolHeader->ExtHeaderOffset);
143
144 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FvExtHeader +
145 FvExtHeader->ExtHeaderSize);
146 } else {
147 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader +
148 FwVolHeader->HeaderLength);
149 }
150
151 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINTN)FwVolHeader +
153 (UINTN)FfsFileHeader -
154 (UINTN)FwVolHeader,
155 8
156 ));
157 } else {
158 //
159 // Length is 24 bits wide so mask upper 8 bits
160 // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
161 //
162 FileLength = IS_FFS_FILE2 (*FileHeader) ?
163 FFS_FILE2_SIZE (*FileHeader) : FFS_FILE_SIZE (*FileHeader);
164 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
165 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);
166 }
167
168 FileOffset = (UINT32)((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);
169
170 while ((UINT64)FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
171 //
172 // Get FileState which is the highest bit of the State
173 //
174 FileState = GetFileState (ErasePolarity, FfsFileHeader);
175
176 switch (FileState) {
177 case EFI_FILE_HEADER_INVALID:
178 if (IS_FFS_FILE2 (FfsFileHeader)) {
179 FileOffset += sizeof (EFI_FFS_FILE_HEADER2);
180 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER2));
181 } else {
182 FileOffset += sizeof (EFI_FFS_FILE_HEADER);
183 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));
184 }
185
186 break;
187
188 case EFI_FILE_DATA_VALID:
189 case EFI_FILE_MARKED_FOR_UPDATE:
190 if (CalculateHeaderChecksum (FfsFileHeader) == 0) {
191 FileLength = IS_FFS_FILE2 (FfsFileHeader) ?
192 FFS_FILE2_SIZE (FfsFileHeader) : FFS_FILE_SIZE (FfsFileHeader);
193 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
194
195 if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) {
196 *FileHeader = FfsFileHeader;
197
198 return EFI_SUCCESS;
199 }
200
201 FileOffset += FileOccupiedSize;
202 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
203 } else {
204 return EFI_NOT_FOUND;
205 }
206
207 break;
208
209 case EFI_FILE_DELETED:
210 FileLength = IS_FFS_FILE2 (FfsFileHeader) ?
211 FFS_FILE2_SIZE (FfsFileHeader) : FFS_FILE_SIZE (FfsFileHeader);
212 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
213 FileOffset += FileOccupiedSize;
214 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
215 break;
216
217 default:
218 return EFI_NOT_FOUND;
219 }
220 }
221
222 return EFI_NOT_FOUND;
223}
224
239EFIAPI
241 IN VOID *Sections,
242 IN UINTN SizeOfSections,
243 IN EFI_SECTION_TYPE SectionType,
244 OUT EFI_COMMON_SECTION_HEADER **FoundSection
245 )
246{
247 EFI_PHYSICAL_ADDRESS CurrentAddress;
248 UINT32 Size;
249 EFI_PHYSICAL_ADDRESS EndOfSections;
251 EFI_PHYSICAL_ADDRESS EndOfSection;
252
253 //
254 // Loop through the FFS file sections
255 //
256 EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN)Sections;
257 EndOfSections = EndOfSection + SizeOfSections;
258 for ( ; ;) {
259 if (EndOfSection == EndOfSections) {
260 break;
261 }
262
263 CurrentAddress = EndOfSection;
264
265 Section = (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress;
266
267 Size = IS_SECTION2 (Section) ? SECTION2_SIZE (Section) : SECTION_SIZE (Section);
268 if (Size < sizeof (*Section)) {
269 return EFI_VOLUME_CORRUPTED;
270 }
271
272 EndOfSection = CurrentAddress + Size;
273 if (EndOfSection > EndOfSections) {
274 return EFI_VOLUME_CORRUPTED;
275 }
276
277 Size = GET_OCCUPIED_SIZE (Size, 4);
278
279 //
280 // Look for the requested section type
281 //
282 if (Section->Type == SectionType) {
283 *FoundSection = Section;
284 return EFI_SUCCESS;
285 }
286 }
287
288 return EFI_NOT_FOUND;
289}
290
304EFIAPI
306 IN EFI_SECTION_TYPE SectionType,
307 IN EFI_FFS_FILE_HEADER *FfsFileHeader,
308 IN OUT EFI_COMMON_SECTION_HEADER **SectionHeader
309 )
310{
311 UINT32 FileSize;
313 EFI_STATUS Status;
314
315 //
316 // Size is 24 bits wide so mask upper 8 bits.
317 // Does not include FfsFileHeader header size
318 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
319 //
320 if (IS_FFS_FILE2 (FfsFileHeader)) {
321 Section = (EFI_COMMON_SECTION_HEADER *)((EFI_FFS_FILE_HEADER2 *)FfsFileHeader + 1);
322 FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
323 } else {
324 Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);
325 FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
326 }
327
328 Status = FindFfsSectionInSections (
329 Section,
330 FileSize,
331 SectionType,
332 SectionHeader
333 );
334 return Status;
335}
336
351EFIAPI
353 IN EFI_SECTION_TYPE SectionType,
354 IN EFI_FFS_FILE_HEADER *FfsFileHeader,
355 IN OUT VOID **SectionData,
356 IN OUT UINTN *SectionDataSize
357 )
358{
359 UINT32 FileSize;
361 UINT32 SectionLength;
362 UINT32 ParsedLength;
363
364 //
365 // Size is 24 bits wide so mask upper 8 bits.
366 // Does not include FfsFileHeader header size
367 // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
368 //
369 if (IS_FFS_FILE2 (FfsFileHeader)) {
370 Section = (EFI_COMMON_SECTION_HEADER *)((EFI_FFS_FILE_HEADER2 *)FfsFileHeader + 1);
371 FileSize = FFS_FILE2_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER2);
372 } else {
373 Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);
374 FileSize = FFS_FILE_SIZE (FfsFileHeader) - sizeof (EFI_FFS_FILE_HEADER);
375 }
376
377 *SectionData = NULL;
378 ParsedLength = 0;
379 while (ParsedLength < FileSize) {
380 if (Section->Type == SectionType) {
381 if (IS_SECTION2 (Section)) {
382 *SectionData = (VOID *)((EFI_COMMON_SECTION_HEADER2 *)Section + 1);
383 *SectionDataSize = SECTION2_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER2);
384 } else {
385 *SectionData = (VOID *)(Section + 1);
386 *SectionDataSize = SECTION_SIZE (Section) - sizeof (EFI_COMMON_SECTION_HEADER);
387 }
388
389 return EFI_SUCCESS;
390 }
391
392 //
393 // Size is 24 bits wide so mask upper 8 bits.
394 // SectionLength is adjusted it is 4 byte aligned.
395 // Go to the next section
396 //
397 SectionLength = IS_SECTION2 (Section) ? SECTION2_SIZE (Section) : SECTION_SIZE (Section);
398 SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
399
400 ParsedLength += SectionLength;
401 Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
402 }
403
404 return EFI_NOT_FOUND;
405}
UINT64 UINTN
EFI_STATUS EFIAPI FfsFindSection(IN EFI_SECTION_TYPE SectionType, IN EFI_FFS_FILE_HEADER *FfsFileHeader, IN OUT EFI_COMMON_SECTION_HEADER **SectionHeader)
Definition: FvLib.c:305
EFI_FFS_FILE_STATE GetFileState(IN UINT8 ErasePolarity, IN EFI_FFS_FILE_HEADER *FfsHeader)
Definition: FvLib.c:29
EFI_STATUS EFIAPI FfsFindNextFile(IN EFI_FV_FILETYPE SearchType, IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader, IN OUT EFI_FFS_FILE_HEADER **FileHeader)
Definition: FvLib.c:112
EFI_STATUS EFIAPI FfsFindSectionData(IN EFI_SECTION_TYPE SectionType, IN EFI_FFS_FILE_HEADER *FfsFileHeader, IN OUT VOID **SectionData, IN OUT UINTN *SectionDataSize)
Definition: FvLib.c:352
EFI_STATUS EFIAPI FindFfsSectionInSections(IN VOID *Sections, IN UINTN SizeOfSections, IN EFI_SECTION_TYPE SectionType, OUT EFI_COMMON_SECTION_HEADER **FoundSection)
Definition: FvLib.c:240
UINT8 CalculateHeaderChecksum(IN EFI_FFS_FILE_HEADER *FileHeader)
Definition: FvLib.c:59
#define NULL
Definition: Base.h:319
#define ALIGN_VALUE(Value, Alignment)
Definition: Base.h:948
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define EFI_FV_FILETYPE_ALL
#define FFS_FILE_SIZE(FfsFileHeaderPtr)
#define SECTION_SIZE(SectionHeaderPtr)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_FV_FILETYPE Type