xref: /plan9-contrib/sys/src/9/vt4/archvt4.c (revision d6dfd9ef91cf0fa8514a249d5f2a550978c19369)
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