arm: socfpga: misc: Add CONFIG_SYS_L2_PL310 switch
[oweals/u-boot.git] / arch / arm / mach-rockchip / make_fit_atf.py
1 #!/usr/bin/env python2
2 """
3 A script to generate FIT image source for rockchip boards
4 with ARM Trusted Firmware
5 and multiple device trees (given on the command line)
6
7 usage: $0 <dt_name> [<dt_name> [<dt_name] ...]
8 """
9
10 import os
11 import sys
12 import getopt
13
14 # pip install pyelftools
15 from elftools.elf.elffile import ELFFile
16
17 ELF_SEG_P_TYPE='p_type'
18 ELF_SEG_P_PADDR='p_paddr'
19 ELF_SEG_P_VADDR='p_vaddr'
20 ELF_SEG_P_OFFSET='p_offset'
21 ELF_SEG_P_FILESZ='p_filesz'
22 ELF_SEG_P_MEMSZ='p_memsz'
23
24 DT_HEADER="""// SPDX-License-Identifier: GPL-2.0+ OR X11
25 /*
26  * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd
27  *
28  * Minimal dts for a SPL FIT image payload.
29  */
30 /dts-v1/;
31
32 / {
33         description = "Configuration to load ATF before U-Boot";
34         #address-cells = <1>;
35
36         images {
37                 uboot@1 {
38                         description = "U-Boot (64-bit)";
39                         data = /incbin/("u-boot-nodtb.bin");
40                         type = "standalone";
41                         os = "U-Boot";
42                         arch = "arm64";
43                         compression = "none";
44                         load = <0x%08x>;
45                 };
46 """
47
48 DT_IMAGES_NODE_END="""
49     };
50 """
51
52 DT_END="""
53 };
54 """
55
56 def append_atf_node(file, atf_index, phy_addr):
57     """
58     Append ATF DT node to input FIT dts file.
59     """
60     data = 'bl31_0x%08x.bin' % phy_addr
61     print >> file, '\t\tatf@%d {' % atf_index
62     print >> file, '\t\t\tdescription = \"ARM Trusted Firmware\";'
63     print >> file, '\t\t\tdata = /incbin/("%s");' % data
64     print >> file, '\t\t\ttype = "firmware";'
65     print >> file, '\t\t\tarch = "arm64";'
66     print >> file, '\t\t\tos = "arm-trusted-firmware";'
67     print >> file, '\t\t\tcompression = "none";'
68     print >> file, '\t\t\tload = <0x%08x>;' % phy_addr
69     if atf_index == 1:
70         print >> file, '\t\t\tentry = <0x%08x>;' % phy_addr
71     print >> file, '\t\t};'
72     print >> file, ''
73
74 def append_fdt_node(file, dtbs):
75     """
76     Append FDT nodes.
77     """
78     cnt = 1
79     for dtb in dtbs:
80         dtname = os.path.basename(dtb)
81         print >> file, '\t\tfdt@%d {' % cnt
82         print >> file, '\t\t\tdescription = "%s";' % dtname
83         print >> file, '\t\t\tdata = /incbin/("%s");' % dtb
84         print >> file, '\t\t\ttype = "flat_dt";'
85         print >> file, '\t\t\tcompression = "none";'
86         print >> file, '\t\t};'
87         print >> file, ''
88         cnt = cnt + 1
89
90 def append_conf_section(file, cnt, dtname, atf_cnt):
91     print >> file, '\t\tconfig@%d {' % cnt
92     print >> file, '\t\t\tdescription = "%s";' % dtname
93     print >> file, '\t\t\tfirmware = "atf@1";'
94     print >> file, '\t\t\tloadables = "uboot@1",',
95     for i in range(1, atf_cnt):
96         print >> file, '"atf@%d"' % (i+1),
97         if i != (atf_cnt - 1):
98             print >> file, ',',
99         else:
100             print >> file, ';'
101     print >> file, '\t\t\tfdt = "fdt@1";'
102     print >> file, '\t\t};'
103     print >> file, ''
104
105 def append_conf_node(file, dtbs, atf_cnt):
106     """
107     Append configeration nodes.
108     """
109     cnt = 1
110     print >> file, '\tconfigurations {'
111     print >> file, '\t\tdefault = "config@1";'
112     for dtb in dtbs:
113         dtname = os.path.basename(dtb)
114         append_conf_section(file, cnt, dtname, atf_cnt)
115         cnt = cnt + 1
116     print >> file, '\t};'
117     print >> file, ''
118
119 def generate_atf_fit_dts(fit_file_name, bl31_file_name, uboot_file_name, dtbs_file_name):
120     """
121     Generate FIT script for ATF image.
122     """
123     if fit_file_name != sys.stdout:
124         fit_file = open(fit_file_name, "wb")
125     else:
126         fit_file = sys.stdout
127
128     num_load_seg = 0
129     p_paddr = 0xFFFFFFFF
130     with open(uboot_file_name) as uboot_file:
131         uboot = ELFFile(uboot_file)
132         for i in range(uboot.num_segments()):
133             seg = uboot.get_segment(i)
134             if ('PT_LOAD' == seg.__getitem__(ELF_SEG_P_TYPE)):
135                 p_paddr = seg.__getitem__(ELF_SEG_P_PADDR)
136                 num_load_seg = num_load_seg + 1
137
138     assert (p_paddr != 0xFFFFFFFF and num_load_seg == 1)
139
140     print >> fit_file, DT_HEADER % p_paddr
141
142     with open(bl31_file_name) as bl31_file:
143         bl31 = ELFFile(bl31_file)
144         for i in range(bl31.num_segments()):
145             seg = bl31.get_segment(i)
146             if ('PT_LOAD' == seg.__getitem__(ELF_SEG_P_TYPE)):
147                 paddr = seg.__getitem__(ELF_SEG_P_PADDR)
148                 p= seg.__getitem__(ELF_SEG_P_PADDR)
149                 append_atf_node(fit_file, i+1, paddr)
150     atf_cnt = i+1
151     append_fdt_node(fit_file, dtbs_file_name)
152     print >> fit_file, '%s' % DT_IMAGES_NODE_END
153     append_conf_node(fit_file, dtbs_file_name, atf_cnt)
154     print >> fit_file, '%s' % DT_END
155
156     if fit_file_name != sys.stdout:
157         fit_file.close()
158
159 def generate_atf_binary(bl31_file_name):
160     with open(bl31_file_name) as bl31_file:
161         bl31 = ELFFile(bl31_file)
162
163         num = bl31.num_segments()
164         for i in range(num):
165             seg = bl31.get_segment(i)
166             if ('PT_LOAD' == seg.__getitem__(ELF_SEG_P_TYPE)):
167                 paddr = seg.__getitem__(ELF_SEG_P_PADDR)
168                 file_name = 'bl31_0x%08x.bin' % paddr
169                 with open(file_name, "wb") as atf:
170                     atf.write(seg.data());
171
172 def get_bl31_segments_info(bl31_file_name):
173     """
174     Get load offset, physical offset, file size
175     from bl31 elf file program headers.
176     """
177     with open(bl31_file_name) as bl31_file:
178         bl31 = ELFFile(bl31_file)
179
180         num = bl31.num_segments()
181         print 'Number of Segments : %d' % bl31.num_segments()
182         for i in range(num):
183             print 'Segment %d' % i
184             seg = bl31.get_segment(i)
185             ptype = seg[ELF_SEG_P_TYPE]
186             poffset = seg[ELF_SEG_P_OFFSET]
187             pmemsz = seg[ELF_SEG_P_MEMSZ]
188             pfilesz = seg[ELF_SEG_P_FILESZ]
189             print 'type: %s\nfilesz: %08x\nmemsz: %08x\noffset: %08x' % (ptype, pfilesz, pmemsz, poffset)
190             paddr = seg[ELF_SEG_P_PADDR]
191             print 'paddr: %08x' % paddr
192
193 def main():
194     uboot_elf="./u-boot"
195     bl31_elf="./bl31.elf"
196     FIT_ITS=sys.stdout
197
198     opts, args = getopt.getopt(sys.argv[1:], "o:u:b:h")
199     for opt, val in opts:
200         if opt == "-o":
201             FIT_ITS=val
202         elif opt == "-u":
203             uboot_elf=val
204         elif opt == "-b":
205             bl31_elf=val
206         elif opt == "-h":
207             print __doc__
208             sys.exit(2)
209
210     dtbs = args
211     #get_bl31_segments_info("u-boot")
212     #get_bl31_segments_info("bl31.elf")
213
214     generate_atf_fit_dts(FIT_ITS, bl31_elf, uboot_elf, dtbs)
215     generate_atf_binary(bl31_elf);
216
217 if __name__ == "__main__":
218     main()