xref: /aosp_15_r20/external/coreboot/util/qualcomm/ipqheader.py (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1#!/usr/bin/env python3
2#
3# SPDX-License-Identifier: BSD-3-Clause
4
5import os
6import struct
7import sys
8
9PROG_NAME = os.path.basename(sys.argv[0])
10
11def create_header(base, size):
12    """Returns a packed MBN header image with the specified base and size.
13
14    @arg base: integer, specifies the image load address in RAM
15    @arg size: integer, specifies the size of the image
16    @returns: string, the MBN header
17    """
18
19    # SBLs require size to be 4 bytes aligned.
20    size = (size + 3) & 0xfffffffc
21
22    # We currently do not support appending certificates. Signing GPL
23    # code might violate the GPL. So U-Boot will never be signed. So
24    # this is not required for U-Boot.
25
26    header = [
27        0x5,         # Type: APPSBL
28        0x3,         # Version: 3
29        0x0,         # Image source pointer
30        base,        # Image destination pointer
31        size,        # Code Size + Cert Size + Signature Size
32        size,        # Code Size
33        base + size, # Destination + Code Size
34        0x0,         # Signature Size
35        base + size, # Destination + Code Size + Signature Size
36        0x0,         # Cert Size
37    ]
38
39    header_packed = struct.pack('<10I', *header)
40    return header_packed
41
42def mkheader(base_addr, infname, outfname):
43    """Prepends the image with the MBN header.
44
45    @arg base_addr: integer, specifies the image load address in RAM
46    @arg infname: string, image filename
47    @arg outfname: string, output image with header prepended
48    @raises IOError: if reading/writing input/output file fails
49    """
50    with open(infname, "rb") as infp:
51        image = infp.read()
52        insize = len(image)
53
54    if base_addr > 0xFFFFFFFF:
55        raise ValueError("invalid base address")
56
57    if base_addr + insize > 0xFFFFFFFF:
58        raise ValueError("invalid destination range")
59
60    header = create_header(base_addr, insize)
61    with open(outfname, "wb") as outfp:
62        outfp.write(header)
63        outfp.write(image)
64
65def usage(msg=None):
66    """Print command usage.
67
68    @arg msg: string, error message if any (default: None)
69    """
70    if msg != None:
71        sys.stderr.write("%s: %s\n" % (PROG_NAME, msg))
72
73    print("Usage: %s <base-addr> <input-file> <output-file>" % PROG_NAME)
74
75    if msg != None:
76        exit(1)
77
78def main():
79    """Main entry function"""
80
81    if len(sys.argv) != 4:
82        usage("incorrect number of arguments")
83
84    try:
85        base_addr = int(sys.argv[1], 0)
86        infname = sys.argv[2]
87        outfname = sys.argv[3]
88    except ValueError as e:
89        sys.stderr.write("mkheader: invalid base address '%s'\n" % sys.argv[1])
90        exit(1)
91
92    try:
93        mkheader(base_addr, infname, outfname)
94    except IOError as e:
95        sys.stderr.write("%s: %s\n" % (PROG_NAME, e))
96        exit(1)
97    except ValueError as e:
98        sys.stderr.write("%s: %s\n" % (PROG_NAME, e))
99        exit(1)
100
101if __name__ == "__main__":
102    main()
103