revert between 56095 -> 55830 in arch
[AROS.git] / arch / ppc-chrp / efika / kernel / syscall.c
blob24659bb1122546cc093f93502bbc743610886488
1 /*
2 Copyright © 2008-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <asm/mpc5200b.h>
7 #include <aros/kernel.h>
8 #include <utility/tagitem.h>
9 #include "kernel_intern.h"
10 #include "syscall.h"
12 extern char * __text_start;
13 extern char * __text_end;
14 extern struct TagItem *BootMsg;
16 void __attribute__((noreturn)) syscall_handler(regs_t *ctx, uint8_t exception, void *self)
18 struct KernelBase *KernelBase = getKernelBase();
19 int cause = 0;
21 //D(bug("[KRN] SysCall handler. context @ %p SC=%d\n", ctx, ctx->gpr[3]));
23 if ((char*)ctx->srr0 < &__text_start || (char*)ctx->srr0 >= &__text_end)
25 D(bug("[KRN] ERROR ERROR! SysCall issued directly outside kernel.resource!!!!!\n"));
26 core_LeaveInterrupt(ctx);
29 switch (ctx->gpr[3])
31 case SC_CLI:
32 ctx->srr1 &= ~MSR_EE;
33 break;
35 case SC_STI:
36 ctx->srr1 |= MSR_EE;
37 break;
39 case SC_SUPERSTATE:
40 ctx->gpr[3] = ctx->srr1;
41 ctx->srr1 &= ~MSR_PR;
42 break;
44 case SC_ISSUPERSTATE:
45 if (ctx->srr1 & MSR_PR)
46 ctx->gpr[3] = 0;
47 else
48 ctx->gpr[3] = 1;
49 break;
51 case SC_CAUSE:
52 // {
53 // struct ExecBase *SysBase = getSysBase();
54 // if (SysBase)
55 // core_Cause(SysBase);
56 // }
57 cause = 1;
58 break;
60 case SC_DISPATCH:
61 core_Dispatch(ctx);
62 break;
64 case SC_SWITCH:
65 core_Switch(ctx);
66 break;
68 case SC_SCHEDULE:
69 core_Schedule(ctx);
70 break;
72 case SC_RTAS:
73 ctx->gpr[3] = core_Rtas(ctx->gpr[4], ctx->gpr[5], ctx->gpr[6]);
74 break;
76 case SC_INVALIDATED:
78 char *start = (char*)((IPTR)ctx->gpr[4] & 0xffffffe0);
79 char *end = (char*)(((IPTR)ctx->gpr[4] + ctx->gpr[5] + 31) & 0xffffffe0);
80 char *ptr;
82 for (ptr = start; ptr < end; ptr +=32)
84 asm volatile("dcbi 0,%0"::"r"(ptr));
86 asm volatile("sync");
87 break;
90 case SC_REBOOT:
92 uint64_t newtbu = mftbu() + 132000000/4;
93 D(bug("[KRN] REBOOT..."));
94 while(newtbu > mftbu());
95 D(bug("3..."));
96 newtbu = mftbu() + 132000000/4;
97 while(newtbu > mftbu());
98 D(bug("2..."));
99 newtbu = mftbu() + 132000000/4;
100 while(newtbu > mftbu());
101 D(bug("1..."));
102 newtbu = mftbu() + 132000000/4;
103 while(newtbu > mftbu());
104 D(bug("\n\n\n"));
106 void (*restart)(struct TagItem *) = krnGetTagData(KRN_KernelBase, NULL, BootMsg);
107 restart(BootMsg);
108 break;
112 if (cause)
113 core_ExitInterrupt(ctx);
114 else
115 core_LeaveInterrupt(ctx);
118 static void __attribute__((used)) __rtas_entry_template()
120 asm volatile(".globl core_Rtas; .type core_Rtas,@function\n"
121 "core_Rtas: stwu %r1, -64(%r1)\n" /* Create proper stack frame */
122 " mflr %r0\n" /* Store the link pointer */
123 " stw %r0,68(%r1)\n"
124 " stw %r1,8(%r1)\n" /* Store the stack pointer for virtual space */
125 " stw %r3,12(%r1)\n" /* Store the rtas call structure */
126 " stw %r4,16(%r1)\n" /* Store the rtas base */
127 " stw %r5,20(%r1)\n" /* Store the entry address */
128 " mfmsr %r0\n"
129 " stw %r0,24(%r1)\n"
130 " lis %r0,virt2phys@ha\n" /* VirtualToPhysical function */
131 " ori %r0, %r0, virt2phys@l\n"
132 " mtctr %r0\n"
133 " stw %r0,28(%r1)\n"
134 " lis %r3,1f@ha\n" /* Get the return point from rtas */
135 " ori %r3, %r3, 1f@l\n"
136 " bctrl \n"
137 " stw %r3,32(%r1)\n"
138 " mr %r3, %r1\n" /* Convert the stack to physical address */
139 " lwz %r0,28(%r1)\n"
140 " mtctr %r0\n"
141 " bctrl \n"
142 " mtsprg2 %r3\n" /* And store it in sprg2 */
143 " lwz %r3,12(%r1)\n"
144 " lwz %r4,16(%r1)\n"
145 " lwz %r0,20(%r1)\n"
146 " mtsrr0 %r0\n"
147 " lwz %r0,32(%r1)\n"
148 " mtlr %r0\n"
149 " lwz %r0,24(%r1)\n"
150 " rlwinm %r0,%r0,0,28,25\n"
151 " mtsrr1 %r0\n"
152 " sync; isync;\n"
153 " rfi\n"
154 "1:\n"
155 " mfsprg2 %r5\n" /* We're back. Get the stack frame */
156 " lwz %r4,24(%r5)\n" /* Old msr */
157 " mtsrr1 %r4\n"
158 " lwz %r4,68(%r5)\n" /* Old link pointer */
159 " mtsrr0 %r4\n"
160 " addi %r1, %r1, 64\n"
161 " sync; isync; rfi\n"