X-Git-Url: https://git.ozlabs.org/?p=bitfield;a=blobdiff_plain;f=bitfield;h=71e495813fb2bc788f1460e08959e00fdf761e49;hp=3651677f86c29ab8a90d9a67df14fa086ffa4503;hb=cef5dceb1252128844bcf0c7039d378a7d635714;hpb=27f2cb1942b6391d3081016260e0d29b0ffa74f6 diff --git a/bitfield b/bitfield index 3651677..71e4958 100644 --- a/bitfield +++ b/bitfield @@ -15,32 +15,33 @@ from getopt import getopt, GetoptError # List of paths to look for configuration files. If a directory is specified, # it will be (recursively) scanned for .conf files. -configs = [os.path.join(os.getenv("HOME"), ".bitfields.conf"), - os.path.join(os.getenv("HOME"), ".bitfields.d")] +configs = ["/etc/bitfield.d", "/etc/bitfield", + os.path.join(os.getenv("HOME"), ".bitfield.d"), + os.path.join(os.getenv("HOME"), ".bitfield.conf")] 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: @@ -54,14 +55,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): @@ -128,6 +130,7 @@ def parse_config(bnf, regs, file): # default to 64 bit registers width = 64 name = None + alias_id = None fields = [] for t in ts: @@ -152,6 +155,22 @@ def parse_config(bnf, regs, file): "Invalid value in %s" % id) fields[-1].add_value(v[0], v[1]) + elif t[0] == 'alias': + alias_id = t[1].strip() + + if alias_id is not None: + if name is not None or fields != []: + raise ConfigurationError(file, ("Definiton " \ + + "for %s is an alias, but has other " \ + + "attributes") % id) + + if not regs.has_key(alias_id): + raise ConfigurationError(file, "Aliasing " + "non-existent register %s (from %s)" \ + % (alias_id, id)) + + regs[id] = regs[alias_id] + continue if name is None or name == '': raise ConfigurationError(file, @@ -225,7 +244,7 @@ def decode_value(reg, value, options): "for %d-bit register '%s'") % (value, reg.width, reg.id) return - print reg.decode(i, options.has_key('non_zero')) + print reg.decode(i, options['non-zero']) def main(): @@ -275,19 +294,19 @@ def main(): print "No such register '%s'" % reg_id return 1 - r = regs[reg_id] - 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: - decode_value(r, value.strip(), options) + value_iter = iter(sys.stdin.readline, '') + + try: + for value in value_iter: + decode_value(reg, value.strip(), options) + except KeyboardInterrupt, e: + pass return 0