-#!/usr/bin/python2.4
+#!/usr/bin/env python3
#
# Utility to decode register values
# Copyright (c) 2006 Jeremy Kerr <jk@ozlabs.org>
import os
import sys
import pprint
+import math
from pyparsing import Literal, Word, ZeroOrMore, Group, Dict, Optional, \
printables, ParseException, restOfLine
from getopt import getopt, GetoptError
return len(self.bits)
def add_value(self, value, description):
- self.values[int(value)] = description
+ self.values[int(value, 0)] = description
- def mask(self, reg_width, value):
+ def mask(self, reg, value):
ret = 0
out_len = len(self.bits)
- for out_bit in range(0, out_len):
- in_bit = self.bits[out_bit]
+
+ if reg.bit_order == reg.bit_0_is_msb:
+ bit_pairs = zip(self.bits, range(0, out_len))
+ else:
+ bit_pairs = zip(self.bits, range(out_len - 1, -1, -1))
+
+ for (in_bit, out_bit) in bit_pairs:
# shift this bit down to the LSB (and mask the rest)
- i = (value >> (reg_width - in_bit - 1)) & 1
+ i = (value >> (reg.width - in_bit - 1)) & 1
# shift back to the output position in the field
i <<= out_len - out_bit - 1
ret |= i
return self.values[value]
return None
+ @staticmethod
+ def mask_and_shift_to_bits(width, mask, shift):
+ bits = []
+ val = mask << shift
+ for i in range(0, width):
+ if mask & (1 << i):
+ bits.insert(0, width - i - 1 - shift)
+ return bits
+
+ @staticmethod
+ def mask_to_bits(width, mask):
+ return bitfield.mask_and_shift_to_bits(width, mask, 0)
+
@staticmethod
def parse_bitfield(line, reg):
a = line.split(None, 1)
bits = []
for s in range_str.split(','):
if ':' in s:
- (start, end) = s.split(':')
- start = reg.bit_number(int(start))
- end = reg.bit_number(int(end))
- bits.extend(range(start, end + 1, 1))
+ (start, end) = map( \
+ lambda s: reg.bit_number(int(s)),
+ s.split(':'))
+ bits.extend(range(start, end - 1, -1))
+ elif '<<' in s:
+ (mask, shift) = map(lambda s: int(s.strip()),
+ s.split('<<'))
+ bits.extend(bitfield.mask_and_shift_to_bits( \
+ reg.width, mask, shift))
+ elif s.startswith('&'):
+ mask = int(s[1:], 0)
+ bits.extend(bitfield.mask_to_bits(reg.width, \
+ mask))
else:
bits.append(reg.bit_number(int(s)))
-
+
return bitfield(bits, name)
+
+
@staticmethod
def parse_value(line):
a = line.split(None, 1)
self.fields.append(field)
def decode(self, value, ignore_zero):
- field_width = (self.width + 3) / 4
+ field_width = math.floor((self.width + 3) / 4)
name_width = max(map(lambda f: len(f.name), self.fields))
str = "0x%0*lx [%d]\n" % (field_width, value, value)
for field in self.fields:
- v = field.mask(self.width, value);
+ v = field.mask(self, value);
if ignore_zero and v == 0:
continue
desc = field.value(v)
str += "%*s: 0x%x\n" \
% (name_width, field.name, v)
return str
-
+
def bit_number(self, number):
if self.bit_order == self.bit_0_is_lsb:
- number = self.width - 1 - number
+ number = self.width - number - 1
return number
def list_regs(regs):
- for (id, r) in regs.iteritems():
- print "%18s : %s" % (id, r.name)
+ for (id, r) in regs.items():
+ print("%18s : %s" % (id, r.name))
def search_regs(regs, str):
return dict((k, regs[k]) for k in regs \
ts = tok.asList()
id = ts.pop(0)
- if regs.has_key(id):
+ if id in regs:
raise ConfigurationError(file,
"Register %s is already defined" % id)
"Invalid bit order %s in %s" % \
(order_str, id))
reg.bit_order = order_map[order_str]
-
+
elif t[0] == 'alias':
alias_id = t[1].strip()
if not os.path.exists(conf):
continue
if os.path.isdir(conf):
- os.path.walk(conf, parse_config_dir, conf_data)
+ for c in os.walk(conf):
+ parse_config_dir(conf_data, c[0], c[2])
else:
parse_config(bnf, regs, conf)
return regs
def usage(prog):
- print "Usage: %s <-l> | <-s pattern> | [-n] register [value...]" % prog
+ print("Usage: %s <-l> | <-s pattern> | [-n] register [value...]" % prog)
def decode_value(reg, value, options):
try:
- i = long(value, 0)
- except ValueError, e:
- print "error: invalid value '%s'" % value
+ i = int(value, 0)
+ except ValueError:
+ print("error: invalid value '%s'" % value)
return
if i > ((1 << reg.width) - 1):
- print ("error: value '%s' is too large " + \
+ print("error: value '%s' is too large " + \
"for %d-bit register '%s'") % (value, reg.width, reg.id)
return
- print reg.decode(i, options['non-zero'])
+ print(reg.decode(i, options['non-zero']))
def main():
try:
regs = parse_all_configs(configs)
- except ConfigurationError, e:
- print "Error parsing configuration file %s:\n\t%s" % \
- (e.file, e.message)
+ except ConfigurationError as e:
+ print("Error parsing configuration file %s:\n\t%s" % \
+ (e.file, e.message))
return 1
if regs == {}:
- print "No configuration available"
+ print("No configuration available")
return 1
options = {}
return 1
reg_id = args.pop(0)
- if not regs.has_key(reg_id):
- print "No such register '%s'" % reg_id
+ if reg_id not in regs:
+ print("No such register '%s'" % reg_id)
return 1
reg = regs[reg_id]
- print "decoding as %s" % reg.name
+ print("decoding as %s" % reg.name)
if args:
value_iter = args.__iter__()
else:
value_iter = iter(sys.stdin.readline, '')
-
+
try:
for value in value_iter:
decode_value(reg, value.strip(), options)
- except KeyboardInterrupt, e:
+ except KeyboardInterrupt:
pass
return 0