118b58024SJens Wiklander#!/usr/bin/env python 218b58024SJens Wiklander# SPDX-License-Identifier: BSD-2-Clause 318b58024SJens Wiklander# 418b58024SJens Wiklander# Copyright (c) 2018, Linaro Limited 518b58024SJens Wiklander# 618b58024SJens Wiklanderfrom __future__ import print_function 718b58024SJens Wiklander 818b58024SJens Wiklanderimport argparse 918b58024SJens Wiklanderimport sys 1018b58024SJens Wiklanderimport re 1118b58024SJens Wiklander 1218b58024SJens Wiklander 1318b58024SJens Wiklanderdef eprint(*args, **kwargs): 1418b58024SJens Wiklander print(*args, file=sys.stderr, **kwargs) 1518b58024SJens Wiklander 1618b58024SJens Wiklander 1718b58024SJens Wiklanderdef my_err(line_number, msg): 1818b58024SJens Wiklander eprint('Error: line:' + repr(line_number) + ' ' + msg) 1918b58024SJens Wiklander sys.exit(1) 2018b58024SJens Wiklander 2118b58024SJens Wiklander 2218b58024SJens Wiklanderdef gen_read64_macro(reg_name, opc1, crm, descr): 2318b58024SJens Wiklander print('') 2418b58024SJens Wiklander if len(descr): 2518b58024SJens Wiklander print('\t# ' + descr) 2618b58024SJens Wiklander print('\t.macro read_' + reg_name.lower() + ' reg0, reg1') 2718b58024SJens Wiklander print('\tmrrc\tp15, ' + opc1 + ', \\reg0, \\reg1, ' + crm) 2818b58024SJens Wiklander print('\t.endm') 2918b58024SJens Wiklander 3018b58024SJens Wiklander 3118b58024SJens Wiklanderdef gen_write64_macro(reg_name, opc1, crm, descr): 3218b58024SJens Wiklander print('') 3318b58024SJens Wiklander if len(descr): 3418b58024SJens Wiklander print('\t# ' + descr) 3518b58024SJens Wiklander print('\t.macro write_' + reg_name.lower() + ' reg0, reg1') 3618b58024SJens Wiklander print('\tmcrr\tp15, ' + opc1 + ', \\reg0, \\reg1, ' + crm) 3718b58024SJens Wiklander print('\t.endm') 3818b58024SJens Wiklander 3918b58024SJens Wiklander 4018b58024SJens Wiklanderdef gen_read32_macro(reg_name, crn, opc1, crm, opc2, descr): 4118b58024SJens Wiklander print('') 4218b58024SJens Wiklander if len(descr): 4318b58024SJens Wiklander print('\t# ' + descr) 4418b58024SJens Wiklander print('\t.macro read_' + reg_name.lower() + ' reg') 4518b58024SJens Wiklander print('\tmrc p15, ' + opc1 + ', \\reg, ' + crn + ', ' + crm + ', ' + opc2) 4618b58024SJens Wiklander print('\t.endm') 4718b58024SJens Wiklander 4818b58024SJens Wiklander 4918b58024SJens Wiklanderdef gen_write32_macro(reg_name, crn, opc1, crm, opc2, descr): 5018b58024SJens Wiklander print('') 5118b58024SJens Wiklander if len(descr): 5218b58024SJens Wiklander print('\t# ' + descr) 5318b58024SJens Wiklander print('\t.macro write_' + reg_name.lower() + ' reg') 5418b58024SJens Wiklander print('\tmcr p15, ' + opc1 + ', \\reg, ' + crn + ', ' + crm + ', ' + opc2) 5518b58024SJens Wiklander print('\t.endm') 5618b58024SJens Wiklander 5718b58024SJens Wiklander 5818b58024SJens Wiklanderdef gen_write32_dummy_macro(reg_name, crn, opc1, crm, opc2, descr): 5918b58024SJens Wiklander print('') 6018b58024SJens Wiklander if len(descr): 6118b58024SJens Wiklander print('\t# ' + descr) 6218b58024SJens Wiklander print('\t.macro write_' + reg_name.lower()) 6318b58024SJens Wiklander print('\t# Register ignored') 6418b58024SJens Wiklander print('\tmcr p15, ' + opc1 + ', r0, ' + crn + ', ' + crm + ', ' + opc2) 6518b58024SJens Wiklander print('\t.endm') 6618b58024SJens Wiklander 6718b58024SJens Wiklander 6818b58024SJens Wiklanderdef gen_read64_func(reg_name, opc1, crm, descr): 6918b58024SJens Wiklander print('') 7018b58024SJens Wiklander if len(descr): 7118b58024SJens Wiklander print('/* ' + descr + ' */') 72*4486d586SSumit Garg print('static inline __noprof uint64_t read_' + reg_name.lower() + '(void)') 7318b58024SJens Wiklander print('{') 7418b58024SJens Wiklander print('\tuint64_t v;') 7518b58024SJens Wiklander print('') 7618b58024SJens Wiklander print('\tasm volatile ("mrrc p15, ' + opc1 + ', %Q0, %R0, ' + 7718b58024SJens Wiklander crm + '"' + ' : "=r" (v));') 7818b58024SJens Wiklander print('') 7918b58024SJens Wiklander print('\treturn v;') 8018b58024SJens Wiklander print('}') 8118b58024SJens Wiklander 8218b58024SJens Wiklander 8318b58024SJens Wiklanderdef gen_write64_func(reg_name, opc1, crm, descr): 8418b58024SJens Wiklander print('') 8518b58024SJens Wiklander if len(descr): 8618b58024SJens Wiklander print('/* ' + descr + ' */') 87*4486d586SSumit Garg print('static inline __noprof void write_' + reg_name.lower() + 88*4486d586SSumit Garg '(uint64_t v)') 8918b58024SJens Wiklander print('{') 9018b58024SJens Wiklander print('\tasm volatile ("mcrr p15, ' + opc1 + ', %Q0, %R0, ' + 9118b58024SJens Wiklander crm + '"' + ' : : "r" (v));') 9218b58024SJens Wiklander print('}') 9318b58024SJens Wiklander 9418b58024SJens Wiklander 9518b58024SJens Wiklanderdef gen_read32_func(reg_name, crn, opc1, crm, opc2, descr): 9618b58024SJens Wiklander print('') 9718b58024SJens Wiklander if len(descr): 9818b58024SJens Wiklander print('/* ' + descr + ' */') 99*4486d586SSumit Garg print('static inline __noprof uint32_t read_' + reg_name.lower() + '(void)') 10018b58024SJens Wiklander print('{') 10118b58024SJens Wiklander print('\tuint32_t v;') 10218b58024SJens Wiklander print('') 10318b58024SJens Wiklander print('\tasm volatile ("mrc p15, ' + opc1 + ', %0, ' + crn + ', ' + 10418b58024SJens Wiklander crm + ', ' + opc2 + '"' + ' : "=r" (v));') 10518b58024SJens Wiklander print('') 10618b58024SJens Wiklander print('\treturn v;') 10718b58024SJens Wiklander print('}') 10818b58024SJens Wiklander 10918b58024SJens Wiklander 11018b58024SJens Wiklanderdef gen_write32_func(reg_name, crn, opc1, crm, opc2, descr): 11118b58024SJens Wiklander print('') 11218b58024SJens Wiklander if len(descr): 11318b58024SJens Wiklander print('/* ' + descr + ' */') 114*4486d586SSumit Garg print('static inline __noprof void write_' + reg_name.lower() + 115*4486d586SSumit Garg '(uint32_t v)') 11618b58024SJens Wiklander print('{') 11718b58024SJens Wiklander print('\tasm volatile ("mcr p15, ' + opc1 + ', %0, ' + crn + ', ' + 11818b58024SJens Wiklander crm + ', ' + opc2 + '"' + ' : : "r" (v));') 11918b58024SJens Wiklander print('}') 12018b58024SJens Wiklander 12118b58024SJens Wiklander 12218b58024SJens Wiklanderdef gen_write32_dummy_func(reg_name, crn, opc1, crm, opc2, descr): 12318b58024SJens Wiklander print('') 12418b58024SJens Wiklander if len(descr): 12518b58024SJens Wiklander print('/* ' + descr + ' */') 12618b58024SJens Wiklander print('static inline void write_' + reg_name.lower() + '(void)') 12718b58024SJens Wiklander print('{') 12818b58024SJens Wiklander print('\t/* Register ignored */') 12918b58024SJens Wiklander print('\tasm volatile ("mcr p15, ' + opc1 + ', r0, ' + crn + ', ' + 13018b58024SJens Wiklander crm + ', ' + opc2 + '");') 13118b58024SJens Wiklander print('}') 13218b58024SJens Wiklander 13318b58024SJens Wiklander 13418b58024SJens Wiklanderdef gen_file(line, line_number, s_file): 13518b58024SJens Wiklander words = line.split() 13618b58024SJens Wiklander if len(words) == 0: 13718b58024SJens Wiklander return 13818b58024SJens Wiklander 13918b58024SJens Wiklander if len(re.findall('^ *#', line)): 14018b58024SJens Wiklander return 14118b58024SJens Wiklander 14218b58024SJens Wiklander if len(re.findall('^ *@', line)): 14318b58024SJens Wiklander comment = re.sub('^ *@', '', line) 14418b58024SJens Wiklander comment = re.sub('^ *', '', comment) 14518b58024SJens Wiklander comment = re.sub('[ \n]*$', '', comment) 14618b58024SJens Wiklander if len(comment) == 0: 14718b58024SJens Wiklander print('') 14818b58024SJens Wiklander return 14918b58024SJens Wiklander if s_file: 15018b58024SJens Wiklander print('# ' + comment) 15118b58024SJens Wiklander else: 15218b58024SJens Wiklander print('/* ' + comment + ' */') 15318b58024SJens Wiklander return 15418b58024SJens Wiklander 15518b58024SJens Wiklander reg_name = words[0] 15618b58024SJens Wiklander crn = words[1] 15718b58024SJens Wiklander opc1 = words[2] 15818b58024SJens Wiklander crm = words[3] 15918b58024SJens Wiklander opc2 = words[4] 16018b58024SJens Wiklander access_type = words[5] 16118b58024SJens Wiklander descr = " ".join(words[6:]) 16218b58024SJens Wiklander 16318b58024SJens Wiklander read_access = access_type == 'RO' or access_type == 'RW' 16418b58024SJens Wiklander write_access = (access_type == 'WO' or access_type == 'RW' or 16518b58024SJens Wiklander access_type == 'WOD') 16618b58024SJens Wiklander dummy_access = access_type == 'WOD' 16718b58024SJens Wiklander 16818b58024SJens Wiklander if not read_access and not write_access: 16918b58024SJens Wiklander my_err(line_number, 'bad Access Type "' + access_type + '"') 17018b58024SJens Wiklander 17118b58024SJens Wiklander if crn == '-': 17218b58024SJens Wiklander if opc2 != '-': 17318b58024SJens Wiklander my_err(line_number, 'bad opc2, expected -') 17418b58024SJens Wiklander 17518b58024SJens Wiklander if read_access: 17618b58024SJens Wiklander if s_file: 17718b58024SJens Wiklander gen_read64_macro(reg_name, opc1, crm, descr) 17818b58024SJens Wiklander else: 17918b58024SJens Wiklander gen_read64_func(reg_name, opc1, crm, descr) 18018b58024SJens Wiklander 18118b58024SJens Wiklander if s_file: 18218b58024SJens Wiklander gen_write64_macro(reg_name, opc1, crm, descr) 18318b58024SJens Wiklander else: 18418b58024SJens Wiklander gen_write64_func(reg_name, opc1, crm, descr) 18518b58024SJens Wiklander else: 18618b58024SJens Wiklander if read_access: 18718b58024SJens Wiklander if s_file: 18818b58024SJens Wiklander gen_read32_macro(reg_name, crn, opc1, crm, opc2, descr) 18918b58024SJens Wiklander else: 19018b58024SJens Wiklander gen_read32_func(reg_name, crn, opc1, crm, opc2, descr) 19118b58024SJens Wiklander 19218b58024SJens Wiklander if write_access: 19318b58024SJens Wiklander if dummy_access: 19418b58024SJens Wiklander if s_file: 19518b58024SJens Wiklander gen_write32_dummy_macro(reg_name, crn, opc1, crm, opc2, 19618b58024SJens Wiklander descr) 19718b58024SJens Wiklander else: 19818b58024SJens Wiklander gen_write32_dummy_func(reg_name, crn, opc1, crm, opc2, 19918b58024SJens Wiklander descr) 20018b58024SJens Wiklander else: 20118b58024SJens Wiklander if s_file: 20218b58024SJens Wiklander gen_write32_macro(reg_name, crn, opc1, crm, opc2, descr) 20318b58024SJens Wiklander else: 20418b58024SJens Wiklander gen_write32_func(reg_name, crn, opc1, crm, opc2, descr) 20518b58024SJens Wiklander 20618b58024SJens Wiklander 20718b58024SJens Wiklanderdef get_args(): 20818b58024SJens Wiklander parser = argparse.ArgumentParser(description='Generates instructions to ' 20918b58024SJens Wiklander 'access ARM32 system registers.') 21018b58024SJens Wiklander 21118b58024SJens Wiklander parser.add_argument('--s_file', action='store_true', 21218b58024SJens Wiklander help='Generate an Assembly instead of a C file') 21318b58024SJens Wiklander parser.add_argument('--guard', 21418b58024SJens Wiklander help='Provide #ifdef <guard_argument> in C file') 21518b58024SJens Wiklander 21618b58024SJens Wiklander return parser.parse_args() 21718b58024SJens Wiklander 21818b58024SJens Wiklander 21918b58024SJens Wiklanderdef main(): 22018b58024SJens Wiklander args = get_args() 22118b58024SJens Wiklander 22218b58024SJens Wiklander cmnt = 'Automatically generated, do not edit' 22318b58024SJens Wiklander if args.s_file: 22418b58024SJens Wiklander print('# ' + cmnt) 22518b58024SJens Wiklander else: 22618b58024SJens Wiklander print('/* ' + cmnt + ' */') 22718b58024SJens Wiklander if args.guard is not None: 22818b58024SJens Wiklander print('#ifndef ' + args.guard.upper().replace('.', '_')) 22918b58024SJens Wiklander print('#define ' + args.guard.upper().replace('.', '_')) 230*4486d586SSumit Garg print('#include <compiler.h>') 23118b58024SJens Wiklander 23218b58024SJens Wiklander line_number = 0 23318b58024SJens Wiklander for line in sys.stdin: 23418b58024SJens Wiklander line_number = line_number + 1 23518b58024SJens Wiklander gen_file(line, line_number, args.s_file) 23618b58024SJens Wiklander 23718b58024SJens Wiklander if not args.s_file and args.guard is not None: 23818b58024SJens Wiklander print('#endif /*' + args.guard.upper().replace('.', '_') + '*/') 23918b58024SJens Wiklander 24018b58024SJens Wiklander 24118b58024SJens Wiklanderif __name__ == '__main__': 24218b58024SJens Wiklander main() 243