1#!/usr/bin/env python3 2# SPDX-License-Identifier: BSD-2-Clause 3# 4# Copyright (c) 2018, Linaro Limited 5# 6 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 __noprof uint64_t read_' + reg_name.lower() + 73 '(void)') 74 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 + ' */') 88 print('static inline __noprof void write_' + reg_name.lower() + 89 '(uint64_t v)') 90 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 + ' */') 100 print('static inline __noprof uint32_t read_' + reg_name.lower() + 101 '(void)') 102 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 + ' */') 116 print('static inline __noprof void write_' + reg_name.lower() + 117 '(uint32_t v)') 118 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 __noprof 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('.', '_')) 232 print('#include <compiler.h>') 233 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() 245