From: Jeremy Kerr Date: Thu, 12 Nov 2009 06:31:36 +0000 (+1100) Subject: Fix bit-0-is-lsb ordering X-Git-Url: https://git.ozlabs.org/?p=bitfield;a=commitdiff_plain;h=6af82b47cb07a95e48d0a578b9e18141950a4ed3;ds=sidebyside Fix bit-0-is-lsb ordering Turns out we weren't handling the lsb-first bit numbering very well, especially for multiple-bit fields. Signed-off-by: Jeremy Kerr --- diff --git a/bitfield b/bitfield index 7740ff2..a35fd20 100644 --- a/bitfield +++ b/bitfield @@ -31,13 +31,18 @@ class bitfield: def add_value(self, 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 @@ -74,9 +79,7 @@ class bitfield: (start, end) = map( \ lambda s: reg.bit_number(int(s)), s.split(':')) - start = reg.bit_number(int(start)) - end = reg.bit_number(int(end)) - bits.extend(range(start, end + 1, 1)) + bits.extend(range(start, end - 1, -1)) elif '<<' in s: (mask, shift) = map(lambda s: int(s.strip()), s.split('<<')) @@ -122,7 +125,7 @@ class register: 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) @@ -136,7 +139,7 @@ class register: 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):