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