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