blob: 4b6f9cfb539a211a1cff681d283610a251fe6582 [file] [log] [blame]
#!/usr/bin/env python3
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018, Linaro Limited
#
import argparse
import sys
import re
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
def my_err(line_number, msg):
eprint('Error: line:' + repr(line_number) + ' ' + msg)
sys.exit(1)
def gen_read64_macro(reg_name, opc1, crm, descr):
print('')
if len(descr):
print('\t# ' + descr)
print('\t.macro read_' + reg_name.lower() + ' reg0, reg1')
print('\tmrrc\tp15, ' + opc1 + ', \\reg0, \\reg1, ' + crm)
print('\t.endm')
def gen_write64_macro(reg_name, opc1, crm, descr):
print('')
if len(descr):
print('\t# ' + descr)
print('\t.macro write_' + reg_name.lower() + ' reg0, reg1')
print('\tmcrr\tp15, ' + opc1 + ', \\reg0, \\reg1, ' + crm)
print('\t.endm')
def gen_read32_macro(reg_name, crn, opc1, crm, opc2, descr):
print('')
if len(descr):
print('\t# ' + descr)
print('\t.macro read_' + reg_name.lower() + ' reg')
print('\tmrc p15, ' + opc1 + ', \\reg, ' + crn + ', ' + crm + ', ' + opc2)
print('\t.endm')
def gen_write32_macro(reg_name, crn, opc1, crm, opc2, descr):
print('')
if len(descr):
print('\t# ' + descr)
print('\t.macro write_' + reg_name.lower() + ' reg')
print('\tmcr p15, ' + opc1 + ', \\reg, ' + crn + ', ' + crm + ', ' + opc2)
print('\t.endm')
def gen_write32_dummy_macro(reg_name, crn, opc1, crm, opc2, descr):
print('')
if len(descr):
print('\t# ' + descr)
print('\t.macro write_' + reg_name.lower())
print('\t# Register ignored')
print('\tmcr p15, ' + opc1 + ', r0, ' + crn + ', ' + crm + ', ' + opc2)
print('\t.endm')
def gen_read64_func(reg_name, opc1, crm, descr):
print('')
if len(descr):
print('/* ' + descr + ' */')
print('static inline __noprof uint64_t read_' + reg_name.lower() +
'(void)')
print('{')
print('\tuint64_t v;')
print('')
print('\tasm volatile ("mrrc p15, ' + opc1 + ', %Q0, %R0, ' +
crm + '"' + ' : "=r" (v));')
print('')
print('\treturn v;')
print('}')
def gen_write64_func(reg_name, opc1, crm, descr):
print('')
if len(descr):
print('/* ' + descr + ' */')
print('static inline __noprof void write_' + reg_name.lower() +
'(uint64_t v)')
print('{')
print('\tasm volatile ("mcrr p15, ' + opc1 + ', %Q0, %R0, ' +
crm + '"' + ' : : "r" (v));')
print('}')
def gen_read32_func(reg_name, crn, opc1, crm, opc2, descr):
print('')
if len(descr):
print('/* ' + descr + ' */')
print('static inline __noprof uint32_t read_' + reg_name.lower() +
'(void)')
print('{')
print('\tuint32_t v;')
print('')
print('\tasm volatile ("mrc p15, ' + opc1 + ', %0, ' + crn + ', ' +
crm + ', ' + opc2 + '"' + ' : "=r" (v));')
print('')
print('\treturn v;')
print('}')
def gen_write32_func(reg_name, crn, opc1, crm, opc2, descr):
print('')
if len(descr):
print('/* ' + descr + ' */')
print('static inline __noprof void write_' + reg_name.lower() +
'(uint32_t v)')
print('{')
print('\tasm volatile ("mcr p15, ' + opc1 + ', %0, ' + crn + ', ' +
crm + ', ' + opc2 + '"' + ' : : "r" (v));')
print('}')
def gen_write32_dummy_func(reg_name, crn, opc1, crm, opc2, descr):
print('')
if len(descr):
print('/* ' + descr + ' */')
print('static inline __noprof void write_' + reg_name.lower() + '(void)')
print('{')
print('\t/* Register ignored */')
print('\tasm volatile ("mcr p15, ' + opc1 + ', r0, ' + crn + ', ' +
crm + ', ' + opc2 + '");')
print('}')
def gen_file(line, line_number, s_file):
words = line.split()
if len(words) == 0:
return
if len(re.findall('^ *#', line)):
return
if len(re.findall('^ *@', line)):
comment = re.sub('^ *@', '', line)
comment = re.sub('^ *', '', comment)
comment = re.sub('[ \n]*$', '', comment)
if len(comment) == 0:
print('')
return
if s_file:
print('# ' + comment)
else:
print('/* ' + comment + ' */')
return
reg_name = words[0]
crn = words[1]
opc1 = words[2]
crm = words[3]
opc2 = words[4]
access_type = words[5]
descr = " ".join(words[6:])
read_access = access_type == 'RO' or access_type == 'RW'
write_access = (access_type == 'WO' or access_type == 'RW' or
access_type == 'WOD')
dummy_access = access_type == 'WOD'
if not read_access and not write_access:
my_err(line_number, 'bad Access Type "' + access_type + '"')
if crn == '-':
if opc2 != '-':
my_err(line_number, 'bad opc2, expected -')
if read_access:
if s_file:
gen_read64_macro(reg_name, opc1, crm, descr)
else:
gen_read64_func(reg_name, opc1, crm, descr)
if s_file:
gen_write64_macro(reg_name, opc1, crm, descr)
else:
gen_write64_func(reg_name, opc1, crm, descr)
else:
if read_access:
if s_file:
gen_read32_macro(reg_name, crn, opc1, crm, opc2, descr)
else:
gen_read32_func(reg_name, crn, opc1, crm, opc2, descr)
if write_access:
if dummy_access:
if s_file:
gen_write32_dummy_macro(reg_name, crn, opc1, crm, opc2,
descr)
else:
gen_write32_dummy_func(reg_name, crn, opc1, crm, opc2,
descr)
else:
if s_file:
gen_write32_macro(reg_name, crn, opc1, crm, opc2, descr)
else:
gen_write32_func(reg_name, crn, opc1, crm, opc2, descr)
def get_args():
parser = argparse.ArgumentParser(description='Generates instructions to '
'access ARM32 system registers.')
parser.add_argument('--s_file', action='store_true',
help='Generate an Assembly instead of a C file')
parser.add_argument('--guard',
help='Provide #ifdef <guard_argument> in C file')
return parser.parse_args()
def main():
args = get_args()
cmnt = 'Automatically generated, do not edit'
if args.s_file:
print('# ' + cmnt)
else:
print('/* ' + cmnt + ' */')
if args.guard is not None:
print('#ifndef ' + args.guard.upper().replace('.', '_'))
print('#define ' + args.guard.upper().replace('.', '_'))
print('#include <compiler.h>')
line_number = 0
for line in sys.stdin:
line_number = line_number + 1
gen_file(line, line_number, args.s_file)
if not args.s_file and args.guard is not None:
print('#endif /*' + args.guard.upper().replace('.', '_') + '*/')
if __name__ == '__main__':
main()