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