xref: /nrf52832-nimble/rt-thread/libcpu/arm/zynq7000/trap.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
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  */
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  */
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  */
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  */
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  */
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  */
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 
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 
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