2 Copyright © 2013, The AROS Development Team. All rights reserved.
7 #include <aros/kernel.h>
8 #include <aros/libcall.h>
10 #include <aros/arm/cpucontext.h>
15 #include <proto/exec.h>
16 #include <proto/kernel.h>
18 #include "kernel_cpu.h"
19 #include "kernel_intern.h"
20 #include "kernel_scheduler.h"
21 #include "kernel_intr.h"
22 #include "kernel_syscall.h"
24 extern char * __text_start
;
25 extern char * __text_end
;
37 this code currently assumes the caller is in user mode (and will break from any other mode)
39 r0 = passed to c handler, r1/r2 = temp
42 ".globl __vectorhand_swi \n"
43 ".type __vectorhand_swi,%function \n"
44 "__vectorhand_swi: \n"
46 " add r1, r0, #13*4 \n" // store sp^ in ctx_sp
48 " add r1, r0, #14*4 \n" // store lr^ in ctx_lr
50 " mov fp, #0 \n" // clear fp(??)
52 " bl handle_syscall \n"
56 void handle_syscall(void *regs
)
58 register unsigned int addr
;
59 register unsigned int swi_no
;
61 /* We determine the SWI number by reading in "tasks"
62 program counter, subtract the instruction from it and
63 obtain the value from there. we also use this to check if
64 we have been called from outwith the kernel's code (illegal!)
67 addr
= ((uint32_t *)regs
)[15];
69 swi_no
= *((unsigned int *)addr
) & 0x00ffffff;
71 D(bug("[KRN] ## SWI %d @ 0x%p\n", swi_no
, addr
));
73 if (((char*)addr
< &__text_start
) || ((char*)addr
>= &__text_end
))
75 D(bug("[KRN] ## SWI : ILLEGAL ACCESS!\n"));
78 if (swi_no
<= 0x0a || swi_no
== 0x100)
80 DREGS(cpu_DumpRegs(regs
));
86 D(bug("[KRN] ## CLI...\n"));
87 ((uint32_t *)regs
)[16] |= 0x80;
93 D(bug("[KRN] ## STI...\n"));
94 ((uint32_t *)regs
)[16] &= ~0x80;
100 D(bug("[KRN] ## SUPERSTATE... (0x%p ->", ((uint32_t *)regs
)[16]));
101 ((uint32_t *)regs
)[16] &= ~CPUMODE_MASK
;
102 ((uint32_t *)regs
)[16] |= (0x80 | CPUMODE_SUPERVISOR
);
103 D(bug(" 0x%p)\n", ((uint32_t *)regs
)[16]));
107 case SC_ISSUPERSTATE
:
109 D(bug("[KRN] ## ISSUPERSTATE... "));
110 ((uint32_t *)regs
)[0] = !(((((uint32_t *)regs
)[16] & CPUMODE_MASK
) == CPUMODE_USER
) || ((((uint32_t *)regs
)[16] & CPUMODE_MASK
) == CPUMODE_SYSTEM
));
111 D(bug("%d\n", ((uint32_t *)regs
)[0]));
117 D(bug("[KRN] ## REBOOT...\n"));
118 asm volatile ("mov pc, #0\n"); // Jump to the reset vector..
122 core_SysCall(swi_no
, regs
);
128 D(bug("[KRN] ## SWI : ILLEGAL SWI!\n"));
132 D(bug("[KRN] ## SWI returning ..\n"));