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