tidy irq debug
[AROS.git] / arch / arm-raspi / kernel / intr.c
blobc390e3a387489afa98a63a1480a2be2a17ac877e
1 /*
2 Copyright © 2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <inttypes.h>
7 #include <aros/kernel.h>
8 #include <aros/libcall.h>
9 #include <hardware/intbits.h>
10 #include <stddef.h>
11 #include <string.h>
13 #include <proto/exec.h>
14 #include <proto/kernel.h>
16 #include "kernel_cpu.h"
17 #include "kernel_intern.h"
18 #include "kernel_debug.h"
19 #include "kernel_interrupts.h"
20 #include "kernel_intr.h"
22 #define BOOT_STACK_SIZE (256 << 2)
23 #define BOOT_TAGS_SIZE (128 << 3)
25 #define IRQBANK_POINTER(bank) ((bank == 0) ? GPUIRQ_ENBL0 : (bank == 1) ? GPUIRQ_ENBL1 : ARMIRQ_ENBL)
27 #define DREGS(x)
28 #define DIRQ(x)
29 #define D(x)
31 void ictl_enable_irq(uint8_t irq, struct KernelBase *KernelBase)
33 int bank = IRQ_BANK(irq);
34 unsigned int val, reg;
36 reg = IRQBANK_POINTER(bank);
38 DIRQ(bug("[KRN] Enabling irq %d [bank %d, reg 0x%p]\n", irq, bank, reg));
40 val = *((volatile unsigned int *)reg);
41 val |= IRQ_MASK(irq);
42 *((volatile unsigned int *)reg) = val;
45 void ictl_disable_irq(uint8_t irq, struct KernelBase *KernelBase)
47 int bank = IRQ_BANK(irq);
48 unsigned int val, reg;
50 reg = IRQBANK_POINTER(bank);
52 DIRQ(bug("[KRN] Dissabling irq %d [bank %d, reg 0x%p]\n", irq, bank, reg));
54 val = *((volatile unsigned int *)reg);
55 val |= IRQ_MASK(irq);
56 *((volatile unsigned int *)reg) = val;
59 /* ** UNDEF INSTRUCTION EXCEPTION ** */
61 asm (
62 ".set MODE_SYSTEM, 0x1f \n"
64 ".globl __vectorhand_undef \n"
65 ".type __vectorhand_undef,%function \n"
66 "__vectorhand_undef: \n"
67 VECTCOMMON_START
68 " cpsid i, #" STR(MODE_SYSTEM)"\n" // switch to system mode, with interrupts disabled..
69 " str sp, [r0, #13*4] \n"
70 " str lr, [r0, #14*4] \n" // store lr in ctx_lr
71 " mov fp, #0 \n" // clear fp
73 " bl handle_undef \n"
75 VECTCOMMON_END
78 void handle_undef(regs_t *regs)
80 bug("[Kernel] Trap ARM Undef Exception -> Exception #4 (Illegal instruction)\n");
82 if (krnRunExceptionHandlers(KernelBase, 4, regs))
83 return;
85 if (core_Trap(4, regs))
87 bug("[Kernel] Trap handler returned\n");
88 return;
91 bug("[Kernel] UNHANDLED EXCEPTION #4\n");
93 while (1)
94 asm volatile ("mov r0, r0\n");
97 /* ** RESET HANDLER ** */
99 asm (
100 ".globl __vectorhand_reset \n"
101 ".type __vectorhand_reset,%function \n"
102 "__vectorhand_reset: \n"
103 " mov sp, #0x1000 - 16 \n" // re-use bootstrap tmp stack
104 " mov r0, sp \n"
105 " sub r0, r0, #" STR(BOOT_STACK_SIZE)"\n" // get the boottag's
106 " sub r0, r0, #" STR(BOOT_TAGS_SIZE) "\n"
107 " mov fp, #0 \n" // clear fp
109 " ldr pc, 2f \n" // jump into kernel resource
110 "1: b 1b \n"
111 "2: .word kernel_cstart \n"
116 /* ** SWI HANDLER ** */
118 /** SWI handled in syscall.c */
120 /* ** IRQ HANDLER ** */
122 asm (
123 ".set MODE_IRQ, 0x12 \n"
124 ".set MODE_SUPERVISOR, 0x13 \n"
125 ".set MODE_SYSTEM, 0x1f \n"
127 ".globl __vectorhand_irq \n"
128 ".type __vectorhand_irq,%function \n"
129 "__vectorhand_irq: \n"
130 " sub lr, lr, #4 \n" // adjust lr_irq
131 VECTCOMMON_START
132 " cpsid i, #MODE_SYSTEM \n" // switch to system mode, with interrupts disabled..
133 " str sp, [r0, #13*4] \n"
134 " str lr, [r0, #14*4] \n" // store lr in ctx_lr
135 " mov fp, #0 \n" // clear fp
137 " bl handle_irq \n"
139 " cpsid i, #MODE_IRQ \n" // switch to IRQ mode, with interrupts disabled..
140 " mov r0, sp \n"
141 " mov fp, #0 \n" // clear fp
142 " bl core_ExitInterrupt \n"
143 VECTCOMMON_END
146 #define IRQ_BANK1 0x00000100
147 #define IRQ_BANK2 0x00000200
149 void handle_irq(regs_t *regs)
151 unsigned int pending, processed, irq;
153 DIRQ(bug("[KRN] ## IRQ ##\n"));
155 DREGS(cpu_DumpRegs(regs));
157 pending = *((volatile unsigned int *)(ARMIRQ_PEND));
158 DIRQ(bug("[KRN] PendingARM %08x\n", pending));
159 if (!(pending & IRQ_BANK1))
161 processed = 0;
162 for (irq = (2 << 5); irq < ((2 << 5) + 32); irq++)
164 if (pending & (1 << (irq - (2 << 5))))
166 DIRQ(bug("[KRN] Handling IRQ %d ..\n", irq));
167 krnRunIRQHandlers(KernelBase, irq);
168 processed |= (1 << (irq - (2 << 5)));
172 else
174 processed = IRQ_BANK1;
176 if (processed) *((volatile unsigned int *)(ARMIRQ_PEND)) = (pending & ~processed);
178 pending = *((volatile unsigned int *)(GPUIRQ_PEND0));
179 DIRQ(bug("[KRN] Pending0 %08x\n", pending));
180 if (!(pending & IRQ_BANK2))
182 processed = 0;
183 for (irq = (0 << 5); irq < ((0 << 5) + 32); irq++)
185 if (pending & (1 << (irq - (0 << 5))))
187 DIRQ(bug("[KRN] Handling IRQ %d ..\n", irq));
188 krnRunIRQHandlers(KernelBase, irq);
189 processed |= (1 << (irq - (0 << 5)));
193 else
195 processed = IRQ_BANK2;
197 if (processed) *((volatile unsigned int *)(GPUIRQ_PEND0)) = (pending & ~processed);
199 pending = *((volatile unsigned int *)(GPUIRQ_PEND1));
200 DIRQ(bug("[KRN] Pending1 %08x\n", pending));
201 processed = 0;
202 for (irq = (1 << 5); irq < ((1 << 5) + 32); irq++)
204 if (pending & (1 << (irq - (1 << 5))))
206 DIRQ(bug("[KRN] Handling IRQ %d ..\n", irq));
207 krnRunIRQHandlers(KernelBase, irq);
208 processed |= (1 << (irq - (1 << 5)));
211 if (processed) *((volatile unsigned int *)(GPUIRQ_PEND1)) = (pending & ~processed);
213 DIRQ(bug("[KRN] IRQ processing finished\n"));
215 return;
218 /* ** FIQ HANDLER ** */
220 __attribute__ ((interrupt ("FIQ"))) void __vectorhand_fiq(void)
222 DIRQ(bug("[KRN] ## FIQ ##\n"));
224 return;
228 /* ** DATA ABORT EXCEPTION ** */
230 asm (
231 ".set MODE_SYSTEM, 0x1f \n"
233 ".globl __vectorhand_dataabort \n"
234 ".type __vectorhand_dataabort,%function \n"
235 "__vectorhand_dataabort: \n"
236 VECTCOMMON_START
237 " cpsid i, #MODE_SYSTEM \n" // switch to system mode, with interrupts disabled..
238 " str sp, [r0, #13*4] \n"
239 " str lr, [r0, #14*4] \n" // store lr in ctx_lr
240 " mov fp, #0 \n" // clear fp
242 " bl handle_dataabort \n"
244 VECTCOMMON_END
247 void handle_dataabort(regs_t *regs)
249 register unsigned int far;
251 // Read fault address register
252 asm volatile("mrc p15, 0, %[far], c6, c0, 0": [far] "=r" (far) );
254 bug("[Kernel] Trap ARM Data Abort Exception -> Exception #2 (Bus Error)\n");
255 bug("[Kernel] attempt to access 0x%p\n", far);
257 if (krnRunExceptionHandlers(KernelBase, 2, regs))
258 return;
260 if (core_Trap(2, regs))
262 bug("[Kernel] Trap handler returned\n");
263 return;
266 bug("[Kernel] UNHANDLED EXCEPTION #2\n");
268 while (1)
269 asm volatile ("mov r0, r0\n");
272 /* ** PREFETCH ABORT EXCEPTION ** */
274 asm (
275 ".set MODE_SYSTEM, 0x1f \n"
277 ".globl __vectorhand_prefetchabort \n"
278 ".type __vectorhand_prefetchabort,%function \n"
279 "__vectorhand_prefetchabort: \n"
280 VECTCOMMON_START
281 " cpsid i, #MODE_SYSTEM \n" // switch to system mode, with interrupts disabled..
282 " str sp, [r0, #13*4] \n"
283 " str lr, [r0, #14*4] \n" // store lr in ctx_lr
284 " mov fp, #0 \n" // clear fp
286 " bl handle_prefetchabort \n"
288 VECTCOMMON_END
291 void handle_prefetchabort(regs_t *regs)
293 bug("[Kernel] Trap ARM Prefetch Abort Exception -> Exception #3 (Address Error)\n");
295 if (krnRunExceptionHandlers(KernelBase, 3, regs))
296 return;
298 if (core_Trap(3, regs))
300 bug("[Kernel] Trap handler returned\n");
301 return;
304 bug("[Kernel] UNHANDLED EXCEPTION #3\n");
306 while (1)
307 asm volatile ("mov r0, r0\n");
311 /* ** SETUP ** */
313 /* linker exports */
314 extern void *__intvecs_start, *__intvecs_end;
316 void core_SetupIntr(void)
318 int irq;
319 bug("[KRN] Initializing cpu vectors\n");
321 /* Copy vectors into place */
322 memcpy(0, &__intvecs_start,
323 (unsigned int)&__intvecs_end -
324 (unsigned int)&__intvecs_start);
326 D(bug("[KRN] Copied %d bytes from 0x%p to 0x00000000\n", (unsigned int)&__intvecs_end - (unsigned int)&__intvecs_start, &__intvecs_start));
329 unsigned int x = 0;
330 bug("[KRN]: Vector dump-:");
331 for (x=0; x < (unsigned int)&__intvecs_end - (unsigned int)&__intvecs_start; x++) {
332 if ((x%16) == 0)
334 bug("\n[KRN]: %08x:", x);
336 bug(" %02x", *((volatile UBYTE *)x));
338 bug("\n");
341 D(bug("[KRN] Disabling IRQs\n"));
342 *(volatile unsigned int *)ARMIRQ_DIBL = ~0;
343 *(volatile unsigned int *)GPUIRQ_DIBL0 = ~0;
344 *(volatile unsigned int *)GPUIRQ_DIBL1 = ~0;