blob: 5703a8d298dc86c0b031ecf7f6259ed566d03bd6 [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 = {
alexander3c798932021-03-26 21:42:19 +000053 "sse-300": {
54 "mmap_mcc" : {
55 # FPGA addr | MCC addr |
56 "0x00000000": "0x00000000", # ITCM (NS)
57 "0x01000000": "0x02000000", # BRAM or FPGA's data SRAM (NS)
58 "0x60000000": "0x08000000", # DDR (NS)
59 "0x70000000": "0x0c000000" # DDR (S)
60 },
61 "bin_names": {
62 0: "itcm.bin",
63 1: "dram.bin"
64 }
65 }
66 }
67
68 self.name = target_subsystem_name
69
70
71 def is_supported(self, target_subsystem: str) -> bool:
72 """
73 Checks if the target subsystem exists within systems
74 supported by this script
75 """
76 if target_subsystem in self.subsystems.keys():
77 return True
78
79 print(f"Platforms supported: {self.subsystems.keys()}")
80 return False
81
82
83 def mps3_mappings(self) -> dict:
84 """
85 Returns the FPGA <--> MCC address translations
86 as a dict
87 """
88 if self.is_supported(self.name):
89 return self.subsystems[self.name]['mmap_mcc']
90 return {}
91
92
93 def mps3_bin_names(self) -> dict:
94 """
95 Returns expected binary names for the executable built
96 for Cortex-M55 or Cortex-M55+Ethos-U55 targets in the
97 form of a dict with index and name
98 """
99 if self.is_supported(self.name):
100 return self.subsystems[self.name]['bin_names']
101
102 return {}
103
104
105def main(args):
106 """
107 Generates the output txt file with MCC to FPGA address mapping used
108 that is used by the MCC on FPGA to load executable regions into
109 correct regions in memory.
110 """
111 # List out arguments used:
112 scatter_file_path = args.scatter_file_path
113 target_subsystem_name = args.target_subsystem
114 output_file_path = args.output_file_path
115
116 target = TargetSubsystem(target_subsystem_name=target_subsystem_name)
117
118 if target.is_supported(target_subsystem_name) != True:
119 print(f'Target {target_subsystem_name} not supported.')
120 return
121
122 with open(scatter_file_path,'r') as scatter_file:
123 lines_read = scatter_file.readlines()
124 str_list = []
125
126 bin_names = None
127 mem_map = None
128
129 mem_map = target.mps3_mappings()
130 bin_names = target.mps3_bin_names()
131
132 str_list.append("TITLE: Arm MPS3 FPGA prototyping board Images Configuration File\n")
133 str_list.append("[IMAGES]\n\n")
134
135 cnt = 0
136 for line in lines_read:
137 if is_commented(line) or is_load_rom(line) != True:
138 continue
139
140 addr = line.split()[1]
141
142 if mem_map.get(addr, None) == None:
143 raise RuntimeError(
144 'Translation for this address unavailable')
145 if cnt > len(bin_names):
146 raise RuntimeError(
147 f"bin names len exceeded: {cnt}")
148
149 str_list.append("IMAGE" + str(cnt) + "ADDRESS: " +
150 mem_map[addr] + " ; MCC@" + mem_map[addr] +
151 " <=> FPGA@" + addr + "\n")
152 str_list.append("IMAGE" + str(cnt) + "UPDATE: AUTO\n")
153 str_list.append("IMAGE" + str(cnt) + "FILE: \SOFTWARE\\" +
154 bin_names[cnt] + "\n\n")
155 cnt += 1
156
157 if cnt > 0 and cnt < 33:
158 str_list.insert(2,
159 "TOTALIMAGES: {} ;Number of Images (Max: 32)\n\n".format(
160 cnt))
161 else:
162 raise RuntimeError('Invalid image count')
163
164 if os.path.exists(output_file_path):
165 os.remove(output_file_path)
166 print(''.join(str_list), file=open(output_file_path, "a"))
167
168
169if __name__ == "__main__":
170 parser = ArgumentParser()
171 parser.add_argument("--scatter_file_path", type=str, required=True,
172 help="Path to the scatter file")
173 parser.add_argument("--target_subsystem", type=str, required=True,
174 help="Target subsystem in use")
175 parser.add_argument("--output_file_path", type=str, required=True,
176 help="Output file path")
177 args = parser.parse_args()
178 main(args)