1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2010-11-13 weety first version
9 */
10
11
12 #include <rtthread.h>
13 #include <rthw.h>
14
15 #include "dm36x.h"
16
17 /**
18 * @addtogroup DM36X
19 */
20 /*@{*/
21
22 extern struct rt_thread *rt_current_thread;
23 #if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS)
24 extern long list_thread(void);
25 #endif
26
27 /**
28 * this function will show registers of CPU
29 *
30 * @param regs the registers point
31 */
32
rt_hw_show_register(struct rt_hw_register * regs)33 void rt_hw_show_register (struct rt_hw_register *regs)
34 {
35 rt_kprintf("Execption:\n");
36 rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
37 rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
38 rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
39 rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
40 rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
41 rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
42 }
43
44 /**
45 * When ARM7TDMI comes across an instruction which it cannot handle,
46 * it takes the undefined instruction trap.
47 *
48 * @param regs system registers
49 *
50 * @note never invoke this function in application
51 */
rt_hw_trap_udef(struct rt_hw_register * regs)52 void rt_hw_trap_udef(struct rt_hw_register *regs)
53 {
54 rt_hw_show_register(regs);
55
56 rt_kprintf("undefined instruction\n");
57 rt_kprintf("thread - %s stack:\n", rt_current_thread->parent.name);
58
59 #if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS)
60 list_thread();
61 #endif
62 rt_hw_cpu_shutdown();
63 }
64
65 /**
66 * The software interrupt instruction (SWI) is used for entering
67 * Supervisor mode, usually to request a particular supervisor
68 * function.
69 *
70 * @param regs system registers
71 *
72 * @note never invoke this function in application
73 */
rt_hw_trap_swi(struct rt_hw_register * regs)74 void rt_hw_trap_swi(struct rt_hw_register *regs)
75 {
76 rt_hw_show_register(regs);
77
78 rt_kprintf("software interrupt\n");
79 rt_hw_cpu_shutdown();
80 }
81
82 /**
83 * An abort indicates that the current memory access cannot be completed,
84 * which occurs during an instruction prefetch.
85 *
86 * @param regs system registers
87 *
88 * @note never invoke this function in application
89 */
rt_hw_trap_pabt(struct rt_hw_register * regs)90 void rt_hw_trap_pabt(struct rt_hw_register *regs)
91 {
92 rt_hw_show_register(regs);
93
94 rt_kprintf("prefetch abort\n");
95 rt_kprintf("thread - %s stack:\n", rt_current_thread->parent.name);
96
97 #if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS)
98 list_thread();
99 #endif
100 rt_hw_cpu_shutdown();
101 }
102
103 /**
104 * An abort indicates that the current memory access cannot be completed,
105 * which occurs during a data access.
106 *
107 * @param regs system registers
108 *
109 * @note never invoke this function in application
110 */
rt_hw_trap_dabt(struct rt_hw_register * regs)111 void rt_hw_trap_dabt(struct rt_hw_register *regs)
112 {
113 rt_uint32_t fault_addr;
114 rt_uint32_t fault_status;
115 asm volatile ("mrc p15, 0, %0, c6, c0, 0"
116 :
117 :"r"(fault_addr)
118 :"cc");
119 rt_kprintf("unhandler access to 0x%08x\n", fault_addr);
120
121 /* read DFSR */
122 asm volatile ("MRC p15, 0, %0, c5, c0, 0"
123 :
124 :"r"(fault_status)
125 :"cc");
126 rt_kprintf("fault status 0x%08x\n", fault_status);
127
128 rt_hw_show_register(regs);
129
130 rt_kprintf("data abort\n");
131 rt_kprintf("thread - %s stack:\n", rt_current_thread->parent.name);
132
133 #if defined(RT_USING_FINSH) && defined(MSH_USING_BUILT_IN_COMMANDS)
134 list_thread();
135 #endif
136 rt_hw_cpu_shutdown();
137 }
138
139 /**
140 * Normally, system will never reach here
141 *
142 * @param regs system registers
143 *
144 * @note never invoke this function in application
145 */
rt_hw_trap_resv(struct rt_hw_register * regs)146 void rt_hw_trap_resv(struct rt_hw_register *regs)
147 {
148 rt_kprintf("not used\n");
149 rt_hw_show_register(regs);
150 rt_hw_cpu_shutdown();
151 }
152
153 extern struct rt_irq_desc irq_desc[];
154
155
rt_hw_trap_irq()156 void rt_hw_trap_irq()
157 {
158 rt_isr_handler_t isr_func;
159 rt_uint32_t val, irq, mask;
160 void *param;
161
162 /* get irq number */
163 val = readl(DAVINCI_ARM_INTC_BASE+0x14) - readl(DAVINCI_ARM_INTC_BASE+0x24);
164 irq = (val >> 2) - 1;
165 /* clear pending register */
166 mask = 1 << (irq & 0x1f);
167 if (irq > 31)
168 writel(mask, DAVINCI_ARM_INTC_BASE+0x0c); //IRQ1
169 else
170 writel(mask, DAVINCI_ARM_INTC_BASE+0x08); //IRQ0
171
172 /* get interrupt service routine */
173 isr_func = irq_desc[irq].handler;
174 param = irq_desc[irq].param;
175
176 /* turn to interrupt service routine */
177 isr_func(irq, param);
178 irq_desc[irq].counter++;
179 }
180
rt_hw_trap_fiq()181 void rt_hw_trap_fiq()
182 {
183 rt_kprintf("fast interrupt request\n");
184 }
185
186 /*@}*/
187