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