xref: /optee_os/core/arch/arm/plat-telechips/scripts/tcmktool.py (revision 2c33d6e619724d2b4dde24a1bda620c0fc65188d)
1#!/usr/bin/env python3
2# SPDX-License-Identifier: BSD-2-Clause
3#
4# Copyright (c) 2024, Telechips Inc.
5#
6
7import sys
8from hashlib import sha256
9
10ALIGN_SIZE = 64
11FOOTER_SIZE = 128
12
13
14def calc_hash(inputfile):
15    sha = sha256()
16    inputfile.seek(0)
17    while True:
18        buf = inputfile.read(ALIGN_SIZE)
19        if len(buf) == 0:
20            break
21        sha.update(buf.ljust(ALIGN_SIZE, b'\0'))
22    return sha.digest()
23
24
25def fill_dummy_cert(outputfile):
26    outputfile.write(b'CERT'.ljust(256, b'\0'))
27    return 0
28
29
30def fill_header(outputfile, inputfile, argv):
31    imagename = bytes(argv[3], 'utf-8')
32    imageversion = bytes(argv[4], 'utf-8')
33    targetaddress = int(argv[5], 16)
34    socname = bytes(argv[6], 'utf-8')
35    inputfile.seek(0, 2)
36    offset = 4096  # Min: 256
37    length = (inputfile.tell() + (ALIGN_SIZE - 1)) & ~(ALIGN_SIZE - 1)
38    length += FOOTER_SIZE
39    buf = bytearray(offset - outputfile.tell())
40    buf[0:4] = b'HDR\0'  # Marker
41    buf[4:8] = length.to_bytes(4, byteorder='little')
42    buf[8:12] = offset.to_bytes(4, byteorder='little')
43    buf[16:20] = socname.ljust(4, b'\0')[-4:]
44    buf[20:32] = imagename.ljust(12, b'\0')[0:12]
45    buf[32:48] = imageversion.ljust(16, b'\0')[0:16]
46    buf[48:56] = targetaddress.to_bytes(8, byteorder='little')
47    buf[96:128] = calc_hash(inputfile)
48    outputfile.write(buf)
49    return 0
50
51
52def fill_image(outputfile, inputfile):
53    inputfile.seek(0)
54    while True:
55        buf = inputfile.read(ALIGN_SIZE)
56        if len(buf) == 0:
57            break
58        outputfile.write(buf.ljust(ALIGN_SIZE, b'\0'))
59    return 0
60
61
62def fill_dummy_footer(outputfile):
63    outputfile.write(bytearray(FOOTER_SIZE))
64    return 0
65
66
67def make_image(inputfile, outputfile, argv):
68    if fill_dummy_cert(outputfile) != 0:
69        return -1
70    if fill_header(outputfile, inputfile, argv) != 0:
71        return -2
72    if fill_image(outputfile, inputfile) != 0:
73        return -3
74    if fill_dummy_footer(outputfile) != 0:
75        return -4
76    return 0
77
78
79def print_help():
80    print("")
81    print("Telechips Image Maker")
82    print("")
83    print("Usage: python tcmktool.py [INPUT] [OUTPUT] [NAME] [VERSION]" +
84          " [TARGET_ADDRESS] [SOC_NAME]")
85    print("")
86    print("  INPUT                  input file name.")
87    print("  OUTPUT                 output file name.")
88    print("  NAME                   image name.")
89    print("  VERSION                string version. (max 16 bytes)")
90    print("  TARGET_ADDRESS         target address")
91    print("  SOC_NAME               SoC name. (only the last 4 bytes are used")
92
93
94def main(argc, argv):
95    ret = -1
96
97    if argc != 7:
98        print_help()
99        return -1
100
101    try:
102        with open(argv[1], "rb") as inputfile:
103            with open(argv[2], "wb") as outputfile:
104                ret = make_image(inputfile, outputfile, argv)
105    except Exception as e:
106        if 'inputfile' not in locals():
107            print("ERROR: input file open error\n")
108        elif 'outputfile' not in locals():
109            print("ERROR: output file open error\n")
110        else:
111            print(e)
112
113    if ret == 0:
114        print("{} was generated successfully\n".format(argv[2]))
115    else:
116        print("Failed to generate output file (error code: {})\n".format(ret))
117
118    return ret
119
120
121if (__name__ == "__main__"):
122    exit(main(len(sys.argv), sys.argv))
123