Browse Source

feat: libcpu/risc-v: unify interrupt & IO on rv64

This patch aims to unify the two currently separated RISC-V 64-bit
architecture ports, 'virt64' and 'c906', into a single generic
'common64' port. The changes include renaming files and updating
includes to use a unified 'interrupt.h' header, as well as making
adjustments to IO and trap handling to be more consistent between the
two architectures.

Changes:
- Renamed 'rt_interrupt.h' to 'interrupt.h' and updated includes accordingly.
- Unified IO register access functions in 'riscv_io.h'.
- Added 'opcode.h' for portable assembly support.
- Updated 'plic.c' and 'plic.h' to handle interrupts in a unified manner.
- Modified 'trap.c' to handle exceptions and interrupts consistently for 'rv64'.

Signed-off-by: Shell <smokewood@qq.com>
Shell 9 months ago
parent
commit
e244c196c4

+ 1 - 1
libcpu/risc-v/t-head/c906/interrupt.c

@@ -11,7 +11,7 @@
 #include <rthw.h>
 #include <rtthread.h>
 
-#include "rt_interrupt.h"
+#include "interrupt.h"
 #include "riscv.h"
 #include "plic.h"
 

+ 0 - 0
libcpu/risc-v/t-head/c906/rt_interrupt.h → libcpu/risc-v/t-head/c906/interrupt.h


+ 1 - 1
libcpu/risc-v/t-head/c906/plic.c

@@ -15,7 +15,7 @@
 #include <rtdbg.h>
 
 #include "plic.h"
-#include "rt_interrupt.h"
+#include "interrupt.h"
 #include "io.h"
 #include "encoding.h"
 #include "ioremap.h"

+ 1 - 1
libcpu/risc-v/t-head/c906/plic.h

@@ -12,7 +12,7 @@
 #ifndef __RISCV64_PLIC_H__
 #define __RISCV64_PLIC_H__
 
-#include <rt_interrupt.h>
+#include <interrupt.h>
 
 #ifndef C906_PLIC_PHY_ADDR
 #define C906_PLIC_PHY_ADDR              (0x10000000)

+ 8 - 5
libcpu/risc-v/t-head/c906/riscv.h

@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
  * 2021-01-30     lizhirui     first version
+ * 2024-08-28     RT-Thread    Fit into rv64ilp32 ABI
  */
 
 #ifndef __RISCV_H__
@@ -13,13 +14,15 @@
 
 #include <encoding.h>
 
-#define __SIZE(bit) (1UL << (bit))
-#define __MASK(bit) (__SIZE(bit) - 1UL)
+/* using unsigned long long for the case of rv64ilp32 */
+#define __SIZE(bit) (1ULL << (bit))
+#define __MASK(bit) (__SIZE(bit) - 1ULL)
+
 #define __UMASK(bit) (~(__MASK(bit)))
 #define __MASKVALUE(value,maskvalue) ((value) & (maskvalue))
 #define __UMASKVALUE(value,maskvalue) ((value) & (~(maskvalue)))
-#define __CHECKUPBOUND(value,bit_count) (!(((rt_size_t)value) & (~__MASK(bit_count))))
-#define __CHECKALIGN(value,start_bit) (!(((rt_size_t)value) & (__MASK(start_bit))))
+#define __CHECKUPBOUND(value,bit_count) (!(((rt_ubase_t)value) & (~__MASK(bit_count))))
+#define __CHECKALIGN(value,start_bit) (!(((rt_ubase_t)value) & (__MASK(start_bit))))
 
 #define __PARTBIT(value,start_bit,length) (((value) >> (start_bit)) & __MASK(length))
 

+ 101 - 95
libcpu/risc-v/t-head/c906/riscv_io.h

@@ -10,100 +10,106 @@
 #ifndef __RISCV_IO_H__
 #define __RISCV_IO_H__
 
