xref: /optee_os/scripts/arm32_sysreg.py (revision 099918f6744c37ce693c38562f11466b19d573c9)
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