xref: /rk3399_ARM-atf/tools/sptool/sp_mk_generator.py (revision f2de48cb143c20ccd7a9c141df3d34cae74049de)
1#!/usr/bin/python3
2# Copyright (c) 2020-2022, Arm Limited. All rights reserved.
3#
4# SPDX-License-Identifier: BSD-3-Clause
5
6"""
7This script is invoked by Make system and generates secure partition makefile.
8It expects platform provided secure partition layout file which contains list
9of Secure Partition Images and Partition manifests(PM).
10Layout file can exist outside of TF-A tree and the paths of Image and PM files
11must be relative to it.
12
13This script parses the layout file and generates a make file which updates
14FDT_SOURCES, FIP_ARGS, CRT_ARGS and SPTOOL_ARGS which are used in later build
15steps.
16If the SP entry in the layout file has a "uuid" field the scripts gets the UUID
17from there, otherwise it parses the associated partition manifest and extracts
18the UUID from there.
19
20param1: Generated mk file "sp_gen.mk"
21param2: "SP_LAYOUT_FILE", json file containing platform provided information
22param3: plat out directory
23param4: CoT parameter
24
25Generated "sp_gen.mk" file contains triplet of following information for each
26Secure Partition entry
27    FDT_SOURCES +=  sp1.dts
28    SPTOOL_ARGS += -i sp1.bin:sp1.dtb -o sp1.pkg
29    FIP_ARGS += --blob uuid=XXXXX-XXX...,file=sp1.pkg
30    CRT_ARGS += --sp-pkg1 sp1.pkg
31
32A typical SP_LAYOUT_FILE file will look like
33{
34        "SP1" : {
35                "image": "sp1.bin",
36                "pm": "test/sp1.dts"
37        },
38
39        "SP2" : {
40                "image": "sp2.bin",
41                "pm": "test/sp2.dts",
42                "uuid": "1b1820fe-48f7-4175-8999-d51da00b7c9f"
43        }
44
45        ...
46}
47
48"""
49
50import getopt
51import json
52import os
53import re
54import sys
55import uuid
56
57with open(sys.argv[2],'r') as in_file:
58    data = json.load(in_file)
59json_file = os.path.abspath(sys.argv[2])
60json_dir = os.path.dirname(json_file)
61gen_file = os.path.abspath(sys.argv[1])
62out_dir = os.path.abspath(sys.argv[3])
63dtb_dir = out_dir + "/fdts/"
64MAX_SP = 8
65dualroot = sys.argv[4].lower() == "dualroot"
66split = int(MAX_SP / 2)
67print(dtb_dir)
68platform_count = 1
69sip_count = 1
70
71with open(gen_file, 'w') as out_file:
72    for idx, key in enumerate(data.keys()):
73
74        pkg_num = idx + 1
75
76        if (pkg_num > MAX_SP):
77            print("WARNING: Too many secure partitions\n")
78            exit(-1)
79
80        if dualroot:
81            owner = data[key].get('owner')
82            if owner == "Plat":
83                if (platform_count > split):
84                    print("WARNING: Maximum Secure partitions by Plat " +
85                    "have been exceeded (" + str(split) + ")\n")
86                    exit(-1)
87                pkg_num = split + platform_count
88                platform_count += 1
89            elif (sip_count > split):
90                print("WARNING: Maximum Secure partitions by SiP " +
91                "have been exceeded (" + str(split) + ")\n")
92                exit(-1)
93            else:
94                pkg_num = sip_count
95                sip_count += 1
96
97        """
98        Append FDT_SOURCES
99        """
100        dts = os.path.join(json_dir, data[key]['pm'])
101        dtb = dtb_dir + os.path.basename(data[key]['pm'][:-1] + "b")
102        out_file.write("FDT_SOURCES += " + dts + "\n")
103
104        """
105        Update SPTOOL_ARGS
106        """
107        dst = out_dir + "/" + key + ".pkg"
108        src = [ json_dir + "/" + data[key]['image'] , dtb  ]
109        out_file.write("SPTOOL_ARGS += -i " + ":".join(src) + " -o " + dst + "\n")
110
111        if "uuid" in data[key]:
112            """
113            Extract the UUID from the JSON file if the SP entry has a 'uuid' field
114            """
115            uuid_std = uuid.UUID(data[key]['uuid'])
116        else:
117            """
118            Extract uuid from partition manifest
119            """
120            pm_file = open(dts)
121            for line in pm_file:
122                if "uuid" in line:
123                    # re.findall returns a list of string tuples.
124                    # uuid_hex is the first item in this list representing the four
125                    # uuid hex integers from the manifest uuid field. The heading
126                    # '0x' of the hexadecimal representation is stripped out.
127                    # e.g. uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>;
128                    # uuid_hex = ('1e67b5b4', 'e14f904a', '13fb1fb8', 'cbdae1da')
129                    uuid_hex = re.findall(r'0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+)', line)[0];
130
131            # uuid_hex is a list of four hex string values
132            if len(uuid_hex) != 4:
133                print("ERROR: malformed UUID")
134                exit(-1)
135
136            # The uuid field in SP manifest is the little endian representation
137            # mapped to arguments as described in SMCCC section 5.3.
138            # Convert each unsigned integer value to a big endian representation
139            # required by fiptool.
140            y=list(map(bytearray.fromhex, uuid_hex))
141            z=(int.from_bytes(y[0], byteorder='little', signed=False),
142            int.from_bytes(y[1], byteorder='little', signed=False),
143            int.from_bytes(y[2], byteorder='little', signed=False),
144            int.from_bytes(y[3], byteorder='little', signed=False))
145            uuid_std = uuid.UUID(f'{z[0]:08x}{z[1]:08x}{z[2]:08x}{z[3]:08x}')
146
147        """
148        Append FIP_ARGS
149        """
150        out_file.write("FIP_ARGS += --blob uuid=" + str(uuid_std) + ",file=" + dst + "\n")
151
152        """
153        Append CRT_ARGS
154        """
155
156        out_file.write("CRT_ARGS += --sp-pkg" + str(pkg_num) + " " + dst + "\n")
157        out_file.write("\n")
158