]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / BaseTools / Source / Python / Common / Uefi / Capsule / FmpCapsuleHeader.py
... / ...
CommitLineData
1## @file\r
2# Module that encodes and decodes a EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER with\r
3# a payload.\r
4#\r
5# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>\r
6# SPDX-License-Identifier: BSD-2-Clause-Patent\r
7#\r
8\r
9'''\r
10FmpCapsuleHeader\r
11'''\r
12\r
13import struct\r
14import uuid\r
15\r
16class FmpCapsuleImageHeaderClass (object):\r
17 # typedef struct {\r
18 # UINT32 Version;\r
19 #\r
20 # ///\r
21 # /// Used to identify device firmware targeted by this update. This guid is matched by\r
22 # /// system firmware against ImageTypeId field within a EFI_FIRMWARE_IMAGE_DESCRIPTOR\r
23 # ///\r
24 # EFI_GUID UpdateImageTypeId;\r
25 #\r
26 # ///\r
27 # /// Passed as ImageIndex in call to EFI_FIRMWARE_MANAGEMENT_PROTOCOL.SetImage ()\r
28 # ///\r
29 # UINT8 UpdateImageIndex;\r
30 # UINT8 reserved_bytes[3];\r
31 #\r
32 # ///\r
33 # /// Size of the binary update image which immediately follows this structure\r
34 # ///\r
35 # UINT32 UpdateImageSize;\r
36 #\r
37 # ///\r
38 # /// Size of the VendorCode bytes which optionally immediately follow binary update image in the capsule\r
39 # ///\r
40 # UINT32 UpdateVendorCodeSize;\r
41 #\r
42 # ///\r
43 # /// The HardwareInstance to target with this update. If value is zero it means match all\r
44 # /// HardwareInstances. This field allows update software to target only a single device in\r
45 # /// cases where there are more than one device with the same ImageTypeId GUID.\r
46 # /// This header is outside the signed data of the Authentication Info structure and\r
47 # /// therefore can be modified without changing the Auth data.\r
48 # ///\r
49 # UINT64 UpdateHardwareInstance;\r
50 #\r
51 # ///\r
52 # /// Bits which indicate authentication and depex information for the image that follows this structure\r
53 # ///\r
54 # UINT64 ImageCapsuleSupport\r
55 # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER;\r
56 #\r
57 # #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION 0x00000003\r
58\r
59 _StructFormat = '<I16sB3BIIQQ'\r
60 _StructSize = struct.calcsize (_StructFormat)\r
61\r
62 EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION = 0x00000003\r
63\r
64 def __init__ (self):\r
65 self._Valid = False\r
66 self.Version = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION\r
67 self.UpdateImageTypeId = uuid.UUID ('00000000-0000-0000-0000-000000000000')\r
68 self.UpdateImageIndex = 0\r
69 self.UpdateImageSize = 0\r
70 self.UpdateVendorCodeSize = 0\r
71 self.UpdateHardwareInstance = 0x0000000000000000\r
72 self.ImageCapsuleSupport = 0x0000000000000000\r
73 self.Payload = b''\r
74 self.VendorCodeBytes = b''\r
75\r
76 def Encode (self):\r
77 self.UpdateImageSize = len (self.Payload)\r
78 self.UpdateVendorCodeSize = len (self.VendorCodeBytes)\r
79 FmpCapsuleImageHeader = struct.pack (\r
80 self._StructFormat,\r
81 self.Version,\r
82 self.UpdateImageTypeId.bytes_le,\r
83 self.UpdateImageIndex,\r
84 0,0,0,\r
85 self.UpdateImageSize,\r
86 self.UpdateVendorCodeSize,\r
87 self.UpdateHardwareInstance,\r
88 self.ImageCapsuleSupport\r
89 )\r
90 self._Valid = True\r
91 return FmpCapsuleImageHeader + self.Payload + self.VendorCodeBytes\r
92\r
93 def Decode (self, Buffer):\r
94 if len (Buffer) < self._StructSize:\r
95 raise ValueError\r
96 (Version, UpdateImageTypeId, UpdateImageIndex, r0, r1, r2, UpdateImageSize, UpdateVendorCodeSize, UpdateHardwareInstance, ImageCapsuleSupport) = \\r
97 struct.unpack (\r
98 self._StructFormat,\r
99 Buffer[0:self._StructSize]\r
100 )\r
101\r
102 if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION:\r
103 raise ValueError\r
104 if UpdateImageIndex < 1:\r
105 raise ValueError\r
106 if UpdateImageSize + UpdateVendorCodeSize != len (Buffer[self._StructSize:]):\r
107 raise ValueError\r
108\r
109 self.Version = Version\r
110 self.UpdateImageTypeId = uuid.UUID (bytes_le = UpdateImageTypeId)\r
111 self.UpdateImageIndex = UpdateImageIndex\r
112 self.UpdateImageSize = UpdateImageSize\r
113 self.UpdateVendorCodeSize = UpdateVendorCodeSize\r
114 self.UpdateHardwareInstance = UpdateHardwareInstance\r
115 self.ImageCapsuleSupport = ImageCapsuleSupport\r
116 self.Payload = Buffer[self._StructSize:self._StructSize + UpdateImageSize]\r
117 self.VendorCodeBytes = Buffer[self._StructSize + UpdateImageSize:]\r
118 self._Valid = True\r
119 return Buffer[self._StructSize:]\r
120\r
121 def DumpInfo (self):\r
122 if not self._Valid:\r
123 raise ValueError\r
124 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.Version = {Version:08X}'.format (Version = self.Version))\r
125 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageTypeId = {UpdateImageTypeId}'.format (UpdateImageTypeId = str(self.UpdateImageTypeId).upper()))\r
126 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageIndex = {UpdateImageIndex:08X}'.format (UpdateImageIndex = self.UpdateImageIndex))\r
127 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageSize = {UpdateImageSize:08X}'.format (UpdateImageSize = self.UpdateImageSize))\r
128 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateVendorCodeSize = {UpdateVendorCodeSize:08X}'.format (UpdateVendorCodeSize = self.UpdateVendorCodeSize))\r
129 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateHardwareInstance = {UpdateHardwareInstance:016X}'.format (UpdateHardwareInstance = self.UpdateHardwareInstance))\r
130 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.ImageCapsuleSupport = {ImageCapsuleSupport:016X}'.format (ImageCapsuleSupport = self.ImageCapsuleSupport))\r
131 print ('sizeof (Payload) = {Size:08X}'.format (Size = len (self.Payload)))\r
132 print ('sizeof (VendorCodeBytes) = {Size:08X}'.format (Size = len (self.VendorCodeBytes)))\r
133\r
134class FmpCapsuleHeaderClass (object):\r
135 # typedef struct {\r
136 # UINT32 Version;\r
137 #\r
138 # ///\r
139 # /// The number of drivers included in the capsule and the number of corresponding\r
140 # /// offsets stored in ItemOffsetList array.\r
141 # ///\r
142 # UINT16 EmbeddedDriverCount;\r
143 #\r
144 # ///\r
145 # /// The number of payload items included in the capsule and the number of\r
146 # /// corresponding offsets stored in the ItemOffsetList array.\r
147 # ///\r
148 # UINT16 PayloadItemCount;\r
149 #\r
150 # ///\r
151 # /// Variable length array of dimension [EmbeddedDriverCount + PayloadItemCount]\r
152 # /// containing offsets of each of the drivers and payload items contained within the capsule\r
153 # ///\r
154 # // UINT64 ItemOffsetList[];\r
155 # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER;\r
156 #\r
157 # #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION 0x00000001\r
158 _StructFormat = '<IHH'\r
159 _StructSize = struct.calcsize (_StructFormat)\r
160\r
161 _ItemOffsetFormat = '<Q'\r
162 _ItemOffsetSize = struct.calcsize (_ItemOffsetFormat)\r
163\r
164 EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION = 0x00000001\r
165 CAPSULE_SUPPORT_AUTHENTICATION = 0x0000000000000001\r
166 CAPSULE_SUPPORT_DEPENDENCY = 0x0000000000000002\r
167\r
168 def __init__ (self):\r
169 self._Valid = False\r
170 self.Version = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION\r
171 self.EmbeddedDriverCount = 0\r
172 self.PayloadItemCount = 0\r
173 self._ItemOffsetList = []\r
174 self._EmbeddedDriverList = []\r
175 self._PayloadList = []\r
176 self._FmpCapsuleImageHeaderList = []\r
177\r
178 def AddEmbeddedDriver (self, EmbeddedDriver):\r
179 self._EmbeddedDriverList.append (EmbeddedDriver)\r
180\r
181 def GetEmbeddedDriver (self, Index):\r
182 if Index > len (self._EmbeddedDriverList):\r
183 raise ValueError\r
184 return self._EmbeddedDriverList[Index]\r
185\r
186 def AddPayload (self, UpdateImageTypeId, Payload = b'', VendorCodeBytes = b'', HardwareInstance = 0, UpdateImageIndex = 1, CapsuleSupport = 0):\r
187 self._PayloadList.append ((UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstance, UpdateImageIndex, CapsuleSupport))\r
188\r
189 def GetFmpCapsuleImageHeader (self, Index):\r
190 if Index >= len (self._FmpCapsuleImageHeaderList):\r
191 raise ValueError\r
192 return self._FmpCapsuleImageHeaderList[Index]\r
193\r
194 def Encode (self):\r
195 self.EmbeddedDriverCount = len (self._EmbeddedDriverList)\r
196 self.PayloadItemCount = len (self._PayloadList)\r
197\r
198 FmpCapsuleHeader = struct.pack (\r
199 self._StructFormat,\r
200 self.Version,\r
201 self.EmbeddedDriverCount,\r
202 self.PayloadItemCount\r
203 )\r
204\r
205 FmpCapsuleData = b''\r
206 Offset = self._StructSize + (self.EmbeddedDriverCount + self.PayloadItemCount) * self._ItemOffsetSize\r
207 for EmbeddedDriver in self._EmbeddedDriverList:\r
208 FmpCapsuleData = FmpCapsuleData + EmbeddedDriver\r
209 self._ItemOffsetList.append (Offset)\r
210 Offset = Offset + len (EmbeddedDriver)\r
211 Index = 1\r
212 for (UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstance, UpdateImageIndex, CapsuleSupport) in self._PayloadList:\r
213 FmpCapsuleImageHeader = FmpCapsuleImageHeaderClass ()\r
214 FmpCapsuleImageHeader.UpdateImageTypeId = UpdateImageTypeId\r
215 FmpCapsuleImageHeader.UpdateImageIndex = UpdateImageIndex\r
216 FmpCapsuleImageHeader.Payload = Payload\r
217 FmpCapsuleImageHeader.VendorCodeBytes = VendorCodeBytes\r
218 FmpCapsuleImageHeader.UpdateHardwareInstance = HardwareInstance\r
219 FmpCapsuleImageHeader.ImageCapsuleSupport = CapsuleSupport\r
220 FmpCapsuleImage = FmpCapsuleImageHeader.Encode ()\r
221 FmpCapsuleData = FmpCapsuleData + FmpCapsuleImage\r
222\r
223 self._ItemOffsetList.append (Offset)\r
224 self._FmpCapsuleImageHeaderList.append (FmpCapsuleImageHeader)\r
225\r
226 Offset = Offset + len (FmpCapsuleImage)\r
227 Index = Index + 1\r
228\r
229 for Offset in self._ItemOffsetList:\r
230 FmpCapsuleHeader = FmpCapsuleHeader + struct.pack (self._ItemOffsetFormat, Offset)\r
231\r
232 self._Valid = True\r
233 return FmpCapsuleHeader + FmpCapsuleData\r
234\r
235 def Decode (self, Buffer):\r
236 if len (Buffer) < self._StructSize:\r
237 raise ValueError\r
238 (Version, EmbeddedDriverCount, PayloadItemCount) = \\r
239 struct.unpack (\r
240 self._StructFormat,\r
241 Buffer[0:self._StructSize]\r
242 )\r
243 if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION:\r
244 raise ValueError\r
245\r
246 self.Version = Version\r
247 self.EmbeddedDriverCount = EmbeddedDriverCount\r
248 self.PayloadItemCount = PayloadItemCount\r
249 self._ItemOffsetList = []\r
250 self._EmbeddedDriverList = []\r
251 self._PayloadList = []\r
252 self._FmpCapsuleImageHeaderList = []\r
253\r
254 #\r
255 # Parse the ItemOffsetList values\r
256 #\r
257 Offset = self._StructSize\r
258 for Index in range (0, EmbeddedDriverCount + PayloadItemCount):\r
259 ItemOffset = struct.unpack (self._ItemOffsetFormat, Buffer[Offset:Offset + self._ItemOffsetSize])[0]\r
260 if ItemOffset >= len (Buffer):\r
261 raise ValueError\r
262 self._ItemOffsetList.append (ItemOffset)\r
263 Offset = Offset + self._ItemOffsetSize\r
264 Result = Buffer[Offset:]\r
265\r
266 #\r
267 # Parse the EmbeddedDrivers\r
268 #\r
269 for Index in range (0, EmbeddedDriverCount):\r
270 Offset = self._ItemOffsetList[Index]\r
271 if Index < (len (self._ItemOffsetList) - 1):\r
272 Length = self._ItemOffsetList[Index + 1] - Offset\r
273 else:\r
274 Length = len (Buffer) - Offset\r
275 self.AddEmbeddedDriver (Buffer[Offset:Offset + Length])\r
276\r
277 #\r
278 # Parse the Payloads that are FMP Capsule Images\r
279 #\r
280 for Index in range (EmbeddedDriverCount, EmbeddedDriverCount + PayloadItemCount):\r
281 Offset = self._ItemOffsetList[Index]\r
282 if Index < (len (self._ItemOffsetList) - 1):\r
283 Length = self._ItemOffsetList[Index + 1] - Offset\r
284 else:\r
285 Length = len (Buffer) - Offset\r
286 FmpCapsuleImageHeader = FmpCapsuleImageHeaderClass ()\r
287 FmpCapsuleImageHeader.Decode (Buffer[Offset:Offset + Length])\r
288 self.AddPayload (\r
289 FmpCapsuleImageHeader.UpdateImageTypeId,\r
290 FmpCapsuleImageHeader.Payload,\r
291 FmpCapsuleImageHeader.VendorCodeBytes\r
292 )\r
293 self._FmpCapsuleImageHeaderList.append (FmpCapsuleImageHeader)\r
294\r
295 self._Valid = True\r
296 return Result\r
297\r
298 def DumpInfo (self):\r
299 if not self._Valid:\r
300 raise ValueError\r
301 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version = {Version:08X}'.format (Version = self.Version))\r
302 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverCount = {EmbeddedDriverCount:08X}'.format (EmbeddedDriverCount = self.EmbeddedDriverCount))\r
303 for EmbeddedDriver in self._EmbeddedDriverList:\r
304 print (' sizeof (EmbeddedDriver) = {Size:08X}'.format (Size = len (EmbeddedDriver)))\r
305 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCount = {PayloadItemCount:08X}'.format (PayloadItemCount = self.PayloadItemCount))\r
306 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.ItemOffsetList = ')\r
307 for Offset in self._ItemOffsetList:\r
308 print (' {Offset:016X}'.format (Offset = Offset))\r
309 for FmpCapsuleImageHeader in self._FmpCapsuleImageHeaderList:\r
310 FmpCapsuleImageHeader.DumpInfo ()\r