]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleHeader.py
BaseTools/Capsule: Add Capsule Generation Tools
[mirror_edk2.git] / BaseTools / Source / Python / Common / Uefi / Capsule / UefiCapsuleHeader.py
1 ## @file
2 # Module that encodes and decodes a EFI_CAPSULE_HEADER with a payload
3 #
4 # Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
9 #
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 #
13
14 '''
15 UefiCapsuleHeader
16 '''
17
18 import struct
19 import uuid
20
21 class UefiCapsuleHeaderClass (object):
22 # typedef struct {
23 # ///
24 # /// A GUID that defines the contents of a capsule.
25 # ///
26 # EFI_GUID CapsuleGuid;
27 # ///
28 # /// The size of the capsule header. This may be larger than the size of
29 # /// the EFI_CAPSULE_HEADER since CapsuleGuid may imply
30 # /// extended header entries
31 # ///
32 # UINT32 HeaderSize;
33 # ///
34 # /// Bit-mapped list describing the capsule attributes. The Flag values
35 # /// of 0x0000 - 0xFFFF are defined by CapsuleGuid. Flag values
36 # /// of 0x10000 - 0xFFFFFFFF are defined by this specification
37 # ///
38 # UINT32 Flags;
39 # ///
40 # /// Size in bytes of the capsule.
41 # ///
42 # UINT32 CapsuleImageSize;
43 # } EFI_CAPSULE_HEADER;
44 #
45 # #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000
46 # #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000
47 # #define CAPSULE_FLAGS_INITIATE_RESET 0x00040000
48 #
49 _StructFormat = '<16sIIII'
50 _StructSize = struct.calcsize (_StructFormat)
51
52 EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID = uuid.UUID ('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A')
53
54 _CAPSULE_FLAGS_PERSIST_ACROSS_RESET = 0x00010000
55 _CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE = 0x00020000
56 _CAPSULE_FLAGS_INITIATE_RESET = 0x00040000
57
58 def __init__ (self):
59 self._Valid = False
60 self.CapsuleGuid = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID
61 self.HeaderSize = self._StructSize
62 self.OemFlags = 0x0000
63 self.PersistAcrossReset = False
64 self.PopulateSystemTable = False
65 self.InitiateReset = False
66 self.CapsuleImageSize = self.HeaderSize
67 self.Payload = b''
68
69 def Encode (self):
70 Flags = self.OemFlags
71 if self.PersistAcrossReset:
72 Flags = Flags | self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET
73 if self.PopulateSystemTable:
74 Flags = Flags | self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
75 if self.InitiateReset:
76 Flags = Flags | self._CAPSULE_FLAGS_INITIATE_RESET
77
78 self.CapsuleImageSize = self.HeaderSize + len (self.Payload)
79
80 UefiCapsuleHeader = struct.pack (
81 self._StructFormat,
82 self.CapsuleGuid.bytes_le,
83 self.HeaderSize,
84 Flags,
85 self.CapsuleImageSize,
86 0
87 )
88 self._Valid = True
89 return UefiCapsuleHeader + self.Payload
90
91 def Decode (self, Buffer):
92 if len (Buffer) < self._StructSize:
93 raise ValueError
94 (CapsuleGuid, HeaderSize, Flags, CapsuleImageSize, Reserved) = \
95 struct.unpack (
96 self._StructFormat,
97 Buffer[0:self._StructSize]
98 )
99 if HeaderSize < self._StructSize:
100 raise ValueError
101 if CapsuleImageSize != len (Buffer):
102 raise ValueError
103 self.CapsuleGuid = uuid.UUID (bytes_le = CapsuleGuid)
104 self.HeaderSize = HeaderSize
105 self.OemFlags = Flags & 0xffff
106 self.PersistAcrossReset = (Flags & self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0
107 self.PopulateSystemTable = (Flags & self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0
108 self.InitiateReset = (Flags & self._CAPSULE_FLAGS_INITIATE_RESET) != 0
109 self.CapsuleImageSize = CapsuleImageSize
110 self.Payload = Buffer[self.HeaderSize:]
111
112 self._Valid = True
113 return self.Payload
114
115 def DumpInfo (self):
116 if not self._Valid:
117 raise ValueError
118 Flags = self.OemFlags
119 if self.PersistAcrossReset:
120 Flags = Flags | self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET
121 if self.PopulateSystemTable:
122 Flags = Flags | self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
123 if self.InitiateReset:
124 Flags = Flags | self._CAPSULE_FLAGS_INITIATE_RESET
125 print ('EFI_CAPSULE_HEADER.CapsuleGuid = {Guid}'.format (Guid = str(self.CapsuleGuid).upper()))
126 print ('EFI_CAPSULE_HEADER.HeaderSize = {Size:08X}'.format (Size = self.HeaderSize))
127 print ('EFI_CAPSULE_HEADER.Flags = {Flags:08X}'.format (Flags = Flags))
128 print (' OEM Flags = {Flags:04X}'.format (Flags = self.OemFlags))
129 if self.PersistAcrossReset:
130 print (' CAPSULE_FLAGS_PERSIST_ACROSS_RESET')
131 if self.PopulateSystemTable:
132 print (' CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE')
133 if self.InitiateReset:
134 print (' CAPSULE_FLAGS_INITIATE_RESET')
135 print ('EFI_CAPSULE_HEADER.CapsuleImageSize = {Size:08X}'.format (Size = self.CapsuleImageSize))
136 print ('sizeof (Payload) = {Size:08X}'.format (Size = len (self.Payload)))