733 lines
20 KiB
Python
Executable file
733 lines
20 KiB
Python
Executable file
#!/usr/bin/env python
|
|
|
|
#
|
|
# This file is part of unicore-mx.
|
|
# Copyright (C) 2014-2016 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
|
|
#
|
|
# uc-def is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# uc-def is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with uc-def. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
# Special exception (same as GNU Bison)
|
|
# As a special exception, you may create a larger work that contains
|
|
# part or all of the uc-def parser skeleton and distribute that work
|
|
# under terms of your choice, so long as that work isn't itself a
|
|
# parser generator using the skeleton or a modified version thereof
|
|
# as a parser skeleton. Alternatively, if you modify or redistribute
|
|
# the parser skeleton itself, you may (at your option) remove this
|
|
# special exception, which will cause the skeleton and the resulting
|
|
# uc-def output files to be licensed under the GNU General Public
|
|
# License without this special exception.
|
|
|
|
# uC Def.
|
|
# Microcontroller register defination
|
|
|
|
import sys
|
|
import logging
|
|
|
|
logging.basicConfig()
|
|
logger = logging.getLogger(__name__)
|
|
|
|
logger.setLevel(logging.ERROR)
|
|
|
|
STRICT_C_OUTPUT = False
|
|
|
|
def verify_access_flags(data):
|
|
for i in data:
|
|
if i not in ('r', 'w', 'c', 's', 'h'):
|
|
raise Exception("'%c' flag of flags '%s' not valid" % (i, data))
|
|
|
|
def next_useful_line(tag, strip_newline=True, strip_comment=True):
|
|
while True:
|
|
tag['last_useful_pos'] = tag['input_file'].tell()
|
|
tag['last_line_number'] = tag['line_number']
|
|
inp = tag['input_file'].readline()
|
|
|
|
if not len(inp):
|
|
break
|
|
|
|
if strip_newline:
|
|
inp = inp.rstrip()
|
|
|
|
if not len(inp):
|
|
logger.debug("** SKIPPING NEWLINE at %i ***" % tag['line_number'])
|
|
tag['line_number'] += 1
|
|
continue
|
|
|
|
if strip_comment:
|
|
if inp[0] == "%":
|
|
tag['line_number'] += 1
|
|
logger.debug("** SKIPPING %i '%s' ***" % (tag['line_number'], inp))
|
|
continue
|
|
|
|
logger.debug("** LINE %i '%s' ***" % (tag['line_number'], inp))
|
|
tag['line_number'] += 1
|
|
return inp
|
|
|
|
logger.debug("** END OF FILE ***")
|
|
return ''
|
|
|
|
def restore_last_useful_line(tag):
|
|
tag['line_number'] = tag['last_line_number']
|
|
tag['input_file'].seek(tag['last_useful_pos'])
|
|
|
|
def get_line_number(tag):
|
|
return tag['line_number']
|
|
|
|
def we_have_problem(msg, tag):
|
|
raise Exception("%s [line: %i]" % (msg, get_line_number(tag)))
|
|
|
|
# this will return the last readed line. (if it could not parse it)
|
|
def parse_family_member(tag):
|
|
family = {
|
|
'name': None,
|
|
'instance': None,
|
|
'register': None,
|
|
'internal_only': False
|
|
}
|
|
|
|
while True:
|
|
inp = next_useful_line(tag)
|
|
if inp == '': break
|
|
|
|
if not inp[0] == ' ':
|
|
# revese back and return
|
|
restore_last_useful_line(tag)
|
|
break
|
|
|
|
data = inp.split()
|
|
assert(len(data) >= 1)
|
|
|
|
if data[0] == "name":
|
|
# name <name>
|
|
family['name'] = data[1]
|
|
elif data[0] == "instance":
|
|
# instance <address>
|
|
assert(family['instance'] is None)
|
|
family['instance'] = " ".join(data[1:])
|
|
elif data[0] == "instance_by_id":
|
|
# instance <id> <address>
|
|
if family['instance'] is None:
|
|
family['instance'] = []
|
|
assert(type(family['instance']) == list)
|
|
family['instance'].append({
|
|
'id': data[1],
|
|
'address': " ".join(data[2:])
|
|
})
|
|
elif data[0] == "register":
|
|
assert(2 <= len(data) <= 3)
|
|
family['register'] = {
|
|
'size': data[1],
|
|
'stride': data[2] if len(data) > 2 else None
|
|
}
|
|
elif data[0] == "internal_only":
|
|
family['internal_only'] = bool(data[1])
|
|
|
|
assert(family['name'] is not None)
|
|
return family
|
|
|
|
def parse_family(tag):
|
|
inp = next_useful_line(tag)
|
|
if inp == '':
|
|
return None
|
|
|
|
if not inp[0] == 'f':
|
|
restore_last_useful_line(tag)
|
|
return None
|
|
|
|
if not inp == "family":
|
|
# fam <name> <address>
|
|
data = inp.slit()
|
|
assert(len(data) < 2 and data[0] == "fam")
|
|
return {
|
|
'name': data[1],
|
|
'instance': data[2] if len(data) > 2 else None,
|
|
'register': None,
|
|
'internal_only': False
|
|
}
|
|
else:
|
|
return parse_family_member(tag)
|
|
|
|
def parse_register_member(tag):
|
|
register = {
|
|
'name': [],
|
|
'offset': None,
|
|
'size': None,
|
|
'access': None,
|
|
'bit_name': [],
|
|
'bits_name': [],
|
|
'variable': [],
|
|
'internal_only': False
|
|
}
|
|
|
|
while True:
|
|
inp = next_useful_line(tag)
|
|
if inp == '': break
|
|
|
|
if not inp[0] == ' ':
|
|
# revese back and return
|
|
restore_last_useful_line(tag)
|
|
break
|
|
|
|
data = inp.split()
|
|
assert(len(data) >= 1)
|
|
|
|
if data[0] == "name":
|
|
# name <name>
|
|
register['name'].append(data[1])
|
|
elif data[0] == "offset":
|
|
# offset <offset>
|
|
assert(register['offset'] is None)
|
|
register['offset'] = " ".join(data[1:])
|
|
elif data[0] == "offset_by_id":
|
|
# offset_by_id <id> <offset>
|
|
if register['offset'] is None:
|
|
register['offset'] = []
|
|
assert(type(register['offset']) == list)
|
|
register['offset'].append({
|
|
'id': data[1],
|
|
'offset': " ".join(data[2:])
|
|
})
|
|
elif data[0] == "size":
|
|
# size <size>
|
|
register['size'] = data[1]
|
|
elif data[0] == "access":
|
|
# access <access>
|
|
for c in data[1]:
|
|
assert(c in ('r', 'w', 'h'))
|
|
register['access'] = data[1]
|
|
elif data[0] == "bit_name":
|
|
# bit_name <bit-name>
|
|
register['bit_name'].append(data[1])
|
|
elif data[0] == "bits_name":
|
|
# bits_name <bits-name>
|
|
register['bits_name'].append(data[1])
|
|
elif data[0] == "variable":
|
|
# variable <variable-name> <variable-equation>
|
|
register['variable'].append({
|
|
'name': data[1],
|
|
'equation': ' '.join(data[2:])
|
|
})
|
|
elif data[0] == "internal_only":
|
|
register['internal_only'] = bool(data[1])
|
|
|
|
assert(len(register['name']))
|
|
|
|
if not len(register['bit_name']):
|
|
# <bit_name> not provided, fallback and use <name>
|
|
register['bit_name'] = register['name']
|
|
|
|
if not len(register['bits_name']):
|
|
# <bits_name> not provided, fallback and use <name>
|
|
register['bits_name'] = register['name']
|
|
|
|
return register
|
|
|
|
def parse_register(tag):
|
|
inp = next_useful_line(tag)
|
|
if inp == '':
|
|
return None
|
|
|
|
if inp[0] is not 'r':
|
|
restore_last_useful_line(tag)
|
|
return None
|
|
|
|
if inp[3] == ' ':
|
|
# reg <name> <offset> <size>
|
|
data = inp.split()
|
|
assert(2 <= len(data) <= 4)
|
|
assert(data[0] == "reg")
|
|
|
|
return {
|
|
'name': [ data[1] ],
|
|
'offset': data[2] if len(data) > 2 else None,
|
|
'size': data[3] if len(data) > 3 else None,
|
|
'access': None,
|
|
'bit_name': [ data[1] ],
|
|
'bits_name': [ data[1] ],
|
|
'variable': [],
|
|
'internal_only': False
|
|
}
|
|
else:
|
|
assert(inp == "register")
|
|
return parse_register_member(tag)
|
|
|
|
def parse_bit_member(tag):
|
|
bit = {
|
|
'name': [],
|
|
'offset': None,
|
|
'access': None,
|
|
'variable': []
|
|
}
|
|
|
|
while True:
|
|
inp = next_useful_line(tag)
|
|
if inp == '': break
|
|
|
|
if not inp[0] == ' ':
|
|
# revese back and return
|
|
restore_last_useful_line(tag)
|
|
break
|
|
|
|
data = inp.split()
|
|
assert(len(data) >= 1)
|
|
|
|
# name <name>
|
|
if data[0] == "name":
|
|
bit['name'].append(data[1])
|
|
elif data[0] == "offset":
|
|
if len(data) == 2:
|
|
# offset <offset>
|
|
assert(bit['offset'] is None)
|
|
bit['offset'] = data[1]
|
|
elif len(data) == 3:
|
|
# offset <id> <offset>
|
|
if bit['offset'] is None:
|
|
bit['offset'] = []
|
|
assert(type(bit['offset']) == list)
|
|
bit['offset'].append({'id': data[1], 'offset': data[2]})
|
|
else:
|
|
we_have_problem("unknown design of offset", tag)
|
|
elif data[0] == "access":
|
|
# access <access>
|
|
verify_access_flags(data[1])
|
|
bit['access'] = data[1]
|
|
elif data[0] == "variable":
|
|
# variable <variable-name> <variable-equation>
|
|
bit['variable'].append({
|
|
'name': data[1],
|
|
'equation': ' '.join(data[2:])
|
|
})
|
|
|
|
assert(len(bit['name']))
|
|
return bit
|
|
|
|
def parse_bit(tag):
|
|
inp = next_useful_line(tag)
|
|
if inp == '':
|
|
return None
|
|
|
|
data = inp.split()
|
|
if data[0] != "bit":
|
|
restore_last_useful_line(tag)
|
|
return None
|
|
|
|
if len(data) > 1:
|
|
# bit <name> <offset>
|
|
return {
|
|
'name' : [ data[1] ],
|
|
'offset': data[2] if len(data) > 2 else None,
|
|
'access': None,
|
|
'variable': []
|
|
}
|
|
else:
|
|
return parse_bit_member(tag)
|
|
|
|
def parse_bits_member(tag):
|
|
bits = {
|
|
'name': [],
|
|
'offset': None,
|
|
'size': None,
|
|
'access': None,
|
|
'values': [],
|
|
'variable': []
|
|
}
|
|
|
|
while True:
|
|
inp = next_useful_line(tag)
|
|
if inp == '': break
|
|
|
|
if not inp[0] == ' ':
|
|
# revese back and return
|
|
restore_last_useful_line(tag)
|
|
break
|
|
|
|
data = inp.split()
|
|
assert(len(data) >= 1)
|
|
|
|
# name <name>
|
|
if data[0] == "name":
|
|
bits['name'].append(data[1])
|
|
elif data[0] == "offset":
|
|
if len(data) == 2:
|
|
# offset <offset>
|
|
assert(bits['offset'] is None)
|
|
bits['offset'] = data[1]
|
|
elif len(data) == 3:
|
|
# offset <id> <offset>
|
|
if bits['offset'] is None:
|
|
bits['offset'] = []
|
|
assert(type(bits['offset']) == list)
|
|
bits['offset'].append({'id': data[1], 'offset': data[2]})
|
|
else:
|
|
we_have_problem("unknown design of offset", tag)
|
|
elif data[0] == "size":
|
|
# size <size>
|
|
bits['size'] = data[1]
|
|
elif data[0] == "value":
|
|
assert(len(data) >= 1)
|
|
# value <value-name> <value-value>
|
|
bits['values'].append({
|
|
'name': data[1],
|
|
'value': data[2] if len(data) > 2 else None
|
|
})
|
|
elif data[0] == "access":
|
|
# access <access>
|
|
verify_access_flags(data[1])
|
|
bits['access'] = data[1]
|
|
elif data[0] == "variable":
|
|
# variable <variable-name> <variable-equation>
|
|
bits['variable'].append({
|
|
'name': data[1],
|
|
'equation': ' '.join(data[2:])
|
|
})
|
|
|
|
assert(bits['name'] is not None)
|
|
assert(bits['size'] is not None)
|
|
return bits
|
|
|
|
def parse_bits(tag):
|
|
inp = next_useful_line(tag)
|
|
if inp == '':
|
|
return None
|
|
|
|
data = inp.split()
|
|
if data[0] != "bits":
|
|
restore_last_useful_line(tag)
|
|
return None
|
|
|
|
if len(data) > 1:
|
|
assert(len(data) > 2)
|
|
# bits <name> <size> <offset>
|
|
return {
|
|
'name' : [ data[1] ] ,
|
|
'size': data[2],
|
|
'offset': data[3] if len(data) > 3 else None,
|
|
'access': None,
|
|
'values': [],
|
|
'variable': []
|
|
}
|
|
else:
|
|
return parse_bits_member(tag)
|
|
|
|
def parse_input(input_file):
|
|
data = []
|
|
inside_block = False
|
|
|
|
tag = {
|
|
'input_file': input_file,
|
|
'last_line_number': 1,
|
|
'line_number': 1,
|
|
'last_useful_pos': 0
|
|
}
|
|
|
|
while True:
|
|
inp = next_useful_line(tag, strip_newline=inside_block, \
|
|
strip_comment=False)
|
|
if not len(inp):
|
|
break
|
|
|
|
if inside_block:
|
|
if inp.strip()[0:6] == "#endif":
|
|
inside_block = False
|
|
continue
|
|
elif inp.strip()[0:3] == "#if" and inp.find("__UCD__") != -1:
|
|
inside_block = True
|
|
continue
|
|
else:
|
|
data.append({'type': 'extra', 'payload': inp})
|
|
continue
|
|
|
|
# parse code
|
|
if inp[0] == "%":
|
|
fmt = "/* %s */" if STRICT_C_OUTPUT else "// %s"
|
|
res = fmt % inp[1:].strip()
|
|
data.append({'type': 'extra', 'payload': res + "\n\n"})
|
|
continue
|
|
|
|
restore_last_useful_line(tag)
|
|
if inp[0] == "f":
|
|
family = parse_family(tag)
|
|
if family is None:
|
|
break
|
|
data.append({'type': 'family', 'payload': family})
|
|
elif inp[0] == "r":
|
|
register = parse_register(tag)
|
|
if register is None:
|
|
break
|
|
data.append({'type': 'register', 'payload': register})
|
|
elif inp[0] == "b":
|
|
bit = parse_bit(tag)
|
|
if bit is not None:
|
|
data.append({'type': 'bit', 'payload': bit})
|
|
else:
|
|
bits = parse_bits(tag)
|
|
if bits is None:
|
|
break
|
|
data.append({'type': 'bits', 'payload': bits})
|
|
else:
|
|
we_have_problem("unknown input: \"%s\"" % inp, tag)
|
|
break
|
|
return data
|
|
|
|
def generate_family(family, output_file):
|
|
|
|
# if instance are not provided
|
|
if family['instance'] is None:
|
|
return
|
|
|
|
if not family['internal_only']:
|
|
if type(family['instance']) == list:
|
|
for i in family['instance']:
|
|
fam_id = '%s%s' % (family['name'], i['id'])
|
|
output_file.write("#define %s (%s)\n" % (fam_id, i['address']))
|
|
else:
|
|
addr = str(family['instance'])
|
|
name = family['name']
|
|
output_file.write("#define %s (%s)\n" % (name, addr))
|
|
|
|
# a final newline to seperate things
|
|
output_file.write("\n")
|
|
|
|
def generate_register(register, family, offset, output_file):
|
|
# calculate register size
|
|
size = 32
|
|
if register['size'] is not None:
|
|
size = int(register['size'], 0)
|
|
elif family['register'] is not None and family['register']['size'] is not None:
|
|
size = int(family['register']['size'], 0)
|
|
|
|
mmio = "MMIO%i" % size
|
|
|
|
# calculate register offset
|
|
if register['offset'] is not None:
|
|
offset = register['offset']
|
|
|
|
if not register['internal_only']:
|
|
extra_arg = ""
|
|
extra_body = ""
|
|
if register['variable']:
|
|
for i in register['variable']:
|
|
extra_arg += ", %s" % i['name']
|
|
extra_body += " + (%s)" % i['equation']
|
|
|
|
#base macros of style PERPH_REG(base)
|
|
# if not instance is provided or multiple instance are there
|
|
if family['instance'] is None or type(family['instance']) is list:
|
|
register_name = register['name'][0]
|
|
actual_name = "%s_%s" % (family['name'], register_name)
|
|
output_file.write("#define %s(base%s) %s((base) + (%s)%s)\n" % (actual_name, extra_arg, mmio, offset, extra_body))
|
|
output_file.write("\n")
|
|
|
|
# alias of regiser (that accept base)
|
|
if len(register['name'][1:]):
|
|
output_file.write("/* Alias of %s */\n" % actual_name)
|
|
for register_name in register['name'][1:]:
|
|
alias_name = "%s_%s" % (family['name'], register_name)
|
|
output_file.write("#define %s(base%s) %s(base%s)\n" % \
|
|
(alias_name, extra_arg, actual_name, extra_arg))
|
|
if len(register['name'][1:]):
|
|
output_file.write("\n")
|
|
|
|
# instace that send base to above macros
|
|
if family['instance'] is not None: # ie family['instance'] type is of list
|
|
for instance in family['instance']:
|
|
for register_name in register['name']:
|
|
frm = "%s%s_%s" % (family['name'], instance['id'], register_name)
|
|
to = "%s_%s" % (family['name'], register_name)
|
|
addr = "%s%s" % (family['name'], instance['id'])
|
|
_extra_arg = "(%s)" % extra_arg[2:] if len(extra_arg) else ""
|
|
output_file.write("#define %s%s %s(%s%s)\n" % (frm, _extra_arg, to, addr, extra_arg))
|
|
output_file.write("\n")
|
|
|
|
else:
|
|
#single instance
|
|
register_name = register['name'][0]
|
|
actual_name = "%s_%s" % (family['name'], register_name)
|
|
_extra_arg = "(%s)" % extra_arg[2:] if len(extra_arg) else ""
|
|
output_file.write("#define %s%s %s((%s) + (%s)%s)\n" % \
|
|
(actual_name, _extra_arg, mmio, family['instance'], offset, extra_body))
|
|
output_file.write("\n")
|
|
|
|
if len(register['name'][1:]):
|
|
output_file.write("/* Alias of %s */\n" % actual_name)
|
|
for register_name in register['name'][1:]:
|
|
alias_name = "%s_%s" % (family['name'], register_name)
|
|
output_file.write("#define %s%s %s%s" % (alias_name, _extra_arg, actual_name, _extra_arg))
|
|
output_file.write("\n")
|
|
if len(register['name'][1:]):
|
|
output_file.write("\n")
|
|
|
|
stride = size
|
|
if family['register'] is not None and family['register']['stride'] is not None:
|
|
stride = int(family['register']['stride'], 0)
|
|
|
|
try: next_offset = int(offset) + stride
|
|
except ValueError: next_offset = "%s + %i" % (offset, stride)
|
|
|
|
return next_offset, size
|
|
|
|
def generate_bit(bit, register, family, offset, register_size, output_file):
|
|
|
|
if bit['offset'] is not None:
|
|
offset = bit['offset']
|
|
|
|
try: assert(int(offset) < register_size)
|
|
except ValueError: pass # cannot be converted to integer
|
|
|
|
extra_arg = ""
|
|
extra_offset = ""
|
|
|
|
if bit["variable"]:
|
|
extra_arg = []
|
|
|
|
for v in bit["variable"]:
|
|
extra_arg.append(v['name'])
|
|
extra_offset += " + (" + v['equation'] + ")"
|
|
|
|
extra_arg = ", ".join(extra_arg)
|
|
extra_arg = "(%s)" % extra_arg
|
|
|
|
actual_name = None
|
|
for register_name in register['bit_name']:
|
|
for bit_name in bit['name']:
|
|
if register['bit_name'].index(register_name) == bit['name'].index(bit_name) == 0:
|
|
actual_name = "%s_%s_%s" % (family['name'], register_name, bit_name)
|
|
output_file.write("#define %s_SHIFT%s (%s%s)\n" % (actual_name, extra_arg, offset, extra_offset))
|
|
output_file.write("#define %s%s (1 << %s_SHIFT%s)\n" % (actual_name, extra_arg, actual_name, extra_arg))
|
|
else:
|
|
alias_name = "%s_%s_%s" % (family['name'], register_name, bit_name)
|
|
output_file.write("/* Alias of %s */\n" % actual_name)
|
|
output_file.write("#define %s_SHIFT%s %s_SHIFT%s\n" % (alias_name, extra_arg, actual_name, extra_arg))
|
|
output_file.write("#define %s%s %s%s\n" % (alias_name, extra_arg, actual_name, extra_arg))
|
|
|
|
output_file.write("\n")
|
|
output_file.write("\n")
|
|
|
|
try: return (int(offset) + 1)
|
|
except ValueError: return "%s + 1" % offset
|
|
|
|
def generate_bits(bits, register, family, offset, register_size, output_file):
|
|
if bits['offset'] is not None:
|
|
offset = bits['offset']
|
|
|
|
size = int(bits['size'], 0)
|
|
|
|
try: assert((int(offset) + size) <= register_size)
|
|
except ValueError: pass # offset not a integer value
|
|
|
|
mask = hex(pow(2, size) - 1)
|
|
|
|
extra_arg = ""
|
|
bracketed_extra_arg = "" #if len(extra_arg) > 0
|
|
all_arg = "v"
|
|
extra_offset = ""
|
|
|
|
if bits["variable"]:
|
|
extra_arg = []
|
|
|
|
for v in bits["variable"]:
|
|
extra_arg.append(v['name'])
|
|
extra_offset += " + (" + v['equation'] + ")"
|
|
|
|
extra_arg = ", ".join(extra_arg)
|
|
|
|
all_arg = "v, %s" % extra_arg
|
|
bracketed_extra_arg = "(%s)" % extra_arg
|
|
|
|
actual_name = None
|
|
for register_name in register['bits_name']:
|
|
for bits_name in bits['name']:
|
|
if (bits['name'].index(bits_name) == 0) and \
|
|
(register['bits_name'].index(register_name) == 0):
|
|
#print original macro
|
|
actual_name = "%s_%s_%s" % (family['name'], register_name, bits_name)
|
|
output_file.write("#define %s_SHIFT%s (%s%s)\n" % (actual_name, bracketed_extra_arg, offset, extra_offset))
|
|
output_file.write("#define %s_MASK%s (%s << (%s_SHIFT%s))\n" % \
|
|
(actual_name, bracketed_extra_arg, mask, actual_name, bracketed_extra_arg))
|
|
output_file.write("#define %s(%s) (((v) << (%s_SHIFT%s)) & (%s_MASK%s))\n" % \
|
|
(actual_name, all_arg, actual_name, bracketed_extra_arg, actual_name, bracketed_extra_arg))
|
|
output_file.write("#define %s_GET(%s) (((v) & (%s_MASK%s)) >> (%s_SHIFT%s))\n" % \
|
|
(actual_name, all_arg, actual_name, bracketed_extra_arg, actual_name, bracketed_extra_arg))
|
|
|
|
# values
|
|
value_value = 0
|
|
for v in bits['values']:
|
|
if v['value'] is not None:
|
|
value_value = int(v['value'], 0)
|
|
_arg = hex(value_value)
|
|
if len(extra_arg):
|
|
_arg = "%s, %s" % (_arg, extra_arg)
|
|
output_file.write("#define %s_%s%s %s(%s)\n" % \
|
|
(actual_name, v['name'], bracketed_extra_arg, actual_name, _arg))
|
|
value_value += 1
|
|
else:
|
|
#print alias macro
|
|
alias_name = "%s_%s_%s" % (family['name'], register_name, bits_name)
|
|
output_file.write("/* Alias of %s */\n" % actual_name)
|
|
output_file.write("#define %s_SHIFT%s %s_SHIFT%s\n" %
|
|
(alias_name, bracketed_extra_arg, actual_name, bracketed_extra_arg))
|
|
output_file.write("#define %s_MASK%s %s_MASK%s\n" %
|
|
(alias_name, bracketed_extra_arg, actual_name, bracketed_extra_arg))
|
|
output_file.write("#define %s(%s) %s(%s)\n" %
|
|
(alias_name, all_arg, actual_name, all_arg))
|
|
output_file.write("#define %s_GET(%s) %s_GET(%s)\n" %
|
|
(alias_name, all_arg, actual_name, all_arg))
|
|
|
|
# alias values
|
|
for v in bits['values']:
|
|
output_file.write("#define %s_%s%s %s_%s%s\n" % \
|
|
(alias_name, v['name'], bracketed_extra_arg, actual_name,
|
|
v['name'], bracketed_extra_arg))
|
|
|
|
output_file.write("\n")
|
|
output_file.write("\n")
|
|
|
|
|
|
try: return (int(offset) + size)
|
|
except ValueError: return "%s + %i" % (offset, size)
|
|
|
|
def generate_output(data, output_file):
|
|
family = None
|
|
register = None
|
|
register_size = None
|
|
register_offset = None
|
|
register_next_bit = None
|
|
|
|
for d in data:
|
|
if d['type'] == 'extra':
|
|
output_file.write(d['payload'])
|
|
|
|
elif d['type'] == 'family':
|
|
family = d['payload']
|
|
register_offset = 0 # reset register offset
|
|
generate_family(family, output_file)
|
|
|
|
elif d['type'] == 'register':
|
|
register = d['payload']
|
|
register_next_bit = 0
|
|
register_offset, register_size = generate_register( \
|
|
register, family, register_offset, output_file)
|
|
elif d['type'] == 'bit':
|
|
register_next_bit = generate_bit(d['payload'], register, family, \
|
|
register_next_bit, register_size, output_file)
|
|
elif d['type'] == 'bits':
|
|
register_next_bit = generate_bits(d['payload'], register, family, \
|
|
register_next_bit, register_size, output_file)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
assert (len(sys.argv) > 1)
|
|
input_file = open(sys.argv[1])
|
|
output_file = open(sys.argv[2], 'w+') if len(sys.argv) > 2 else sys.stdout
|
|
data = parse_input(input_file)
|
|
generate_output(data, output_file)
|