2 Copyright � 2013-2015, The AROS Development Team. All rights reserved.
7 #include <aros/kernel.h>
8 #include <aros/libcall.h>
9 #include <hardware/intbits.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)
30 extern void *__intvecs_start
, *__intvecs_end
;
31 extern void __arm_halt(void);
33 void ictl_enable_irq(uint8_t irq
, struct KernelBase
*KernelBase
)
35 if (__arm_arosintern
.ARMI_IRQEnable
)
36 __arm_arosintern
.ARMI_IRQEnable(irq
);
39 void ictl_disable_irq(uint8_t irq
, struct KernelBase
*KernelBase
)
41 if (__arm_arosintern
.ARMI_IRQDisable
)
42 __arm_arosintern
.ARMI_IRQDisable(irq
);
46 ".globl __arm_halt \n"
47 ".type __arm_halt,%function \n"
53 ** UNDEF INSTRUCTION EXCEPTION
59 ".set MODE_SYSTEM, 0x1f \n"
61 ".globl __vectorhand_undef \n"
62 ".type __vectorhand_undef,%function \n"
63 "__vectorhand_undef: \n"
69 void handle_undef(regs_t
*regs
)
71 bug("[Kernel] Trap ARM Undef Exception\n");
72 bug("[Kernel] exception #4 (Illegal instruction)\n");
73 bug("[Kernel] at 0x%p\n", regs
->pc
);
75 if (krnRunExceptionHandlers(KernelBase
, 4, regs
))
78 D(bug("[Kernel] exception handler(s) returned\n"));
80 if (core_Trap(4, regs
))
82 D(bug("[Kernel] trap handler(s) returned\n"));
86 bug("[Kernel] UNHANDLED EXCEPTION #4\n");
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 " sub r0, sp, #" STR(BOOT_STACK_SIZE
)"\n" // get the boottag's
105 " sub r0, r0, #" STR(BOOT_TAGS_SIZE
) "\n"
106 " mov fp, #0 \n" // clear fp
108 " ldr pc, 2f \n" // jump into kernel resource
110 "2: .word kernel_cstart \n"
114 /* ** SWI HANDLER ** */
116 /** SWI handled in syscall.c */
120 return address = lr - 4
125 ".set MODE_IRQ, 0x12 \n"
126 ".set MODE_SUPERVISOR, 0x13 \n"
127 ".set MODE_SYSTEM, 0x1f \n"
129 ".globl __vectorhand_irq \n"
130 ".type __vectorhand_irq,%function \n"
131 "__vectorhand_irq: \n"
132 " sub lr, lr, #4 \n" // adjust lr_irq
136 " ldr r1, [r0, #16*4] \n" // load the spr register
137 " and r1, r1, #31 \n" // mask processor mode
138 " cmp r1, #0x10 \n" // will we go back to user mode?
139 " cmpne r1, #0x1f \n" // or system mode (falls we use it)
140 " bne 1f \n" // no? don't call core_ExitInterrupt!
141 " mov fp, #0 \n" // clear fp
142 " bl core_ExitInterrupt \n"
147 void handle_irq(regs_t
*regs
)
149 DIRQ(bug("[KRN] ## IRQ ##\n"));
151 DREGS(cpu_DumpRegs(regs
));
153 if (__arm_arosintern
.ARMI_IRQProcess
)
154 __arm_arosintern
.ARMI_IRQProcess();
156 DIRQ(bug("[KRN] IRQ processing finished\n"));
163 return address = lr -4
167 __attribute__ ((interrupt ("FIQ"))) void __vectorhand_fiq(void)
169 DIRQ(bug("[KRN] ## FIQ ##\n"));
171 if (__arm_arosintern
.ARMI_FIQProcess
)
172 __arm_arosintern
.ARMI_FIQProcess();
174 DIRQ(bug("[KRN] FIQ processing finished\n"));
180 ** DATA ABORT EXCEPTION
181 return address = lr - 8
186 ".set MODE_SYSTEM, 0x1f \n"
188 ".globl __vectorhand_dataabort \n"
189 ".type __vectorhand_dataabort,%function \n"
190 "__vectorhand_dataabort: \n"
191 " sub lr, lr, #8 \n" // adjust lr_irq
193 " bl handle_dataabort \n"
197 void handle_dataabort(regs_t
*regs
)
199 register unsigned int far
;
201 // Read fault address register
202 asm volatile("mrc p15, 0, %[far], c6, c0, 0": [far
] "=r" (far
) );
204 bug("[Kernel] Trap ARM Data Abort Exception\n");
205 bug("[Kernel] exception #2 (Bus Error)\n");
206 bug("[Kernel] attempt to access 0x%p from 0x%p\n", far
, regs
->pc
);
210 if (krnRunExceptionHandlers(KernelBase
, 2, regs
))
213 D(bug("[Kernel] exception handler(s) returned\n"));
215 if (core_Trap(2, regs
))
217 D(bug("[Kernel] trap handler(s) returned\n"));
221 bug("[Kernel] UNHANDLED EXCEPTION #2\n");
229 ** PREFETCH ABORT EXCEPTION
230 return address = lr - 4
235 ".set MODE_SYSTEM, 0x1f \n"
237 ".globl __vectorhand_prefetchabort \n"
238 ".type __vectorhand_prefetchabort,%function \n"
239 "__vectorhand_prefetchabort: \n"
240 " sub lr, lr, #4 \n" // adjust lr_irq
243 " bl handle_prefetchabort \n"
248 void handle_prefetchabort(regs_t
*regs
)
250 bug("[Kernel] Trap ARM Prefetch Abort Exception\n");
251 bug("[Kernel] exception #3 (Address Error)\n");
252 bug("[Kernel] at 0x%p\n", regs
->pc
);
256 if (krnRunExceptionHandlers(KernelBase
, 3, regs
))
259 D(bug("[Kernel] exception handler(s) returned\n"));
261 if (core_Trap(3, regs
))
263 D(bug("[Kernel] trap handler(s) returned\n"));
267 bug("[Kernel] UNHANDLED EXCEPTION #3\n");
277 void arm_flush_cache(uint32_t addr
, uint32_t length
)
281 __asm__
__volatile__("mcr p15, 0, %0, c7, c14, 1"::"r"(addr
));
285 __asm__
__volatile__("mcr p15, 0, %0, c7, c10, 4"::"r"(addr
));
288 void arm_icache_invalidate(uint32_t addr
, uint32_t length
)
292 __asm__
__volatile__("mcr p15, 0, %0, c7, c5, 1"::"r"(addr
));
296 __asm__
__volatile__("mcr p15, 0, %0, c7, c10, 4"::"r"(addr
));
299 void core_SetupIntr(void)
302 bug("[KRN] Initializing cpu vectors\n");
304 /* Copy vectors into place */
305 memcpy(0, &__intvecs_start
,
306 (unsigned int)&__intvecs_end
-
307 (unsigned int)&__intvecs_start
);
309 arm_flush_cache(0, 1024);
310 arm_icache_invalidate(0, 1024);
312 D(bug("[KRN] Copied %d bytes from 0x%p to 0x00000000\n", (unsigned int)&__intvecs_end
- (unsigned int)&__intvecs_start
, &__intvecs_start
));
316 bug("[KRN]: Vector dump-:");
317 for (x
=0; x
< (unsigned int)&__intvecs_end
- (unsigned int)&__intvecs_start
; x
++) {
320 bug("\n[KRN]: %08x:", x
);
322 bug(" %02x", *((volatile UBYTE
*)x
));
327 if (__arm_arosintern
.ARMI_IRQInit
)
328 __arm_arosintern
.ARMI_IRQInit();