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