From ee511c588acd37d2c032a2d6dc427bf28412d983 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 9 Sep 2024 16:56:57 +0800 Subject: [PATCH 1/2] arch: riscv: isr.S: restore s0 before jumping to z_riscv_fatal_error_csf Restore the s0 we saved early in ISR entry so it shows up properly in the CSF. Signed-off-by: David Reiss Signed-off-by: Yong Cong Sin --- arch/riscv/core/isr.S | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/riscv/core/isr.S b/arch/riscv/core/isr.S index 7e885da93a4698..65c40e63456e15 100644 --- a/arch/riscv/core/isr.S +++ b/arch/riscv/core/isr.S @@ -443,6 +443,12 @@ do_fault: 1: mv a1, sp #ifdef CONFIG_EXCEPTION_DEBUG + /* + * Restore the s0 we saved early in ISR entry + * so it shows up properly in the CSF. + */ + lr s0, __struct_arch_esf_s0_OFFSET(sp) + /* Allocate space for caller-saved registers on current thread stack */ addi sp, sp, -__callee_saved_t_SIZEOF From ae8bfb4dbacdafcae3c9d1e862bac484bfd78463 Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Mon, 9 Sep 2024 16:57:35 +0800 Subject: [PATCH 2/2] tests: arch: riscv: test csf registers value Test if callee-saved-registers values are as expected. Signed-off-by: David Reiss Signed-off-by: Yong Cong Sin --- tests/arch/riscv/fatal/CMakeLists.txt | 8 ++++ tests/arch/riscv/fatal/prj.conf | 2 + tests/arch/riscv/fatal/src/main.c | 62 +++++++++++++++++++++++++++ tests/arch/riscv/fatal/testcase.yaml | 27 ++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 tests/arch/riscv/fatal/CMakeLists.txt create mode 100644 tests/arch/riscv/fatal/prj.conf create mode 100644 tests/arch/riscv/fatal/src/main.c create mode 100644 tests/arch/riscv/fatal/testcase.yaml diff --git a/tests/arch/riscv/fatal/CMakeLists.txt b/tests/arch/riscv/fatal/CMakeLists.txt new file mode 100644 index 00000000000000..366f13f660da48 --- /dev/null +++ b/tests/arch/riscv/fatal/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(riscv_fatal) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/arch/riscv/fatal/prj.conf b/tests/arch/riscv/fatal/prj.conf new file mode 100644 index 00000000000000..15ada69e712dd9 --- /dev/null +++ b/tests/arch/riscv/fatal/prj.conf @@ -0,0 +1,2 @@ +CONFIG_TEST=y +CONFIG_LOG=y diff --git a/tests/arch/riscv/fatal/src/main.c b/tests/arch/riscv/fatal/src/main.c new file mode 100644 index 00000000000000..fc75192a22d5e5 --- /dev/null +++ b/tests/arch/riscv/fatal/src/main.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 Meta Platforms + * + * SPDX-License-Identifier: Apache-2.0 + */ + +int main(void) +{ + __asm__( + /** + * Load up a bunch of known values into registers + * and expect them to show up in the core dump. + * Value is register ABI name kinda spelled out, + * followed by zeros to pad to 32 bits, + * followed by FF00, followed by hex number of the register, + * follwed by the "hex-coded-decismal" number of the register. + */ + + /* "RA" -> "DA". Kind of a stretch, but okay. */ + "li x1, 0xDADA0000FF000101\n\t" + + /* Skip stack pointer because it can mess stuff up. */ + /* "li x2, 0\n\t" */ + + /* T0 -> D0. Kinda close in pronunciation. */ + "li x5, 0xD0FF0000FF000505\n\t" + "li x6, 0xD1FF0000FF000606\n\t" + "li x7, 0xD2FF0000FF000707\n\t" + /* S0 -> C0. Kinda close in pronunciation. */ + "li x8, 0xC0FF0000FF000808\n\t" + "li x9, 0xC1FF0000FF000909\n\t" + /* A0 -> A0. Actual match! */ + "li x10, 0xA0FF0000FF000A10\n\t" + "li x11, 0xA1FF0000FF000B11\n\t" + "li x12, 0xA2FF0000FF000C12\n\t" + "li x13, 0xA3FF0000FF000D13\n\t" + "li x14, 0xA4FF0000FF000E14\n\t" + "li x15, 0xA5FF0000FF000F15\n\t" + "li x16, 0xA6FF0000FF001016\n\t" + "li x17, 0xA7FF0000FF001117\n\t" + "li x18, 0xC2FF0000FF001218\n\t" + "li x19, 0xC3FF0000FF001319\n\t" + "li x20, 0xC4FF0000FF001420\n\t" + "li x21, 0xC5FF0000FF001521\n\t" + "li x22, 0xC6FF0000FF001622\n\t" + "li x23, 0xC7FF0000FF001723\n\t" + "li x24, 0xC8FF0000FF001824\n\t" + "li x25, 0xC9FF0000FF001925\n\t" + "li x26, 0xC10FF000FF001A26\n\t" + "li x27, 0xC11FF000FF001B27\n\t" + "li x28, 0xD3FF0000FF001C28\n\t" + "li x29, 0xD4FF0000FF001D29\n\t" + "li x30, 0xD5FF0000FF001E30\n\t" + "li x31, 0xD6FF0000FF001F31\n\t" + /* K_ERR_KERNEL_PANIC */ + "li a0, 4\n\t" + /* RV_ECALL_RUNTIME_EXCEPT */ + "li t0, 0\n\t" + "ecall\n"); + + return 0; +} diff --git a/tests/arch/riscv/fatal/testcase.yaml b/tests/arch/riscv/fatal/testcase.yaml new file mode 100644 index 00000000000000..1355991bca580a --- /dev/null +++ b/tests/arch/riscv/fatal/testcase.yaml @@ -0,0 +1,27 @@ +common: + ignore_faults: true + harness: console + ignore_qemu_crash: true + tags: kernel riscv + platform_allow: + - qemu_riscv64 +tests: + arch.riscv64.fatal: + harness_config: + type: multi_line + regex: + - "E: a0: 0000000000000004 t0: 0000000000000000" + - "E: a1: a1ff0000ff000b11 t1: d1ff0000ff000606" + - "E: a2: a2ff0000ff000c12 t2: d2ff0000ff000707" + - "E: a3: a3ff0000ff000d13 t3: d3ff0000ff001c28" + - "E: a4: a4ff0000ff000e14 t4: d4ff0000ff001d29" + - "E: a5: a5ff0000ff000f15 t5: d5ff0000ff001e30" + - "E: a6: a6ff0000ff001016 t6: d6ff0000ff001f31" + - "E: a7: a7ff0000ff001117" + - "E: ra: dada0000ff000101" + - "E: s0: c0ff0000ff000808 s6: c6ff0000ff001622" + - "E: s1: c1ff0000ff000909 s7: c7ff0000ff001723" + - "E: s2: c2ff0000ff001218 s8: c8ff0000ff001824" + - "E: s3: c3ff0000ff001319 s9: c9ff0000ff001925" + - "E: s4: c4ff0000ff001420 s10: c10ff000ff001a26" + - "E: s5: c5ff0000ff001521 s11: c11ff000ff001b27"