machdep.c revision 1.76 1 /* $NetBSD: machdep.c,v 1.76 2002/07/05 18:45:19 matt Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by TooLs GmbH.
19 * 4. The name of TooLs GmbH may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include "opt_compat_netbsd.h"
35 #include "opt_ddb.h"
36
37 #include <sys/param.h>
38 #include <sys/buf.h>
39 #include <sys/exec.h>
40 #include <sys/malloc.h>
41 #include <sys/map.h>
42 #include <sys/mbuf.h>
43 #include <sys/mount.h>
44 #include <sys/msgbuf.h>
45 #include <sys/proc.h>
46 #include <sys/reboot.h>
47 #include <sys/syscallargs.h>
48 #include <sys/syslog.h>
49 #include <sys/systm.h>
50 #include <sys/kernel.h>
51 #include <sys/user.h>
52 #include <sys/boot_flag.h>
53
54 #include <uvm/uvm_extern.h>
55
56 #include <net/netisr.h>
57
58 #include <machine/db_machdep.h>
59 #include <ddb/db_extern.h>
60
61 #include <dev/ofw/openfirm.h>
62
63 #include <machine/autoconf.h>
64 #include <machine/bat.h>
65 #include <machine/pmap.h>
66 #include <machine/powerpc.h>
67 #include <machine/trap.h>
68
69 #include <machine/platform.h>
70
71 #include <dev/cons.h>
72
73 /*
74 * Global variables used here and there
75 */
76 char *bootpath;
77
78 int lcsplx(int); /* called from locore.S */
79
80 static int fake_spl __P((int));
81 static void fake_splx __P((int));
82 static void fake_setsoft __P((int));
83 static void fake_clock_return __P((struct clockframe *, int));
84 static void *fake_intr_establish __P((int, int, int, int (*)(void *), void *));
85 static void fake_intr_disestablish __P((void *));
86
87 struct machvec machine_interface = {
88 fake_spl,
89 fake_spl,
90 fake_splx,
91 fake_setsoft,
92 fake_clock_return,
93 fake_intr_establish,
94 fake_intr_disestablish,
95 };
96
97 void ofppc_bootstrap_console(void);
98
99 void
100 initppc(startkernel, endkernel, args)
101 u_int startkernel, endkernel;
102 char *args;
103 {
104 #ifdef DDB
105 extern void *startsym, *endsym;
106 #endif
107
108 /* Initialize the bootstrap console. */
109 ofppc_bootstrap_console();
110
111 /*
112 * Initialize the bat registers
113 */
114 mpc6xx_batinit(0);
115
116 /*
117 * Initialize the platform structure. This may add entries
118 * to the BAT table.
119 */
120 platform_init();
121
122 #ifdef __notyet__ /* Needs some rethinking regarding real/virtual OFW */
123 OF_set_callback(callback);
124 #endif
125
126 mpc6xx_init(NULL);
127
128 /*
129 * Now that translation is enabled (and we can access bus space),
130 * initialize the console.
131 */
132 (*platform.cons_init)();
133
134 /*
135 * Parse arg string.
136 */
137 bootpath = args;
138 while (*++args && *args != ' ');
139 if (*args) {
140 for(*args++ = 0; *args; args++)
141 BOOT_FLAG(*args, boothowto);
142 }
143
144 /*
145 * Set the page size.
146 */
147 uvm_setpagesize();
148
149 /*
150 * Initialize pmap module.
151 */
152 pmap_bootstrap(startkernel, endkernel, NULL);
153
154 #ifdef DDB
155 ddb_init((int)((u_int)endsym - (u_int)startsym), startsym, endsym);
156 if (boothowto & RB_KDB)
157 Debugger();
158 #endif
159 #ifdef IPKDB
160 /*
161 * Now trap to IPKDB
162 */
163 ipkdb_init();
164 if (boothowto & RB_KDB)
165 ipkdb_connect(0);
166 #endif
167 }
168
169 /*
170 * Machine dependent startup code.
171 */
172 void
173 cpu_startup()
174 {
175 int msr;
176 mpc6xx_startup(NULL);
177
178 /*
179 * Now allow hardware interrupts.
180 */
181 splhigh();
182 asm volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0"
183 : "=r"(msr)
184 : "K"((u_short)(PSL_EE|PSL_RI)));
185 }
186
187 void
188 consinit()
189 {
190
191 /* Nothing to do; console is already initialized. */
192 }
193
194 int ofppc_cngetc(dev_t);
195 void ofppc_cnputc(dev_t, int);
196
197 struct consdev ofppc_bootcons = {
198 NULL, NULL, ofppc_cngetc, ofppc_cnputc, nullcnpollc, NULL,
199 makedev(0,0), 1,
200 };
201
202 int ofppc_stdin_ihandle, ofppc_stdout_ihandle;
203 int ofppc_stdin_phandle, ofppc_stdout_phandle;
204
205 void
206 ofppc_bootstrap_console(void)
207 {
208 int chosen;
209 char data[4];
210
211 chosen = OF_finddevice("/chosen");
212
213 if (OF_getprop(chosen, "stdin", data, sizeof(data)) != sizeof(int))
214 goto nocons;
215 ofppc_stdin_ihandle = of_decode_int(data);
216 ofppc_stdin_phandle = OF_instance_to_package(ofppc_stdin_ihandle);
217
218 if (OF_getprop(chosen, "stdout", data, sizeof(data)) != sizeof(int))
219 goto nocons;
220 ofppc_stdout_ihandle = of_decode_int(data);
221 ofppc_stdout_phandle = OF_instance_to_package(ofppc_stdout_ihandle);
222
223 cn_tab = &ofppc_bootcons;
224
225 nocons:
226 return;
227 }
228
229 int
230 ofppc_cngetc(dev_t dev)
231 {
232 u_char ch = '\0';
233 int l;
234
235 while ((l = OF_read(ofppc_stdin_ihandle, &ch, 1)) != 1)
236 if (l != -2 && l != 0)
237 return (-1);
238
239 return (ch);
240 }
241
242 void
243 ofppc_cnputc(dev_t dev, int c)
244 {
245 char ch = c;
246
247 OF_write(ofppc_stdout_ihandle, &ch, 1);
248 }
249
250 /*
251 * Crash dump handling.
252 */
253
254 /*
255 * Stray interrupts.
256 */
257 void
258 strayintr(irq)
259 int irq;
260 {
261 log(LOG_ERR, "stray interrupt %d\n", irq);
262 }
263
264 /*
265 * Halt or reboot the machine after syncing/dumping according to howto.
266 */
267 void
268 cpu_reboot(howto, what)
269 int howto;
270 char *what;
271 {
272 static int syncing;
273 static char str[256];
274 char *ap = str, *ap1 = ap;
275
276 boothowto = howto;
277 if (!cold && !(howto & RB_NOSYNC) && !syncing) {
278 syncing = 1;
279 vfs_shutdown(); /* sync */
280 resettodr(); /* set wall clock */
281 }
282 splhigh();
283 if (howto & RB_HALT) {
284 doshutdownhooks();
285 printf("halted\n\n");
286 ppc_exit();
287 }
288 if (!cold && (howto & RB_DUMP))
289 mpc6xx_dumpsys();
290 doshutdownhooks();
291 printf("rebooting\n\n");
292 if (what && *what) {
293 if (strlen(what) > sizeof str - 5)
294 printf("boot string too large, ignored\n");
295 else {
296 strcpy(str, what);
297 ap1 = ap = str + strlen(str);
298 *ap++ = ' ';
299 }
300 }
301 *ap++ = '-';
302 if (howto & RB_SINGLE)
303 *ap++ = 's';
304 if (howto & RB_KDB)
305 *ap++ = 'd';
306 *ap++ = 0;
307 if (ap[-2] == '-')
308 *ap1 = 0;
309 ppc_boot(str);
310 }
311
312 #ifdef notyet
313 /*
314 * OpenFirmware callback routine
315 */
316 void
317 callback(p)
318 void *p;
319 {
320 panic("callback"); /* for now XXX */
321 }
322 #endif
323
324 /*
325 * Perform an `splx()' for locore.
326 */
327 int
328 lcsplx(int ipl)
329 {
330
331 return (_spllower(ipl));
332 }
333
334 /*
335 * Initial Machine Interface.
336 */
337 static int
338 fake_spl(int new)
339 {
340 int scratch;
341
342 asm volatile ("mfmsr %0; andi. %0,%0,%1; mtmsr %0; isync"
343 : "=r"(scratch) : "K"((u_short)~(PSL_EE|PSL_ME)));
344 return (-1);
345 }
346
347 static void
348 fake_setsoft(int ipl)
349 {
350 /* Do nothing */
351 }
352
353 static void
354 fake_splx(new)
355 int new;
356 {
357
358 (void) fake_spl(0);
359 }
360
361 static void
362 fake_clock_return(frame, nticks)
363 struct clockframe *frame;
364 int nticks;
365 {
366 /* Do nothing */
367 }
368
369 static void *
370 fake_intr_establish(irq, level, ist, handler, arg)
371 int irq, level, ist;
372 int (*handler) __P((void *));
373 void *arg;
374 {
375
376 panic("fake_intr_establish");
377 }
378
379 static void
380 fake_intr_disestablish(cookie)
381 void *cookie;
382 {
383
384 panic("fake_intr_disestablish");
385 }
386