Support dynamic ARM_PERIIOBASE as requred by rpi2
[AROS.git] / arch / arm-raspi / kernel / intr.c
blobac63302b15f3cdeb8b8da0c328f96ff3d6c4079a
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 #undef ARM_PERIIOBASE
23 extern uint32_t __arm_periiobase;
24 #define ARM_PERIIOBASE (__arm_periiobase)
26 #define BOOT_STACK_SIZE (256 << 2)
27 #define BOOT_TAGS_SIZE (128 << 3)
29 #define IRQBANK_POINTER(bank) ((bank == 0) ? GPUIRQ_ENBL0 : (bank == 1) ? GPUIRQ_ENBL1 : ARMIRQ_ENBL)
31 #define DREGS(x)
32 #define DIRQ(x)
33 #define D(x)
35 void ictl_enable_irq(uint8_t irq, struct KernelBase *KernelBase)
37 int bank = IRQ_BANK(irq);
38 unsigned int val, reg;
40 reg = IRQBANK_POINTER(bank);
42 DIRQ(bug("[KRN] Enabling irq %d [bank %d, reg 0x%p]\n", irq, bank, reg));
44 val = *((volatile unsigned int *)reg);
45 val |= IRQ_MASK(irq);
46 *((volatile unsigned int *)reg) = val;
49 void ictl_disable_irq(uint8_t irq, struct KernelBase *KernelBase)
51 int bank = IRQ_BANK(irq);
52 unsigned int val, reg;
54 reg = IRQBANK_POINTER(bank);
56 DIRQ(bug("[KRN] Dissabling irq %d [bank %d, reg 0x%p]\n", irq, bank, reg));
58 val = *((volatile unsigned int *)reg);
59 val |= IRQ_MASK(irq);
60 *((volatile unsigned int *)reg) = val;
64 ** UNDEF INSTRUCTION EXCEPTION
65 return addr = lr
66 entered in UND mode.
69 asm (
70 ".set MODE_SYSTEM, 0x1f \n"
72 ".globl __vectorhand_undef \n"
73 ".type __vectorhand_undef,%function \n"
74 "__vectorhand_undef: \n"
75 VECTCOMMON_START
76 " cpsid i, #" STR(MODE_SYSTEM)"\n" // switch to system mode, with interrupts disabled..
77 " str sp, [r0, #13*4] \n"
78 " str lr, [r0, #14*4] \n" // store lr in ctx_lr
79 " mov fp, #0 \n" // clear fp
81 " bl handle_undef \n"
83 VECTCOMMON_END
86 void handle_undef(regs_t *regs)
88 bug("[Kernel] Trap ARM Undef Exception -> Exception #4 (Illegal instruction)\n");
90 if (krnRunExceptionHandlers(KernelBase, 4, regs))
91 return;
93 if (core_Trap(4, regs))
95 bug("[Kernel] Trap handler returned\n");
96 return;
99 bug("[Kernel] UNHANDLED EXCEPTION #4\n");
101 while (1)
102 asm volatile ("mov r0, r0\n");
106 ** RESET HANDLER
107 no return address,
108 entered in SVC mode.
111 asm (
112 ".globl __vectorhand_reset \n"
113 ".type __vectorhand_reset,%function \n"
114 "__vectorhand_reset: \n"
115 " mov sp, #0x1000 - 16 \n" // re-use bootstrap tmp stack
116 " mov r0, sp \n"
117 " sub r0, r0, #" STR(BOOT_STACK_SIZE)"\n" // get the boottag's
118 " sub r0, r0, #" STR(BOOT_TAGS_SIZE) "\n"
119 " mov fp, #0 \n" // clear fp
121 " ldr pc, 2f \n" // jump into kernel resource
122 "1: b 1b \n"
123 "2: .word kernel_cstart \n"
128 /* ** SWI HANDLER ** */
130 /** SWI handled in syscall.c */
133 ** IRQ HANDLER
134 return address = lr - 4
135 entered in IRQ mode.
138 asm (
139 ".set MODE_IRQ, 0x12 \n"
140 ".set MODE_SUPERVISOR, 0x13 \n"
141 ".set MODE_SYSTEM, 0x1f \n"
143 ".globl __vectorhand_irq \n"
144 ".type __vectorhand_irq,%function \n"
145 "__vectorhand_irq: \n"
146 " sub lr, lr, #4 \n" // adjust lr_irq
147 VECTCOMMON_START
148 " cpsid i, #MODE_SYSTEM \n" // switch to system mode, with interrupts disabled..
149 " str sp, [r0, #13*4] \n"
150 " str lr, [r0, #14*4] \n" // store lr in ctx_lr
151 " mov fp, #0 \n" // clear fp
153 " bl handle_irq \n"
155 " cpsid i, #MODE_IRQ \n" // switch to IRQ mode, with interrupts disabled..
156 " mov r0, sp \n"
157 " mov fp, #0 \n" // clear fp
158 " bl core_ExitInterrupt \n"
159 VECTCOMMON_END
162 #define IRQ_BANK1 0x00000100
163 #define IRQ_BANK2 0x00000200
165 void handle_irq(regs_t *regs)
167 unsigned int pending, processed, irq;
169 DIRQ(bug("[KRN] ## IRQ ##\n"));
171 DREGS(cpu_DumpRegs(regs));
173 pending = *((volatile unsigned int *)(ARMIRQ_PEND));
174 DIRQ(bug("[KRN] PendingARM %08x\n", pending));
175 if (!(pending & IRQ_BANK1))
177 processed = 0;
178 for (irq = (2 << 5); irq < ((2 << 5) + 32); irq++)
180 if (pending & (1 << (irq - (2 << 5))))
182 DIRQ(bug("[KRN] Handling IRQ %d ..\n", irq));
183 krnRunIRQHandlers(KernelBase, irq);
184 processed |= (1 << (irq - (2 << 5)));
188 else
190 processed = IRQ_BANK1;
192 if (processed) *((volatile unsigned int *)(ARMIRQ_PEND)) = (pending & ~processed);
194 pending = *((volatile unsigned int *)(GPUIRQ_PEND0));
195 DIRQ(bug("[KRN] Pending0 %08x\n", pending));
196 if (!(pending & IRQ_BANK2))
198 processed = 0;
199 for (irq = (0 << 5); irq < ((0 << 5) + 32); irq++)
201 if (pending & (1 << (irq - (0 << 5))))
203 DIRQ(bug("[KRN] Handling IRQ %d ..\n", irq));
204 krnRunIRQHandlers(KernelBase, irq);
205 processed |= (1 << (irq - (0 << 5)));
209 else
211 processed = IRQ_BANK2;
213 if (processed) *((volatile unsigned int *)(GPUIRQ_PEND0)) = (pending & ~processed);
215 pending = *((volatile unsigned int *)(GPUIRQ_PEND1));
216 DIRQ(bug("[KRN] Pending1 %08x\n", pending));
217 processed = 0;
218 for (irq = (1 << 5); irq < ((1 << 5) + 32); irq++)
220 if (pending & (1 << (irq - (1 << 5))))
222 DIRQ(bug("[KRN] Handling IRQ %d ..\n", irq));
223 krnRunIRQHandlers(KernelBase, irq);
224 processed |= (1 << (irq - (1 << 5)));
227 if (processed) *((volatile unsigned int *)(GPUIRQ_PEND1)) = (pending & ~processed);
229 DIRQ(bug("[KRN] IRQ processing finished\n"));
231 return;
235 ** FIQ HANDLER
236 return address = lr -4
237 entered in FIQ mode.
240 __attribute__ ((interrupt ("FIQ"))) void __vectorhand_fiq(void)
242 DIRQ(bug("[KRN] ## FIQ ##\n"));
244 return;
249 ** DATA ABORT EXCEPTION
250 return address = lr - 8
251 entered in ABT mode.
254 asm (
255 ".set MODE_SYSTEM, 0x1f \n"
257 ".globl __vectorhand_dataabort \n"
258 ".type __vectorhand_dataabort,%function \n"
259 "__vectorhand_dataabort: \n"
260 " sub lr, lr, #8 \n" // adjust lr_irq
261 VECTCOMMON_START
262 " cpsid i, #MODE_SYSTEM \n" // switch to system mode, with interrupts disabled..
263 " str sp, [r0, #13*4] \n"
264 " str lr, [r0, #14*4] \n" // store lr in ctx_lr
265 " mov fp, #0 \n" // clear fp
267 " bl handle_dataabort \n"
269 VECTCOMMON_END
272 void handle_dataabort(regs_t *regs)
274 register unsigned int far;
276 // Read fault address register
277 asm volatile("mrc p15, 0, %[far], c6, c0, 0": [far] "=r" (far) );
279 bug("[Kernel] Trap ARM Data Abort Exception -> Exception #2 (Bus Error)\n");
280 bug("[Kernel] attempt to access 0x%p\n", far);
282 if (krnRunExceptionHandlers(KernelBase, 2, regs))
283 return;
285 if (core_Trap(2, regs))
287 bug("[Kernel] Trap handler returned\n");
288 return;
291 bug("[Kernel] UNHANDLED EXCEPTION #2\n");
293 while (1)
294 asm volatile ("mov r0, r0\n");
298 ** PREFETCH ABORT EXCEPTION
299 return address = lr - 4
300 entered in ABT mode.
303 asm (
304 ".set MODE_SYSTEM, 0x1f \n"
306 ".globl __vectorhand_prefetchabort \n"
307 ".type __vectorhand_prefetchabort,%function \n"
308 "__vectorhand_prefetchabort: \n"
309 " sub lr, lr, #4 \n" // adjust lr_irq
310 VECTCOMMON_START
311 " cpsid i, #MODE_SYSTEM \n" // switch to system mode, with interrupts disabled..
312 " str sp, [r0, #13*4] \n"
313 " str lr, [r0, #14*4] \n" // store lr in ctx_lr
314 " mov fp, #0 \n" // clear fp
316 " bl handle_prefetchabort \n"
318 VECTCOMMON_END
321 void handle_prefetchabort(regs_t *regs)
323 bug("[Kernel] Trap ARM Prefetch Abort Exception -> Exception #3 (Address Error)\n");
325 if (krnRunExceptionHandlers(KernelBase, 3, regs))
326 return;
328 if (core_Trap(3, regs))
330 bug("[Kernel] Trap handler returned\n");
331 return;
334 bug("[Kernel] UNHANDLED EXCEPTION #3\n");
336 while (1)
337 asm volatile ("mov r0, r0\n");
341 /* ** SETUP ** */
343 /* linker exports */
344 extern void *__intvecs_start, *__intvecs_end;
346 void core_SetupIntr(void)
348 int irq;
349 bug("[KRN] Initializing cpu vectors\n");
351 /* Copy vectors into place */
352 memcpy(0, &__intvecs_start,
353 (unsigned int)&__intvecs_end -
354 (unsigned int)&__intvecs_start);
356 D(bug("[KRN] Copied %d bytes from 0x%p to 0x00000000\n", (unsigned int)&__intvecs_end - (unsigned int)&__intvecs_start, &__intvecs_start));
359 unsigned int x = 0;
360 bug("[KRN]: Vector dump-:");
361 for (x=0; x < (unsigned int)&__intvecs_end - (unsigned int)&__intvecs_start; x++) {
362 if ((x%16) == 0)
364 bug("\n[KRN]: %08x:", x);
366 bug(" %02x", *((volatile UBYTE *)x));
368 bug("\n");
371 D(bug("[KRN] Disabling IRQs\n"));
372 *(volatile unsigned int *)ARMIRQ_DIBL = ~0;
373 *(volatile unsigned int *)GPUIRQ_DIBL0 = ~0;
374 *(volatile unsigned int *)GPUIRQ_DIBL1 = ~0;