xref: /nrf52832-nimble/rt-thread/libcpu/arm/s3c44b0/trap.c (revision 104654410c56c573564690304ae786df310c91fc)
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