summaryrefslogtreecommitdiff
path: root/arch/riscv/lib/interrupts.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv/lib/interrupts.c')
-rw-r--r--arch/riscv/lib/interrupts.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index 7525c152b8..100be2e966 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -51,6 +51,38 @@ static void show_regs(struct pt_regs *regs)
#endif
}
+/**
+ * instr_len() - get instruction length
+ *
+ * @i: low 16 bits of the instruction
+ * Return: number of u16 in instruction
+ */
+static int instr_len(u16 i)
+{
+ if ((i & 0x03) != 0x03)
+ return 1;
+ /* Instructions with more than 32 bits are not yet specified */
+ return 2;
+}
+
+/**
+ * show_code() - display code leading to exception
+ *
+ * @epc: program counter
+ */
+static void show_code(ulong epc)
+{
+ u16 *pos = (u16 *)(epc & ~1UL);
+ int i, len = instr_len(*pos);
+
+ printf("\nCode: ");
+ for (i = -8; i; ++i)
+ printf("%04x ", pos[i]);
+ printf("(");
+ for (i = 0; i < len; ++i)
+ printf("%04x%s", pos[i], i + 1 == len ? ")\n" : " ");
+}
+
static void _exit_trap(ulong code, ulong epc, ulong tval, struct pt_regs *regs)
{
static const char * const exception_code[] = {
@@ -85,6 +117,7 @@ static void _exit_trap(ulong code, ulong epc, ulong tval, struct pt_regs *regs)
epc - gd->reloc_off, regs->ra - gd->reloc_off);
show_regs(regs);
+ show_code(epc);
show_efi_loaded_images(epc);
panic("\n");
}