* [PATCH v2 1/1] riscv: show code leading to exception
@ 2021-09-04 8:36 Heinrich Schuchardt
2021-09-04 14:47 ` Bin Meng
2021-09-04 14:58 ` Sean Anderson
0 siblings, 2 replies; 3+ messages in thread
From: Heinrich Schuchardt @ 2021-09-04 8:36 UTC (permalink / raw)
To: Rick Chen
Cc: Leo, Bin Meng, Simon Glass, Sean Anderson, u-boot, Heinrich Schuchardt
To make analyzing exceptions easier output the code that leads to it.
We already do the same on the ARM platform.
Here is an example:
=> exception ebreak
Unhandled exception: Breakpoint
EPC: 000000008ff5d50e RA: 000000008ff5d62c TVAL: 0000000000000000
EPC: 000000008020b50e RA: 000000008020b62c reloc adjusted
Code: 2785 0693 07a0 dce3 fef6 47a5 d563 00e7 (9002)
To disassemble the code we can use the decodecode script:
$ echo 'Code: 2785 0693 07a0 dce3 fef6 47a5 d563 00e7 (9002)' | \
CROSS_COMPILE=riscv64-linux-gnu- scripts/decodecode
Code: 2785 0693 07a0 dce3 fef6 47a5 d563 00e7 (9002)
All code
========
0: 2785 addiw a5,a5,1
2: 07a00693 li a3,122
6: fef6dce3 bge a3,a5,0xfffffffffffffffe
a: 47a5 li a5,9
c: 00e7d563 bge a5,a4,0x16
10:* 9002 ebreak <-- trapping instruction
...
Code starting with the faulting instruction
===========================================
0: 9002 ebreak
...
As it is not always clear if the first 16 bits are at the start or in the
middle of a 32bit instruction it may become necessary to strip the first
u16 from the output before calling decodecode to get the correct
disassembled code.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v2:
remove support for instructions longer than 32 bit as these are
not yet specified
---
arch/riscv/lib/interrupts.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
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");
}
--
2.30.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2 1/1] riscv: show code leading to exception
2021-09-04 8:36 [PATCH v2 1/1] riscv: show code leading to exception Heinrich Schuchardt
@ 2021-09-04 14:47 ` Bin Meng
2021-09-04 14:58 ` Sean Anderson
1 sibling, 0 replies; 3+ messages in thread
From: Bin Meng @ 2021-09-04 14:47 UTC (permalink / raw)
To: Heinrich Schuchardt
Cc: Rick Chen, Leo, Bin Meng, Simon Glass, Sean Anderson,
U-Boot Mailing List
On Sat, Sep 4, 2021 at 4:37 PM Heinrich Schuchardt <xypron.glpk@gmx.de> wrote:
>
> To make analyzing exceptions easier output the code that leads to it.
> We already do the same on the ARM platform.
>
> Here is an example:
>
> => exception ebreak
> Unhandled exception: Breakpoint
> EPC: 000000008ff5d50e RA: 000000008ff5d62c TVAL: 0000000000000000
> EPC: 000000008020b50e RA: 000000008020b62c reloc adjusted
>
> Code: 2785 0693 07a0 dce3 fef6 47a5 d563 00e7 (9002)
>
> To disassemble the code we can use the decodecode script:
>
> $ echo 'Code: 2785 0693 07a0 dce3 fef6 47a5 d563 00e7 (9002)' | \
> CROSS_COMPILE=riscv64-linux-gnu- scripts/decodecode
>
> Code: 2785 0693 07a0 dce3 fef6 47a5 d563 00e7 (9002)
> All code
> ========
> 0: 2785 addiw a5,a5,1
> 2: 07a00693 li a3,122
> 6: fef6dce3 bge a3,a5,0xfffffffffffffffe
> a: 47a5 li a5,9
> c: 00e7d563 bge a5,a4,0x16
> 10:* 9002 ebreak <-- trapping instruction
> ...
>
> Code starting with the faulting instruction
> ===========================================
> 0: 9002 ebreak
> ...
>
> As it is not always clear if the first 16 bits are at the start or in the
> middle of a 32bit instruction it may become necessary to strip the first
> u16 from the output before calling decodecode to get the correct
> disassembled code.
>
> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
> ---
> v2:
> remove support for instructions longer than 32 bit as these are
> not yet specified
> ---
> arch/riscv/lib/interrupts.c | 33 +++++++++++++++++++++++++++++++++
> 1 file changed, 33 insertions(+)
>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2 1/1] riscv: show code leading to exception
2021-09-04 8:36 [PATCH v2 1/1] riscv: show code leading to exception Heinrich Schuchardt
2021-09-04 14:47 ` Bin Meng
@ 2021-09-04 14:58 ` Sean Anderson
1 sibling, 0 replies; 3+ messages in thread
From: Sean Anderson @ 2021-09-04 14:58 UTC (permalink / raw)
To: Heinrich Schuchardt, Rick Chen; +Cc: Leo, Bin Meng, Simon Glass, u-boot
On 9/4/21 4:36 AM, Heinrich Schuchardt wrote:
> To make analyzing exceptions easier output the code that leads to it.
> We already do the same on the ARM platform.
>
> Here is an example:
>
> => exception ebreak
> Unhandled exception: Breakpoint
> EPC: 000000008ff5d50e RA: 000000008ff5d62c TVAL: 0000000000000000
> EPC: 000000008020b50e RA: 000000008020b62c reloc adjusted
>
> Code: 2785 0693 07a0 dce3 fef6 47a5 d563 00e7 (9002)
>
> To disassemble the code we can use the decodecode script:
>
> $ echo 'Code: 2785 0693 07a0 dce3 fef6 47a5 d563 00e7 (9002)' | \
> CROSS_COMPILE=riscv64-linux-gnu- scripts/decodecode
>
> Code: 2785 0693 07a0 dce3 fef6 47a5 d563 00e7 (9002)
> All code
> ========
> 0: 2785 addiw a5,a5,1
> 2: 07a00693 li a3,122
> 6: fef6dce3 bge a3,a5,0xfffffffffffffffe
> a: 47a5 li a5,9
> c: 00e7d563 bge a5,a4,0x16
> 10:* 9002 ebreak <-- trapping instruction
> ...
>
> Code starting with the faulting instruction
> ===========================================
> 0: 9002 ebreak
> ...
>
> As it is not always clear if the first 16 bits are at the start or in the
> middle of a 32bit instruction it may become necessary to strip the first
> u16 from the output before calling decodecode to get the correct
> disassembled code.
>
> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
> ---
> v2:
> remove support for instructions longer than 32 bit as these are
> not yet specified
> ---
> arch/riscv/lib/interrupts.c | 33 +++++++++++++++++++++++++++++++++
> 1 file changed, 33 insertions(+)
>
> 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");
> }
> --
> 2.30.2
>
Reviewed-by: Sean Anderson <seanga2@gmail.com>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-09-04 14:58 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-04 8:36 [PATCH v2 1/1] riscv: show code leading to exception Heinrich Schuchardt
2021-09-04 14:47 ` Bin Meng
2021-09-04 14:58 ` Sean Anderson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.