prism2.device: Compiler delint
[AROS.git] / arch / ppc-sam440 / kernel / syscall.c
bloba41fa8810bc908056faabee81d1eff448a96ff18
2 #include <aros/debug.h>
3 #include <asm/amcc440.h>
4 #include <asm/io.h>
6 #include LC_LIBDEFS_FILE
7 #include "kernel_intern.h"
8 #include "kernel_syscall.h"
9 #include "kernel_globals.h"
10 #include "kernel_scheduler.h"
11 #include "kernel_intr.h"
13 extern char * __text_start;
14 extern char * __text_end;
16 #define CFGADD(bus,dev,func,reg) \
17 ( 0x80000000 | ((bus)<<16) | \
18 ((dev)<<11) | ((func)<<8) | ((reg)&~3))
20 typedef union _pcicfg
22 uint32_t ul;
23 uint16_t uw[2];
24 uint8_t ub[4];
25 } pcicfg;
27 static uint32_t _read_config_long(int reg)
29 uint32_t temp;
30 outl_le(CFGADD(0, 0, 0, reg),PCI0_CFGADDR);
31 temp=inl_le(PCI0_CFGDATA);
32 return temp;
35 static uint16_t _read_config_word(int reg)
37 pcicfg temp;
39 temp.ul = _read_config_long(reg);
40 return temp.uw[1 - ((reg&2)>>1)];
43 static void _write_config_long(int reg, uint32_t val)
45 outl_le(CFGADD(0, 0, 0, reg),PCI0_CFGADDR);
46 outl_le(val,PCI0_CFGDATA);
49 static void _write_config_word(int reg, uint16_t val)
51 pcicfg temp;
53 temp.ul = _read_config_long(reg);
54 temp.uw[1 - ((reg&2)>>1)] = val;
55 _write_config_long(reg, temp.ul);
58 void syscall_handler(context_t *ctx, uint8_t exception)
60 struct KernelBase *KernelBase = getKernelBase();
62 D(bug("[KRN] SysCall: SRR0=%p, SRR1=%p, SC=%d\n", ctx->cpu.srr0, ctx->cpu.srr1, ctx->cpu.gpr[3]));
64 switch (ctx->cpu.gpr[3])
66 case SC_CLI:
67 /* Disable all external interrupts */
68 wrdcr(UIC0_ER, 0);
69 break;
71 case SC_STI:
72 /* Enable selected external interrupts */
73 wrdcr(UIC0_ER, uic_er[0]);
74 break;
76 case SC_IRQ_ENABLE:
77 uic_enable(ctx->cpu.gpr[4]);
78 break;
80 case SC_IRQ_DISABLE:
81 uic_disable(ctx->cpu.gpr[4]);
82 break;
84 case SC_SUPERSTATE:
85 ctx->cpu.gpr[3] = ctx->cpu.srr1;
86 ctx->cpu.srr1 &= ~MSR_PR;
87 break;
89 case SC_ISSUPERSTATE:
90 if (ctx->cpu.srr1 & MSR_PR)
91 ctx->cpu.gpr[3] = 0;
92 else
93 ctx->cpu.gpr[3] = 1;
94 break;
96 case SC_INVALIDATED:
98 char *start = (char*)((IPTR)ctx->cpu.gpr[4] & 0xffffffe0);
99 char *end = (char*)(((IPTR)ctx->cpu.gpr[4] + ctx->cpu.gpr[5] + 31) & 0xffffffe0);
100 char *ptr;
102 for (ptr = start; ptr < end; ptr +=32)
104 asm volatile("dcbi 0,%0"::"r"(ptr));
106 asm volatile("sync");
107 break;
110 case SC_REBOOT:
113 * Hard case on Sam440. First of all, the CPU has to be found on PCI bus.
114 * The PCI Bus reset signal will be issued there. Further, CPU returns from
115 * exception to address 0xfffffffc.
118 D(bug("[KRN] REBOOT..."));
120 D(bug("[KRN] LR=%08x", ctx->cpu.lr));
121 D(bug("[KRN] Backtrace:\n"));
122 uint32_t *sp = (uint32_t *)ctx->cpu.gpr[1];
123 while(*sp) {
124 sp = (uint32_t *)sp[0];
125 D(bug("[KRN] %08x\n", sp[1]));
128 uint64_t newtbu = mftbu() + KernelBase->kb_PlatformData->pd_OPBFreq;
129 while(newtbu > mftbu());
130 D(bug("3..."));
131 newtbu = mftbu() + KernelBase->kb_PlatformData->pd_OPBFreq;
132 while(newtbu > mftbu());
133 D(bug("2..."));
134 newtbu = mftbu() + KernelBase->kb_PlatformData->pd_OPBFreq;
135 while(newtbu > mftbu());
136 D(bug("1..."));
137 newtbu = mftbu() + KernelBase->kb_PlatformData->pd_OPBFreq;
138 while(newtbu > mftbu());
139 D(bug("\n\n\n"));
141 /* PCI Bridge options 2 register */
142 uint16_t val = _read_config_word(0x60);
143 /* Set the PCI reset signal */
144 _write_config_word(0x60, val | (1 << 12));
145 int i;
146 /* Let the PCI reset last as long as needed */
147 for (i=0; i < 100; i++)
148 asm volatile("sync");
149 /* De-assert the PCI reset */
150 _write_config_word(0x60, val & ~(1 << 12));
152 /* Restart CPU */
153 asm volatile("mtsrr0 %0; mtsrr1 %1; rfi"::"r"(0xfffffffc), "r"(1 << 6));
154 while(1);
156 default:
157 core_SysCall(ctx->cpu.gpr[3], ctx);
158 break;