2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
6 #include <aros/debug.h>
7 #include <asm/amcc440.h>
10 #include LC_LIBDEFS_FILE
11 #include "kernel_intern.h"
12 #include "kernel_syscall.h"
13 #include "kernel_globals.h"
14 #include "kernel_scheduler.h"
15 #include "kernel_intr.h"
17 extern char * __text_start
;
18 extern char * __text_end
;
20 #define CFGADD(bus,dev,func,reg) \
21 ( 0x80000000 | ((bus)<<16) | \
22 ((dev)<<11) | ((func)<<8) | ((reg)&~3))
31 static uint32_t _read_config_long(int reg
)
34 outl_le(CFGADD(0, 0, 0, reg
),PCI0_CFGADDR
);
35 temp
=inl_le(PCI0_CFGDATA
);
39 static uint16_t _read_config_word(int reg
)
43 temp
.ul
= _read_config_long(reg
);
44 return temp
.uw
[1 - ((reg
&2)>>1)];
47 static void _write_config_long(int reg
, uint32_t val
)
49 outl_le(CFGADD(0, 0, 0, reg
),PCI0_CFGADDR
);
50 outl_le(val
,PCI0_CFGDATA
);
53 static void _write_config_word(int reg
, uint16_t val
)
57 temp
.ul
= _read_config_long(reg
);
58 temp
.uw
[1 - ((reg
&2)>>1)] = val
;
59 _write_config_long(reg
, temp
.ul
);
62 void syscall_handler(context_t
*ctx
, uint8_t exception
)
64 struct KernelBase
*KernelBase
= getKernelBase();
66 D(bug("[KRN] SysCall: SRR0=%p, SRR1=%p, SC=%d\n", ctx
->cpu
.srr0
, ctx
->cpu
.srr1
, ctx
->cpu
.gpr
[3]));
68 switch (ctx
->cpu
.gpr
[3])
71 /* Disable all external interrupts */
76 /* Enable selected external interrupts */
77 wrdcr(UIC0_ER
, uic_er
[0]);
81 uic_enable(ctx
->cpu
.gpr
[4]);
85 uic_disable(ctx
->cpu
.gpr
[4]);
89 ctx
->cpu
.gpr
[3] = ctx
->cpu
.srr1
;
90 ctx
->cpu
.srr1
&= ~MSR_PR
;
94 if (ctx
->cpu
.srr1
& MSR_PR
)
102 char *start
= (char*)((IPTR
)ctx
->cpu
.gpr
[4] & 0xffffffe0);
103 char *end
= (char*)(((IPTR
)ctx
->cpu
.gpr
[4] + ctx
->cpu
.gpr
[5] + 31) & 0xffffffe0);
106 for (ptr
= start
; ptr
< end
; ptr
+=32)
108 asm volatile("dcbi 0,%0"::"r"(ptr
));
110 asm volatile("sync");
117 * Hard case on Sam440. First of all, the CPU has to be found on PCI bus.
118 * The PCI Bus reset signal will be issued there. Further, CPU returns from
119 * exception to address 0xfffffffc.
122 D(bug("[KRN] REBOOT..."));
124 D(bug("[KRN] LR=%08x", ctx
->cpu
.lr
));
125 D(bug("[KRN] Backtrace:\n"));
126 uint32_t *sp
= (uint32_t *)ctx
->cpu
.gpr
[1];
128 sp
= (uint32_t *)sp
[0];
129 D(bug("[KRN] %08x\n", sp
[1]));
132 uint64_t newtbu
= mftbu() + KernelBase
->kb_PlatformData
->pd_OPBFreq
;
133 while(newtbu
> mftbu());
135 newtbu
= mftbu() + KernelBase
->kb_PlatformData
->pd_OPBFreq
;
136 while(newtbu
> mftbu());
138 newtbu
= mftbu() + KernelBase
->kb_PlatformData
->pd_OPBFreq
;
139 while(newtbu
> mftbu());
141 newtbu
= mftbu() + KernelBase
->kb_PlatformData
->pd_OPBFreq
;
142 while(newtbu
> mftbu());
145 /* PCI Bridge options 2 register */
146 uint16_t val
= _read_config_word(0x60);
147 /* Set the PCI reset signal */
148 _write_config_word(0x60, val
| (1 << 12));
150 /* Let the PCI reset last as long as needed */
151 for (i
=0; i
< 100; i
++)
152 asm volatile("sync");
153 /* De-assert the PCI reset */
154 _write_config_word(0x60, val
& ~(1 << 12));
157 asm volatile("mtsrr0 %0; mtsrr1 %1; rfi"::"r"(0xfffffffc), "r"(1 << 6));
161 core_SysCall(ctx
->cpu
.gpr
[3], ctx
);