1#!/usr/bin/python3
2# Copyright (c) 2020, 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.
16This script also gets SP "uuid" from parsing its PM and converting it to a
17standard format.
18
19param1: Generated mk file "sp_gen.mk"
20param2: "SP_LAYOUT_FILE", json file containing platform provided information
21param3: plat out directory
22param4: CoT parameter
23
24Generated "sp_gen.mk" file contains triplet of following information for each
25Secure Partition entry
26    FDT_SOURCES +=  sp1.dts
27    SPTOOL_ARGS += -i sp1.bin:sp1.dtb -o sp1.pkg
28    FIP_ARGS += --blob uuid=XXXXX-XXX...,file=sp1.pkg
29    CRT_ARGS += --sp-pkg1 sp1.pkg
30
31A typical SP_LAYOUT_FILE file will look like
32{
33        "SP1" : {
34                "image": "sp1.bin",
35                "pm": "test/sp1.dts"
36        },
37
38        "SP2" : {
39                "image": "sp2.bin",
40                "pm": "test/sp2.dts"
41        }
42
43        ...
44}
45
46"""
47
48import getopt
49import json
50import os
51import re
52import sys
53import uuid
54
55with open(sys.argv[2],'r') as in_file:
56    data = json.load(in_file)
57json_file = os.path.abspath(sys.argv[2])
58json_dir = os.path.dirname(json_file)
59gen_file = os.path.abspath(sys.argv[1])
60out_dir = os.path.abspath(sys.argv[3])
61dtb_dir = out_dir + "/fdts/"
62MAX_SP = 8
63dualroot = sys.argv[4].lower() == "dualroot"
64split = int(MAX_SP / 2)
65print(dtb_dir)
66platform_count = 1
67sip_count = 1
68
69with open(gen_file, 'w') as out_file:
70    for idx, key in enumerate(data.keys()):
71
72        pkg_num = idx + 1
73
74        if (pkg_num > MAX_SP):
75            print("WARNING: Too many secure partitions\n")
76            exit(-1)
77
78        if dualroot:
79            owner = data[key].get('owner')
80            if owner == "Plat":
81                if (platform_count > split):
82                    print("WARNING: Maximum Secure partitions by Plat " +
83                    "have been exceeded (" + str(split) + ")\n")
84                    exit(-1)
85                pkg_num = split + platform_count
86                platform_count += 1
87            elif (sip_count > split):
88                print("WARNING: Maximum Secure partitions by SiP " +
89                "have been exceeded (" + str(split) + ")\n")
90                exit(-1)
91            else:
92                pkg_num = sip_count
93                sip_count += 1
94
95        """
96        Append FDT_SOURCES
97        """
98        dts = os.path.join(json_dir, data[key]['pm'])
99        dtb = dtb_dir + os.path.basename(data[key]['pm'][:-1] + "b")
100        out_file.write("FDT_SOURCES += " + dts + "\n")
101
102        """
103        Update SPTOOL_ARGS
104        """
105        dst = out_dir + "/" + key + ".pkg"
106        src = [ json_dir + "/" + data[key]['image'] , dtb  ]
107        out_file.write("SPTOOL_ARGS += -i " + ":".join(src) + " -o " + dst + "\n")
108
109        """
110        Extract uuid from partition manifest
111        """
112        pm_file = open(dts)
113        uuid_key = "uuid"
114
115        for line in pm_file:
116            if uuid_key in line:
117                uuid_hex = re.findall(r'\<(.+?)\>', line)[0];
118
119        # PM has uuid in format 0xABC... 0x... 0x... 0x...
120        # Get rid of '0x' and spaces and convert to string of hex digits
121        uuid_hex = uuid_hex.replace('0x','').replace(' ','')
122        # make UUID from a string of hex digits
123        uuid_std = uuid.UUID(uuid_hex)
124        # convert UUID to a string of hex digits in standard form
125        uuid_std = str(uuid_std)
126
127        """
128        Append FIP_ARGS
129        """
130        out_file.write("FIP_ARGS += --blob uuid=" + uuid_std + ",file=" + dst + "\n")
131
132        """
133        Append CRT_ARGS
134        """
135
136        out_file.write("CRT_ARGS += --sp-pkg" + str(pkg_num) + " " + dst + "\n")
137        out_file.write("\n")
138