--- /dev/null
+/**
+ * @file arch/x86/decode.c
+ *
+ * Helper routines for decoding x86 architectural state.
+ */
+#include <xtf/lib.h>
+#include <xtf/libc.h>
+
+#include <arch/x86/decode.h>
+#include <arch/x86/processor.h>
+
+const char *x86_exc_short_name(unsigned int exc)
+{
+ static const char *const names[] =
+ {
+/** @cond */
+#define NAME(x) [X86_EXC_ ## x] = "#" #x
+ NAME(DE), NAME(DB), NAME(NMI), NAME(BP), NAME(OF), NAME(BR),
+ NAME(UD), NAME(NM), NAME(DF), NAME(CSO), NAME(TS), NAME(NP),
+ NAME(SS), NAME(GP), NAME(PF), NAME(SPV), NAME(MF), NAME(AC),
+ NAME(MC), NAME(XM), NAME(VE),
+#undef NAME
+/** @endcond */
+ };
+
+ return (exc < ARRAY_SIZE(names) && names[exc]) ? names[exc] : "??";
+}
+
+int x86_exc_decode_ec(char *buf, size_t bufsz, unsigned int ev, unsigned int ec)
+{
+ switch ( ev )
+ {
+ case X86_EXC_PF:
+ return snprintf(buf, bufsz, "%c%c%c%c%c%c",
+ ec & X86_PFEC_PK ? 'K' : '-',
+ ec & X86_PFEC_INSN ? 'I' : 'd',
+ ec & X86_PFEC_RSVD ? 'R' : '-',
+ ec & X86_PFEC_USER ? 'U' : 's',
+ ec & X86_PFEC_WRITE ? 'W' : 'r',
+ ec & X86_PFEC_PRESENT ? 'P' : '-');
+
+ case X86_EXC_TS: case X86_EXC_NP: case X86_EXC_SS:
+ case X86_EXC_GP: case X86_EXC_AC:
+ if ( ec != 0 )
+ {
+ if ( ec & X86_EC_IDT )
+ return snprintf(buf, bufsz,
+ "IDT vec %u%s",
+ ec >> X86_EC_SEL_SHIFT,
+ ec & X86_EC_EXT ? " EXT" : "");
+ else
+ return snprintf(buf, bufsz,
+ "%cDT sel %#x%s",
+ ec & X86_EC_TI ? 'L' : 'G',
+ ec & X86_EC_SEL_MASK,
+ ec & X86_EC_EXT ? " EXT" : "");
+ }
+
+ /* Fallthrough */
+ default:
+ return snprintf(buf, bufsz, "%04x", ec);
+ }
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--- /dev/null
+/**
+ * @file include/arch/x86/decode.h
+ *
+ * Helper routines for decoding x86 architectural state.
+ */
+#ifndef XTF_X86_DECODE_H
+#define XTF_X86_DECODE_H
+
+#include <xtf/types.h>
+
+/**
+ * String abbreviation of @p ev.
+ *
+ * @param ev Entry Vector.
+ * @return String abbreviation.
+ */
+const char *x86_exc_short_name(unsigned int ev);
+
+/**
+ * Decodes an x86 error code into a readable form.
+ *
+ * @param buf Buffer to fill.
+ * @param bufsz Size of @p buf.
+ * @param ev Entry Vector.
+ * @param ec Error Code.
+ * @return snprintf(buf, bufsz, ...)
+ */
+int x86_exc_decode_ec(char *buf, size_t bufsz,
+ unsigned int ev, unsigned int ec);
+
+#endif /* XTF_X86_DECODE_H */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
#define X86_EC_TI (1U << 2) /* Only if !IDT. LDT or GDT. */
/* Segment-based Error Code - supplemental constants. */
-#define X86_EC_TABLE_MASK (3U << 1)
-#define X86_EC_SEL_MASK (-1L << 3)
+#define X86_EC_TABLE_MASK (3 << 1)
+#define X86_EC_SEL_SHIFT 3
+#define X86_EC_SEL_MASK (-1 << X86_EC_SEL_SHIFT)
#define X86_EC_GDT 0
#define X86_EC_LDT X86_EC_TI
+/* Pagefault Error Code - architecturally defined. */
+#define X86_PFEC_PRESENT (1U << 0)
+#define X86_PFEC_WRITE (1U << 1)
+#define X86_PFEC_USER (1U << 2)
+#define X86_PFEC_RSVD (1U << 3)
+#define X86_PFEC_INSN (1U << 4)
+#define X86_PFEC_PK (1U << 5)
+
#endif /* XTF_X86_PROCESSOR_H */
/*