1 /*
2  * Copyright (c) 2006-2024, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2024/01/11     flyingcys    The first version
9  */
10 
11 #include <rtthread.h>
12 
13 #include <encoding.h>
14 
15 
16 struct exception_stack_frame
17 {
18     uint64_t x1;
19     uint64_t x2;
20     uint64_t x3;
21     uint64_t x4;
22     uint64_t x5;
23     uint64_t x6;
24     uint64_t x7;
25     uint64_t x8;
26     uint64_t x9;
27     uint64_t x10;
28     uint64_t x11;
29     uint64_t x12;
30     uint64_t x13;
31     uint64_t x14;
32     uint64_t x15;
33     uint64_t x16;
34     uint64_t x17;
35     uint64_t x18;
36     uint64_t x19;
37     uint64_t x20;
38     uint64_t x21;
39     uint64_t x22;
40     uint64_t x23;
41     uint64_t x24;
42     uint64_t x25;
43     uint64_t x26;
44     uint64_t x27;
45     uint64_t x28;
46     uint64_t x29;
47     uint64_t x30;
48     uint64_t x31;
49 };
50 
print_stack_frame(uintptr_t * sp)51 static void print_stack_frame(uintptr_t * sp)
52 {
53     struct exception_stack_frame * esf = (struct exception_stack_frame *)(sp+1);
54 
55     rt_kprintf("\n=================================================================\n");
56     rt_kprintf("x1 (ra   : Return address                ) ==> 0x%08x%08x\n", esf->x1 >> 32  , esf->x1 & UINT32_MAX);
57     rt_kprintf("x2 (sp   : Stack pointer                 ) ==> 0x%08x%08x\n", esf->x2 >> 32  , esf->x2 & UINT32_MAX);
58     rt_kprintf("x3 (gp   : Global pointer                ) ==> 0x%08x%08x\n", esf->x3 >> 32  , esf->x3 & UINT32_MAX);
59     rt_kprintf("x4 (tp   : Thread pointer                ) ==> 0x%08x%08x\n", esf->x4 >> 32  , esf->x4 & UINT32_MAX);
60     rt_kprintf("x5 (t0   : Temporary                     ) ==> 0x%08x%08x\n", esf->x5 >> 32  , esf->x5 & UINT32_MAX);
61     rt_kprintf("x6 (t1   : Temporary                     ) ==> 0x%08x%08x\n", esf->x6 >> 32  , esf->x6 & UINT32_MAX);
62     rt_kprintf("x7 (t2   : Temporary                     ) ==> 0x%08x%08x\n", esf->x7 >> 32  , esf->x7 & UINT32_MAX);
63     rt_kprintf("x8 (s0/fp: Save register,frame pointer   ) ==> 0x%08x%08x\n", esf->x8 >> 32  , esf->x8 & UINT32_MAX);
64     rt_kprintf("x9 (s1   : Save register                 ) ==> 0x%08x%08x\n", esf->x9 >> 32  , esf->x9 & UINT32_MAX);
65     rt_kprintf("x10(a0   : Function argument,return value) ==> 0x%08x%08x\n", esf->x10 >> 32 , esf->x10 & UINT32_MAX);
66     rt_kprintf("x11(a1   : Function argument,return value) ==> 0x%08x%08x\n", esf->x11 >> 32 , esf->x11 & UINT32_MAX);
67     rt_kprintf("x12(a2   : Function argument             ) ==> 0x%08x%08x\n", esf->x12 >> 32 , esf->x12 & UINT32_MAX);
68     rt_kprintf("x13(a3   : Function argument             ) ==> 0x%08x%08x\n", esf->x13 >> 32 , esf->x13 & UINT32_MAX);
69     rt_kprintf("x14(a4   : Function argument             ) ==> 0x%08x%08x\n", esf->x14 >> 32 , esf->x14 & UINT32_MAX);
70     rt_kprintf("x15(a5   : Function argument             ) ==> 0x%08x%08x\n", esf->x15 >> 32 , esf->x15 & UINT32_MAX);
71     rt_kprintf("x16(a6   : Function argument             ) ==> 0x%08x%08x\n", esf->x16 >> 32 , esf->x16 & UINT32_MAX);
72     rt_kprintf("x17(a7   : Function argument             ) ==> 0x%08x%08x\n", esf->x17 >> 32 , esf->x17 & UINT32_MAX);
73     rt_kprintf("x18(s2   : Save register                 ) ==> 0x%08x%08x\n", esf->x18 >> 32 , esf->x18 & UINT32_MAX);
74     rt_kprintf("x19(s3   : Save register                 ) ==> 0x%08x%08x\n", esf->x19 >> 32 , esf->x19 & UINT32_MAX);
75     rt_kprintf("x20(s4   : Save register                 ) ==> 0x%08x%08x\n", esf->x20 >> 32 , esf->x20 & UINT32_MAX);
76     rt_kprintf("x21(s5   : Save register                 ) ==> 0x%08x%08x\n", esf->x21 >> 32 , esf->x21 & UINT32_MAX);
77     rt_kprintf("x22(s6   : Save register                 ) ==> 0x%08x%08x\n", esf->x22 >> 32 , esf->x22 & UINT32_MAX);
78     rt_kprintf("x23(s7   : Save register                 ) ==> 0x%08x%08x\n", esf->x23 >> 32 , esf->x23 & UINT32_MAX);
79     rt_kprintf("x24(s8   : Save register                 ) ==> 0x%08x%08x\n", esf->x24 >> 32 , esf->x24 & UINT32_MAX);
80     rt_kprintf("x25(s9   : Save register                 ) ==> 0x%08x%08x\n", esf->x25 >> 32 , esf->x25 & UINT32_MAX);
81     rt_kprintf("x26(s10  : Save register                 ) ==> 0x%08x%08x\n", esf->x26 >> 32 , esf->x26 & UINT32_MAX);
82     rt_kprintf("x27(s11  : Save register                 ) ==> 0x%08x%08x\n", esf->x27 >> 32 , esf->x27 & UINT32_MAX);
83     rt_kprintf("x28(t3   : Temporary                     ) ==> 0x%08x%08x\n", esf->x28 >> 32 , esf->x28 & UINT32_MAX);
84     rt_kprintf("x29(t4   : Temporary                     ) ==> 0x%08x%08x\n", esf->x29 >> 32 , esf->x29 & UINT32_MAX);
85     rt_kprintf("x30(t5   : Temporary                     ) ==> 0x%08x%08x\n", esf->x30 >> 32 , esf->x30 & UINT32_MAX);
86     rt_kprintf("x31(t6   : Temporary                     ) ==> 0x%08x%08x\n", esf->x31 >> 32 , esf->x31 & UINT32_MAX);
87     rt_kprintf("=================================================================\n");
88 }
89 
rt_hw_soft_irq_isr(void)90 rt_weak void rt_hw_soft_irq_isr(void)
91 {
92 
93 }
94 
rt_hw_tick_isr(void)95 rt_weak int rt_hw_tick_isr(void)
96 {
97     return 0;
98 }
99 
rt_hw_irq_isr(void)100 rt_weak void rt_hw_irq_isr(void)
101 {
102 
103 }
104 
handle_trap(rt_size_t cause,rt_size_t epc,rt_size_t * sp)105 rt_weak rt_size_t handle_trap(rt_size_t cause, rt_size_t epc, rt_size_t *sp)
106 {
107     if (cause & (1UL << (__riscv_xlen - 1)))          //interrupt
108     {
109         if ((cause & 0x1f) == IRQ_M_SOFT)
110         {
111             rt_hw_soft_irq_isr();
112         }
113         else if ((cause & 0x1f) == IRQ_M_TIMER)
114         {
115             rt_hw_tick_isr();
116         }
117         else if ((cause & 0x1f) == IRQ_M_EXT)
118         {
119             rt_hw_irq_isr();
120         }
121     }
122     else
123     {
124         rt_thread_t tid;
125 #if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS)
126         extern long list_thread();
127 #endif
128 
129         rt_hw_interrupt_disable();
130 
131         tid = rt_thread_self();
132         rt_kprintf("\nException:\n");
133         switch (cause)
134         {
135             case CAUSE_MISALIGNED_FETCH:
136                 rt_kprintf("Instruction address misaligned");
137                 break;
138             case CAUSE_FAULT_FETCH:
139                 rt_kprintf("Instruction access fault");
140                 break;
141             case CAUSE_ILLEGAL_INSTRUCTION:
142                 rt_kprintf("Illegal instruction");
143                 break;
144             case CAUSE_BREAKPOINT:
145                 rt_kprintf("Breakpoint");
146                 break;
147             case CAUSE_MISALIGNED_LOAD:
148                 rt_kprintf("Load address misaligned");
149                 break;
150             case CAUSE_FAULT_LOAD:
151                 rt_kprintf("Load access fault");
152                 break;
153             case CAUSE_MISALIGNED_STORE:
154                 rt_kprintf("Store address misaligned");
155                 break;
156             case CAUSE_FAULT_STORE:
157                 rt_kprintf("Store access fault");
158                 break;
159             case CAUSE_USER_ECALL:
160                 rt_kprintf("Environment call from U-mode");
161                 break;
162             case CAUSE_SUPERVISOR_ECALL:
163                 rt_kprintf("Environment call from S-mode");
164                 break;
165             case CAUSE_HYPERVISOR_ECALL:
166                 rt_kprintf("Environment call from H-mode");
167                 break;
168             case CAUSE_MACHINE_ECALL:
169                 rt_kprintf("Environment call from M-mode");
170                 break;
171             default:
172                 rt_kprintf("Uknown exception : %08lX", cause);
173                 break;
174         }
175         rt_kprintf("\n");
176         print_stack_frame(sp);
177         rt_kprintf("exception pc => 0x%08x\n", epc);
178         rt_kprintf("current thread: %.*s\n", RT_NAME_MAX, tid->parent.name);
179 #if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS)
180         list_thread();
181 #endif
182         while(1);
183     }
184 
185     return epc;
186 }
187