2 Copyright © 2013, The AROS Development Team. All rights reserved.
9 #include <aros/kernel.h>
10 #include <aros/libcall.h>
14 #include <proto/exec.h>
15 #include <proto/kernel.h>
17 #include "kernel_cpu.h"
18 #include "kernel_intern.h"
19 #include "kernel_scheduler.h"
21 #include "kernel_syscall.h"
23 extern char * __text_start
;
24 extern char * __text_end
;
30 /* r0 = passed to function, r1/r2 = temp */
31 asm (".globl __intrhand_swi\n\t"
32 ".type __intrhand_swi,%function\n"
34 " sub sp, sp, #3*4 \n" // make space to store spsr, stack pointer and link register
35 " stmfd sp!, {r0-r12} \n" // store registers to pass to c handler ..
36 " str lr, [sp, #14*4] \n"
37 " mrs r2, spsr \n" // store spsr above registers
38 " str r2, [sp, #15*4] \n"
39 " mov r0, sp \n" // r0 = registers r0-r12 on the stack
41 " add r1, r1, #16*4 \n" // r1 = orig (callers) stack pointer
42 " str r1, [sp, #13*4] \n"
43 " ldr r1, [sp, #1*4] \n" // restore r1 ..
44 " ldr r2, [sp, #2*4] \n" // .. and r2 ..
45 " mov fp, #0 \n" // clear fp(??)
46 " bl handle_syscall \n"
47 " ldr lr, [sp, #14*4] \n" // restore lr
48 " ldr r2, [sp, #15*4] \n" // restore spsr
50 " ldmfd sp!, {r0-r12} \n" // restore registers
51 " add sp, sp, #12 \n" // correct the stack pointer ..
52 " movs pc, lr \n" // ..and return
55 void core_Cause(unsigned char n
, unsigned int mask
)
57 D(bug("[KRN] core_Cause(%d, %08x)", n
, mask
));
61 struct IntVector
*iv
= &SysBase
->IntVects
[n
];
63 /* If the SoftInt vector in SysBase is set, call it. It will do the rest for us */
65 AROS_INTC3(iv
->iv_Code
, iv
->iv_Data
, mask
, _CUSTOM
);
69 void handle_syscall(void *regs
)
71 register unsigned int addr
;
72 register unsigned int swi_no
;
73 struct ExceptionContext
*ctx
;
74 struct Task
*thisTask
;
76 /* We determine the SWI number by reading in the return address
77 from the link register, subtract the instruction from it and
78 obtain the value from there. we also use this to check if
79 we have been called from outwith the kernel's code (illegal!)
82 addr
= ((uint32_t *)regs
)[14];
84 swi_no
= *((unsigned int *)addr
) & 0x00ffffff;
86 D(bug("[KRN] ## SWI %d @ 0x%p\n", swi_no
, addr
));
88 if (((char*)addr
< &__text_start
) || ((char*)addr
>= &__text_end
))
90 D(bug("[KRN] ## SWI : ILLEGAL ACCESS!\n"));
93 if (swi_no
<= 0x0a || swi_no
== 0x100)
95 if ((thisTask
= SysBase
->ThisTask
) != NULL
)
97 D(bug("[KRN] SWI invoked in '%s'", thisTask
->tc_Node
.ln_Name
));
98 if ((ctx
= thisTask
->tc_UnionETask
.tc_ETask
->et_RegFrame
) != NULL
)
102 D(bug(", ExceptionContext @ 0x%p\n", ctx
));
103 for (i
= 0; i
< 12; i
++)
105 ctx
->r
[i
] = ((uint32_t *)regs
)[i
];
106 D(bug("[KRN] r%02d: 0x%08x\n", i
, ctx
->r
[i
]));
108 ctx
->ip
= ((uint32_t *)regs
)[12];
109 D(bug("[KRN] (ip) r12: 0x%08x\n", ctx
->ip
));
110 ctx
->sp
= ((uint32_t *)regs
)[13];
111 D(bug("[KRN] (sp) r13: 0x%08x\n", ctx
->sp
));
112 ctx
->lr
= ((uint32_t *)regs
)[14];
113 D(bug("[KRN] (lr) r14: 0x%08x\n", ctx
->lr
));
114 ctx
->cpsr
= ((uint32_t *)regs
)[15];;
115 D(bug("[KRN] cpsr: 0x%08x", ctx
->cpsr
));
116 thisTask
->tc_SPReg
= ctx
->sp
;
125 D(bug("[KRN] ## CLI...\n"));
131 D(bug("[KRN] ## STI...\n"));
137 D(bug("[KRN] ## SUPERSTATE...\n"));
141 case SC_ISSUPERSTATE
:
143 D(bug("[KRN] ## ISSUPERSTATE...\n"));
149 D(bug("[KRN] ## CAUSE...\n"));
150 //core_Cause(SysBase);
156 D(bug("[KRN] ## DISPATCH...\n"));
163 D(bug("[KRN] ## SWITCH...\n"));
170 D(bug("[KRN] ## SCHEDULE...\n"));
187 D(bug("[KRN] ## REBOOT...\n"));
188 asm volatile ("mov pc, #0\n"); // Jump to the reset vector..
195 D(bug("[KRN] ## SWI : ILLEGAL SWI!\n"));
199 D(bug("[KRN] ## SWI returning ..\n"));