]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/FMMT/core/BiosTreeNode.py
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / BaseTools / Source / Python / FMMT / core / BiosTreeNode.py
1 ## @file
2 # This file is used to define the BIOS Tree Node.
3 #
4 # Copyright (c) 2021-, Intel Corporation. All rights reserved.<BR>
5 # SPDX-License-Identifier: BSD-2-Clause-Patent
6 ##
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
12 import uuid
13
14 SectionHeaderType = {
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'
30 }
31 HeaderType = [0x01, 0x02, 0x14, 0x15, 0x18]
32
33 class BinaryNode:
34 def __init__(self, name: str) -> None:
35 self.Size = 0
36 self.Name = "BINARY" + str(name)
37 self.HOffset = 0
38 self.Data = b''
39
40 class FvNode:
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:])
54 self.ExtTypeExist = 1
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:])
63 else:
64 self.ExtTypeExist = 0
65 else:
66 self.ExtEntryExist = 0
67 self.Size = self.Header.FvLength
68 self.HeaderLength = self.Header.HeaderLength
69 self.HOffset = 0
70 self.DOffset = 0
71 self.ROffset = 0
72 self.Data = b''
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!")
76 self.PadData = b''
77 self.Free_Space = 0
78 self.ModCheckSum()
79
80 def ModCheckSum(self) -> None:
81 # Fv Header Sums to 0.
82 Header = struct2stream(self.Header)[::-1]
83 Size = self.HeaderLength // 2
84 Sum = 0
85 for i in range(Size):
86 Sum += int(Header[i*2: i*2 + 2].hex(), 16)
87 if Sum & 0xffff:
88 self.Header.Checksum = 0x10000 - (Sum - self.Header.Checksum) % 0x10000
89
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
94
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
101
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):]
111
112 class FfsNode:
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))
122 self.UiName = b''
123 self.Version = b''
124 self.Size = self.Header.FFS_FILE_SIZE
125 self.HeaderLength = self.Header.HeaderLength
126 self.HOffset = 0
127 self.DOffset = 0
128 self.ROffset = 0
129 self.Data = b''
130 self.PadData = b''
131 self.SectionMaxAlignment = SECTION_COMMON_ALIGNMENT # 4-align
132
133 def ModCheckSum(self) -> None:
134 HeaderData = struct2stream(self.Header)
135 HeaderSum = 0
136 for item in HeaderData:
137 HeaderSum += item
138 HeaderSum -= self.Header.State
139 HeaderSum -= self.Header.IntegrityCheck.Checksum.File
140 if HeaderSum & 0xff:
141 Header = self.Header.IntegrityCheck.Checksum.Header + 0x100 - HeaderSum % 0x100
142 self.Header.IntegrityCheck.Checksum.Header = Header % 0x100
143
144 class SectionNode:
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)
148 else:
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"
154 else:
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()
159 else:
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
164 self.HOffset = 0
165 self.DOffset = 0
166 self.ROffset = 0
167 self.Data = b''
168 self.OriData = b''
169 self.OriHeader = b''
170 self.PadData = b''
171 self.IsPadSection = False
172 self.SectionMaxAlignment = SECTION_COMMON_ALIGNMENT # 4-align
173
174 def GetExtHeader(self, Type: int, buffer: bytes, nums: int=0) -> None:
175 if Type == 0x01:
176 return EFI_COMPRESSION_SECTION.from_buffer_copy(buffer)
177 elif Type == 0x02:
178 return EFI_GUID_DEFINED_SECTION.from_buffer_copy(buffer)
179 elif Type == 0x14:
180 return Get_VERSION_Header((nums - 2)//2).from_buffer_copy(buffer)
181 elif Type == 0x15:
182 return Get_USER_INTERFACE_Header(nums//2).from_buffer_copy(buffer)
183 elif Type == 0x18:
184 return EFI_FREEFORM_SUBTYPE_GUID_SECTION.from_buffer_copy(buffer)
185
186 class FreeSpaceNode:
187 def __init__(self, buffer: bytes) -> None:
188 self.Name = 'Free_Space'
189 self.Data = buffer
190 self.Size = len(buffer)
191 self.HOffset = 0
192 self.DOffset = 0
193 self.ROffset = 0
194 self.PadData = b''