-    static inline void __raw_writeb(rt_uint8_t val, volatile void *addr)
-    {
-        asm volatile("sb %0, 0(%1)" : : "r"(val), "r"(addr));
-    }
-
-    static inline void __raw_writew(rt_uint16_t val, volatile void *addr)
-    {
-        asm volatile("sh %0, 0(%1)" : : "r"(val), "r"(addr));
-    }
-
-    static inline void __raw_writel(rt_uint32_t val, volatile void *addr)
-    {
-        asm volatile("sw %0, 0(%1)" : : "r"(val), "r"(addr));
-    }
-
-    #if __riscv_xlen != 32
-    static inline void __raw_writeq(rt_uint64_t val, volatile void *addr)
-    {
-        asm volatile("sd %0, 0(%1)" : : "r"(val), "r"(addr));
-    }
-    #endif
-
-    static inline rt_uint8_t __raw_readb(const volatile void *addr)
-    {
-        rt_uint8_t val;
-
-        asm volatile("lb %0, 0(%1)" : "=r"(val) : "r"(addr));
-        return val;
-    }
-
-    static inline rt_uint16_t __raw_readw(const volatile void *addr)
-    {
-        rt_uint16_t val;
-
-        asm volatile("lh %0, 0(%1)" : "=r"(val) : "r"(addr));
-        return val;
-    }
-
-    static inline rt_uint32_t __raw_readl(const volatile void *addr)
-    {
-        rt_uint32_t val;
-
-        asm volatile("lw %0, 0(%1)" : "=r"(val) : "r"(addr));
-        return val;
-    }
-
-    #if __riscv_xlen != 32
-    static inline rt_uint64_t __raw_readq(const volatile void *addr)
-    {
-        rt_uint64_t val;
-
-        asm volatile("ld %0, 0(%1)" : "=r"(val) : "r"(addr));
-        return val;
-    }
-    #endif
-
-    /* FIXME: These are now the same as asm-generic */
-
-    /* clang-format off */
-
-    #define __io_rbr()      do {} while (0)
-    #define __io_rar()      do {} while (0)
-    #define __io_rbw()      do {} while (0)
-    #define __io_raw()      do {} while (0)
-
-    #define readb_relaxed(c)    ({ rt_uint8_t  __v; __io_rbr(); __v = __raw_readb(c); __io_rar(); __v; })
-    #define readw_relaxed(c)    ({ rt_uint16_t __v; __io_rbr(); __v = __raw_readw(c); __io_rar(); __v; })
-    #define readl_relaxed(c)    ({ rt_uint32_t __v; __io_rbr(); __v = __raw_readl(c); __io_rar(); __v; })
-
-    #define writeb_relaxed(v,c) ({ __io_rbw(); __raw_writeb((v),(c)); __io_raw(); })
-    #define writew_relaxed(v,c) ({ __io_rbw(); __raw_writew((v),(c)); __io_raw(); })
-    #define writel_relaxed(v,c) ({ __io_rbw(); __raw_writel((v),(c)); __io_raw(); })
-
-    #if __riscv_xlen != 32
-    #define readq_relaxed(c)    ({ rt_uint64_t __v; __io_rbr(); __v = __raw_readq(c); __io_rar(); __v; })
-    #define writeq_relaxed(v,c) ({ __io_rbw(); __raw_writeq((v),(c)); __io_raw(); })
-    #endif
-
-    #define __io_br()   do {} while (0)
-    #define __io_ar()   __asm__ __volatile__ ("fence i,r" : : : "memory");
-    #define __io_bw()   __asm__ __volatile__ ("fence w,o" : : : "memory");
-    #define __io_aw()   do {} while (0)
-
-    #define readb(c)    ({ rt_uint8_t  __v; __io_br(); __v = __raw_readb(c); __io_ar(); __v; })
-    #define readw(c)    ({ rt_uint16_t __v; __io_br(); __v = __raw_readw(c); __io_ar(); __v; })
-    #define readl(c)    ({ rt_uint32_t __v; __io_br(); __v = __raw_readl(c); __io_ar(); __v; })
-
-    #define writeb(v,c) ({ __io_bw(); __raw_writeb((v),(c)); __io_aw(); })
-    #define writew(v,c) ({ __io_bw(); __raw_writew((v),(c)); __io_aw(); })
-    #define writel(v,c) ({ __io_bw(); __raw_writel((v),(c)); __io_aw(); })
-
-    #if __riscv_xlen != 32
-    #define readq(c)    ({ rt_uint64_t __v; __io_br(); __v = __raw_readq(c); __io_ar(); __v; })
-    #define writeq(v,c) ({ __io_bw(); __raw_writeq((v),(c)); __io_aw(); })
-    #endif
+static inline uint32_t __raw_hartid(void)
+{
+    extern int boot_hartid;
+    return boot_hartid;
+}
+
+static inline void __raw_writeb(rt_uint8_t val, volatile void *addr)
+{
+    asm volatile("sb %0, 0(%1)" : : "r"(val), "r"(addr));
+}
+
+static inline void __raw_writew(rt_uint16_t val, volatile void *addr)
+{
+    asm volatile("sh %0, 0(%1)" : : "r"(val), "r"(addr));
+}
+
+static inline void __raw_writel(rt_uint32_t val, volatile void *addr)
+{
+    asm volatile("sw %0, 0(%1)" : : "r"(val), "r"(addr));
+}
+
+#if __riscv_xlen != 32
+static inline void __raw_writeq(rt_uint64_t val, volatile void *addr)
+{
+    asm volatile("sd %0, 0(%1)" : : "r"(val), "r"(addr));
+}
+#endif
+
+static inline rt_uint8_t __raw_readb(const volatile void *addr)
+{
+    rt_uint8_t val;
+
+    asm volatile("lb %0, 0(%1)" : "=r"(val) : "r"(addr));
+    return val;
+}
+
+static inline rt_uint16_t __raw_readw(const volatile void *addr)
+{
+    rt_uint16_t val;
+
+    asm volatile("lh %0, 0(%1)" : "=r"(val) : "r"(addr));
+    return val;
+}
+
+static inline rt_uint32_t __raw_readl(const volatile void *addr)
+{
+    rt_uint32_t val;
+
+    asm volatile("lw %0, 0(%1)" : "=r"(val) : "r"(addr));
+    return val;
+}
+
+#if __riscv_xlen != 32
+static inline rt_uint64_t __raw_readq(const volatile void *addr)
+{
+    rt_uint64_t val;
+
+    asm volatile("ld %0, 0(%1)" : "=r"(val) : "r"(addr));
+    return val;
+}
+#endif
+
+/* FIXME: These are now the same as asm-generic */
+
+/* clang-format off */
+
+#define __io_rbr()      do {} while (0)
+#define __io_rar()      do {} while (0)
+#define __io_rbw()      do {} while (0)
+#define __io_raw()      do {} while (0)
+
+#define readb_relaxed(c)    ({ rt_uint8_t  __v; __io_rbr(); __v = __raw_readb(c); __io_rar(); __v; })
+#define readw_relaxed(c)    ({ rt_uint16_t __v; __io_rbr(); __v = __raw_readw(c); __io_rar(); __v; })
+#define readl_relaxed(c)    ({ rt_uint32_t __v; __io_rbr(); __v = __raw_readl(c); __io_rar(); __v; })
+
+#define writeb_relaxed(v,c) ({ __io_rbw(); __raw_writeb((v),(c)); __io_raw(); })
+#define writew_relaxed(v,c) ({ __io_rbw(); __raw_writew((v),(c)); __io_raw(); })
+#define writel_relaxed(v,c) ({ __io_rbw(); __raw_writel((v),(c)); __io_raw(); })
+
+#if __riscv_xlen != 32
+#define readq_relaxed(c)    ({ rt_uint64_t __v; __io_rbr(); __v = __raw_readq(c); __io_rar(); __v; })
+#define writeq_relaxed(v,c) ({ __io_rbw(); __raw_writeq((v),(c)); __io_raw(); })
+#endif
+
+#define __io_br()   do {} while (0)
+#define __io_ar()   __asm__ __volatile__ ("fence i,r" : : : "memory");
+#define __io_bw()   __asm__ __volatile__ ("fence w,o" : : : "memory");
+#define __io_aw()   do {} while (0)
+
+#define readb(c)    ({ rt_uint8_t  __v; __io_br(); __v = __raw_readb(c); __io_ar(); __v; })
+#define readw(c)    ({ rt_uint16_t __v; __io_br(); __v = __raw_readw(c); __io_ar(); __v; })
+#define readl(c)    ({ rt_uint32_t __v; __io_br(); __v = __raw_readl(c); __io_ar(); __v; })
+
+#define writeb(v,c) ({ __io_bw(); __raw_writeb((v),(c)); __io_aw(); })
+#define writew(v,c) ({ __io_bw(); __raw_writew((v),(c)); __io_aw(); })
+#define writel(v,c) ({ __io_bw(); __raw_writel((v),(c)); __io_aw(); })
+
+#if __riscv_xlen != 32
+#define readq(c)    ({ rt_uint64_t __v; __io_br(); __v = __raw_readq(c); __io_ar(); __v; })
+#define writeq(v,c) ({ __io_bw(); __raw_writeq((v),(c)); __io_aw(); })
+#endif
 
 #endif

+ 159 - 123
libcpu/risc-v/t-head/c906/trap.c

@@ -1,36 +1,29 @@
 /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
+ * Copyright (c) 2006-2024, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
- * 2021/1/30      lizirui      first version
- * 2021/10/20     JasonHu      move to trap.c
+ * 2022-12-08     RT-Thread    first version
  */
 
 #include <rthw.h>
 #include <rtthread.h>
 #include <stdint.h>
 
-
-#include "board.h"
-#include "tick.h"
-
 #include <mm_fault.h>
-#include "mmu.h"
-#include "encoding.h"
-#include "stack.h"
-#include "sbi.h"
-#include "riscv.h"
-#include "rt_interrupt.h"
-#include "plic.h"
+#include <mmu.h>
+#include <encoding.h>
+#include <stack.h>
+#include <sbi.h>
+#include <riscv.h>
+#include <interrupt.h>
+#include <plic.h>
+#include <tick.h>
 
 #ifdef RT_USING_SMART
 #include <lwp_arch.h>
