| #!/usr/bin/python3 |
| # Copyright (c) 2020-2022, Arm Limited. All rights reserved. |
| # |
| # SPDX-License-Identifier: BSD-3-Clause |
| |
| """ |
| This script is invoked by Make system and generates secure partition makefile. |
| It expects platform provided secure partition layout file which contains list |
| of Secure Partition Images and Partition manifests(PM). |
| Layout file can exist outside of TF-A tree and the paths of Image and PM files |
| must be relative to it. |
| |
| This script parses the layout file and generates a make file which updates |
| FDT_SOURCES, FIP_ARGS, CRT_ARGS and SPTOOL_ARGS which are used in later build |
| steps. |
| If the SP entry in the layout file has a "uuid" field the scripts gets the UUID |
| from there, otherwise it parses the associated partition manifest and extracts |
| the UUID from there. |
| |
| param1: Generated mk file "sp_gen.mk" |
| param2: "SP_LAYOUT_FILE", json file containing platform provided information |
| param3: plat out directory |
| param4: CoT parameter |
| |
| Generated "sp_gen.mk" file contains triplet of following information for each |
| Secure Partition entry |
| FDT_SOURCES += sp1.dts |
| SPTOOL_ARGS += -i sp1.bin:sp1.dtb -o sp1.pkg |
| FIP_ARGS += --blob uuid=XXXXX-XXX...,file=sp1.pkg |
| CRT_ARGS += --sp-pkg1 sp1.pkg |
| |
| A typical SP_LAYOUT_FILE file will look like |
| { |
| "SP1" : { |
| "image": "sp1.bin", |
| "pm": "test/sp1.dts" |
| }, |
| |
| "SP2" : { |
| "image": "sp2.bin", |
| "pm": "test/sp2.dts", |
| "uuid": "1b1820fe-48f7-4175-8999-d51da00b7c9f" |
| } |
| |
| ... |
| } |
| |
| """ |
| |
| import getopt |
| import json |
| import os |
| import re |
| import sys |
| import uuid |
| |
| with open(sys.argv[2],'r') as in_file: |
| data = json.load(in_file) |
| json_file = os.path.abspath(sys.argv[2]) |
| json_dir = os.path.dirname(json_file) |
| gen_file = os.path.abspath(sys.argv[1]) |
| out_dir = os.path.abspath(sys.argv[3]) |
| dtb_dir = out_dir + "/fdts/" |
| MAX_SP = 8 |
| dualroot = sys.argv[4].lower() == "dualroot" |
| split = int(MAX_SP / 2) |
| print(dtb_dir) |
| platform_count = 1 |
| sip_count = 1 |
| |
| with open(gen_file, 'w') as out_file: |
| for idx, key in enumerate(data.keys()): |
| |
| pkg_num = idx + 1 |
| |
| if (pkg_num > MAX_SP): |
| print("WARNING: Too many secure partitions\n") |
| exit(-1) |
| |
| if dualroot: |
| owner = data[key].get('owner') |
| if owner == "Plat": |
| if (platform_count > split): |
| print("WARNING: Maximum Secure partitions by Plat " + |
| "have been exceeded (" + str(split) + ")\n") |
| exit(-1) |
| pkg_num = split + platform_count |
| platform_count += 1 |
| elif (sip_count > split): |
| print("WARNING: Maximum Secure partitions by SiP " + |
| "have been exceeded (" + str(split) + ")\n") |
| exit(-1) |
| else: |
| pkg_num = sip_count |
| sip_count += 1 |
| |
| """ |
| Append FDT_SOURCES |
| """ |
| dts = os.path.join(json_dir, data[key]['pm']) |
| dtb = dtb_dir + os.path.basename(data[key]['pm'][:-1] + "b") |
| out_file.write("FDT_SOURCES += " + dts + "\n") |
| |
| """ |
| Update SPTOOL_ARGS |
| """ |
| dst = out_dir + "/" + key + ".pkg" |
| src = [ json_dir + "/" + data[key]['image'] , dtb ] |
| out_file.write("SPTOOL_ARGS += -i " + ":".join(src) + " -o " + dst + "\n") |
| |
| if "uuid" in data[key]: |
| """ |
| Extract the UUID from the JSON file if the SP entry has a 'uuid' field |
| """ |
| uuid_std = uuid.UUID(data[key]['uuid']) |
| else: |
| """ |
| Extract uuid from partition manifest |
| """ |
| pm_file = open(dts) |
| for line in pm_file: |
| if "uuid" in line: |
| # re.findall returns a list of string tuples. |
| # uuid_hex is the first item in this list representing the four |
| # uuid hex integers from the manifest uuid field. The heading |
| # '0x' of the hexadecimal representation is stripped out. |
| # e.g. uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; |
| # uuid_hex = ('1e67b5b4', 'e14f904a', '13fb1fb8', 'cbdae1da') |
| uuid_hex = re.findall(r'0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+) 0x([0-9a-f]+)', line)[0]; |
| |
| # uuid_hex is a list of four hex string values |
| if len(uuid_hex) != 4: |
| print("ERROR: malformed UUID") |
| exit(-1) |
| |
| # The uuid field in SP manifest is the little endian representation |
| # mapped to arguments as described in SMCCC section 5.3. |
| # Convert each unsigned integer value to a big endian representation |
| # required by fiptool. |
| y=list(map(bytearray.fromhex, uuid_hex)) |
| z=(int.from_bytes(y[0], byteorder='little', signed=False), |
| int.from_bytes(y[1], byteorder='little', signed=False), |
| int.from_bytes(y[2], byteorder='little', signed=False), |
| int.from_bytes(y[3], byteorder='little', signed=False)) |
| uuid_std = uuid.UUID(f'{z[0]:08x}{z[1]:08x}{z[2]:08x}{z[3]:08x}') |
| |
| """ |
| Append FIP_ARGS |
| """ |
| out_file.write("FIP_ARGS += --blob uuid=" + str(uuid_std) + ",file=" + dst + "\n") |
| |
| """ |
| Append CRT_ARGS |
| """ |
| |
| out_file.write("CRT_ARGS += --sp-pkg" + str(pkg_num) + " " + dst + "\n") |
| out_file.write("\n") |