]> git.proxmox.com Git - mirror_edk2.git/blobdiff - 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
diff --git a/BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleHeader.py b/BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleHeader.py
new file mode 100644 (file)
index 0000000..cfe1cb6
--- /dev/null
@@ -0,0 +1,136 @@
+## @file\r
+# Module that encodes and decodes a EFI_CAPSULE_HEADER with a payload\r
+#\r
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+\r
+'''\r
+UefiCapsuleHeader\r
+'''\r
+\r
+import struct\r
+import uuid\r
+\r
+class UefiCapsuleHeaderClass (object):\r
+    # typedef struct {\r
+    #   ///\r
+    #   /// A GUID that defines the contents of a capsule.\r
+    #   ///\r
+    #   EFI_GUID          CapsuleGuid;\r
+    #   ///\r
+    #   /// The size of the capsule header. This may be larger than the size of\r
+    #   /// the EFI_CAPSULE_HEADER since CapsuleGuid may imply\r
+    #   /// extended header entries\r
+    #   ///\r
+    #   UINT32            HeaderSize;\r
+    #   ///\r
+    #   /// Bit-mapped list describing the capsule attributes. The Flag values\r
+    #   /// of 0x0000 - 0xFFFF are defined by CapsuleGuid. Flag values\r
+    #   /// of 0x10000 - 0xFFFFFFFF are defined by this specification\r
+    #   ///\r
+    #   UINT32            Flags;\r
+    #   ///\r
+    #   /// Size in bytes of the capsule.\r
+    #   ///\r
+    #   UINT32            CapsuleImageSize;\r
+    # } EFI_CAPSULE_HEADER;\r
+    #\r
+    # #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET          0x00010000\r
+    # #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE         0x00020000\r
+    # #define CAPSULE_FLAGS_INITIATE_RESET                0x00040000\r
+    #\r
+    _StructFormat = '<16sIIII'\r
+    _StructSize   = struct.calcsize (_StructFormat)\r
+\r
+    EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID = uuid.UUID ('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A')\r
+\r
+    _CAPSULE_FLAGS_PERSIST_ACROSS_RESET  = 0x00010000\r
+    _CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE = 0x00020000\r
+    _CAPSULE_FLAGS_INITIATE_RESET        = 0x00040000\r
+\r
+    def __init__ (self):\r
+        self._Valid              = False\r
+        self.CapsuleGuid         = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID\r
+        self.HeaderSize          = self._StructSize\r
+        self.OemFlags            = 0x0000\r
+        self.PersistAcrossReset  = False\r
+        self.PopulateSystemTable = False\r
+        self.InitiateReset       = False\r
+        self.CapsuleImageSize    = self.HeaderSize\r
+        self.Payload             = b''\r
+\r
+    def Encode (self):\r
+        Flags = self.OemFlags\r
+        if self.PersistAcrossReset:\r
+            Flags = Flags | self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET\r
+        if self.PopulateSystemTable:\r
+            Flags = Flags | self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE\r
+        if self.InitiateReset:\r
+            Flags = Flags | self._CAPSULE_FLAGS_INITIATE_RESET\r
+\r
+        self.CapsuleImageSize = self.HeaderSize + len (self.Payload)\r
+\r
+        UefiCapsuleHeader = struct.pack (\r
+                                     self._StructFormat,\r
+                                     self.CapsuleGuid.bytes_le,\r
+                                     self.HeaderSize,\r
+                                     Flags,\r
+                                     self.CapsuleImageSize,\r
+                                     0\r
+                                     )\r
+        self._Valid = True\r
+        return UefiCapsuleHeader + self.Payload\r
+\r
+    def Decode (self, Buffer):\r
+        if len (Buffer) < self._StructSize:\r
+            raise ValueError\r
+        (CapsuleGuid, HeaderSize, Flags, CapsuleImageSize, Reserved) = \\r
+            struct.unpack (\r
+                     self._StructFormat,\r
+                     Buffer[0:self._StructSize]\r
+                     )\r
+        if HeaderSize < self._StructSize:\r
+            raise ValueError\r
+        if CapsuleImageSize != len (Buffer):\r
+            raise ValueError\r
+        self.CapsuleGuid         = uuid.UUID (bytes_le = CapsuleGuid)\r
+        self.HeaderSize          = HeaderSize\r
+        self.OemFlags            = Flags & 0xffff\r
+        self.PersistAcrossReset  = (Flags & self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0\r
+        self.PopulateSystemTable = (Flags & self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0\r
+        self.InitiateReset       = (Flags & self._CAPSULE_FLAGS_INITIATE_RESET) != 0\r
+        self.CapsuleImageSize    = CapsuleImageSize\r
+        self.Payload             = Buffer[self.HeaderSize:]\r
+\r
+        self._Valid              = True\r
+        return self.Payload\r
+\r
+    def DumpInfo (self):\r
+        if not self._Valid:\r
+            raise ValueError\r
+        Flags = self.OemFlags\r
+        if self.PersistAcrossReset:\r
+            Flags = Flags | self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET\r
+        if self.PopulateSystemTable:\r
+            Flags = Flags | self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE\r
+        if self.InitiateReset:\r
+            Flags = Flags | self._CAPSULE_FLAGS_INITIATE_RESET\r
+        print ('EFI_CAPSULE_HEADER.CapsuleGuid      = {Guid}'.format (Guid = str(self.CapsuleGuid).upper()))\r
+        print ('EFI_CAPSULE_HEADER.HeaderSize       = {Size:08X}'.format (Size = self.HeaderSize))\r
+        print ('EFI_CAPSULE_HEADER.Flags            = {Flags:08X}'.format (Flags = Flags))\r
+        print ('  OEM Flags                         = {Flags:04X}'.format (Flags = self.OemFlags))\r
+        if self.PersistAcrossReset:\r
+            print ('  CAPSULE_FLAGS_PERSIST_ACROSS_RESET')\r
+        if self.PopulateSystemTable:\r
+            print ('  CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE')\r
+        if self.InitiateReset:\r
+            print ('  CAPSULE_FLAGS_INITIATE_RESET')\r
+        print ('EFI_CAPSULE_HEADER.CapsuleImageSize = {Size:08X}'.format (Size = self.CapsuleImageSize))\r
+        print ('sizeof (Payload)                    = {Size:08X}'.format (Size = len (self.Payload)))\r