-void rt_hw_backtrace(rt_uint32_t *ffp, rt_ubase_t sepc);
-#else
-#define rt_hw_backtrace(...) (0)
 #endif
 
 #define DBG_TAG "libcpu.trap"
@@ -42,7 +35,8 @@ void dump_regs(struct rt_hw_stack_frame *regs)
     rt_kprintf("--------------Dump Registers-----------------\n");
 
     rt_kprintf("Function Registers:\n");
-    rt_kprintf("\tra(x1) = 0x%p\tuser_sp = 0x%p\n", regs->ra, regs->user_sp_exc_stack);
+    rt_kprintf("\tra(x1) = 0x%p\tuser_sp = 0x%p\n", regs->ra,
+               regs->user_sp_exc_stack);
     rt_kprintf("\tgp(x3) = 0x%p\ttp(x4) = 0x%p\n", regs->gp, regs->tp);
     rt_kprintf("Temporary Registers:\n");
     rt_kprintf("\tt0(x5) = 0x%p\tt1(x6) = 0x%p\n", regs->t0, regs->t1);
@@ -62,15 +56,27 @@ void dump_regs(struct rt_hw_stack_frame *regs)
     rt_kprintf("\ta4(x14) = 0x%p\ta5(x15) = 0x%p\n", regs->a4, regs->a5);
     rt_kprintf("\ta6(x16) = 0x%p\ta7(x17) = 0x%p\n", regs->a6, regs->a7);
     rt_kprintf("sstatus = 0x%p\n", regs->sstatus);
-    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SIE) ? "Supervisor Interrupt Enabled" : "Supervisor Interrupt Disabled");
-    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SPIE) ? "Last Time Supervisor Interrupt Enabled" : "Last Time Supervisor Interrupt Disabled");
-    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SPP) ? "Last Privilege is Supervisor Mode" : "Last Privilege is User Mode");
-    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SUM) ? "Permit to Access User Page" : "Not Permit to Access User Page");
-    rt_kprintf("\t%s\n", (regs->sstatus & (1 << 19)) ? "Permit to Read Executable-only Page" : "Not Permit to Read Executable-only Page");
-    rt_size_t satp_v = read_csr(satp);
+    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SIE)
+                             ? "Supervisor Interrupt Enabled"
+                             : "Supervisor Interrupt Disabled");
+    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SPIE)
+                             ? "Last Time Supervisor Interrupt Enabled"
+                             : "Last Time Supervisor Interrupt Disabled");
+    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SPP)
+                             ? "Last Privilege is Supervisor Mode"
+                             : "Last Privilege is User Mode");
+    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SUM)
+                             ? "Permit to Access User Page"
+                             : "Not Permit to Access User Page");
+    rt_kprintf("\t%s\n", (regs->sstatus & (1 << 19))
+                             ? "Permit to Read Executable-only Page"
+                             : "Not Permit to Read Executable-only Page");
+    rt_ubase_t satp_v = read_csr(satp);
     rt_kprintf("satp = 0x%p\n", satp_v);
-    rt_kprintf("\tCurrent Page Table(Physical) = 0x%p\n", __MASKVALUE(satp_v, __MASK(44)) << PAGE_OFFSET_BIT);
-    rt_kprintf("\tCurrent ASID = 0x%p\n", __MASKVALUE(satp_v >> 44, __MASK(16)) << PAGE_OFFSET_BIT);
+    rt_kprintf("\tCurrent Page Table(Physical) = 0x%p\n",
+               __MASKVALUE(satp_v, __MASK(44)) << PAGE_OFFSET_BIT);
+    rt_kprintf("\tCurrent ASID = 0x%p\n", __MASKVALUE(satp_v >> 44, __MASK(16))
+                                              << PAGE_OFFSET_BIT);
     const char *mode_str = "Unknown Address Translation/Protection Mode";
 
     switch (__MASKVALUE(satp_v >> 60, __MASK(4)))
@@ -92,50 +98,44 @@ void dump_regs(struct rt_hw_stack_frame *regs)
     rt_kprintf("-----------------Dump OK---------------------\n");
 }
 
-static const char *Exception_Name[] =
-    {
-        "Instruction Address Misaligned",
-        "Instruction Access Fault",
-        "Illegal Instruction",
-        "Breakpoint",
-        "Load Address Misaligned",
-        "Load Access Fault",
-        "Store/AMO Address Misaligned",
-        "Store/AMO Access Fault",
-        "Environment call from U-mode",
-        "Environment call from S-mode",
-        "Reserved-10",
-        "Reserved-11",
-        "Instruction Page Fault",
-        "Load Page Fault",
-        "Reserved-14",
-        "Store/AMO Page Fault"};
-
-static const char *Interrupt_Name[] =
-    {
-        "User Software Interrupt",
-        "Supervisor Software Interrupt",
-        "Reversed-2",
-        "Reversed-3",
-        "User Timer Interrupt",
-        "Supervisor Timer Interrupt",
-        "Reversed-6",
-        "Reversed-7",
-        "User External Interrupt",
-        "Supervisor External Interrupt",
-        "Reserved-10",
-        "Reserved-11",
+static const char *Exception_Name[] = {"Instruction Address Misaligned",
+                                       "Instruction Access Fault",
+                                       "Illegal Instruction",
+                                       "Breakpoint",
+                                       "Load Address Misaligned",
+                                       "Load Access Fault",
+                                       "Store/AMO Address Misaligned",
+                                       "Store/AMO Access Fault",
+                                       "Environment call from U-mode",
+                                       "Environment call from S-mode",
+                                       "Reserved-10",
+                                       "Reserved-11",
+                                       "Instruction Page Fault",
+                                       "Load Page Fault",
+                                       "Reserved-14",
+                                       "Store/AMO Page Fault"};
+
+static const char *Interrupt_Name[] = {
+    "User Software Interrupt",
+    "Supervisor Software Interrupt",
+    "Reversed-2",
+    "Reversed-3",
+    "User Timer Interrupt",
+    "Supervisor Timer Interrupt",
+    "Reversed-6",
+    "Reversed-7",
+    "User External Interrupt",
+    "Supervisor External Interrupt",
+    "Reserved-10",
+    "Reserved-11",
 };
 
 #ifndef RT_USING_SMP
 static volatile int nested = 0;
-#define ENTER_TRAP \
-    nested += 1
-#define EXIT_TRAP \
-    nested -= 1
+#define ENTER_TRAP nested += 1
+#define EXIT_TRAP  nested -= 1
 #define CHECK_NESTED_PANIC(cause, tval, epc, eframe) \
-    if (nested != 1)                                 \
-    handle_nested_trap_panic(cause, tval, epc, eframe)
+    if (nested != 1) handle_nested_trap_panic(cause, tval, epc, eframe)
 #endif /* RT_USING_SMP */
 
 static const char *get_exception_msg(int id)
@@ -153,9 +153,11 @@ static const char *get_exception_msg(int id)
 }
 
 #ifdef RT_USING_SMART
