1 /*
2 * Copyright (c) 2006-2018, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2011-01-13 weety modified from mini2440
9 * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP
10 */
11
12 #include <rtthread.h>
13 #include <rthw.h>
14
15 #define INT_IRQ 0x00
16 #define INT_FIQ 0x01
17
18 extern struct rt_thread *rt_current_thread;
19 #ifdef RT_USING_FINSH
20 extern long list_thread(void);
21 #endif
22
23 struct rt_hw_register
24 {
25 rt_uint32_t r0;
26 rt_uint32_t r1;
27 rt_uint32_t r2;
28 rt_uint32_t r3;
29 rt_uint32_t r4;
30 rt_uint32_t r5;
31 rt_uint32_t r6;
32 rt_uint32_t r7;
33 rt_uint32_t r8;
34 rt_uint32_t r9;
35 rt_uint32_t r10;
36 rt_uint32_t fp;
37 rt_uint32_t ip;
38 rt_uint32_t sp;
39 rt_uint32_t lr;
40 rt_uint32_t pc;
41 rt_uint32_t cpsr;
42 rt_uint32_t ORIG_r0;
43 };
44
45 /**
46 * this function will show registers of CPU
47 *
48 * @param regs the registers point
49 */
50
rt_hw_show_register(struct rt_hw_register * regs)51 void rt_hw_show_register (struct rt_hw_register *regs)
52 {
53 rt_kprintf("Execption:\n");
54 rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n",
55 regs->r0, regs->r1, regs->r2, regs->r3);
56 rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n",
57 regs->r4, regs->r5, regs->r6, regs->r7);
58 rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n",
59 regs->r8, regs->r9, regs->r10);
60 rt_kprintf("fp :0x%08x ip :0x%08x\n",
61 regs->fp, regs->ip);
62 rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n",
63 regs->sp, regs->lr, regs->pc);
64 rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
65 }
66
67 /**
68 * When ARM7TDMI comes across an instruction which it cannot handle,
69 * it takes the undefined instruction trap.
70 *
71 * @param regs system registers
72 *
73 * @note never invoke this function in application
74 */
rt_hw_trap_udef(struct rt_hw_register * regs)75 void rt_hw_trap_udef(struct rt_hw_register *regs)
76 {
77 rt_hw_show_register(regs);
78
79 rt_kprintf("undefined instruction\n");
80 rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
81
82 #ifdef RT_USING_FINSH
83 list_thread();
84 #endif
85 rt_hw_cpu_shutdown();
86 }
87
88 /**
89 * The software interrupt instruction (SWI) is used for entering
90 * Supervisor mode, usually to request a particular supervisor
91 * function.
92 *
93 * @param regs system registers
94 *
95 * @note never invoke this function in application
96 */
rt_hw_trap_swi(struct rt_hw_register * regs)97 void rt_hw_trap_swi(struct rt_hw_register *regs)
98 {
99 rt_hw_show_register(regs);
100
101 rt_kprintf("software interrupt\n");
102 rt_hw_cpu_shutdown();
103 }
104
105 /**
106 * An abort indicates that the current memory access cannot be completed,
107 * which occurs during an instruction prefetch.
108 *
109 * @param regs system registers
110 *
111 * @note never invoke this function in application
112 */
rt_hw_trap_pabt(struct rt_hw_register * regs)113 void rt_hw_trap_pabt(struct rt_hw_register *regs)
114 {
115 rt_hw_show_register(regs);
116
117 rt_kprintf("prefetch abort\n");
118 rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name);
119
120 #ifdef RT_USING_FINSH
121 list_thread();
122 #endif
123 rt_hw_cpu_shutdown();
124 }
125
126 /**
127 * An abort indicates that the current memory access cannot be completed,
128 * which occurs during a data access.
129 *
130 * @param regs system registers
131 *
132 * @note never invoke this function in application
133 */
rt_hw_trap_dabt(struct rt_hw_register * regs)134 void rt_hw_trap_dabt(struct rt_hw_register *regs)
135 {
136 rt_hw_show_register(regs);
137
138 rt_kprintf("data abort\n");
139 rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name);
140
141 #ifdef RT_USING_FINSH
142 list_thread();
143 #endif
144 rt_hw_cpu_shutdown();
145 }
146
147 /**
148 * Normally, system will never reach here
149 *
150 * @param regs system registers
151 *
152 * @note never invoke this function in application
153 */
rt_hw_trap_resv(struct rt_hw_register * regs)154 void rt_hw_trap_resv(struct rt_hw_register *regs)
155 {
156 rt_kprintf("not used\n");
157 rt_hw_show_register(regs);
158 rt_hw_cpu_shutdown();
159 }
160
161 extern struct rt_irq_desc irq_desc[];
162 extern rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq);
163 extern void rt_hw_interrupt_ack(rt_uint32_t fiq_irq, rt_uint32_t id);
164
rt_hw_trap_irq()165 void rt_hw_trap_irq()
166 {
167 rt_isr_handler_t isr_func;
168 rt_uint32_t irq;
169 void *param;
170
171 /* get irq number */
172 irq = rt_hw_interrupt_get_active(INT_IRQ);
173
174 /* get interrupt service routine */
175 isr_func = irq_desc[irq].handler;
176 param = irq_desc[irq].param;
177
178 /* turn to interrupt service routine */
179 isr_func(irq, param);
180
181 rt_hw_interrupt_ack(INT_IRQ, irq);
182 #ifdef RT_USING_INTERRUPT_INFO
183 irq_desc[irq].counter ++;
184 #endif
185 }
186
rt_hw_trap_fiq()187 void rt_hw_trap_fiq()
188 {
189 rt_isr_handler_t isr_func;
190 rt_uint32_t irq;
191 void *param;
192
193 /* get irq number */
194 irq = rt_hw_interrupt_get_active(INT_FIQ);
195
196 /* get interrupt service routine */
197 isr_func = irq_desc[irq].handler;
198 param = irq_desc[irq].param;
199
200 /* turn to interrupt service routine */
201 isr_func(irq, param);
202
203 rt_hw_interrupt_ack(INT_FIQ, irq);
204 #ifdef RT_USING_INTERRUPT_INFO
205 irq_desc[irq].counter ++;
206 #endif
207 }
208