blob: 08524715c42bac353b0b66bd41f64713cbd04445 [file] [log] [blame]
Jens Wiklander18b58022018-08-16 22:12:26 +02001#!/usr/bin/env python
2# SPDX-License-Identifier: BSD-2-Clause
3#
4# Copyright (c) 2018, Linaro Limited
5#
6from __future__ import print_function
7
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 + ' */')
Sumit Garg4486d582019-07-04 12:41:52 +053072 print('static inline __noprof uint64_t read_' + reg_name.lower() + '(void)')
Jens Wiklander18b58022018-08-16 22:12:26 +020073 print('{')
74 print('\tuint64_t v;')
75 print('')
76 print('\tasm volatile ("mrrc p15, ' + opc1 + ', %Q0, %R0, ' +
77 crm + '"' + ' : "=r" (v));')
78 print('')
79 print('\treturn v;')
80 print('}')
81
82
83def gen_write64_func(reg_name, opc1, crm, descr):
84 print('')
85 if len(descr):
86 print('/* ' + descr + ' */')
Sumit Garg4486d582019-07-04 12:41:52 +053087 print('static inline __noprof void write_' + reg_name.lower() +
88 '(uint64_t v)')
Jens Wiklander18b58022018-08-16 22:12:26 +020089 print('{')
90 print('\tasm volatile ("mcrr p15, ' + opc1 + ', %Q0, %R0, ' +
91 crm + '"' + ' : : "r" (v));')
92 print('}')
93
94
95def gen_read32_func(reg_name, crn, opc1, crm, opc2, descr):
96 print('')
97 if len(descr):
98 print('/* ' + descr + ' */')
Sumit Garg4486d582019-07-04 12:41:52 +053099 print('static inline __noprof uint32_t read_' + reg_name.lower() + '(void)')
Jens Wiklander18b58022018-08-16 22:12:26 +0200100 print('{')
101 print('\tuint32_t v;')
102 print('')
103 print('\tasm volatile ("mrc p15, ' + opc1 + ', %0, ' + crn + ', ' +
104 crm + ', ' + opc2 + '"' + ' : "=r" (v));')
105 print('')
106 print('\treturn v;')
107 print('}')
108
109
110def gen_write32_func(reg_name, crn, opc1, crm, opc2, descr):
111 print('')
112 if len(descr):
113 print('/* ' + descr + ' */')
Sumit Garg4486d582019-07-04 12:41:52 +0530114 print('static inline __noprof void write_' + reg_name.lower() +
115 '(uint32_t v)')
Jens Wiklander18b58022018-08-16 22:12:26 +0200116 print('{')
117 print('\tasm volatile ("mcr p15, ' + opc1 + ', %0, ' + crn + ', ' +
118 crm + ', ' + opc2 + '"' + ' : : "r" (v));')
119 print('}')
120
121
122def gen_write32_dummy_func(reg_name, crn, opc1, crm, opc2, descr):
123 print('')
124 if len(descr):
125 print('/* ' + descr + ' */')
126 print('static inline void write_' + reg_name.lower() + '(void)')
127 print('{')
128 print('\t/* Register ignored */')
129 print('\tasm volatile ("mcr p15, ' + opc1 + ', r0, ' + crn + ', ' +
130 crm + ', ' + opc2 + '");')
131 print('}')
132
133
134def gen_file(line, line_number, s_file):
135 words = line.split()
136 if len(words) == 0:
137 return
138
139 if len(re.findall('^ *#', line)):
140 return
141
142 if len(re.findall('^ *@', line)):
143 comment = re.sub('^ *@', '', line)
144 comment = re.sub('^ *', '', comment)
145 comment = re.sub('[ \n]*$', '', comment)
146 if len(comment) == 0:
147 print('')
148 return
149 if s_file:
150 print('# ' + comment)
151 else:
152 print('/* ' + comment + ' */')
153 return
154
155 reg_name = words[0]
156 crn = words[1]
157 opc1 = words[2]
158 crm = words[3]
159 opc2 = words[4]
160 access_type = words[5]
161 descr = " ".join(words[6:])
162
163 read_access = access_type == 'RO' or access_type == 'RW'
164 write_access = (access_type == 'WO' or access_type == 'RW' or
165 access_type == 'WOD')
166 dummy_access = access_type == 'WOD'
167
168 if not read_access and not write_access:
169 my_err(line_number, 'bad Access Type "' + access_type + '"')
170
171 if crn == '-':
172 if opc2 != '-':
173 my_err(line_number, 'bad opc2, expected -')
174
175 if read_access:
176 if s_file:
177 gen_read64_macro(reg_name, opc1, crm, descr)
178 else:
179 gen_read64_func(reg_name, opc1, crm, descr)
180
181 if s_file:
182 gen_write64_macro(reg_name, opc1, crm, descr)
183 else:
184 gen_write64_func(reg_name, opc1, crm, descr)
185 else:
186 if read_access:
187 if s_file:
188 gen_read32_macro(reg_name, crn, opc1, crm, opc2, descr)
189 else:
190 gen_read32_func(reg_name, crn, opc1, crm, opc2, descr)
191
192 if write_access:
193 if dummy_access:
194 if s_file:
195 gen_write32_dummy_macro(reg_name, crn, opc1, crm, opc2,
196 descr)
197 else:
198 gen_write32_dummy_func(reg_name, crn, opc1, crm, opc2,
199 descr)
200 else:
201 if s_file:
202 gen_write32_macro(reg_name, crn, opc1, crm, opc2, descr)
203 else:
204 gen_write32_func(reg_name, crn, opc1, crm, opc2, descr)
205
206
207def get_args():
208 parser = argparse.ArgumentParser(description='Generates instructions to '
209 'access ARM32 system registers.')
210
211 parser.add_argument('--s_file', action='store_true',
212 help='Generate an Assembly instead of a C file')
213 parser.add_argument('--guard',
214 help='Provide #ifdef <guard_argument> in C file')
215
216 return parser.parse_args()
217
218
219def main():
220 args = get_args()
221
222 cmnt = 'Automatically generated, do not edit'
223 if args.s_file:
224 print('# ' + cmnt)
225 else:
226 print('/* ' + cmnt + ' */')
227 if args.guard is not None:
228 print('#ifndef ' + args.guard.upper().replace('.', '_'))
229 print('#define ' + args.guard.upper().replace('.', '_'))
Sumit Garg4486d582019-07-04 12:41:52 +0530230 print('#include <compiler.h>')
Jens Wiklander18b58022018-08-16 22:12:26 +0200231
232 line_number = 0
233 for line in sys.stdin:
234 line_number = line_number + 1
235 gen_file(line, line_number, args.s_file)
236
237 if not args.s_file and args.guard is not None:
238 print('#endif /*' + args.guard.upper().replace('.', '_') + '*/')
239
240
241if __name__ == '__main__':
242 main()