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 " bl handle_syscall \n"
50 void cache_clear_e(void *addr
, uint32_t length
, uint32_t flags
)
54 if (addr
== NULL
&& length
== 0xffffffff)
60 void *end_addr
= ((uintptr_t)addr
+ length
+ 31) & ~31;
61 addr
= (void *)((uintptr_t)addr
& ~31);
62 count
= (uintptr_t)(end_addr
- addr
) >> 5;
65 D(bug("[KRN] CacheClearE from %p length %d count %d, flags %x\n", addr
, length
, count
, flags
));
69 if (flags
& CACRF_ClearD
)
71 __asm__
__volatile__("mcr p15, 0, %0, c7, c14, 1"::"r"(addr
));
73 if (flags
& CACRF_ClearI
)
75 __asm__
__volatile__("mcr p15, 0, %0, c7, c5, 1"::"r"(addr
));
77 if (flags
& CACRF_InvalidateD
)
79 __asm__
__volatile__("mcr p15, 0, %0, c7, c6, 1"::"r"(addr
));
85 __asm__
__volatile__("mcr p15, 0, %0, c7, c10, 4"::"r"(addr
));
88 void handle_syscall(void *regs
)
90 register unsigned int addr
;
91 register unsigned int swi_no
;
93 /* We determine the SWI number by reading in "tasks"
94 program counter, subtract the instruction from it and
95 obtain the value from there. we also use this to check if
96 we have been called from outwith the kernel's code (illegal!)
99 addr
= ((uint32_t *)regs
)[15];
101 swi_no
= *((unsigned int *)addr
) & 0x00ffffff;
103 D(bug("[KRN] ## SWI %d @ 0x%p\n", swi_no
, addr
));
105 if (((char*)addr
< &__text_start
) || ((char*)addr
>= &__text_end
))
107 D(bug("[KRN] ## SWI : ILLEGAL ACCESS!\n"));
110 if (swi_no
<= 0x0b || swi_no
== 0x100)
112 DREGS(cpu_DumpRegs(regs
));
118 D(bug("[KRN] ## CLI...\n"));
119 ((uint32_t *)regs
)[16] |= 0x80;
125 D(bug("[KRN] ## STI...\n"));
126 ((uint32_t *)regs
)[16] &= ~0x80;
132 D(bug("[KRN] ## SUPERSTATE... (0x%p ->", ((uint32_t *)regs
)[16]));
133 ((uint32_t *)regs
)[16] &= ~CPUMODE_MASK
;
134 ((uint32_t *)regs
)[16] |= (0x80 | CPUMODE_SUPERVISOR
);
135 D(bug(" 0x%p)\n", ((uint32_t *)regs
)[16]));
139 case SC_ISSUPERSTATE
:
141 D(bug("[KRN] ## ISSUPERSTATE... "));
142 ((uint32_t *)regs
)[0] = !(((((uint32_t *)regs
)[16] & CPUMODE_MASK
) == CPUMODE_USER
) || ((((uint32_t *)regs
)[16] & CPUMODE_MASK
) == CPUMODE_SYSTEM
));
143 D(bug("%d\n", ((uint32_t *)regs
)[0]));
149 D(bug("[KRN] ## REBOOT...\n"));
150 asm volatile ("mov pc, #0\n"); // Jump to the reset vector..
156 D(bug("[KRN] ## CACHECLEARE...\n"));
157 void * address
= ((void **)regs
)[0];
158 uint32_t length
= ((uint32_t *)regs
)[1];
159 uint32_t flags
= ((uint32_t *)regs
)[2];
161 cache_clear_e(address
, length
, flags
);
167 * Execure core_SysCall only when we will go back to user mode. Default core_SysCall does
168 * not check this condition and could execute Cause() handler before IRQ is entirely handled.
172 uint32_t mode
= (((uint32_t *)regs
)[16]) & 0x1f;
173 if (mode
== 0x10 || mode
== 0x1f)
174 core_SysCall(swi_no
, regs
);
179 core_SysCall(swi_no
, regs
);
185 D(bug("[KRN] ## SWI : ILLEGAL SWI!\n"));
189 D(bug("[KRN] ## SWI returning ..\n"));