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-09-23 Bernard first version
9 */
10
11 #include <rtthread.h>
12 #include <rthw.h>
13
14 #include "am33xx.h"
15 #include "interrupt.h"
16
17 #ifdef RT_USING_GDB
18 #include "gdb_stub.h"
19 #endif
20
21 /**
22 * @addtogroup AM33XX
23 */
24 /*@{*/
25
26 extern struct rt_thread *rt_current_thread;
27 #ifdef RT_USING_FINSH
28 extern long list_thread(void);
29 #endif
30
31 /**
32 * this function will show registers of CPU
33 *
34 * @param regs the registers point
35 */
36
rt_hw_show_register(struct rt_hw_register * regs)37 void rt_hw_show_register (struct rt_hw_register *regs)
38 {
39 rt_kprintf("Execption:\n");
40 rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
41 rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
42 rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
43 rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
44 rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
45 rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
46 }
47
48 /**
49 * When ARM7TDMI comes across an instruction which it cannot handle,
50 * it takes the undefined instruction trap.
51 *
52 * @param regs system registers
53 *
54 * @note never invoke this function in application
55 */
rt_hw_trap_udef(struct rt_hw_register * regs)56 void rt_hw_trap_udef(struct rt_hw_register *regs)
57 {
58
59 #ifdef RT_USING_GDB
60 regs->pc -= 4; //lr in undef is pc + 4
61 if (gdb_undef_hook(regs))
62 return;
63 #endif
64
65 rt_hw_show_register(regs);
66
67 rt_kprintf("undefined instruction\n");
68 rt_kprintf("thread %.*s stack:\n", RT_NAME_MAX, rt_current_thread->name);
69
70 #ifdef RT_USING_FINSH
71 list_thread();
72 #endif
73 rt_hw_cpu_shutdown();
74 }
75
76 /**
77 * The software interrupt instruction (SWI) is used for entering
78 * Supervisor mode, usually to request a particular supervisor
79 * function.
80 *
81 * @param regs system registers
82 *
83 * @note never invoke this function in application
84 */
rt_hw_trap_swi(struct rt_hw_register * regs)85 void rt_hw_trap_swi(struct rt_hw_register *regs)
86 {
87 rt_hw_show_register(regs);
88
89 rt_kprintf("software interrupt\n");
90 rt_hw_cpu_shutdown();
91 }
92
93 /**
94 * An abort indicates that the current memory access cannot be completed,
95 * which occurs during an instruction prefetch.
96 *
97 * @param regs system registers
98 *
99 * @note never invoke this function in application
100 */
rt_hw_trap_pabt(struct rt_hw_register * regs)101 void rt_hw_trap_pabt(struct rt_hw_register *regs)
102 {
103 rt_hw_show_register(regs);
104
105 rt_kprintf("prefetch abort\n");
106 rt_kprintf("thread %.*s stack:\n", RT_NAME_MAX, rt_current_thread->name);
107
108 #ifdef RT_USING_FINSH
109 list_thread();
110 #endif
111 rt_hw_cpu_shutdown();
112 }
113
114 /**
115 * An abort indicates that the current memory access cannot be completed,
116 * which occurs during a data access.
117 *
118 * @param regs system registers
119 *
120 * @note never invoke this function in application
121 */
rt_hw_trap_dabt(struct rt_hw_register * regs)122 void rt_hw_trap_dabt(struct rt_hw_register *regs)
123 {
124
125 #ifdef RT_USING_GDB
126 if (gdb_mem_fault_handler) {
127 regs->pc = (unsigned long)gdb_mem_fault_handler;
128 return;
129 }
130 #endif
131 rt_hw_show_register(regs);
132
133 rt_kprintf("data abort\n");
134 rt_kprintf("thread %.*s stack:\n", RT_NAME_MAX, rt_current_thread->name);
135
136 #ifdef RT_USING_FINSH
137 list_thread();
138 #endif
139 rt_hw_cpu_shutdown();
140 }
141
rt_hw_trap_irq()142 void rt_hw_trap_irq()
143 {
144 void *param;
145 unsigned long ir;
146 rt_isr_handler_t isr_func;
147 extern struct rt_irq_desc isr_table[];
148
149 ir = rt_hw_interrupt_get_active(INT_IRQ);
150 if (ir == 127)
151 {
152 /* new IRQ generation */
153 rt_hw_interrupt_ack(INT_IRQ);
154 ir = rt_hw_interrupt_get_active(INT_IRQ);
155 if (ir == 127)
156 {
157 /* still spurious interrupt, get out */
158 /*rt_kprintf("still spurious interrupt\n");*/
159 return;
160 }
161 /*rt_kprintf("new IRQ: %d\n", ir);*/
162 }
163
164 /* get interrupt service routine */
165 isr_func = isr_table[ir].handler;
166 param = isr_table[ir].param;
167
168 /* turn to interrupt service routine */
169 if (isr_func != RT_NULL)
170 isr_func(ir, param);
171
172 /* new IRQ generation */
173 rt_hw_interrupt_ack(INT_IRQ);
174 }
175
rt_hw_trap_fiq()176 void rt_hw_trap_fiq()
177 {
178 void *param;
179 unsigned long ir;
180 rt_isr_handler_t isr_func;
181 extern struct rt_irq_desc isr_table[];
182
183 ir = rt_hw_interrupt_get_active(INT_FIQ);
184
185 /* get interrupt service routine */
186 isr_func = isr_table[ir].handler;
187 param = isr_table[ir].param;
188
189 /* turn to interrupt service routine */
190 isr_func(ir, param);
191
192 /* new FIQ generation */
193 rt_hw_interrupt_ack(INT_FIQ);
194 }
195
196 /*@}*/
197