X-Git-Url: https://git.ozlabs.org/?p=bitfield;a=blobdiff_plain;f=bitfield;h=8aab6f8b617bd868264f50f12a392f4bf7c43285;hp=965d8cac2c2c5eee17bae01748c7b173f71e0347;hb=40265d54d2dba5f1a567fdc3b47714c1b0405149;hpb=aacf370c1fdb132f63207ef611720af5e77a6e01 diff --git a/bitfield b/bitfield index 965d8ca..8aab6f8 100644 --- a/bitfield +++ b/bitfield @@ -19,38 +19,34 @@ configs = [os.path.join(os.getenv("HOME"), ".bitfields.conf"), os.path.join(os.getenv("HOME"), ".bitfields.d")] class bitfield: - def __init__(self, start_bit, end_bit, name): - self.start_bit = start_bit - self.end_bit = end_bit + def __init__(self, bits, name): + self.bits = bits self.name = name self.values = {} - def start_bit(self): - return self.start_bit - - def end_bit(self): - return self.end_bit - def width(self): - return 1 + self.end_bit - self.start_bit + return len(self.bits) def add_value(self, value, description): self.values[int(value)] = description def mask(self, reg_width, value): - shift = (reg_width - 1) - self.end_bit - return (((2 ** self.width() - 1) << (shift)) - & value) >> shift + ret = 0 + out_len = len(self.bits) + for out_bit in range(0, out_len): + in_bit = self.bits[out_bit] + # shift this bit down to the LSB (and mask the rest) + 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 ret def value(self, value): if value in self.values: return self.values[value] return None - def __str__(self): - return "[%2d:%-2d] %s 0x%x" % (int(self.start_bit), - int(self.end_bit), self.name, self.mask()) - @staticmethod def parse_bitfield(line): a = line.split(None, 1) @@ -58,14 +54,15 @@ class bitfield: return None (range_str, name) = a - range = (None,None) - if range_str.find(':') != -1: - r = range_str.split(":") - range = (int(r[0]),int(r[1])) - else: - range = (int(range_str),int(range_str)) - - return bitfield(range[0], range[1], name) + bits = [] + for s in range_str.split(','): + if ':' in s: + (start, end) = s.split(':') + bits.extend(range(int(start), int(end) + 1, 1)) + else: + bits.append(int(s)) + + return bitfield(bits, name) @staticmethod def parse_value(line): @@ -75,35 +72,34 @@ class bitfield: return a class register: - def __init__(self, name, width): + def __init__(self, id, name, width): + self.id = id self.name = name self.width = width self.fields = [] - def add_field(self, field,): + def add_field(self, field): self.fields.append(field) - def decode(self, value): + def decode(self, value, ignore_zero): field_width = (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); + if ignore_zero and v == 0: + continue desc = field.value(v) if desc is not None: - str += "%*s: 0x%s [%s]\n" \ + str += "%*s: 0x%x [%s]\n" \ % (name_width, field.name, v, desc) else: str += "%*s: 0x%x\n" \ % (name_width, field.name, v) return str - def __str__(self): - str = self.name + "\n" - for f in self.fields: - str += "\t%s\n" % f - return str - def list_regs(regs): for (id, r) in regs.iteritems(): print "%18s : %s" % (id, r.name) @@ -120,7 +116,7 @@ class ConfigurationError(Exception): def parse_config(bnf, regs, file): f = open(file) - tokens = bnf.parseString("".join(f.readlines())) + tokens = bnf.parseString(f.read()) for tok in tokens: ts = tok.asList() @@ -166,7 +162,7 @@ def parse_config(bnf, regs, file): raise ConfigurationError(file, "Register %s has no fields" % id) - r = register(name, width) + r = register(id, name, width) for f in fields: r.add_field(f) @@ -216,12 +212,27 @@ def parse_all_configs(configs): return regs def usage(prog): - print "Usage: %s <-l> | <-s pattern> | 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 + return + + if i > ((1 << reg.width) - 1): + 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']) + def main(): try: - (opts, args) = getopt(sys.argv[1:], "hls:", \ - ["help", "list", "search="]) + (opts, args) = getopt(sys.argv[1:], "hlns:", \ + ["help", "list", "non-zero", "search="]) except GetoptError: usage(sys.argv[0]) return 1 @@ -237,6 +248,9 @@ def main(): print "No configuration available" return 1 + options = {} + options['non-zero'] = False + for o, a in opts: if o in ("-h", "--help"): usage(sys.argv[0]) @@ -250,31 +264,31 @@ def main(): list_regs(search_regs(regs, a)) return + if o in ("-n", "--non-zero"): + options['non-zero'] = True if not args: usage(sys.argv[0]) return 1 - a = args.pop(0) - if not regs.has_key(a): - print "No such register '%s'. Valid regs are:" % a - list_regs(regs) + reg_id = args.pop(0) + if not regs.has_key(reg_id): + print "No such register '%s'" % reg_id return 1 - r = regs[a] - print "decoding as %s" % r.name + reg = regs[reg_id] + print "decoding as %s" % reg.name if args: - values = args + value_iter = args.__iter__() else: - try: - values = sys.stdin.readlines() - except KeyboardInterrupt, e: - return - - for value in values: - i = long(value.strip(), 0) - print r.decode(i) + value_iter = iter(sys.stdin.readline, '') + + try: + for value in value_iter: + decode_value(reg, value.strip(), options) + except KeyboardInterrupt, e: + pass return 0