-void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw_stack_frame *sp)
+#include "lwp.h"
+void handle_user(rt_ubase_t scause, rt_ubase_t stval, rt_ubase_t sepc,
+                 struct rt_hw_stack_frame *sp)
 {
-    rt_size_t id = __MASKVALUE(scause, __MASK(63UL));
+    rt_ubase_t id = __MASKVALUE(scause, __MASK(63UL));
     struct rt_lwp *lwp;
 
     /* user page fault */
@@ -165,11 +167,11 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw
     {
         case EP_LOAD_PAGE_FAULT:
             fault_op = MM_FAULT_OP_READ;
-            fault_type = MM_FAULT_TYPE_PAGE_FAULT;
+            fault_type = MM_FAULT_TYPE_GENERIC_MMU;
             break;
         case EP_LOAD_ACCESS_FAULT:
             fault_op = MM_FAULT_OP_READ;
-            fault_type = MM_FAULT_TYPE_GENERIC;
+            fault_type = MM_FAULT_TYPE_BUS_ERROR;
             break;
         case EP_LOAD_ADDRESS_MISALIGNED:
             fault_op = MM_FAULT_OP_READ;
@@ -177,11 +179,11 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw
             break;
         case EP_STORE_PAGE_FAULT:
             fault_op = MM_FAULT_OP_WRITE;
-            fault_type = MM_FAULT_TYPE_PAGE_FAULT;
+            fault_type = MM_FAULT_TYPE_GENERIC_MMU;
             break;
         case EP_STORE_ACCESS_FAULT:
             fault_op = MM_FAULT_OP_WRITE;
-            fault_type = MM_FAULT_TYPE_GENERIC;
+            fault_type = MM_FAULT_TYPE_BUS_ERROR;
             break;
         case EP_STORE_ADDRESS_MISALIGNED:
             fault_op = MM_FAULT_OP_WRITE;
@@ -189,11 +191,11 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw
             break;
         case EP_INSTRUCTION_PAGE_FAULT:
             fault_op = MM_FAULT_OP_EXECUTE;
-            fault_type = MM_FAULT_TYPE_PAGE_FAULT;
+            fault_type = MM_FAULT_TYPE_GENERIC_MMU;
             break;
         case EP_INSTRUCTION_ACCESS_FAULT:
             fault_op = MM_FAULT_OP_EXECUTE;
-            fault_type = MM_FAULT_TYPE_GENERIC;
+            fault_type = MM_FAULT_TYPE_BUS_ERROR;
             break;
         case EP_INSTRUCTION_ADDRESS_MISALIGNED:
             fault_op = MM_FAULT_OP_EXECUTE;
@@ -213,28 +215,31 @@ void handle_user(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw
             .fault_vaddr = (void *)stval,
         };
 
-        __asm__ volatile ("csrrsi %0, sstatus, 2":"=r"(saved_stat));
+        __asm__ volatile("csrrsi %0, sstatus, 2" : "=r"(saved_stat));
         if (lwp && rt_aspace_fault_try_fix(lwp->aspace, &msg))
         {
-            __asm__ volatile ("csrw sstatus, %0"::"r"(saved_stat));
+            __asm__ volatile("csrw sstatus, %0" ::"r"(saved_stat));
             return;
         }
-        __asm__ volatile ("csrw sstatus, %0"::"r"(saved_stat));
+        __asm__ volatile("csrw sstatus, %0" ::"r"(saved_stat));
     }
     LOG_E("[FATAL ERROR] Exception %ld:%s\n", id, get_exception_msg(id));
     LOG_E("scause:0x%p,stval:0x%p,sepc:0x%p\n", scause, stval, sepc);
     dump_regs(sp);
 
-    rt_hw_backtrace((uint32_t *)sp->s0_fp, sepc);
+    rt_thread_t cur_thr = rt_thread_self();
+    struct rt_hw_backtrace_frame frame = {.fp = sp->s0_fp, .pc = sepc};
+    rt_kprintf("fp = %p\n", frame.fp);
+    lwp_backtrace_frame(cur_thr, &frame);
 
-    LOG_E("User Fault, killing thread: %s", rt_thread_self()->parent.name);
+    LOG_E("User Fault, killing thread: %s", cur_thr->parent.name);
 
     EXIT_TRAP;
     sys_exit_group(-1);
 }
 #endif
 
