xref: /optee_os/scripts/arm32_sysreg.py (revision 18b580248e9dfd46f90bbddf2a6d104052a29635)
1*18b58024SJens Wiklander#!/usr/bin/env python
2*18b58024SJens Wiklander# SPDX-License-Identifier: BSD-2-Clause
3*18b58024SJens Wiklander#
4*18b58024SJens Wiklander# Copyright (c) 2018, Linaro Limited
5*18b58024SJens Wiklander#
6*18b58024SJens Wiklanderfrom __future__ import print_function
7*18b58024SJens Wiklander
8*18b58024SJens Wiklanderimport argparse
9*18b58024SJens Wiklanderimport sys
10*18b58024SJens Wiklanderimport re
11*18b58024SJens Wiklander
12*18b58024SJens Wiklander
13*18b58024SJens Wiklanderdef eprint(*args, **kwargs):
14*18b58024SJens Wiklander    print(*args, file=sys.stderr, **kwargs)
15*18b58024SJens Wiklander
16*18b58024SJens Wiklander
17*18b58024SJens Wiklanderdef my_err(line_number, msg):
18*18b58024SJens Wiklander    eprint('Error: line:' + repr(line_number) + ' ' + msg)
19*18b58024SJens Wiklander    sys.exit(1)
20*18b58024SJens Wiklander
21*18b58024SJens Wiklander
22*18b58024SJens Wiklanderdef gen_read64_macro(reg_name, opc1, crm, descr):
23*18b58024SJens Wiklander    print('')
24*18b58024SJens Wiklander    if len(descr):
25*18b58024SJens Wiklander        print('\t# ' + descr)
26*18b58024SJens Wiklander    print('\t.macro read_' + reg_name.lower() + ' reg0, reg1')
27*18b58024SJens Wiklander    print('\tmrrc\tp15, ' + opc1 + ', \\reg0, \\reg1, ' + crm)
28*18b58024SJens Wiklander    print('\t.endm')
29*18b58024SJens Wiklander
30*18b58024SJens Wiklander
31*18b58024SJens Wiklanderdef gen_write64_macro(reg_name, opc1, crm, descr):
32*18b58024SJens Wiklander    print('')
33*18b58024SJens Wiklander    if len(descr):
34*18b58024SJens Wiklander        print('\t# ' + descr)
35*18b58024SJens Wiklander    print('\t.macro write_' + reg_name.lower() + ' reg0, reg1')
36*18b58024SJens Wiklander    print('\tmcrr\tp15, ' + opc1 + ', \\reg0, \\reg1, ' + crm)
37*18b58024SJens Wiklander    print('\t.endm')
38*18b58024SJens Wiklander
39*18b58024SJens Wiklander
40*18b58024SJens Wiklanderdef gen_read32_macro(reg_name, crn, opc1, crm, opc2, descr):
41*18b58024SJens Wiklander    print('')
42*18b58024SJens Wiklander    if len(descr):
43*18b58024SJens Wiklander        print('\t# ' + descr)
44*18b58024SJens Wiklander    print('\t.macro read_' + reg_name.lower() + ' reg')
45*18b58024SJens Wiklander    print('\tmrc p15, ' + opc1 + ', \\reg, ' + crn + ', ' + crm + ', ' + opc2)
46*18b58024SJens Wiklander    print('\t.endm')
47*18b58024SJens Wiklander
48*18b58024SJens Wiklander
49*18b58024SJens Wiklanderdef gen_write32_macro(reg_name, crn, opc1, crm, opc2, descr):
50*18b58024SJens Wiklander    print('')
51*18b58024SJens Wiklander    if len(descr):
52*18b58024SJens Wiklander        print('\t# ' + descr)
53*18b58024SJens Wiklander    print('\t.macro write_' + reg_name.lower() + ' reg')
54*18b58024SJens Wiklander    print('\tmcr p15, ' + opc1 + ', \\reg, ' + crn + ', ' + crm + ', ' + opc2)
55*18b58024SJens Wiklander    print('\t.endm')
56*18b58024SJens Wiklander
57*18b58024SJens Wiklander
58*18b58024SJens Wiklanderdef gen_write32_dummy_macro(reg_name, crn, opc1, crm, opc2, descr):
59*18b58024SJens Wiklander    print('')
60*18b58024SJens Wiklander    if len(descr):
61*18b58024SJens Wiklander        print('\t# ' + descr)
62*18b58024SJens Wiklander    print('\t.macro write_' + reg_name.lower())
63*18b58024SJens Wiklander    print('\t# Register ignored')
64*18b58024SJens Wiklander    print('\tmcr p15, ' + opc1 + ', r0, ' + crn + ', ' + crm + ', ' + opc2)
65*18b58024SJens Wiklander    print('\t.endm')
66*18b58024SJens Wiklander
67*18b58024SJens Wiklander
68*18b58024SJens Wiklanderdef gen_read64_func(reg_name, opc1, crm, descr):
69*18b58024SJens Wiklander    print('')
70*18b58024SJens Wiklander    if len(descr):
71*18b58024SJens Wiklander        print('/* ' + descr + ' */')
72*18b58024SJens Wiklander    print('static inline uint64_t read_' + reg_name.lower() + '(void)')
73*18b58024SJens Wiklander    print('{')
74*18b58024SJens Wiklander    print('\tuint64_t v;')
75*18b58024SJens Wiklander    print('')
76*18b58024SJens Wiklander    print('\tasm volatile ("mrrc p15, ' + opc1 + ', %Q0, %R0, ' +
77*18b58024SJens Wiklander          crm + '"' + ' : "=r"  (v));')
78*18b58024SJens Wiklander    print('')
79*18b58024SJens Wiklander    print('\treturn v;')
80*18b58024SJens Wiklander    print('}')
81*18b58024SJens Wiklander
82*18b58024SJens Wiklander
83*18b58024SJens Wiklanderdef gen_write64_func(reg_name, opc1, crm, descr):
84*18b58024SJens Wiklander    print('')
85*18b58024SJens Wiklander    if len(descr):
86*18b58024SJens Wiklander        print('/* ' + descr + ' */')
87*18b58024SJens Wiklander    print('static inline void write_' + reg_name.lower() + '(uint64_t v)')
88*18b58024SJens Wiklander    print('{')
89*18b58024SJens Wiklander    print('\tasm volatile ("mcrr p15, ' + opc1 + ', %Q0, %R0, ' +
90*18b58024SJens Wiklander          crm + '"' + ' : : "r"  (v));')
91*18b58024SJens Wiklander    print('}')
92*18b58024SJens Wiklander
93*18b58024SJens Wiklander
94*18b58024SJens Wiklanderdef gen_read32_func(reg_name, crn, opc1, crm, opc2, descr):
95*18b58024SJens Wiklander    print('')
96*18b58024SJens Wiklander    if len(descr):
97*18b58024SJens Wiklander        print('/* ' + descr + ' */')
98*18b58024SJens Wiklander    print('static inline uint32_t read_' + reg_name.lower() + '(void)')
99*18b58024SJens Wiklander    print('{')
100*18b58024SJens Wiklander    print('\tuint32_t v;')
101*18b58024SJens Wiklander    print('')
102*18b58024SJens Wiklander    print('\tasm volatile ("mrc p15, ' + opc1 + ', %0, ' + crn + ', ' +
103*18b58024SJens Wiklander          crm + ', ' + opc2 + '"' + ' : "=r"  (v));')
104*18b58024SJens Wiklander    print('')
105*18b58024SJens Wiklander    print('\treturn v;')
106*18b58024SJens Wiklander    print('}')
107*18b58024SJens Wiklander
108*18b58024SJens Wiklander
109*18b58024SJens Wiklanderdef gen_write32_func(reg_name, crn, opc1, crm, opc2, descr):
110*18b58024SJens Wiklander    print('')
111*18b58024SJens Wiklander    if len(descr):
112*18b58024SJens Wiklander        print('/* ' + descr + ' */')
113*18b58024SJens Wiklander    print('static inline void write_' + reg_name.lower() + '(uint32_t v)')
114*18b58024SJens Wiklander    print('{')
115*18b58024SJens Wiklander    print('\tasm volatile ("mcr p15, ' + opc1 + ', %0, ' + crn + ', ' +
116*18b58024SJens Wiklander          crm + ', ' + opc2 + '"' + ' : : "r"  (v));')
117*18b58024SJens Wiklander    print('}')
118*18b58024SJens Wiklander
119*18b58024SJens Wiklander
120*18b58024SJens Wiklanderdef gen_write32_dummy_func(reg_name, crn, opc1, crm, opc2, descr):
121*18b58024SJens Wiklander    print('')
122*18b58024SJens Wiklander    if len(descr):
123*18b58024SJens Wiklander        print('/* ' + descr + ' */')
124*18b58024SJens Wiklander    print('static inline void write_' + reg_name.lower() + '(void)')
125*18b58024SJens Wiklander    print('{')
126*18b58024SJens Wiklander    print('\t/* Register ignored */')
127*18b58024SJens Wiklander    print('\tasm volatile ("mcr p15, ' + opc1 + ', r0, ' + crn + ', ' +
128*18b58024SJens Wiklander          crm + ', ' + opc2 + '");')
129*18b58024SJens Wiklander    print('}')
130*18b58024SJens Wiklander
131*18b58024SJens Wiklander
132*18b58024SJens Wiklanderdef gen_file(line, line_number, s_file):
133*18b58024SJens Wiklander    words = line.split()
134*18b58024SJens Wiklander    if len(words) == 0:
135*18b58024SJens Wiklander        return
136*18b58024SJens Wiklander
137*18b58024SJens Wiklander    if len(re.findall('^ *#', line)):
138*18b58024SJens Wiklander        return
139*18b58024SJens Wiklander
140*18b58024SJens Wiklander    if len(re.findall('^ *@', line)):
141*18b58024SJens Wiklander        comment = re.sub('^ *@', '', line)
142*18b58024SJens Wiklander        comment = re.sub('^ *', '', comment)
143*18b58024SJens Wiklander        comment = re.sub('[ \n]*$', '', comment)
144*18b58024SJens Wiklander        if len(comment) == 0:
145*18b58024SJens Wiklander            print('')
146*18b58024SJens Wiklander            return
147*18b58024SJens Wiklander        if s_file:
148*18b58024SJens Wiklander            print('# ' + comment)
149*18b58024SJens Wiklander        else:
150*18b58024SJens Wiklander            print('/* ' + comment + ' */')
151*18b58024SJens Wiklander        return
152*18b58024SJens Wiklander
153*18b58024SJens Wiklander    reg_name = words[0]
154*18b58024SJens Wiklander    crn = words[1]
155*18b58024SJens Wiklander    opc1 = words[2]
156*18b58024SJens Wiklander    crm = words[3]
157*18b58024SJens Wiklander    opc2 = words[4]
158*18b58024SJens Wiklander    access_type = words[5]
159*18b58024SJens Wiklander    descr = " ".join(words[6:])
160*18b58024SJens Wiklander
161*18b58024SJens Wiklander    read_access = access_type == 'RO' or access_type == 'RW'
162*18b58024SJens Wiklander    write_access = (access_type == 'WO' or access_type == 'RW' or
163*18b58024SJens Wiklander                    access_type == 'WOD')
164*18b58024SJens Wiklander    dummy_access = access_type == 'WOD'
165*18b58024SJens Wiklander
166*18b58024SJens Wiklander    if not read_access and not write_access:
167*18b58024SJens Wiklander        my_err(line_number, 'bad Access Type "' + access_type + '"')
168*18b58024SJens Wiklander
169*18b58024SJens Wiklander    if crn == '-':
170*18b58024SJens Wiklander        if opc2 != '-':
171*18b58024SJens Wiklander            my_err(line_number, 'bad opc2, expected -')
172*18b58024SJens Wiklander
173*18b58024SJens Wiklander        if read_access:
174*18b58024SJens Wiklander            if s_file:
175*18b58024SJens Wiklander                gen_read64_macro(reg_name, opc1, crm, descr)
176*18b58024SJens Wiklander            else:
177*18b58024SJens Wiklander                gen_read64_func(reg_name, opc1, crm, descr)
178*18b58024SJens Wiklander
179*18b58024SJens Wiklander        if s_file:
180*18b58024SJens Wiklander            gen_write64_macro(reg_name, opc1, crm, descr)
181*18b58024SJens Wiklander        else:
182*18b58024SJens Wiklander            gen_write64_func(reg_name, opc1, crm, descr)
183*18b58024SJens Wiklander    else:
184*18b58024SJens Wiklander        if read_access:
185*18b58024SJens Wiklander            if s_file:
186*18b58024SJens Wiklander                gen_read32_macro(reg_name, crn, opc1, crm, opc2, descr)
187*18b58024SJens Wiklander            else:
188*18b58024SJens Wiklander                gen_read32_func(reg_name, crn, opc1, crm, opc2, descr)
189*18b58024SJens Wiklander
190*18b58024SJens Wiklander        if write_access:
191*18b58024SJens Wiklander            if dummy_access:
192*18b58024SJens Wiklander                if s_file:
193*18b58024SJens Wiklander                    gen_write32_dummy_macro(reg_name, crn, opc1, crm, opc2,
194*18b58024SJens Wiklander                                            descr)
195*18b58024SJens Wiklander                else:
196*18b58024SJens Wiklander                    gen_write32_dummy_func(reg_name, crn, opc1, crm, opc2,
197*18b58024SJens Wiklander                                           descr)
198*18b58024SJens Wiklander            else:
199*18b58024SJens Wiklander                if s_file:
200*18b58024SJens Wiklander                    gen_write32_macro(reg_name, crn, opc1, crm, opc2, descr)
201*18b58024SJens Wiklander                else:
202*18b58024SJens Wiklander                    gen_write32_func(reg_name, crn, opc1, crm, opc2, descr)
203*18b58024SJens Wiklander
204*18b58024SJens Wiklander
205*18b58024SJens Wiklanderdef get_args():
206*18b58024SJens Wiklander    parser = argparse.ArgumentParser(description='Generates instructions to '
207*18b58024SJens Wiklander                                     'access ARM32 system registers.')
208*18b58024SJens Wiklander
209*18b58024SJens Wiklander    parser.add_argument('--s_file', action='store_true',
210*18b58024SJens Wiklander                        help='Generate an Assembly instead of a C file')
211*18b58024SJens Wiklander    parser.add_argument('--guard',
212*18b58024SJens Wiklander                        help='Provide #ifdef <guard_argument> in C file')
213*18b58024SJens Wiklander
214*18b58024SJens Wiklander    return parser.parse_args()
215*18b58024SJens Wiklander
216*18b58024SJens Wiklander
217*18b58024SJens Wiklanderdef main():
218*18b58024SJens Wiklander    args = get_args()
219*18b58024SJens Wiklander
220*18b58024SJens Wiklander    cmnt = 'Automatically generated, do not edit'
221*18b58024SJens Wiklander    if args.s_file:
222*18b58024SJens Wiklander        print('# ' + cmnt)
223*18b58024SJens Wiklander    else:
224*18b58024SJens Wiklander        print('/* ' + cmnt + ' */')
225*18b58024SJens Wiklander        if args.guard is not None:
226*18b58024SJens Wiklander            print('#ifndef ' + args.guard.upper().replace('.', '_'))
227*18b58024SJens Wiklander            print('#define ' + args.guard.upper().replace('.', '_'))
228*18b58024SJens Wiklander
229*18b58024SJens Wiklander    line_number = 0
230*18b58024SJens Wiklander    for line in sys.stdin:
231*18b58024SJens Wiklander        line_number = line_number + 1
232*18b58024SJens Wiklander        gen_file(line, line_number, args.s_file)
233*18b58024SJens Wiklander
234*18b58024SJens Wiklander    if not args.s_file and args.guard is not None:
235*18b58024SJens Wiklander        print('#endif /*' + args.guard.upper().replace('.', '_') + '*/')
236*18b58024SJens Wiklander
237*18b58024SJens Wiklander
238*18b58024SJens Wiklanderif __name__ == '__main__':
239*18b58024SJens Wiklander    main()
240