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