diff options
author | Andi Kleen <ak@linux.intel.com> | 2008-09-05 14:45:46 +0200 |
---|---|---|
committer | Andi Kleen <ak@linux.intel.com> | 2008-09-05 15:35:19 +0200 |
commit | ed413f0f3aaa2382fc906122cdf25e6a9702ef33 (patch) | |
tree | 7b1d6401b082939ac631ee64bbb52162ca33b545 /bitfield.c | |
parent | f0dbc6ceb0a06946c8d3c2b667fd854a78496de6 (diff) | |
download | mcelog-ed413f0f3aaa2382fc906122cdf25e6a9702ef33.tar.gz |
Extract generic bitfield decoder into bitfield.[ch]
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Diffstat (limited to 'bitfield.c')
-rw-r--r-- | bitfield.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/bitfield.c b/bitfield.c new file mode 100644 index 0000000..8e1c46b --- /dev/null +++ b/bitfield.c @@ -0,0 +1,47 @@ +#include <string.h> +#include <stdio.h> +#include "mcelog.h" +#include "bitfield.h" + +char *reserved_3bits[8]; +char *reserved_1bit[2]; +char *reserved_2bits[4]; + +static u64 bitmask(u64 i) +{ + u64 mask = 1; + while (mask < i) + mask = (mask << 1) | 1; + return mask; +} + +void decode_bitfield(u64 status, struct field *fields) +{ + struct field *f; + int linelen = 0; + char *delim = ""; + + for (f = fields; f->str; f++) { + u64 v = (status >> f->start_bit) & bitmask(f->stringlen - 1); + char *s = NULL; + if (v < f->stringlen) + s = f->str[v]; + if (!s) { + if (v == 0) + continue; + char buf[60]; + s = buf; + snprintf(buf, sizeof buf, "<%u:%Lx>", f->start_bit, v); + } + int len = strlen(s); + if (linelen + len > 75) { + delim = "\n"; + linelen = 0; + } + Wprintf("%s%s", delim, s); + delim = " "; + linelen += len + 1; + } + if (linelen > 0) + Wprintf("\n"); +} |