1*d6dfd9efSDavid du Colombier /*
2*d6dfd9efSDavid du Colombier * rae's virtex4 ml410 ppc405
3*d6dfd9efSDavid du Colombier */
4*d6dfd9efSDavid du Colombier
5*d6dfd9efSDavid du Colombier #include "u.h"
6*d6dfd9efSDavid du Colombier #include "../port/lib.h"
7*d6dfd9efSDavid du Colombier #include "mem.h"
8*d6dfd9efSDavid du Colombier #include "dat.h"
9*d6dfd9efSDavid du Colombier #include "fns.h"
10*d6dfd9efSDavid du Colombier
11*d6dfd9efSDavid du Colombier #include "io.h"
12*d6dfd9efSDavid du Colombier #include "../port/netif.h"
13*d6dfd9efSDavid du Colombier #include "etherif.h"
14*d6dfd9efSDavid du Colombier #include "../ip/ip.h"
15*d6dfd9efSDavid du Colombier
16*d6dfd9efSDavid du Colombier #include "reboot.h"
17*d6dfd9efSDavid du Colombier
18*d6dfd9efSDavid du Colombier typedef struct Gpioregs Gpioregs;
19*d6dfd9efSDavid du Colombier
20*d6dfd9efSDavid du Colombier struct Gpioregs {
21*d6dfd9efSDavid du Colombier ulong data; /* write only? */
22*d6dfd9efSDavid du Colombier ulong tri; /* tri-state */
23*d6dfd9efSDavid du Colombier ulong data2; /* 2nd channel */
24*d6dfd9efSDavid du Colombier ulong tri2;
25*d6dfd9efSDavid du Colombier
26*d6dfd9efSDavid du Colombier /* silly bits */
27*d6dfd9efSDavid du Colombier ulong pad[67]; /* sheesh */
28*d6dfd9efSDavid du Colombier ulong gie; /* global intr enable */
29*d6dfd9efSDavid du Colombier ulong ier; /* intr enable */
30*d6dfd9efSDavid du Colombier ulong isr; /* intr status */
31*d6dfd9efSDavid du Colombier };
32*d6dfd9efSDavid du Colombier
33*d6dfd9efSDavid du Colombier static void twinkle(void);
34*d6dfd9efSDavid du Colombier
35*d6dfd9efSDavid du Colombier void (*archclocktick)(void) = twinkle;
36*d6dfd9efSDavid du Colombier /* ether= for sys=torment */
37*d6dfd9efSDavid du Colombier uchar mymac[Eaddrlen] = { 0x00, 0x0A, 0x35, 0x01, 0x8B, 0xB1 };
38*d6dfd9efSDavid du Colombier uintptr memsz;
39*d6dfd9efSDavid du Colombier
40*d6dfd9efSDavid du Colombier void
startcpu(int)41*d6dfd9efSDavid du Colombier startcpu(int)
42*d6dfd9efSDavid du Colombier {
43*d6dfd9efSDavid du Colombier for (;;)
44*d6dfd9efSDavid du Colombier ;
45*d6dfd9efSDavid du Colombier }
46*d6dfd9efSDavid du Colombier
47*d6dfd9efSDavid du Colombier void
uncinit(void)48*d6dfd9efSDavid du Colombier uncinit(void)
49*d6dfd9efSDavid du Colombier {
50*d6dfd9efSDavid du Colombier }
51*d6dfd9efSDavid du Colombier
52*d6dfd9efSDavid du Colombier void
archreset(void)53*d6dfd9efSDavid du Colombier archreset(void)
54*d6dfd9efSDavid du Colombier {
55*d6dfd9efSDavid du Colombier m->cpuhz = 300000000;
56*d6dfd9efSDavid du Colombier m->opbhz = 66600000;
57*d6dfd9efSDavid du Colombier m->clockgen = m->cpuhz; /* it's the internal cpu clock */
58*d6dfd9efSDavid du Colombier }
59*d6dfd9efSDavid du Colombier
60*d6dfd9efSDavid du Colombier void
archvt4link(void)61*d6dfd9efSDavid du Colombier archvt4link(void)
62*d6dfd9efSDavid du Colombier {
63*d6dfd9efSDavid du Colombier }
64*d6dfd9efSDavid du Colombier
65*d6dfd9efSDavid du Colombier int
cmpswap(long * addr,long old,long new)66*d6dfd9efSDavid du Colombier cmpswap(long *addr, long old, long new)
67*d6dfd9efSDavid du Colombier {
68*d6dfd9efSDavid du Colombier return cas32(addr, old, new);
69*d6dfd9efSDavid du Colombier }
70*d6dfd9efSDavid du Colombier
71*d6dfd9efSDavid du Colombier /*
72*d6dfd9efSDavid du Colombier * only use of GPIO now is access to LEDs
73*d6dfd9efSDavid du Colombier */
74*d6dfd9efSDavid du Colombier
75*d6dfd9efSDavid du Colombier static int leds;
76*d6dfd9efSDavid du Colombier static uchar oldbits;
77*d6dfd9efSDavid du Colombier static Lock lightlck;
78*d6dfd9efSDavid du Colombier
79*d6dfd9efSDavid du Colombier static void
ledinit(void)80*d6dfd9efSDavid du Colombier ledinit(void)
81*d6dfd9efSDavid du Colombier {
82*d6dfd9efSDavid du Colombier Gpioregs *g;
83*d6dfd9efSDavid du Colombier
84*d6dfd9efSDavid du Colombier /* set access to LED */
85*d6dfd9efSDavid du Colombier g = (Gpioregs*)Gpio;
86*d6dfd9efSDavid du Colombier /* g->gie = 0; /* wouldn't use intrs even if we had them */
87*d6dfd9efSDavid du Colombier g->tri = 0; /* outputs */
88*d6dfd9efSDavid du Colombier g->data = ~0;
89*d6dfd9efSDavid du Colombier barriers();
90*d6dfd9efSDavid du Colombier }
91*d6dfd9efSDavid du Colombier
92*d6dfd9efSDavid du Colombier uchar
lightstate(int state)93*d6dfd9efSDavid du Colombier lightstate(int state)
94*d6dfd9efSDavid du Colombier {
95*d6dfd9efSDavid du Colombier int r;
96*d6dfd9efSDavid du Colombier
97*d6dfd9efSDavid du Colombier if (m->machno != 0)
98*d6dfd9efSDavid du Colombier return oldbits;
99*d6dfd9efSDavid du Colombier ilock(&lightlck);
100*d6dfd9efSDavid du Colombier r = oldbits;
101*d6dfd9efSDavid du Colombier oldbits &= ~(Ledtrap|Ledkern|Leduser|Ledidle);
102*d6dfd9efSDavid du Colombier oldbits |= state & (Ledtrap|Ledkern|Leduser|Ledidle);
103*d6dfd9efSDavid du Colombier ((Gpioregs*)Gpio)->data = (uchar)~oldbits; /* 0 == lit */
104*d6dfd9efSDavid du Colombier iunlock(&lightlck);
105*d6dfd9efSDavid du Colombier barriers();
106*d6dfd9efSDavid du Colombier return r;
107*d6dfd9efSDavid du Colombier }
108*d6dfd9efSDavid du Colombier
109*d6dfd9efSDavid du Colombier uchar
lightbiton(int bit)110*d6dfd9efSDavid du Colombier lightbiton(int bit)
111*d6dfd9efSDavid du Colombier {
112*d6dfd9efSDavid du Colombier int r;
113*d6dfd9efSDavid du Colombier
114*d6dfd9efSDavid du Colombier if (m->machno != 0)
115*d6dfd9efSDavid du Colombier return oldbits;
116*d6dfd9efSDavid du Colombier ilock(&lightlck);
117*d6dfd9efSDavid du Colombier r = oldbits;
118*d6dfd9efSDavid du Colombier oldbits |= bit;
119*d6dfd9efSDavid du Colombier ((Gpioregs*)Gpio)->data = (uchar)~oldbits; /* 0 == lit */
120*d6dfd9efSDavid du Colombier iunlock(&lightlck);
121*d6dfd9efSDavid du Colombier barriers();
122*d6dfd9efSDavid du Colombier return r;
123*d6dfd9efSDavid du Colombier }
124*d6dfd9efSDavid du Colombier
125*d6dfd9efSDavid du Colombier uchar
lightbitoff(int bit)126*d6dfd9efSDavid du Colombier lightbitoff(int bit)
127*d6dfd9efSDavid du Colombier {
128*d6dfd9efSDavid du Colombier int r;
129*d6dfd9efSDavid du Colombier
130*d6dfd9efSDavid du Colombier if (m->machno != 0)
131*d6dfd9efSDavid du Colombier return oldbits;
132*d6dfd9efSDavid du Colombier ilock(&lightlck);
133*d6dfd9efSDavid du Colombier r = oldbits;
134*d6dfd9efSDavid du Colombier oldbits &= ~bit;
135*d6dfd9efSDavid du Colombier ((Gpioregs*)Gpio)->data = (uchar)~oldbits; /* 0 == lit */
136*d6dfd9efSDavid du Colombier iunlock(&lightlck);
137*d6dfd9efSDavid du Colombier barriers();
138*d6dfd9efSDavid du Colombier return r;
139*d6dfd9efSDavid du Colombier }
140*d6dfd9efSDavid du Colombier
141*d6dfd9efSDavid du Colombier static void
twinkle(void)142*d6dfd9efSDavid du Colombier twinkle(void)
143*d6dfd9efSDavid du Colombier {
144*d6dfd9efSDavid du Colombier static int bit;
145*d6dfd9efSDavid du Colombier
146*d6dfd9efSDavid du Colombier if (m->machno != 0)
147*d6dfd9efSDavid du Colombier return;
148*d6dfd9efSDavid du Colombier if(m->ticks % (HZ/4) == 0) {
149*d6dfd9efSDavid du Colombier bit ^= 1;
150*d6dfd9efSDavid du Colombier if (bit)
151*d6dfd9efSDavid du Colombier lightbiton(Ledpulse);
152*d6dfd9efSDavid du Colombier else
153*d6dfd9efSDavid du Colombier lightbitoff(Ledpulse);
154*d6dfd9efSDavid du Colombier barriers();
155*d6dfd9efSDavid du Colombier }
156*d6dfd9efSDavid du Colombier
157*d6dfd9efSDavid du Colombier if(securemem)
158*d6dfd9efSDavid du Colombier qtmclock();
159*d6dfd9efSDavid du Colombier if(m->ticks % HZ == 0) {
160*d6dfd9efSDavid du Colombier intrs1sec = 0;
161*d6dfd9efSDavid du Colombier etherclock();
162*d6dfd9efSDavid du Colombier }
163*d6dfd9efSDavid du Colombier barriers();
164*d6dfd9efSDavid du Colombier }
165*d6dfd9efSDavid du Colombier
166*d6dfd9efSDavid du Colombier /*
167*d6dfd9efSDavid du Colombier * virtex 4 systems always have 128MB.
168*d6dfd9efSDavid du Colombier */
169*d6dfd9efSDavid du Colombier uintptr
memsize(void)170*d6dfd9efSDavid du Colombier memsize(void)
171*d6dfd9efSDavid du Colombier {
172*d6dfd9efSDavid du Colombier uintptr sz = 128*MB;
173*d6dfd9efSDavid du Colombier
174*d6dfd9efSDavid du Colombier return securemem? MEMTOP(sz): sz;
175*d6dfd9efSDavid du Colombier }
176*d6dfd9efSDavid du Colombier
177*d6dfd9efSDavid du Colombier void
meminit(void)178*d6dfd9efSDavid du Colombier meminit(void)
179*d6dfd9efSDavid du Colombier {
180*d6dfd9efSDavid du Colombier ulong paddr;
181*d6dfd9efSDavid du Colombier ulong *vaddr;
182*d6dfd9efSDavid du Colombier static int ro[] = {0, -1};
183*d6dfd9efSDavid du Colombier
184*d6dfd9efSDavid du Colombier /* size memory */
185*d6dfd9efSDavid du Colombier securemem = gotsecuremem();
186*d6dfd9efSDavid du Colombier memsz = memsize();
187*d6dfd9efSDavid du Colombier conf.mem[0].npage = memsz / BY2PG;
188*d6dfd9efSDavid du Colombier conf.mem[0].base = PGROUND(PADDR(end));
189*d6dfd9efSDavid du Colombier conf.mem[0].npage -= conf.mem[0].base/BY2PG;
190*d6dfd9efSDavid du Colombier
191*d6dfd9efSDavid du Colombier /* verify that it really is memory */
192*d6dfd9efSDavid du Colombier for (paddr = ROUNDUP(PADDR(end), MB); paddr + BY2WD*(12+1) < memsz;
193*d6dfd9efSDavid du Colombier paddr += MB) {
194*d6dfd9efSDavid du Colombier vaddr = (ulong *)KADDR(paddr + BY2WD*12); /* a few bytes in */
195*d6dfd9efSDavid du Colombier *vaddr = paddr;
196*d6dfd9efSDavid du Colombier barriers();
197*d6dfd9efSDavid du Colombier dcflush(PTR2UINT(vaddr), BY2WD);
198*d6dfd9efSDavid du Colombier if (*vaddr != paddr)
199*d6dfd9efSDavid du Colombier panic("address %#lux is not memory", paddr);
200*d6dfd9efSDavid du Colombier }
201*d6dfd9efSDavid du Colombier
202*d6dfd9efSDavid du Colombier memset(end, 0, memsz - PADDR(end));
203*d6dfd9efSDavid du Colombier sync();
204*d6dfd9efSDavid du Colombier }
205*d6dfd9efSDavid du Colombier
206*d6dfd9efSDavid du Colombier void
ioinit(void)207*d6dfd9efSDavid du Colombier ioinit(void)
208*d6dfd9efSDavid du Colombier {
209*d6dfd9efSDavid du Colombier ledinit();
210*d6dfd9efSDavid du Colombier addconf("console", "0");
211*d6dfd9efSDavid du Colombier addconf("nobootprompt", "tcp");
212*d6dfd9efSDavid du Colombier }
213*d6dfd9efSDavid du Colombier
214*d6dfd9efSDavid du Colombier int
archether(int ctlno,Ether * ether)215*d6dfd9efSDavid du Colombier archether(int ctlno, Ether *ether)
216*d6dfd9efSDavid du Colombier {
217*d6dfd9efSDavid du Colombier if(ctlno > 0)
218*d6dfd9efSDavid du Colombier return -1;
219*d6dfd9efSDavid du Colombier
220*d6dfd9efSDavid du Colombier ether->type = "lltemac";
221*d6dfd9efSDavid du Colombier ether->port = ctlno;
222*d6dfd9efSDavid du Colombier return 1;
223*d6dfd9efSDavid du Colombier }
224*d6dfd9efSDavid du Colombier
225*d6dfd9efSDavid du Colombier void
clrmchk(void)226*d6dfd9efSDavid du Colombier clrmchk(void)
227*d6dfd9efSDavid du Colombier {
228*d6dfd9efSDavid du Colombier putesr(0); /* clears machine check */
229*d6dfd9efSDavid du Colombier }
230*d6dfd9efSDavid du Colombier
231*d6dfd9efSDavid du Colombier /*
232*d6dfd9efSDavid du Colombier * the new kernel is already loaded at address `code'
233*d6dfd9efSDavid du Colombier * of size `size' and entry point `entry'.
234*d6dfd9efSDavid du Colombier */
235*d6dfd9efSDavid du Colombier void
reboot(void * entry,void * code,ulong size)236*d6dfd9efSDavid du Colombier reboot(void *entry, void *code, ulong size)
237*d6dfd9efSDavid du Colombier {
238*d6dfd9efSDavid du Colombier void (*f)(ulong, ulong, ulong);
239*d6dfd9efSDavid du Colombier
240*d6dfd9efSDavid du Colombier writeconf();
241*d6dfd9efSDavid du Colombier shutdown(0);
242*d6dfd9efSDavid du Colombier
243*d6dfd9efSDavid du Colombier /*
244*d6dfd9efSDavid du Colombier * should be the only processor running now
245*d6dfd9efSDavid du Colombier */
246*d6dfd9efSDavid du Colombier
247*d6dfd9efSDavid du Colombier print("shutting down...\n");
248*d6dfd9efSDavid du Colombier delay(200);
249*d6dfd9efSDavid du Colombier
250*d6dfd9efSDavid du Colombier splhi();
251*d6dfd9efSDavid du Colombier
252*d6dfd9efSDavid du Colombier /* turn off buffered serial console */
253*d6dfd9efSDavid du Colombier // serialoq = nil;
254*d6dfd9efSDavid du Colombier
255*d6dfd9efSDavid du Colombier /* shutdown devices */
256*d6dfd9efSDavid du Colombier devtabshutdown();
257*d6dfd9efSDavid du Colombier
258*d6dfd9efSDavid du Colombier /* setup reboot trampoline function */
259*d6dfd9efSDavid du Colombier f = (void*)REBOOTADDR;
260*d6dfd9efSDavid du Colombier memmove(f, rebootcode, sizeof(rebootcode));
261*d6dfd9efSDavid du Colombier sync();
262*d6dfd9efSDavid du Colombier dcflush(PTR2UINT(f), sizeof rebootcode);
263*d6dfd9efSDavid du Colombier icflush(PTR2UINT(f), sizeof rebootcode);
264*d6dfd9efSDavid du Colombier
265*d6dfd9efSDavid du Colombier print("rebooting...");
266*d6dfd9efSDavid du Colombier iprint("entry %#lux code %#lux size %ld\n",
267*d6dfd9efSDavid du Colombier PADDR(entry), PADDR(code), size);
268*d6dfd9efSDavid du Colombier delay(100); /* wait for uart to quiesce */
269*d6dfd9efSDavid du Colombier
270*d6dfd9efSDavid du Colombier /* off we go - never to return */
271*d6dfd9efSDavid du Colombier sync();
272*d6dfd9efSDavid du Colombier dcflush(PTR2UINT(entry), size);
273*d6dfd9efSDavid du Colombier icflush(PTR2UINT(entry), size);
274*d6dfd9efSDavid du Colombier (*f)(PADDR(entry), PADDR(code), size);
275*d6dfd9efSDavid du Colombier
276*d6dfd9efSDavid du Colombier iprint("kernel returned!\n");
277*d6dfd9efSDavid du Colombier archreboot();
278*d6dfd9efSDavid du Colombier }
279