]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / Python / Common / Uefi / Capsule / FmpCapsuleHeader.py
CommitLineData
8b63877a
KM
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, Intel Corporation. All rights reserved.<BR>\r
2e351cbe 6# SPDX-License-Identifier: BSD-2-Clause-Patent\r
8b63877a
KM
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 # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER;\r
51 #\r
52 # #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION 0x00000002\r
53\r
54 _StructFormat = '<I16sB3BIIQ'\r
55 _StructSize = struct.calcsize (_StructFormat)\r
56\r
57 EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION = 0x00000002\r
58\r
59 def __init__ (self):\r
60 self._Valid = False\r
61 self.Version = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION\r
62 self.UpdateImageTypeId = uuid.UUID ('00000000-0000-0000-0000-000000000000')\r
63 self.UpdateImageIndex = 0\r
64 self.UpdateImageSize = 0\r
65 self.UpdateVendorCodeSize = 0\r
66 self.UpdateHardwareInstance = 0x0000000000000000\r
67 self.Payload = b''\r
68 self.VendorCodeBytes = b''\r
69\r
70 def Encode (self):\r
71 self.UpdateImageSize = len (self.Payload)\r
72 self.UpdateVendorCodeSize = len (self.VendorCodeBytes)\r
73 FmpCapsuleImageHeader = struct.pack (\r
74 self._StructFormat,\r
75 self.Version,\r
76 self.UpdateImageTypeId.bytes_le,\r
77 self.UpdateImageIndex,\r
78 0,0,0,\r
79 self.UpdateImageSize,\r
80 self.UpdateVendorCodeSize,\r
81 self.UpdateHardwareInstance\r
82 )\r
83 self._Valid = True\r
84 return FmpCapsuleImageHeader + self.Payload + self.VendorCodeBytes\r
85\r
86 def Decode (self, Buffer):\r
87 if len (Buffer) < self._StructSize:\r
88 raise ValueError\r
89 (Version, UpdateImageTypeId, UpdateImageIndex, r0, r1, r2, UpdateImageSize, UpdateVendorCodeSize, UpdateHardwareInstance) = \\r
90 struct.unpack (\r
91 self._StructFormat,\r
92 Buffer[0:self._StructSize]\r
93 )\r
94\r
95 if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION:\r
96 raise ValueError\r
97 if UpdateImageIndex < 1:\r
98 raise ValueError\r
99 if UpdateImageSize + UpdateVendorCodeSize != len (Buffer[self._StructSize:]):\r
100 raise ValueError\r
101\r
102 self.Version = Version\r
103 self.UpdateImageTypeId = uuid.UUID (bytes_le = UpdateImageTypeId)\r
104 self.UpdateImageIndex = UpdateImageIndex\r
105 self.UpdateImageSize = UpdateImageSize\r
106 self.UpdateVendorCodeSize = UpdateVendorCodeSize\r
107 self.UpdateHardwareInstance = UpdateHardwareInstance\r
108 self.Payload = Buffer[self._StructSize:self._StructSize + UpdateImageSize]\r
109 self.VendorCodeBytes = Buffer[self._StructSize + UpdateImageSize:]\r
110 self._Valid = True\r
111 return Buffer[self._StructSize:]\r
112\r
113 def DumpInfo (self):\r
114 if not self._Valid:\r
115 raise ValueError\r
116 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.Version = {Version:08X}'.format (Version = self.Version))\r
117 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageTypeId = {UpdateImageTypeId}'.format (UpdateImageTypeId = str(self.UpdateImageTypeId).upper()))\r
118 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageIndex = {UpdateImageIndex:08X}'.format (UpdateImageIndex = self.UpdateImageIndex))\r
119 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageSize = {UpdateImageSize:08X}'.format (UpdateImageSize = self.UpdateImageSize))\r
120 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateVendorCodeSize = {UpdateVendorCodeSize:08X}'.format (UpdateVendorCodeSize = self.UpdateVendorCodeSize))\r
121 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateHardwareInstance = {UpdateHardwareInstance:016X}'.format (UpdateHardwareInstance = self.UpdateHardwareInstance))\r
122 print ('sizeof (Payload) = {Size:08X}'.format (Size = len (self.Payload)))\r
123 print ('sizeof (VendorCodeBytes) = {Size:08X}'.format (Size = len (self.VendorCodeBytes)))\r
124\r
125class FmpCapsuleHeaderClass (object):\r
126 # typedef struct {\r
127 # UINT32 Version;\r
128 #\r
129 # ///\r
130 # /// The number of drivers included in the capsule and the number of corresponding\r
131 # /// offsets stored in ItemOffsetList array.\r
132 # ///\r
133 # UINT16 EmbeddedDriverCount;\r
134 #\r
135 # ///\r
136 # /// The number of payload items included in the capsule and the number of\r
137 # /// corresponding offsets stored in the ItemOffsetList array.\r
138 # ///\r
139 # UINT16 PayloadItemCount;\r
140 #\r
141 # ///\r
142 # /// Variable length array of dimension [EmbeddedDriverCount + PayloadItemCount]\r
143 # /// containing offsets of each of the drivers and payload items contained within the capsule\r
144 # ///\r
145 # // UINT64 ItemOffsetList[];\r
146 # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER;\r
147 #\r
148 # #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION 0x00000001\r
149 _StructFormat = '<IHH'\r
150 _StructSize = struct.calcsize (_StructFormat)\r
151\r
152 _ItemOffsetFormat = '<Q'\r
153 _ItemOffsetSize = struct.calcsize (_ItemOffsetFormat)\r
154\r
155 EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION = 0x00000001\r
156\r
157 def __init__ (self):\r
158 self._Valid = False\r
159 self.Version = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION\r
160 self.EmbeddedDriverCount = 0\r
161 self.PayloadItemCount = 0\r
162 self._ItemOffsetList = []\r
163 self._EmbeddedDriverList = []\r
164 self._PayloadList = []\r
165 self._FmpCapsuleImageHeaderList = []\r
166\r
167 def AddEmbeddedDriver (self, EmbeddedDriver):\r
168 self._EmbeddedDriverList.append (EmbeddedDriver)\r
169\r
170 def GetEmbeddedDriver (self, Index):\r
171 if Index > len (self._EmbeddedDriverList):\r
172 raise ValueError\r
173 return self._EmbeddedDriverList[Index]\r
174\r
175 def AddPayload (self, UpdateImageTypeId, Payload = b'', VendorCodeBytes = b'', HardwareInstance = 0):\r
176 self._PayloadList.append ((UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstance))\r
177\r
178 def GetFmpCapsuleImageHeader (self, Index):\r
179 if Index >= len (self._FmpCapsuleImageHeaderList):\r
180 raise ValueError\r
181 return self._FmpCapsuleImageHeaderList[Index]\r
182\r
183 def Encode (self):\r
184 self.EmbeddedDriverCount = len (self._EmbeddedDriverList)\r
185 self.PayloadItemCount = len (self._PayloadList)\r
186\r
187 FmpCapsuleHeader = struct.pack (\r
188 self._StructFormat,\r
189 self.Version,\r
190 self.EmbeddedDriverCount,\r
191 self.PayloadItemCount\r
192 )\r
193\r
194 FmpCapsuleData = b''\r
195 Offset = self._StructSize + (self.EmbeddedDriverCount + self.PayloadItemCount) * self._ItemOffsetSize\r
196 for EmbeddedDriver in self._EmbeddedDriverList:\r
197 FmpCapsuleData = FmpCapsuleData + EmbeddedDriver\r
198 self._ItemOffsetList.append (Offset)\r
199 Offset = Offset + len (EmbeddedDriver)\r
200 Index = 1\r
201 for (UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstance) in self._PayloadList:\r
202 FmpCapsuleImageHeader = FmpCapsuleImageHeaderClass ()\r
203 FmpCapsuleImageHeader.UpdateImageTypeId = UpdateImageTypeId\r
204 FmpCapsuleImageHeader.UpdateImageIndex = Index\r
205 FmpCapsuleImageHeader.Payload = Payload\r
206 FmpCapsuleImageHeader.VendorCodeBytes = VendorCodeBytes\r
207 FmpCapsuleImageHeader.UpdateHardwareInstance = HardwareInstance\r
208 FmpCapsuleImage = FmpCapsuleImageHeader.Encode ()\r
209 FmpCapsuleData = FmpCapsuleData + FmpCapsuleImage\r
210\r
211 self._ItemOffsetList.append (Offset)\r
212 self._FmpCapsuleImageHeaderList.append (FmpCapsuleImageHeader)\r
213\r
214 Offset = Offset + len (FmpCapsuleImage)\r
215 Index = Index + 1\r
216\r
217 for Offset in self._ItemOffsetList:\r
218 FmpCapsuleHeader = FmpCapsuleHeader + struct.pack (self._ItemOffsetFormat, Offset)\r
219\r
220 self._Valid = True\r
221 return FmpCapsuleHeader + FmpCapsuleData\r
222\r
223 def Decode (self, Buffer):\r
224 if len (Buffer) < self._StructSize:\r
225 raise ValueError\r
226 (Version, EmbeddedDriverCount, PayloadItemCount) = \\r
227 struct.unpack (\r
228 self._StructFormat,\r
229 Buffer[0:self._StructSize]\r
230 )\r
231 if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION:\r
232 raise ValueError\r
233\r
234 self.Version = Version\r
235 self.EmbeddedDriverCount = EmbeddedDriverCount\r
236 self.PayloadItemCount = PayloadItemCount\r
237 self._ItemOffsetList = []\r
238 self._EmbeddedDriverList = []\r
239 self._PayloadList = []\r
240 self._FmpCapsuleImageHeaderList = []\r
241\r
242 #\r
243 # Parse the ItemOffsetList values\r
244 #\r
245 Offset = self._StructSize\r
246 for Index in range (0, EmbeddedDriverCount + PayloadItemCount):\r
247 ItemOffset = struct.unpack (self._ItemOffsetFormat, Buffer[Offset:Offset + self._ItemOffsetSize])[0]\r
248 if ItemOffset >= len (Buffer):\r
249 raise ValueError\r
250 self._ItemOffsetList.append (ItemOffset)\r
251 Offset = Offset + self._ItemOffsetSize\r
252 Result = Buffer[Offset:]\r
253\r
254 #\r
255 # Parse the EmbeddedDrivers\r
256 #\r
257 for Index in range (0, EmbeddedDriverCount):\r
258 Offset = self._ItemOffsetList[Index]\r
259 if Index < (len (self._ItemOffsetList) - 1):\r
260 Length = self._ItemOffsetList[Index + 1] - Offset\r
261 else:\r
262 Length = len (Buffer) - Offset\r
263 self.AddEmbeddedDriver (Buffer[Offset:Offset + Length])\r
264\r
265 #\r
266 # Parse the Payloads that are FMP Capsule Images\r
267 #\r
268 for Index in range (EmbeddedDriverCount, EmbeddedDriverCount + PayloadItemCount):\r
269 Offset = self._ItemOffsetList[Index]\r
270 if Index < (len (self._ItemOffsetList) - 1):\r
271 Length = self._ItemOffsetList[Index + 1] - Offset\r
272 else:\r
273 Length = len (Buffer) - Offset\r
274 FmpCapsuleImageHeader = FmpCapsuleImageHeaderClass ()\r
275 FmpCapsuleImageHeader.Decode (Buffer[Offset:Offset + Length])\r
276 self.AddPayload (\r
277 FmpCapsuleImageHeader.UpdateImageTypeId,\r
278 FmpCapsuleImageHeader.Payload,\r
279 FmpCapsuleImageHeader.VendorCodeBytes\r
280 )\r
281 self._FmpCapsuleImageHeaderList.append (FmpCapsuleImageHeader)\r
282\r
283 self._Valid = True\r
284 return Result\r
285\r
286 def DumpInfo (self):\r
287 if not self._Valid:\r
288 raise ValueError\r
289 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version = {Version:08X}'.format (Version = self.Version))\r
290 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverCount = {EmbeddedDriverCount:08X}'.format (EmbeddedDriverCount = self.EmbeddedDriverCount))\r
291 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCount = {PayloadItemCount:08X}'.format (PayloadItemCount = self.PayloadItemCount))\r
292 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.ItemOffsetList = ')\r
293 for Offset in self._ItemOffsetList:\r
294 print (' {Offset:016X}'.format (Offset = Offset))\r
295 for FmpCapsuleImageHeader in self._FmpCapsuleImageHeaderList:\r
296 FmpCapsuleImageHeader.DumpInfo ()\r