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