blob: 6a2d1d2054bf34517b5cf50c93513051ced27a64 [file] [log] [blame]
alexander3c798932021-03-26 21:42:19 +00001# Copyright (c) 2021 Arm Limited. All rights reserved.
2# SPDX-License-Identifier: Apache-2.0
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import os
17from argparse import ArgumentParser
18
19"""
20This file is used as part of post build steps to generate 'images.txt' file
21which can be copied over onto the MPS3 board's SD card. The purpose is to
22limit having to manually edit the file based on different load regions that
23the build scatter file might dictate.
24"""
25
26def is_commented(line):
27 if (line.startswith(";")):
28 return True
29 else:
30 return False
31
32
33def is_load_rom(line):
34 load_region_specifiers = ['LOAD_ROM', 'LD_ROM', 'LOAD_REGION']
35
36 for load_specifier in load_region_specifiers:
37 if line.startswith(load_specifier):
38 return True
39
40 return False
41
42
43class TargetSubsystem:
44
45 def __init__(self, target_subsystem_name: str):
46 """
47 Constructor for target class.
48 Arguments:
49 target_subsystem_name: name of the target subsystem
50 """
51 # Dict with mem map and binary names we expect
52 self.subsystems = {
53 "sse-200": {
54 "mmap_mcc" : {
55 # FPGA addr | MCC addr |
56 "0x00000000": "0x00000000", # ITCM (NS)
57 "0x10000000": "0x01000000", # ITCM (S)
58 "0x20000000": "0x02000000", # DTCM (NS)
59 "0x30000000": "0x03000000", # DTCM (S)
60 "0x60000000": "0x08000000" # DDR (NS)
61 },
62 "bin_names": {
63 0: "itcm.bin",
64 1: "dram.bin"
65 }
66 },
67 "sse-300": {
68 "mmap_mcc" : {
69 # FPGA addr | MCC addr |
70 "0x00000000": "0x00000000", # ITCM (NS)
71 "0x01000000": "0x02000000", # BRAM or FPGA's data SRAM (NS)
72 "0x60000000": "0x08000000", # DDR (NS)
73 "0x70000000": "0x0c000000" # DDR (S)
74 },
75 "bin_names": {
76 0: "itcm.bin",
77 1: "dram.bin"
78 }
79 }
80 }
81
82 self.name = target_subsystem_name
83
84
85 def is_supported(self, target_subsystem: str) -> bool:
86 """
87 Checks if the target subsystem exists within systems
88 supported by this script
89 """
90 if target_subsystem in self.subsystems.keys():
91 return True
92
93 print(f"Platforms supported: {self.subsystems.keys()}")
94 return False
95
96
97 def mps3_mappings(self) -> dict:
98 """
99 Returns the FPGA <--> MCC address translations
100 as a dict
101 """
102 if self.is_supported(self.name):
103 return self.subsystems[self.name]['mmap_mcc']
104 return {}
105
106
107 def mps3_bin_names(self) -> dict:
108 """
109 Returns expected binary names for the executable built
110 for Cortex-M55 or Cortex-M55+Ethos-U55 targets in the
111 form of a dict with index and name
112 """
113 if self.is_supported(self.name):
114 return self.subsystems[self.name]['bin_names']
115
116 return {}
117
118
119def main(args):
120 """
121 Generates the output txt file with MCC to FPGA address mapping used
122 that is used by the MCC on FPGA to load executable regions into
123 correct regions in memory.
124 """
125 # List out arguments used:
126 scatter_file_path = args.scatter_file_path
127 target_subsystem_name = args.target_subsystem
128 output_file_path = args.output_file_path
129
130 target = TargetSubsystem(target_subsystem_name=target_subsystem_name)
131
132 if target.is_supported(target_subsystem_name) != True:
133 print(f'Target {target_subsystem_name} not supported.')
134 return
135
136 with open(scatter_file_path,'r') as scatter_file:
137 lines_read = scatter_file.readlines()
138 str_list = []
139
140 bin_names = None
141 mem_map = None
142
143 mem_map = target.mps3_mappings()
144 bin_names = target.mps3_bin_names()
145
146 str_list.append("TITLE: Arm MPS3 FPGA prototyping board Images Configuration File\n")
147 str_list.append("[IMAGES]\n\n")
148
149 cnt = 0
150 for line in lines_read:
151 if is_commented(line) or is_load_rom(line) != True:
152 continue
153
154 addr = line.split()[1]
155
156 if mem_map.get(addr, None) == None:
157 raise RuntimeError(
158 'Translation for this address unavailable')
159 if cnt > len(bin_names):
160 raise RuntimeError(
161 f"bin names len exceeded: {cnt}")
162
163 str_list.append("IMAGE" + str(cnt) + "ADDRESS: " +
164 mem_map[addr] + " ; MCC@" + mem_map[addr] +
165 " <=> FPGA@" + addr + "\n")
166 str_list.append("IMAGE" + str(cnt) + "UPDATE: AUTO\n")
167 str_list.append("IMAGE" + str(cnt) + "FILE: \SOFTWARE\\" +
168 bin_names[cnt] + "\n\n")
169 cnt += 1
170
171 if cnt > 0 and cnt < 33:
172 str_list.insert(2,
173 "TOTALIMAGES: {} ;Number of Images (Max: 32)\n\n".format(
174 cnt))
175 else:
176 raise RuntimeError('Invalid image count')
177
178 if os.path.exists(output_file_path):
179 os.remove(output_file_path)
180 print(''.join(str_list), file=open(output_file_path, "a"))
181
182
183if __name__ == "__main__":
184 parser = ArgumentParser()
185 parser.add_argument("--scatter_file_path", type=str, required=True,
186 help="Path to the scatter file")
187 parser.add_argument("--target_subsystem", type=str, required=True,
188 help="Target subsystem in use")
189 parser.add_argument("--output_file_path", type=str, required=True,
190 help="Output file path")
191 args = parser.parse_args()
192 main(args)