aboutsummaryrefslogtreecommitdiffstats
path: root/bitfield.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2008-09-05 14:45:46 +0200
committerAndi Kleen <ak@linux.intel.com>2008-09-05 15:35:19 +0200
commited413f0f3aaa2382fc906122cdf25e6a9702ef33 (patch)
tree7b1d6401b082939ac631ee64bbb52162ca33b545 /bitfield.c
parentf0dbc6ceb0a06946c8d3c2b667fd854a78496de6 (diff)
downloadmcelog-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.c47
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");
+}