-#ifdef ENABLE_VECTOR
+#ifdef ARCH_RISCV_VECTOR
 static void vector_enable(struct rt_hw_stack_frame *sp)
 {
     sp->sstatus |= SSTATUS_VS_INITIAL;
@@ -243,7 +248,8 @@ static void vector_enable(struct rt_hw_stack_frame *sp)
 /**
  * detect V/D support, and do not distinguish V/D instruction
  */
-static int illegal_inst_recoverable(rt_ubase_t stval, struct rt_hw_stack_frame *sp)
+static int illegal_inst_recoverable(rt_ubase_t stval,
+                                    struct rt_hw_stack_frame *sp)
 {
     // first 7 bits is opcode
     int opcode = stval & 0x7f;
@@ -254,12 +260,12 @@ static int illegal_inst_recoverable(rt_ubase_t stval, struct rt_hw_stack_frame *
 
     switch (opcode)
     {
-    case 0x57: // V
-    case 0x27: // scalar FLOAT
-    case 0x07:
-    case 0x73: // CSR
-        flag = 1;
-        break;
+        case 0x57: // V
+        case 0x27: // scalar FLOAT
+        case 0x07:
+        case 0x73: // CSR
+            flag = 1;
+            break;
     }
 
     if (flag)
@@ -271,11 +277,9 @@ static int illegal_inst_recoverable(rt_ubase_t stval, struct rt_hw_stack_frame *
 }
 #endif
 
-static void handle_nested_trap_panic(
-    rt_size_t cause,
-    rt_size_t tval,
-    rt_size_t epc,
-    struct rt_hw_stack_frame *eframe)
+static void handle_nested_trap_panic(rt_ubase_t cause, rt_ubase_t tval,
+                                     rt_ubase_t epc,
+                                     struct rt_hw_stack_frame *eframe)
 {
     LOG_E("\n-------- [SEVER ERROR] --------");
     LOG_E("Nested trap detected");
@@ -285,21 +289,23 @@ static void handle_nested_trap_panic(
 }
 
 #define IN_USER_SPACE (stval >= USER_VADDR_START && stval < USER_VADDR_TOP)
-#define PAGE_FAULT (id == EP_LOAD_PAGE_FAULT || id == EP_STORE_PAGE_FAULT)
+#define PAGE_FAULT    (id == EP_LOAD_PAGE_FAULT || id == EP_STORE_PAGE_FAULT)
 
 /* Trap entry */
-void handle_trap(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw_stack_frame *sp)
+void handle_trap(rt_ubase_t scause, rt_ubase_t stval, rt_ubase_t sepc,
+                 struct rt_hw_stack_frame *sp)
 {
-    rt_size_t id = __MASKVALUE(scause,__MASK(63UL));
+    ENTER_TRAP;
+    rt_ubase_t id = __MASKVALUE(scause, __MASK(63UL));
     const char *msg;
 
     /* supervisor external interrupt */
-    if ((SCAUSE_INTERRUPT & scause) && SCAUSE_S_EXTERNAL_INTR == (scause & 0xff))
+    if ((SCAUSE_INTERRUPT & scause) &&
+        SCAUSE_S_EXTERNAL_INTR == (scause & 0xff))
     {
         rt_interrupt_enter();
         plic_handle_irq();
         rt_interrupt_leave();
-        return;
     }
     else if ((SCAUSE_INTERRUPT | SCAUSE_S_TIMER_INTR) == scause)
     {
@@ -307,44 +313,74 @@ void handle_trap(rt_size_t scause, rt_size_t stval, rt_size_t sepc, struct rt_hw
         rt_interrupt_enter();
         tick_isr();
         rt_interrupt_leave();
-        return;
     }
-    else if (SCAUSE_INTERRUPT & scause)
+    else
     {
-        if(id < sizeof(Interrupt_Name) / sizeof(const char *))
+        if (SCAUSE_INTERRUPT & scause)
         {
-            msg = Interrupt_Name[id];
+            if (id < sizeof(Interrupt_Name) / sizeof(const char *))
+            {
+                msg = Interrupt_Name[id];
+            }
+            else
+            {
+                msg = "Unknown Interrupt";
+            }
+
+            LOG_E("Unhandled Interrupt %ld:%s\n", id, msg);
         }
         else
         {
-            msg = "Unknown Interrupt";
+#ifdef ARCH_RISCV_VECTOR
+            if (scause == 0x2)
+            {
+                if (!(sp->sstatus & SSTATUS_VS) &&
+                    illegal_inst_recoverable(stval, sp))
+                    goto _exit;
+            }
+#endif /* ARCH_RISCV_VECTOR */
+#ifdef RT_USING_SMART
+            if (!(sp->sstatus & 0x100) || (PAGE_FAULT && IN_USER_SPACE))
+            {
+                handle_user(scause, stval, sepc, sp);
+                // if handle_user() return here, jump to u mode then
+                goto _exit;
+            }
+#endif
+
+            // handle kernel exception:
+            rt_kprintf("Unhandled Exception %ld:%s\n", id,
+                       get_exception_msg(id));
         }
-        LOG_E("Unhandled Interrupt %ld:%s\n",id,msg);
-    }
-    else
-    {
+
+        // trap cannot nested when handling another trap / interrupt
+        CHECK_NESTED_PANIC(scause, stval, sepc, sp);
+
+        rt_kprintf("scause:0x%p,stval:0x%p,sepc:0x%p\n", scause, stval, sepc);
+        dump_regs(sp);
+
+        rt_thread_t cur_thr = rt_thread_self();
+        rt_kprintf("--------------Thread list--------------\n");
+        rt_kprintf("current thread: %s\n", cur_thr->parent.name);
+
+        rt_kprintf("--------------Backtrace--------------\n");
+        struct rt_hw_backtrace_frame frame = {.fp = sp->s0_fp, .pc = sepc};
+
 #ifdef RT_USING_SMART
-        if (!(sp->sstatus & 0x100) || (PAGE_FAULT && IN_USER_SPACE))
+        if (!(sp->sstatus & 0x100))
         {
-            handle_user(scause, stval, sepc, sp);
-            // if handle_user() return here, jump to u mode then
-            return ;
+            lwp_backtrace_frame(cur_thr, &frame);
         }
+        else
 #endif
+        {
+            rt_backtrace_frame(cur_thr, &frame);
+        }
 
-        // handle kernel exception:
-        rt_kprintf("Unhandled Exception %ld:%s\n", id, get_exception_msg(id));
+        while (1)
+            ;
     }
-
-    rt_kprintf("scause:0x%p,stval:0x%p,sepc:0x%p\n", scause, stval, sepc);
-    dump_regs(sp);
-    rt_kprintf("--------------Thread list--------------\n");
-    rt_kprintf("current thread: %s\n", rt_thread_self()->parent.name);
-
-    extern struct rt_thread *rt_current_thread;
-    rt_kprintf("--------------Backtrace--------------\n");
-    rt_hw_backtrace((uint32_t *)sp->s0_fp, sepc);
-
-    while (1)
-        ;
+_exit:
+    EXIT_TRAP;
+    return;
 }

+ 2 - 2
libcpu/risc-v/virt64/io.h

@@ -40,13 +40,13 @@ static inline uint32_t readl(const volatile void *addr)
 static inline void write_reg(
     uint32_t val, volatile void *addr, unsigned offset)
 {
-    writel(val, addr + offset);
+    writel(val, (void *)((rt_size_t)addr + offset));
 }
 
 static inline uint32_t read_reg(
     const volatile void *addr, unsigned offset)
 {
-    return readl(addr + offset);
+    return readl((void *)((rt_size_t)addr + offset));
 }
 
 #endif // ARCH_IO_H

+ 40 - 0
libcpu/risc-v/virt64/opcode.h

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-09     Shell        Add portable asm support
+ */
+#ifndef __OPCODE_H__
+#define __OPCODE_H__
+
+/**
+ * @brief binary opcode pseudo operations
+ * Used to bypass toolchain restriction on extension ISA
+ *
+ */
+
+/**
+ * @brief RISC-V instruction formats
+ */
+
+/**
+ * R type: .insn r opcode6, func3, func7, rd, rs1, rs2
+ *
+ * +-------+-----+-----+-------+----+---------+
+ * | func7 | rs2 | rs1 | func3 | rd | opcode6 |
+ * +-------+-----+-----+-------+----+---------+
+ * 31      25    20    15      12   7        0
+ */
+#define __OPC_INSN_FORMAT_R(opcode, func3, func7, rd, rs1, rs2) \
+    ".insn r "RT_STRINGIFY(opcode)","RT_STRINGIFY(func3)","RT_STRINGIFY(func7)","RT_STRINGIFY(rd)","RT_STRINGIFY(rs1)","RT_STRINGIFY(rs2)
+
+#ifdef _TOOLCHAIN_SUPP_ZIFENCEI_ISA_
+#define OPC_FENCE_I             "fence.i"
+#else /* !_TOOLCHAIN_SUPP_ZIFENCEI_ISA_ */
+#define OPC_FENCE_I             ".long 0x0000100F"
+#endif /* _TOOLCHAIN_SUPP_ZIFENCEI_ISA_ */
+
+#endif /* __OPCODE_H__ */

+ 15 - 0
libcpu/risc-v/virt64/plic.c

@@ -14,6 +14,7 @@
 #include "plic.h"
 #include <riscv_io.h>
 #include "encoding.h"
+#include <interrupt.h>
 
 #include <riscv.h>
 #include <string.h>
@@ -139,3 +140,17 @@ void plic_init()
     // in a single core system, only current context was set
     _set_sie(__raw_hartid());
 }
+
+extern struct rt_irq_desc irq_desc[MAX_HANDLERS];
+/*
+ * Handling an interrupt is a two-step process: first you claim the interrupt
+ * by reading the claim register, then you complete the interrupt by writing
+ * that source ID back to the same claim register.  This automatically enables
+ * and disables the interrupt, so there's nothing else to do.
+ */
+void plic_handle_irq(void)
+{
+    int plic_irq = plic_claim();
+    plic_complete(plic_irq);
+    irq_desc[plic_irq].handler(plic_irq, irq_desc[plic_irq].param);
+}

+ 1 - 0
libcpu/risc-v/virt64/plic.h

@@ -72,5 +72,6 @@ void plic_complete(int irq);
 void plic_set_thresh(rt_uint32_t val);
 void plic_set_ie(rt_uint32_t word_index,rt_uint32_t val);
 void plic_init();
+void plic_handle_irq(void);
 
 #endif

+ 9 - 25
libcpu/risc-v/virt64/riscv_io.h

@@ -10,7 +10,7 @@
 #ifndef __RISCV_IO_H__
 #define __RISCV_IO_H__
 
-static inline uint32_t  __raw_hartid(void)
+static inline uint32_t __raw_hartid(void)
 {
     extern int boot_hartid;
     return boot_hartid;
@@ -18,31 +18,23 @@ static inline uint32_t  __raw_hartid(void)
 
 static inline void __raw_writeb(rt_uint8_t val, volatile void *addr)
 {
-    asm volatile("sb %0, 0(%1)"
-                 :
-                 : "r"(val), "r"(addr));
+    asm volatile("sb %0, 0(%1)" : : "r"(val), "r"(addr));
 }
 
 static inline void __raw_writew(rt_uint16_t val, volatile void *addr)
 {
-    asm volatile("sh %0, 0(%1)"
-                 :
-                 : "r"(val), "r"(addr));
+    asm volatile("sh %0, 0(%1)" : : "r"(val), "r"(addr));
 }
 
 static inline void __raw_writel(rt_uint32_t val, volatile void *addr)
 {
-    asm volatile("sw %0, 0(%1)"
-                 :
-                 : "r"(val), "r"(addr));
+    asm volatile("sw %0, 0(%1)" : : "r"(val), "r"(addr));
 }
 
 #if __riscv_xlen != 32
 static inline void __raw_writeq(rt_uint64_t val, volatile void *addr)
 {
-    asm volatile("sd %0, 0(%1)"
-                 :
-                 : "r"(val), "r"(addr));
+    asm volatile("sd %0, 0(%1)" : : "r"(val), "r"(addr));
 }
 #endif
 
@@ -50,9 +42,7 @@ static inline rt_uint8_t __raw_readb(const volatile void *addr)
 {
     rt_uint8_t val;
 
-    asm volatile("lb %0, 0(%1)"
-                 : "=r"(val)
-                 : "r"(addr));
+    asm volatile("lb %0, 0(%1)" : "=r"(val) : "r"(addr));
     return val;
 }
 
@@ -60,9 +50,7 @@ static inline rt_uint16_t __raw_readw(const volatile void *addr)
 {
     rt_uint16_t val;
 
-    asm volatile("lh %0, 0(%1)"
-                 : "=r"(val)
-                 : "r"(addr));
+    asm volatile("lh %0, 0(%1)" : "=r"(val) : "r"(addr));
     return val;
 }
 
@@ -70,9 +58,7 @@ static inline rt_uint32_t __raw_readl(const volatile void *addr)
 {
     rt_uint32_t val;
 
-    asm volatile("lw %0, 0(%1)"
-                 : "=r"(val)
-                 : "r"(addr));
+    asm volatile("lw %0, 0(%1)" : "=r"(val) : "r"(addr));
     return val;
 }
 
@@ -81,9 +67,7 @@ static inline rt_uint64_t __raw_readq(const volatile void *addr)
 {
     rt_uint64_t val;
 
-    asm volatile("ld %0, 0(%1)"
-                 : "=r"(val)
-                 : "r"(addr));
+    asm volatile("ld %0, 0(%1)" : "=r"(val) : "r"(addr));
     return val;
 }
 #endif

+ 119 - 109
libcpu/risc-v/virt64/trap.c

@@ -7,24 +7,23 @@
  * Date           Author       Notes
  * 2022-12-08     RT-Thread    first version
  */
+
 #include <rthw.h>
 #include <rtthread.h>
 #include <stdint.h>
 
 #include <mm_fault.h>
-#include "mmu.h"
-#include "encoding.h"
-#include "stack.h"
-#include "sbi.h"
-#include "riscv.h"
-#include "interrupt.h"
-#include "plic.h"
-#include "tick.h"
+#include <mmu.h>
+#include <encoding.h>
+#include <stack.h>
+#include <sbi.h>
+#include <riscv.h>
+#include <interrupt.h>
+#include <plic.h>
+#include <tick.h>
 
 #ifdef RT_USING_SMART
 #include <lwp_arch.h>
-#else
-#define rt_hw_backtrace(...) (0)
 #endif
 
 #define DBG_TAG "libcpu.trap"
@@ -36,7 +35,8 @@ void dump_regs(struct rt_hw_stack_frame *regs)
     rt_kprintf("--------------Dump Registers-----------------\n");
 
     rt_kprintf("Function Registers:\n");
-    rt_kprintf("\tra(x1) = 0x%p\tuser_sp = 0x%p\n", regs->ra, regs->user_sp_exc_stack);
+    rt_kprintf("\tra(x1) = 0x%p\tuser_sp = 0x%p\n", regs->ra,
+               regs->user_sp_exc_stack);
     rt_kprintf("\tgp(x3) = 0x%p\ttp(x4) = 0x%p\n", regs->gp, regs->tp);
     rt_kprintf("Temporary Registers:\n");
     rt_kprintf("\tt0(x5) = 0x%p\tt1(x6) = 0x%p\n", regs->t0, regs->t1);
@@ -56,15 +56,27 @@ void dump_regs(struct rt_hw_stack_frame *regs)
     rt_kprintf("\ta4(x14) = 0x%p\ta5(x15) = 0x%p\n", regs->a4, regs->a5);
     rt_kprintf("\ta6(x16) = 0x%p\ta7(x17) = 0x%p\n", regs->a6, regs->a7);
     rt_kprintf("sstatus = 0x%p\n", regs->sstatus);
-    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SIE) ? "Supervisor Interrupt Enabled" : "Supervisor Interrupt Disabled");
-    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SPIE) ? "Last Time Supervisor Interrupt Enabled" : "Last Time Supervisor Interrupt Disabled");
-    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SPP) ? "Last Privilege is Supervisor Mode" : "Last Privilege is User Mode");
-    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SUM) ? "Permit to Access User Page" : "Not Permit to Access User Page");
-    rt_kprintf("\t%s\n", (regs->sstatus & (1 << 19)) ? "Permit to Read Executable-only Page" : "Not Permit to Read Executable-only Page");
+    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SIE)
+                             ? "Supervisor Interrupt Enabled"
+                             : "Supervisor Interrupt Disabled");
+    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SPIE)
+                             ? "Last Time Supervisor Interrupt Enabled"
+                             : "Last Time Supervisor Interrupt Disabled");
+    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SPP)
+                             ? "Last Privilege is Supervisor Mode"
+                             : "Last Privilege is User Mode");
+    rt_kprintf("\t%s\n", (regs->sstatus & SSTATUS_SUM)
+                             ? "Permit to Access User Page"
+                             : "Not Permit to Access User Page");
+    rt_kprintf("\t%s\n", (regs->sstatus & (1 << 19))
+                             ? "Permit to Read Executable-only Page"
+                             : "Not Permit to Read Executable-only Page");
     rt_ubase_t satp_v = read_csr(satp);
     rt_kprintf("satp = 0x%p\n", satp_v);
