blob: bd0c619eafe1f6c555e7f583cef943c0015ae9b4 [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 + ' */')
72 print('static inline uint64_t read_' + reg_name.lower() + '(void)')
73 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 + ' */')
87 print('static inline void write_' + reg_name.lower() + '(uint64_t v)')
88 print('{')
89 print('\tasm volatile ("mcrr p15, ' + opc1 + ', %Q0, %R0, ' +
90 crm + '"' + ' : : "r" (v));')
91 print('}')
92
93
94def gen_read32_func(reg_name, crn, opc1, crm, opc2, descr):
95 print('')
96 if len(descr):
97 print('/* ' + descr + ' */')
98 print('static inline uint32_t read_' + reg_name.lower() + '(void)')
99 print('{')
100 print('\tuint32_t v;')
101 print('')
102 print('\tasm volatile ("mrc p15, ' + opc1 + ', %0, ' + crn + ', ' +
103 crm + ', ' + opc2 + '"' + ' : "=r" (v));')
104 print('')
105 print('\treturn v;')
106 print('}')
107
108
109def gen_write32_func(reg_name, crn, opc1, crm, opc2, descr):
110 print('')
111 if len(descr):
112 print('/* ' + descr + ' */')
113 print('static inline void write_' + reg_name.lower() + '(uint32_t v)')
114 print('{')
115 print('\tasm volatile ("mcr p15, ' + opc1 + ', %0, ' + crn + ', ' +
116 crm + ', ' + opc2 + '"' + ' : : "r" (v));')
117 print('}')
118
119
120def gen_write32_dummy_func(reg_name, crn, opc1, crm, opc2, descr):
121 print('')
122 if len(descr):
123 print('/* ' + descr + ' */')
124 print('static inline void write_' + reg_name.lower() + '(void)')
125 print('{')
126 print('\t/* Register ignored */')
127 print('\tasm volatile ("mcr p15, ' + opc1 + ', r0, ' + crn + ', ' +
128 crm + ', ' + opc2 + '");')
129 print('}')
130
131
132def gen_file(line, line_number, s_file):
133 words = line.split()
134 if len(words) == 0:
135 return
136
137 if len(re.findall('^ *#', line)):
138 return
139
140 if len(re.findall('^ *@', line)):
141 comment = re.sub('^ *@', '', line)
142 comment = re.sub('^ *', '', comment)
143 comment = re.sub('[ \n]*$', '', comment)
144 if len(comment) == 0:
145 print('')
146 return
147 if s_file:
148 print('# ' + comment)
149 else:
150 print('/* ' + comment + ' */')
151 return
152
153 reg_name = words[0]
154 crn = words[1]
155 opc1 = words[2]
156 crm = words[3]
157 opc2 = words[4]
158 access_type = words[5]
159 descr = " ".join(words[6:])
160
161 read_access = access_type == 'RO' or access_type == 'RW'
162 write_access = (access_type == 'WO' or access_type == 'RW' or
163 access_type == 'WOD')
164 dummy_access = access_type == 'WOD'
165
166 if not read_access and not write_access:
167 my_err(line_number, 'bad Access Type "' + access_type + '"')
168
169 if crn == '-':
170 if opc2 != '-':
171 my_err(line_number, 'bad opc2, expected -')
172
173 if read_access:
174 if s_file:
175 gen_read64_macro(reg_name, opc1, crm, descr)
176 else:
177 gen_read64_func(reg_name, opc1, crm, descr)
178
179 if s_file:
180 gen_write64_macro(reg_name, opc1, crm, descr)
181 else:
182 gen_write64_func(reg_name, opc1, crm, descr)
183 else:
184 if read_access:
185 if s_file:
186 gen_read32_macro(reg_name, crn, opc1, crm, opc2, descr)
187 else:
188 gen_read32_func(reg_name, crn, opc1, crm, opc2, descr)
189
190 if write_access:
191 if dummy_access:
192 if s_file:
193 gen_write32_dummy_macro(reg_name, crn, opc1, crm, opc2,
194 descr)
195 else:
196 gen_write32_dummy_func(reg_name, crn, opc1, crm, opc2,
197 descr)
198 else:
199 if s_file:
200 gen_write32_macro(reg_name, crn, opc1, crm, opc2, descr)
201 else:
202 gen_write32_func(reg_name, crn, opc1, crm, opc2, descr)
203
204
205def get_args():
206 parser = argparse.ArgumentParser(description='Generates instructions to '
207 'access ARM32 system registers.')
208
209 parser.add_argument('--s_file', action='store_true',
210 help='Generate an Assembly instead of a C file')
211 parser.add_argument('--guard',
212 help='Provide #ifdef <guard_argument> in C file')
213
214 return parser.parse_args()
215
216
217def main():
218 args = get_args()
219
220 cmnt = 'Automatically generated, do not edit'
221 if args.s_file:
222 print('# ' + cmnt)
223 else:
224 print('/* ' + cmnt + ' */')
225 if args.guard is not None:
226 print('#ifndef ' + args.guard.upper().replace('.', '_'))
227 print('#define ' + args.guard.upper().replace('.', '_'))
228
229 line_number = 0
230 for line in sys.stdin:
231 line_number = line_number + 1
232 gen_file(line, line_number, args.s_file)
233
234 if not args.s_file and args.guard is not None:
235 print('#endif /*' + args.guard.upper().replace('.', '_') + '*/')
236
237
238if __name__ == '__main__':
239 main()