1bbaeed4dSRouven Czerwinski#!/usr/bin/env python3 218b58024SJens Wiklander# SPDX-License-Identifier: BSD-2-Clause 318b58024SJens Wiklander# 418b58024SJens Wiklander# Copyright (c) 2018, Linaro Limited 518b58024SJens Wiklander# 6bbaeed4dSRouven Czerwinski 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 + ' */') 7246656a3cSJerome Forissier print('static inline __noprof uint64_t read_' + reg_name.lower() + 7346656a3cSJerome Forissier '(void)') 7418b58024SJens Wiklander print('{') 7518b58024SJens Wiklander print('\tuint64_t v;') 7618b58024SJens Wiklander print('') 7718b58024SJens Wiklander print('\tasm volatile ("mrrc p15, ' + opc1 + ', %Q0, %R0, ' + 7818b58024SJens Wiklander crm + '"' + ' : "=r" (v));') 7918b58024SJens Wiklander print('') 8018b58024SJens Wiklander print('\treturn v;') 8118b58024SJens Wiklander print('}') 8218b58024SJens Wiklander 8318b58024SJens Wiklander 8418b58024SJens Wiklanderdef gen_write64_func(reg_name, opc1, crm, descr): 8518b58024SJens Wiklander print('') 8618b58024SJens Wiklander if len(descr): 8718b58024SJens Wiklander print('/* ' + descr + ' */') 884486d586SSumit Garg print('static inline __noprof void write_' + reg_name.lower() + 894486d586SSumit Garg '(uint64_t v)') 9018b58024SJens Wiklander print('{') 9118b58024SJens Wiklander print('\tasm volatile ("mcrr p15, ' + opc1 + ', %Q0, %R0, ' + 9218b58024SJens Wiklander crm + '"' + ' : : "r" (v));') 9318b58024SJens Wiklander print('}') 9418b58024SJens Wiklander 9518b58024SJens Wiklander 9618b58024SJens Wiklanderdef gen_read32_func(reg_name, crn, opc1, crm, opc2, descr): 9718b58024SJens Wiklander print('') 9818b58024SJens Wiklander if len(descr): 9918b58024SJens Wiklander print('/* ' + descr + ' */') 10046656a3cSJerome Forissier print('static inline __noprof uint32_t read_' + reg_name.lower() + 10146656a3cSJerome Forissier '(void)') 10218b58024SJens Wiklander print('{') 10318b58024SJens Wiklander print('\tuint32_t v;') 10418b58024SJens Wiklander print('') 10518b58024SJens Wiklander print('\tasm volatile ("mrc p15, ' + opc1 + ', %0, ' + crn + ', ' + 10618b58024SJens Wiklander crm + ', ' + opc2 + '"' + ' : "=r" (v));') 10718b58024SJens Wiklander print('') 10818b58024SJens Wiklander print('\treturn v;') 10918b58024SJens Wiklander print('}') 11018b58024SJens Wiklander 11118b58024SJens Wiklander 11218b58024SJens Wiklanderdef gen_write32_func(reg_name, crn, opc1, crm, opc2, descr): 11318b58024SJens Wiklander print('') 11418b58024SJens Wiklander if len(descr): 11518b58024SJens Wiklander print('/* ' + descr + ' */') 1164486d586SSumit Garg print('static inline __noprof void write_' + reg_name.lower() + 1174486d586SSumit Garg '(uint32_t v)') 11818b58024SJens Wiklander print('{') 11918b58024SJens Wiklander print('\tasm volatile ("mcr p15, ' + opc1 + ', %0, ' + crn + ', ' + 12018b58024SJens Wiklander crm + ', ' + opc2 + '"' + ' : : "r" (v));') 12118b58024SJens Wiklander print('}') 12218b58024SJens Wiklander 12318b58024SJens Wiklander 12418b58024SJens Wiklanderdef gen_write32_dummy_func(reg_name, crn, opc1, crm, opc2, descr): 12518b58024SJens Wiklander print('') 12618b58024SJens Wiklander if len(descr): 12718b58024SJens Wiklander print('/* ' + descr + ' */') 128*099918f6SSumit Garg print('static inline __noprof void write_' + reg_name.lower() + '(void)') 12918b58024SJens Wiklander print('{') 13018b58024SJens Wiklander print('\t/* Register ignored */') 13118b58024SJens Wiklander print('\tasm volatile ("mcr p15, ' + opc1 + ', r0, ' + crn + ', ' + 13218b58024SJens Wiklander crm + ', ' + opc2 + '");') 13318b58024SJens Wiklander print('}') 13418b58024SJens Wiklander 13518b58024SJens Wiklander 13618b58024SJens Wiklanderdef gen_file(line, line_number, s_file): 13718b58024SJens Wiklander words = line.split() 13818b58024SJens Wiklander if len(words) == 0: 13918b58024SJens Wiklander return 14018b58024SJens Wiklander 14118b58024SJens Wiklander if len(re.findall('^ *#', line)): 14218b58024SJens Wiklander return 14318b58024SJens Wiklander 14418b58024SJens Wiklander if len(re.findall('^ *@', line)): 14518b58024SJens Wiklander comment = re.sub('^ *@', '', line) 14618b58024SJens Wiklander comment = re.sub('^ *', '', comment) 14718b58024SJens Wiklander comment = re.sub('[ \n]*$', '', comment) 14818b58024SJens Wiklander if len(comment) == 0: 14918b58024SJens Wiklander print('') 15018b58024SJens Wiklander return 15118b58024SJens Wiklander if s_file: 15218b58024SJens Wiklander print('# ' + comment) 15318b58024SJens Wiklander else: 15418b58024SJens Wiklander print('/* ' + comment + ' */') 15518b58024SJens Wiklander return 15618b58024SJens Wiklander 15718b58024SJens Wiklander reg_name = words[0] 15818b58024SJens Wiklander crn = words[1] 15918b58024SJens Wiklander opc1 = words[2] 16018b58024SJens Wiklander crm = words[3] 16118b58024SJens Wiklander opc2 = words[4] 16218b58024SJens Wiklander access_type = words[5] 16318b58024SJens Wiklander descr = " ".join(words[6:]) 16418b58024SJens Wiklander 16518b58024SJens Wiklander read_access = access_type == 'RO' or access_type == 'RW' 16618b58024SJens Wiklander write_access = (access_type == 'WO' or access_type == 'RW' or 16718b58024SJens Wiklander access_type == 'WOD') 16818b58024SJens Wiklander dummy_access = access_type == 'WOD' 16918b58024SJens Wiklander 17018b58024SJens Wiklander if not read_access and not write_access: 17118b58024SJens Wiklander my_err(line_number, 'bad Access Type "' + access_type + '"') 17218b58024SJens Wiklander 17318b58024SJens Wiklander if crn == '-': 17418b58024SJens Wiklander if opc2 != '-': 17518b58024SJens Wiklander my_err(line_number, 'bad opc2, expected -') 17618b58024SJens Wiklander 17718b58024SJens Wiklander if read_access: 17818b58024SJens Wiklander if s_file: 17918b58024SJens Wiklander gen_read64_macro(reg_name, opc1, crm, descr) 18018b58024SJens Wiklander else: 18118b58024SJens Wiklander gen_read64_func(reg_name, opc1, crm, descr) 18218b58024SJens Wiklander 18318b58024SJens Wiklander if s_file: 18418b58024SJens Wiklander gen_write64_macro(reg_name, opc1, crm, descr) 18518b58024SJens Wiklander else: 18618b58024SJens Wiklander gen_write64_func(reg_name, opc1, crm, descr) 18718b58024SJens Wiklander else: 18818b58024SJens Wiklander if read_access: 18918b58024SJens Wiklander if s_file: 19018b58024SJens Wiklander gen_read32_macro(reg_name, crn, opc1, crm, opc2, descr) 19118b58024SJens Wiklander else: 19218b58024SJens Wiklander gen_read32_func(reg_name, crn, opc1, crm, opc2, descr) 19318b58024SJens Wiklander 19418b58024SJens Wiklander if write_access: 19518b58024SJens Wiklander if dummy_access: 19618b58024SJens Wiklander if s_file: 19718b58024SJens Wiklander gen_write32_dummy_macro(reg_name, crn, opc1, crm, opc2, 19818b58024SJens Wiklander descr) 19918b58024SJens Wiklander else: 20018b58024SJens Wiklander gen_write32_dummy_func(reg_name, crn, opc1, crm, opc2, 20118b58024SJens Wiklander descr) 20218b58024SJens Wiklander else: 20318b58024SJens Wiklander if s_file: 20418b58024SJens Wiklander gen_write32_macro(reg_name, crn, opc1, crm, opc2, descr) 20518b58024SJens Wiklander else: 20618b58024SJens Wiklander gen_write32_func(reg_name, crn, opc1, crm, opc2, descr) 20718b58024SJens Wiklander 20818b58024SJens Wiklander 20918b58024SJens Wiklanderdef get_args(): 21018b58024SJens Wiklander parser = argparse.ArgumentParser(description='Generates instructions to ' 21118b58024SJens Wiklander 'access ARM32 system registers.') 21218b58024SJens Wiklander 21318b58024SJens Wiklander parser.add_argument('--s_file', action='store_true', 21418b58024SJens Wiklander help='Generate an Assembly instead of a C file') 21518b58024SJens Wiklander parser.add_argument('--guard', 21618b58024SJens Wiklander help='Provide #ifdef <guard_argument> in C file') 21718b58024SJens Wiklander 21818b58024SJens Wiklander return parser.parse_args() 21918b58024SJens Wiklander 22018b58024SJens Wiklander 22118b58024SJens Wiklanderdef main(): 22218b58024SJens Wiklander args = get_args() 22318b58024SJens Wiklander 22418b58024SJens Wiklander cmnt = 'Automatically generated, do not edit' 22518b58024SJens Wiklander if args.s_file: 22618b58024SJens Wiklander print('# ' + cmnt) 22718b58024SJens Wiklander else: 22818b58024SJens Wiklander print('/* ' + cmnt + ' */') 22918b58024SJens Wiklander if args.guard is not None: 23018b58024SJens Wiklander print('#ifndef ' + args.guard.upper().replace('.', '_')) 23118b58024SJens Wiklander print('#define ' + args.guard.upper().replace('.', '_')) 2324486d586SSumit Garg print('#include <compiler.h>') 23318b58024SJens Wiklander 23418b58024SJens Wiklander line_number = 0 23518b58024SJens Wiklander for line in sys.stdin: 23618b58024SJens Wiklander line_number = line_number + 1 23718b58024SJens Wiklander gen_file(line, line_number, args.s_file) 23818b58024SJens Wiklander 23918b58024SJens Wiklander if not args.s_file and args.guard is not None: 24018b58024SJens Wiklander print('#endif /*' + args.guard.upper().replace('.', '_') + '*/') 24118b58024SJens Wiklander 24218b58024SJens Wiklander 24318b58024SJens Wiklanderif __name__ == '__main__': 24418b58024SJens Wiklander main() 245