allocate enough storage for the page table! move cache invalidating and page table...
[AROS.git] / arch / arm-raspi / kernel / intr.c
blobbef9369ce22a9464b99d85fe10fe6a0cc203c47d
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 IRQBANK_POINTER(bank) ((bank == 0) ? GPUIRQ_ENBL0 : (bank == 1) ? GPUIRQ_ENBL1 : ARMIRQ_ENBL)
24 #define DREGS(x)
25 #define D(x)
27 void ictl_enable_irq(uint8_t irq, struct KernelBase *KernelBase)
29 int bank = IRQ_BANK(irq);
30 unsigned int val, reg;
32 reg = IRQBANK_POINTER(bank);
34 D(bug("[KRN] Enabling irq %d [bank %d, reg 0x%p]\n", irq, bank, reg));
35 val = *((volatile unsigned int *)reg);
36 val |= IRQ_MASK(irq);
37 *((volatile unsigned int *)reg) = val;
40 void ictl_disable_irq(uint8_t irq, struct KernelBase *KernelBase)
42 int bank = IRQ_BANK(irq);
43 unsigned int val, reg;
45 reg = IRQBANK_POINTER(bank);
47 D(bug("[KRN] Dissabling irq %d [bank %d, reg 0x%p]\n", irq, bank, reg));
49 val = *((volatile unsigned int *)reg);
50 val |= IRQ_MASK(irq);
51 *((volatile unsigned int *)reg) = val;
54 void __vectorhand_undef(void)
56 register unsigned int addr;
58 *(volatile unsigned int *)GPSET0 = 1<<16; // LED OFF
60 asm volatile("mov %[addr], lr" : [addr] "=r" (addr) );
62 krnPanic(KernelBase, "CPU Unknown Instruction @ 0x%p", (addr - 4));
65 void __vectorhand_reset(void)
67 *(volatile unsigned int *)GPSET0 = 1<<16; // LED OFF
69 D(bug("[KRN] ## RESET ##\n"));
70 while(1)
72 asm("mov r0,r0\n\t");
74 return;
77 /** SWI handled in syscall.c */
79 asm (
80 ".set MODE_IRQ, 0x12 \n"
81 ".set MODE_SUPERVISOR, 0x13 \n"
82 ".set MODE_SYSTEM, 0x1f \n"
84 ".globl __vectorhand_irq \n"
85 ".type __vectorhand_irq,%function \n"
86 "__vectorhand_irq: \n"
87 " sub lr, lr, #4 \n" // adjust lr_irq
88 VECTCOMMON_START
89 " cpsid i, #MODE_SYSTEM \n" // switch to system mode, with interrupts disabled..
90 " str sp, [r0, #13*4] \n"
91 " str lr, [r0, #14*4] \n" // store lr in ctx_lr
92 " mov fp, #0 \n" // clear fp
94 " bl handle_irq \n"
96 " cpsid i, #MODE_IRQ \n" // switch to IRQ mode, with interrupts disabled..
97 " mov r0, sp \n"
98 " mov fp, #0 \n" // clear fp
99 " bl core_ExitInterrupt \n"
100 VECTCOMMON_END
103 #define IRQ_BANK1 0x00000100
104 #define IRQ_BANK2 0x00000200
106 void handle_irq(regs_t *regs)
108 unsigned int pending, processed, irq;
110 D(bug("[KRN] ## IRQ ##\n"));
112 DREGS(cpu_DumpRegs(regs));
114 pending = *((volatile unsigned int *)(ARMIRQ_PEND));
115 D(bug("[KRN] PendingARM %08x\n", pending));
116 if (!(pending & IRQ_BANK1))
118 processed = 0;
119 for (irq = (2 << 5); irq < ((2 << 5) + 32); irq++)
121 if (pending & (1 << (irq - (2 << 5))))
123 D(bug("[KRN] Handling IRQ %d ..\n", irq));
124 krnRunIRQHandlers(KernelBase, irq);
125 processed |= (1 << (irq - (2 << 5)));
129 else
131 processed = IRQ_BANK1;
133 if (processed) *((volatile unsigned int *)(ARMIRQ_PEND)) = (pending & ~processed);
135 pending = *((volatile unsigned int *)(GPUIRQ_PEND0));
136 D(bug("[KRN] Pending0 %08x\n", pending));
137 if (!(pending & IRQ_BANK2))
139 processed = 0;
140 for (irq = (0 << 5); irq < ((0 << 5) + 32); irq++)
142 if (pending & (1 << (irq - (0 << 5))))
144 D(bug("[KRN] Handling IRQ %d ..\n", irq));
145 krnRunIRQHandlers(KernelBase, irq);
146 processed |= (1 << (irq - (0 << 5)));
150 else
152 processed = IRQ_BANK2;
154 if (processed) *((volatile unsigned int *)(GPUIRQ_PEND0)) = (pending & ~processed);
156 pending = *((volatile unsigned int *)(GPUIRQ_PEND1));
157 D(bug("[KRN] Pending1 %08x\n", pending));
158 processed = 0;
159 for (irq = (1 << 5); irq < ((1 << 5) + 32); irq++)
161 if (pending & (1 << (irq - (1 << 5))))
163 D(bug("[KRN] Handling IRQ %d ..\n", irq));
164 krnRunIRQHandlers(KernelBase, irq);
165 processed |= (1 << (irq - (1 << 5)));
168 if (processed) *((volatile unsigned int *)(GPUIRQ_PEND1)) = (pending & ~processed);
170 D(bug("[KRN] IRQ processing finished\n"));
172 return;
175 __attribute__ ((interrupt ("FIQ"))) void __vectorhand_fiq(void)
177 *(volatile unsigned int *)GPSET0 = 1<<16; // LED OFF
179 D(bug("[KRN] ## FIQ ##\n"));
180 while(1)
182 asm("mov r0,r0\n\t");
186 #ifndef RASPI_VIRTMEMSUPPORT
187 __attribute__ ((interrupt ("ABORT"))) void __vectorhand_dataabort(void)
189 register unsigned int addr, far;
190 asm volatile("mov %[addr], lr" : [addr] "=r" (addr) );
191 /* Read fault address register */
192 asm volatile("mrc p15, 0, %[addr], c6, c0, 0": [addr] "=r" (far) );
194 *(volatile unsigned int *)GPSET0 = 1<<16; // LED OFF
196 /* Routine terminates by returning to LR-4, which is the instruction
197 * after the aborted one
198 * GCC doesn't properly deal with data aborts in its interrupt
199 * handling - no option to return to the failed instruction
201 krnPanic(KernelBase, "CPU Data Abort @ 0x%p, fault address: 0x%p", (addr - 4), far);
204 /* Return to this function after a prefetch abort */
205 __attribute__ ((interrupt ("ABORT"))) void __vectorhand_prefetchabort(void)
207 register unsigned int addr;
208 asm volatile("mov %[addr], lr" : [addr] "=r" (addr) );
210 *(volatile unsigned int *)GPSET0 = 1<<16; // LED OFF
212 krnPanic(KernelBase, "CPU Prefetch Abort @ 0x%p", (addr - 4));
214 #else
215 #warning "TODO: Implement support for retrieving pages from medium, and reattempting access"
216 #endif
219 /* linker exports */
220 extern void *__intvecs_start, *__intvecs_end;
222 void core_SetupIntr(void)
224 int irq;
225 bug("[KRN] Initializing cpu vectors\n");
227 /* Copy vectors into place */
228 memcpy(0, &__intvecs_start,
229 (unsigned int)&__intvecs_end -
230 (unsigned int)&__intvecs_start);
232 D(bug("[KRN] Copied %d bytes from 0x%p to 0x00000000\n", (unsigned int)&__intvecs_end - (unsigned int)&__intvecs_start, &__intvecs_start));
235 unsigned int x = 0;
236 bug("[KRN]: Vector dump-:");
237 for (x=0; x < (unsigned int)&__intvecs_end - (unsigned int)&__intvecs_start; x++) {
238 if ((x%16) == 0)
240 bug("\n[KRN]: %08x:", x);
242 bug(" %02x", *((volatile UBYTE *)x));
244 bug("\n");
247 D(bug("[KRN] Disabling IRQs\n"));
248 *(volatile unsigned int *)ARMIRQ_DIBL = ~0;
249 *(volatile unsigned int *)GPUIRQ_DIBL0 = ~0;
250 *(volatile unsigned int *)GPUIRQ_DIBL1 = ~0;