2 # This file is used to define the BIOS Tree Node.
4 # Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
5 # SPDX-License-Identifier: BSD-2-Clause-Patent
7 from FirmwareStorageFormat
.FvHeader
import *
8 from FirmwareStorageFormat
.FfsFileHeader
import *
9 from FirmwareStorageFormat
.SectionHeader
import *
10 from FirmwareStorageFormat
.Common
import *
11 from utils
.FmmtLogger
import FmmtLogger
as logger
15 0x01:'EFI_COMPRESSION_SECTION',
16 0x02:'EFI_GUID_DEFINED_SECTION',
17 0x03:'EFI_SECTION_DISPOSABLE',
18 0x10:'EFI_SECTION_PE32',
19 0x11:'EFI_SECTION_PIC',
20 0x12:'EFI_SECTION_TE',
21 0x13:'EFI_SECTION_DXE_DEPEX',
22 0x14:'EFI_SECTION_VERSION',
23 0x15:'EFI_SECTION_USER_INTERFACE',
24 0x16:'EFI_SECTION_COMPATIBILITY16',
25 0x17:'EFI_SECTION_FIRMWARE_VOLUME_IMAGE',
26 0x18:'EFI_FREEFORM_SUBTYPE_GUID_SECTION',
27 0x19:'EFI_SECTION_RAW',
28 0x1B:'EFI_SECTION_PEI_DEPEX',
29 0x1C:'EFI_SECTION_MM_DEPEX'
31 HeaderType
= [0x01, 0x02, 0x14, 0x15, 0x18]
34 def __init__(self
, name
: str) -> None:
36 self
.Name
= "BINARY" + str(name
)
41 def __init__(self
, name
, buffer: bytes
) -> None:
42 self
.Header
= EFI_FIRMWARE_VOLUME_HEADER
.from_buffer_copy(buffer)
43 Map_num
= (self
.Header
.HeaderLength
- 56)//8
44 self
.Header
= Refine_FV_Header(Map_num
).from_buffer_copy(buffer)
45 self
.FvId
= "FV" + str(name
)
46 self
.Name
= "FV" + str(name
)
47 if self
.Header
.ExtHeaderOffset
:
48 self
.ExtHeader
= EFI_FIRMWARE_VOLUME_EXT_HEADER
.from_buffer_copy(buffer[self
.Header
.ExtHeaderOffset
:])
49 self
.Name
= uuid
.UUID(bytes_le
=struct2stream(self
.ExtHeader
.FvName
))
50 self
.ExtEntryOffset
= self
.Header
.ExtHeaderOffset
+ 20
51 if self
.ExtHeader
.ExtHeaderSize
!= 20:
52 self
.ExtEntryExist
= 1
53 self
.ExtEntry
= EFI_FIRMWARE_VOLUME_EXT_ENTRY
.from_buffer_copy(buffer[self
.ExtEntryOffset
:])
55 if self
.ExtEntry
.ExtEntryType
== 0x01:
56 nums
= (self
.ExtEntry
.ExtEntrySize
- 8) // 16
57 self
.ExtEntry
= Refine_FV_EXT_ENTRY_OEM_TYPE_Header(nums
).from_buffer_copy(buffer[self
.ExtEntryOffset
:])
58 elif self
.ExtEntry
.ExtEntryType
== 0x02:
59 nums
= self
.ExtEntry
.ExtEntrySize
- 20
60 self
.ExtEntry
= Refine_FV_EXT_ENTRY_GUID_TYPE_Header(nums
).from_buffer_copy(buffer[self
.ExtEntryOffset
:])
61 elif self
.ExtEntry
.ExtEntryType
== 0x03:
62 self
.ExtEntry
= EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE
.from_buffer_copy(buffer[self
.ExtEntryOffset
:])
66 self
.ExtEntryExist
= 0
67 self
.Size
= self
.Header
.FvLength
68 self
.HeaderLength
= self
.Header
.HeaderLength
73 if self
.Header
.Signature
!= 1213613663:
74 logger
.error('Invalid Fv Header! Fv {} signature {} is not "_FVH".'.format(struct2stream(self
.Header
), self
.Header
.Signature
))
75 raise Exception("Process Failed: Fv Header Signature!")
80 def ModCheckSum(self
) -> None:
81 # Fv Header Sums to 0.
82 Header
= struct2stream(self
.Header
)[::-1]
83 Size
= self
.HeaderLength
// 2
86 Sum
+= int(Header
[i
*2: i
*2 + 2].hex(), 16)
88 self
.Header
.Checksum
= 0x10000 - (Sum
- self
.Header
.Checksum
) % 0x10000
90 def ModFvExt(self
) -> None:
91 # If used space changes and self.ExtEntry.UsedSize exists, self.ExtEntry.UsedSize need to be changed.
92 if self
.Header
.ExtHeaderOffset
and self
.ExtEntryExist
and self
.ExtTypeExist
and self
.ExtEntry
.Hdr
.ExtEntryType
== 0x03:
93 self
.ExtEntry
.UsedSize
= self
.Header
.FvLength
- self
.Free_Space
95 def ModFvSize(self
) -> None:
96 # If Fv Size changed, self.Header.FvLength and self.Header.BlockMap[i].NumBlocks need to be changed.
97 BlockMapNum
= len(self
.Header
.BlockMap
)
98 for i
in range(BlockMapNum
):
99 if self
.Header
.BlockMap
[i
].Length
:
100 self
.Header
.BlockMap
[i
].NumBlocks
= self
.Header
.FvLength
// self
.Header
.BlockMap
[i
].Length
102 def ModExtHeaderData(self
) -> None:
103 if self
.Header
.ExtHeaderOffset
:
104 ExtHeaderData
= struct2stream(self
.ExtHeader
)
105 ExtHeaderDataOffset
= self
.Header
.ExtHeaderOffset
- self
.HeaderLength
106 self
.Data
= self
.Data
[:ExtHeaderDataOffset
] + ExtHeaderData
+ self
.Data
[ExtHeaderDataOffset
+20:]
107 if self
.Header
.ExtHeaderOffset
and self
.ExtEntryExist
:
108 ExtHeaderEntryData
= struct2stream(self
.ExtEntry
)
109 ExtHeaderEntryDataOffset
= self
.Header
.ExtHeaderOffset
+ 20 - self
.HeaderLength
110 self
.Data
= self
.Data
[:ExtHeaderEntryDataOffset
] + ExtHeaderEntryData
+ self
.Data
[ExtHeaderEntryDataOffset
+len(ExtHeaderEntryData
):]
113 def __init__(self
, buffer: bytes
) -> None:
114 self
.Header
= EFI_FFS_FILE_HEADER
.from_buffer_copy(buffer)
115 # self.Attributes = unpack("<B", buffer[21:22])[0]
116 if self
.Header
.FFS_FILE_SIZE
!= 0 and self
.Header
.Attributes
!= 0xff and self
.Header
.Attributes
& 0x01 == 1:
117 logger
.error('Error Ffs Header! Ffs {} Header Size and Attributes is not matched!'.format(uuid
.UUID(bytes_le
=struct2stream(self
.Header
.Name
))))
118 raise Exception("Process Failed: Error Ffs Header!")
119 if self
.Header
.FFS_FILE_SIZE
== 0 and self
.Header
.Attributes
& 0x01 == 1:
120 self
.Header
= EFI_FFS_FILE_HEADER2
.from_buffer_copy(buffer)
121 self
.Name
= uuid
.UUID(bytes_le
=struct2stream(self
.Header
.Name
))
124 self
.Size
= self
.Header
.FFS_FILE_SIZE
125 self
.HeaderLength
= self
.Header
.HeaderLength
131 self
.SectionMaxAlignment
= SECTION_COMMON_ALIGNMENT
# 4-align
133 def ModCheckSum(self
) -> None:
134 HeaderData
= struct2stream(self
.Header
)
136 for item
in HeaderData
:
138 HeaderSum
-= self
.Header
.State
139 HeaderSum
-= self
.Header
.IntegrityCheck
.Checksum
.File
141 Header
= self
.Header
.IntegrityCheck
.Checksum
.Header
+ 0x100 - HeaderSum
% 0x100
142 self
.Header
.IntegrityCheck
.Checksum
.Header
= Header
% 0x100
145 def __init__(self
, buffer: bytes
) -> None:
146 if buffer[0:3] != b
'\xff\xff\xff':
147 self
.Header
= EFI_COMMON_SECTION_HEADER
.from_buffer_copy(buffer)
149 self
.Header
= EFI_COMMON_SECTION_HEADER2
.from_buffer_copy(buffer)
150 if self
.Header
.Type
in SectionHeaderType
:
151 self
.Name
= SectionHeaderType
[self
.Header
.Type
]
152 elif self
.Header
.Type
== 0:
153 self
.Name
= "EFI_SECTION_ALL"
155 self
.Name
= "SECTION"
156 if self
.Header
.Type
in HeaderType
:
157 self
.ExtHeader
= self
.GetExtHeader(self
.Header
.Type
, buffer[self
.Header
.Common_Header_Size():], (self
.Header
.SECTION_SIZE
-self
.Header
.Common_Header_Size()))
158 self
.HeaderLength
= self
.Header
.Common_Header_Size() + self
.ExtHeader
.ExtHeaderSize()
160 self
.ExtHeader
= None
161 self
.HeaderLength
= self
.Header
.Common_Header_Size()
162 self
.Size
= self
.Header
.SECTION_SIZE
163 self
.Type
= self
.Header
.Type
171 self
.IsPadSection
= False
172 self
.SectionMaxAlignment
= SECTION_COMMON_ALIGNMENT
# 4-align
174 def GetExtHeader(self
, Type
: int, buffer: bytes
, nums
: int=0) -> None:
176 return EFI_COMPRESSION_SECTION
.from_buffer_copy(buffer)
178 return EFI_GUID_DEFINED_SECTION
.from_buffer_copy(buffer)
180 return Get_VERSION_Header((nums
- 2)//2).from_buffer_copy(buffer)
182 return Get_USER_INTERFACE_Header(nums
//2).from_buffer_copy(buffer)
184 return EFI_FREEFORM_SUBTYPE_GUID_SECTION
.from_buffer_copy(buffer)
187 def __init__(self
, buffer: bytes
) -> None:
188 self
.Name
= 'Free_Space'
190 self
.Size
= len(buffer)