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 * 2006-09-06 XuXinming first version
9 * 2006-09-15 Bernard modify rt_hw_trap_irq for more effective
10 */
11
12 #include <rtthread.h>
13 #include <rthw.h>
14
15 #include "s3c44b0.h"
16
17 extern unsigned char interrupt_bank0[256];
18 extern unsigned char interrupt_bank1[256];
19 extern unsigned char interrupt_bank2[256];
20 extern unsigned char interrupt_bank3[256];
21
22 extern struct rt_thread *rt_current_thread;
23
24 /**
25 * @addtogroup S3C44B0
26 */
27 /*@{*/
28
29 /**
30 * this function will show registers of CPU
31 *
32 * @param regs the registers point
33 */
rt_hw_show_register(struct rt_hw_register * regs)34 void rt_hw_show_register (struct rt_hw_register *regs)
35 {
36 rt_kprintf("Execption:\n");
37 rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
38 rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
39 rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
40 rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
41 rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
42 rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
43 }
44
45 /**
46 * When ARM7TDMI comes across an instruction which it cannot handle,
47 * it takes the undefined instruction trap.
48 *
49 * @param regs system registers
50 *
51 * @note never invoke this function in application
52 */
rt_hw_trap_udef(struct rt_hw_register * regs)53 void rt_hw_trap_udef(struct rt_hw_register *regs)
54 {
55 rt_hw_show_register(regs);
56
57 rt_kprintf("undefined instruction\n");
58 rt_hw_cpu_shutdown();
59 }
60
61 /**
62 * The software interrupt instruction (SWI) is used for entering
63 * Supervisor mode, usually to request a particular supervisor
64 * function.
65 *
66 * @param regs system registers
67 *
68 * @note never invoke this function in application
69 */
rt_hw_trap_swi(struct rt_hw_register * regs)70 void rt_hw_trap_swi(struct rt_hw_register *regs)
71 {
72 rt_kprintf("software interrupt\n");
73 rt_hw_show_register(regs);
74 rt_hw_cpu_shutdown();
75 }
76
77 /**
78 * An abort indicates that the current memory access cannot be completed,
79 * which occurs during an instruction prefetch.
80 *
81 * @param regs system registers
82 *
83 * @note never invoke this function in application
84 */
rt_hw_trap_pabt(struct rt_hw_register * regs)85 void rt_hw_trap_pabt(struct rt_hw_register *regs)
86 {
87 rt_hw_show_register(regs);
88
89 rt_kprintf("prefetch abort\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 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_register * regs)101 void rt_hw_trap_dabt(struct rt_hw_register *regs)
102 {
103 rt_hw_show_register(regs);
104
105 rt_kprintf("data abort\n");
106 rt_hw_cpu_shutdown();
107 }
108
109 /**
110 * Normally, system will never reach here
111 *
112 * @param regs system registers
113 *
114 * @note never invoke this function in application
115 */
rt_hw_trap_resv(struct rt_hw_register * regs)116 void rt_hw_trap_resv(struct rt_hw_register *regs)
117 {
118 rt_kprintf("not used\n");
119 rt_hw_show_register(regs);
120 rt_hw_cpu_shutdown();
121 }
122
123 extern rt_isr_handler_t isr_table[];
rt_hw_trap_irq()124 void rt_hw_trap_irq()
125 {
126 register unsigned long ispr, intstat;
127 register rt_isr_handler_t isr_func;
128
129 #ifdef BSP_INT_DEBUG
130 rt_kprintf("irq coming, ");
131 #endif
132 intstat = I_ISPR & 0x7ffffff;
133 #ifdef BSP_INT_DEBUG
134 rt_kprintf("I_ISPR: %d\n", intstat);
135 #endif
136
137 ispr = intstat;
138
139 /* to find interrupt */
140 if ( intstat & 0xff ) /* lowest 8bits */
141 {
142 intstat = interrupt_bank0[intstat & 0xff];
143 isr_func = (rt_isr_handler_t)isr_table[ intstat ];
144 }
145 else if ( intstat & 0xff00 ) /* low 8bits */
146 {
147 intstat = interrupt_bank1[(intstat & 0xff00) >> 8];
148 isr_func = (rt_isr_handler_t)isr_table[ intstat ];
149 }
150 else if ( intstat & 0xff0000 ) /* high 8bits */
151 {
152 intstat = interrupt_bank2[(intstat & 0xff0000) >> 16];
153 isr_func = (rt_isr_handler_t)isr_table[ intstat ];
154 }
155 else if ( intstat & 0xff000000 ) /* highest 8bits */
156 {
157 intstat = interrupt_bank3[(intstat & 0xff000000) >> 24];
158 isr_func = (rt_isr_handler_t)isr_table[ intstat ];
159 }
160 else return;
161
162 #ifdef BSP_INT_DEBUG
163 rt_kprintf("irq: %d happen\n", intstat);
164 #endif
165
166 /* turn to interrupt service routine */
167 isr_func(intstat);
168
169 I_ISPC = ispr; /* clear interrupt */
170 }
171
rt_hw_trap_fiq()172 void rt_hw_trap_fiq()
173 {
174 rt_kprintf("fast interrupt request\n");
175 }
176
177 /*@}*/
178