-    rt_kprintf("\tCurrent Page Table(Physical) = 0x%p\n", __MASKVALUE(satp_v, __MASK(44)) << PAGE_OFFSET_BIT);
-    rt_kprintf("\tCurrent ASID = 0x%p\n", __MASKVALUE(satp_v >> 44, __MASK(16)) << PAGE_OFFSET_BIT);
+    rt_kprintf("\tCurrent Page Table(Physical) = 0x%p\n",
+               __MASKVALUE(satp_v, __MASK(44)) << PAGE_OFFSET_BIT);
+    rt_kprintf("\tCurrent ASID = 0x%p\n", __MASKVALUE(satp_v >> 44, __MASK(16))
+                                              << PAGE_OFFSET_BIT);
     const char *mode_str = "Unknown Address Translation/Protection Mode";
 
     switch (__MASKVALUE(satp_v >> 60, __MASK(4)))
@@ -86,52 +98,44 @@ void dump_regs(struct rt_hw_stack_frame *regs)
     rt_kprintf("-----------------Dump OK---------------------\n");
 }
 
-static const char *Exception_Name[] =
-    {
-        "Instruction Address Misaligned",
-        "Instruction Access Fault",
-        "Illegal Instruction",
-        "Breakpoint",
-        "Load Address Misaligned",
-        "Load Access Fault",
-        "Store/AMO Address Misaligned",
-        "Store/AMO Access Fault",
-        "Environment call from U-mode",
-        "Environment call from S-mode",
-        "Reserved-10",
-        "Reserved-11",
-        "Instruction Page Fault",
-        "Load Page Fault",
-        "Reserved-14",
-        "Store/AMO Page Fault"};
-
-static const char *Interrupt_Name[] =
-    {
-        "User Software Interrupt",
-        "Supervisor Software Interrupt",
-        "Reversed-2",
-        "Reversed-3",
-        "User Timer Interrupt",
-        "Supervisor Timer Interrupt",
-        "Reversed-6",
-        "Reversed-7",
-        "User External Interrupt",
-        "Supervisor External Interrupt",
-        "Reserved-10",
-        "Reserved-11",
+static const char *Exception_Name[] = {"Instruction Address Misaligned",
+                                       "Instruction Access Fault",
+                                       "Illegal Instruction",
+                                       "Breakpoint",
+                                       "Load Address Misaligned",
+                                       "Load Access Fault",
+                                       "Store/AMO Address Misaligned",
+                                       "Store/AMO Access Fault",
+                                       "Environment call from U-mode",
+                                       "Environment call from S-mode",
+                                       "Reserved-10",
+                                       "Reserved-11",
+                                       "Instruction Page Fault",
+                                       "Load Page Fault",
+                                       "Reserved-14",
+                                       "Store/AMO Page Fault"};
+
+static const char *Interrupt_Name[] = {
+    "User Software Interrupt",
+    "Supervisor Software Interrupt",
+    "Reversed-2",
+    "Reversed-3",
+    "User Timer Interrupt",
+    "Supervisor Timer Interrupt",
+    "Reversed-6",
+    "Reversed-7",
+    "User External Interrupt",
+    "Supervisor External Interrupt",
+    "Reserved-10",
+    "Reserved-11",
 };
 
-extern struct rt_irq_desc irq_desc[];
-
 #ifndef RT_USING_SMP
 static volatile int nested = 0;
-#define ENTER_TRAP \
-    nested += 1
-#define EXIT_TRAP \
-    nested -= 1
+#define ENTER_TRAP nested += 1
+#define EXIT_TRAP  nested -= 1
 #define CHECK_NESTED_PANIC(cause, tval, epc, eframe) \
-    if (nested != 1)                                 \
-    handle_nested_trap_panic(cause, tval, epc, eframe)
+    if (nested != 1) handle_nested_trap_panic(cause, tval, epc, eframe)
 #endif /* RT_USING_SMP */
 
 static const char *get_exception_msg(int id)
@@ -150,7 +154,8 @@ static const char *get_exception_msg(int id)
 
 #ifdef RT_USING_SMART
 #include "lwp.h"
-void handle_user(rt_ubase_t scause, rt_ubase_t stval, rt_ubase_t sepc, struct rt_hw_stack_frame *sp)
+void handle_user(rt_ubase_t scause, rt_ubase_t stval, rt_ubase_t sepc,
+                 struct rt_hw_stack_frame *sp)
 {
     rt_ubase_t id = __MASKVALUE(scause, __MASK(63UL));
     struct rt_lwp *lwp;
@@ -210,23 +215,20 @@ void handle_user(rt_ubase_t scause, rt_ubase_t stval, rt_ubase_t sepc, struct rt
             .fault_vaddr = (void *)stval,
         };
 
-        __asm__ volatile ("csrrsi %0, sstatus, 2":"=r"(saved_stat));
+        __asm__ volatile("csrrsi %0, sstatus, 2" : "=r"(saved_stat));
         if (lwp && rt_aspace_fault_try_fix(lwp->aspace, &msg))
         {
-            __asm__ volatile ("csrw sstatus, %0"::"r"(saved_stat));
+            __asm__ volatile("csrw sstatus, %0" ::"r"(saved_stat));
             return;
         }
-        __asm__ volatile ("csrw sstatus, %0"::"r"(saved_stat));
+        __asm__ volatile("csrw sstatus, %0" ::"r"(saved_stat));
     }
     LOG_E("[FATAL ERROR] Exception %ld:%s\n", id, get_exception_msg(id));
     LOG_E("scause:0x%p,stval:0x%p,sepc:0x%p\n", scause, stval, sepc);
     dump_regs(sp);
 
     rt_thread_t cur_thr = rt_thread_self();
-    struct rt_hw_backtrace_frame frame = {
-        .fp = sp->s0_fp,
-        .pc = sepc
-    };
+    struct rt_hw_backtrace_frame frame = {.fp = sp->s0_fp, .pc = sepc};
     rt_kprintf("fp = %p\n", frame.fp);
     lwp_backtrace_frame(cur_thr, &frame);
 
@@ -237,7 +239,7 @@ void handle_user(rt_ubase_t scause, rt_ubase_t stval, rt_ubase_t sepc, struct rt
 }
 #endif
 
-#ifdef ENABLE_VECTOR
+#ifdef ARCH_RISCV_VECTOR
 static void vector_enable(struct rt_hw_stack_frame *sp)
 {
     sp->sstatus |= SSTATUS_VS_INITIAL;
@@ -246,7 +248,8 @@ static void vector_enable(struct rt_hw_stack_frame *sp)
 /**
  * detect V/D support, and do not distinguish V/D instruction
  */
-static int illegal_inst_recoverable(rt_ubase_t stval, struct rt_hw_stack_frame *sp)
+static int illegal_inst_recoverable(rt_ubase_t stval,
+                                    struct rt_hw_stack_frame *sp)
 {
     // first 7 bits is opcode
     int opcode = stval & 0x7f;
@@ -257,12 +260,12 @@ static int illegal_inst_recoverable(rt_ubase_t stval, struct rt_hw_stack_frame *
 
     switch (opcode)
     {
-    case 0x57: // V
-    case 0x27: // scalar FLOAT
-    case 0x07:
-    case 0x73: // CSR
-        flag = 1;
-        break;
+        case 0x57: // V
+        case 0x27: // scalar FLOAT
+        case 0x07:
+        case 0x73: // CSR
+            flag = 1;
+            break;
     }
 
     if (flag)
@@ -274,11 +277,9 @@ static int illegal_inst_recoverable(rt_ubase_t stval, struct rt_hw_stack_frame *
 }
 #endif
 
-static void handle_nested_trap_panic(
-    rt_ubase_t cause,
-    rt_ubase_t tval,
-    rt_ubase_t epc,
-    struct rt_hw_stack_frame *eframe)
+static void handle_nested_trap_panic(rt_ubase_t cause, rt_ubase_t tval,
+                                     rt_ubase_t epc,
+                                     struct rt_hw_stack_frame *eframe)
 {
     LOG_E("\n-------- [SEVER ERROR] --------");
     LOG_E("Nested trap detected");
@@ -288,38 +289,34 @@ static void handle_nested_trap_panic(
 }
 
 #define IN_USER_SPACE (stval >= USER_VADDR_START && stval < USER_VADDR_TOP)
-#define PAGE_FAULT (id == EP_LOAD_PAGE_FAULT || id == EP_STORE_PAGE_FAULT)
+#define PAGE_FAULT    (id == EP_LOAD_PAGE_FAULT || id == EP_STORE_PAGE_FAULT)
 
 /* Trap entry */
-void handle_trap(rt_ubase_t scause, rt_ubase_t stval, rt_ubase_t sepc, struct rt_hw_stack_frame *sp)
+void handle_trap(rt_ubase_t scause, rt_ubase_t stval, rt_ubase_t sepc,
+                 struct rt_hw_stack_frame *sp)
 {
     ENTER_TRAP;
     rt_ubase_t id = __MASKVALUE(scause, __MASK(63UL));
     const char *msg;
 
     /* supervisor external interrupt */
-    if (scause == (uint64_t)(0x8000000000000005))
+    if ((SCAUSE_INTERRUPT & scause) &&
+        SCAUSE_S_EXTERNAL_INTR == (scause & 0xff))
     {
         rt_interrupt_enter();
-        tick_isr();
+        plic_handle_irq();
         rt_interrupt_leave();
     }
-    else if (scause == (uint64_t)(0x8000000000000009))
+    else if ((SCAUSE_INTERRUPT | SCAUSE_S_TIMER_INTR) == scause)
     {
+        /* supervisor timer */
         rt_interrupt_enter();
-        int plic_irq = plic_claim();
-        plic_complete(plic_irq);
-        irq_desc[plic_irq].handler(plic_irq, irq_desc[plic_irq].param);
+        tick_isr();
         rt_interrupt_leave();
     }
     else
     {
-        // trap cannot nested when handling another trap / interrupt
-        CHECK_NESTED_PANIC(scause, stval, sepc, sp);
-        rt_ubase_t id = __MASKVALUE(scause, __MASK(63UL));
-        const char *msg;
-
-        if (scause >> 63)
+        if (SCAUSE_INTERRUPT & scause)
         {
             if (id < sizeof(Interrupt_Name) / sizeof(const char *))
             {
@@ -330,17 +327,18 @@ void handle_trap(rt_ubase_t scause, rt_ubase_t stval, rt_ubase_t sepc, struct rt
                 msg = "Unknown Interrupt";
             }
 
-            rt_kprintf("Unhandled Interrupt %ld:%s\n", id, msg);
+            LOG_E("Unhandled Interrupt %ld:%s\n", id, msg);
         }
         else
         {
-#ifdef ENABLE_VECTOR
+#ifdef ARCH_RISCV_VECTOR
             if (scause == 0x2)
             {
-                if (!(sp->sstatus & SSTATUS_VS) && illegal_inst_recoverable(stval, sp))
+                if (!(sp->sstatus & SSTATUS_VS) &&
+                    illegal_inst_recoverable(stval, sp))
                     goto _exit;
             }
-#endif /* ENABLE_VECTOR */
+#endif /* ARCH_RISCV_VECTOR */
 #ifdef RT_USING_SMART
             if (!(sp->sstatus & 0x100) || (PAGE_FAULT && IN_USER_SPACE))
             {
@@ -351,26 +349,38 @@ void handle_trap(rt_ubase_t scause, rt_ubase_t stval, rt_ubase_t sepc, struct rt
 #endif
 
             // handle kernel exception:
-            rt_kprintf("Unhandled Exception %ld:%s\n", id, get_exception_msg(id));
+            rt_kprintf("Unhandled Exception %ld:%s\n", id,
+                       get_exception_msg(id));
         }
 
+        // trap cannot nested when handling another trap / interrupt
+        CHECK_NESTED_PANIC(scause, stval, sepc, sp);
+
         rt_kprintf("scause:0x%p,stval:0x%p,sepc:0x%p\n", scause, stval, sepc);
         dump_regs(sp);
+
+        rt_thread_t cur_thr = rt_thread_self();
         rt_kprintf("--------------Thread list--------------\n");
-        rt_kprintf("current thread: %s\n", rt_thread_self()->parent.name);
+        rt_kprintf("current thread: %s\n", cur_thr->parent.name);
 
-        extern struct rt_thread *rt_current_thread;
         rt_kprintf("--------------Backtrace--------------\n");
-        struct rt_hw_backtrace_frame frame = {
-            .fp = sp->s0_fp,
-            .pc = sepc
-        };
-        rt_kprintf("fp = %p", frame.fp);
-        rt_backtrace_frame(rt_thread_self(), &frame);
+        struct rt_hw_backtrace_frame frame = {.fp = sp->s0_fp, .pc = sepc};
+
+#ifdef RT_USING_SMART
+        if (!(sp->sstatus & 0x100))
+        {
+            lwp_backtrace_frame(cur_thr, &frame);
+        }
+        else
+#endif
+        {
+            rt_backtrace_frame(cur_thr, &frame);
+        }
 
-        RT_ASSERT(0);
+        while (1)
+            ;
     }
 _exit:
     EXIT_TRAP;
-    return ;
+    return;
 }