machdep.c revision 1.80 1 /* $NetBSD: machdep.c,v 1.80 2003/01/18 06:11:51 thorpej 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/mbuf.h>
42 #include <sys/mount.h>
43 #include <sys/msgbuf.h>
44 #include <sys/proc.h>
45 #include <sys/reboot.h>
46 #include <sys/sa.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[256];
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 struct pmap ofw_pmap;
100
101 void
102 initppc(startkernel, endkernel, args)
103 u_int startkernel, endkernel;
104 char *args;
105 {
106 #ifdef DDB
107 extern void *startsym, *endsym;
108 #endif
109
110 /* Initialize the bootstrap console. */
111 ofppc_bootstrap_console();
112
113 /*
114 * Initialize the bat registers
115 */
116 mpc6xx_batinit(0);
117
118 /*
119 * Initialize the platform structure. This may add entries
120 * to the BAT table.
121 */
122 platform_init();
123
124 #ifdef __notyet__ /* Needs some rethinking regarding real/virtual OFW */
125 OF_set_callback(callback);
126 #endif
127
128 mpc6xx_init(NULL);
129
130 /*
131 * Now that translation is enabled (and we can access bus space),
132 * initialize the console.
133 */
134 (*platform.cons_init)();
135
136 /*
137 * Parse arg string.
138 */
139 strcpy(bootpath, args);
140 while (*++args && *args != ' ');
141 if (*args) {
142 for(*args++ = 0; *args; args++)
143 BOOT_FLAG(*args, boothowto);
144 }
145
146 /*
147 * Set the page size.
148 */
149 uvm_setpagesize();
150
151 /*
152 * Initialize pmap module.
153 */
154 pmap_bootstrap(startkernel, endkernel, NULL);
155
156 #ifdef DDB
157 ddb_init((int)((u_int)endsym - (u_int)startsym), startsym, endsym);
158 if (boothowto & RB_KDB)
159 Debugger();
160 #endif
161 #ifdef IPKDB
162 /*
163 * Now trap to IPKDB
164 */
165 ipkdb_init();
166 if (boothowto & RB_KDB)
167 ipkdb_connect(0);
168 #endif
169 }
170
171 /*
172 * Machine dependent startup code.
173 */
174 void
175 cpu_startup()
176 {
177
178 mpc6xx_startup(NULL);
179
180 /*
181 * Now allow hardware interrupts.
182 */
183 splhigh();
184 mtmsr(mfmsr() | PSL_EE | PSL_RI);
185 (*platform.softintr_init)();
186 }
187
188 void
189 consinit()
190 {
191
192 (*cn_tab->cn_probe)(cn_tab);
193 }
194
195 void ofcons_cnprobe(struct consdev *);
196 int ofppc_cngetc(dev_t);
197 void ofppc_cnputc(dev_t, int);
198
199 struct consdev ofppc_bootcons = {
200 ofcons_cnprobe, NULL, ofppc_cngetc, ofppc_cnputc, nullcnpollc, NULL,
201 makedev(0,0), 1,
202 };
203
204 int ofppc_stdin_ihandle, ofppc_stdout_ihandle;
205 int ofppc_stdin_phandle, ofppc_stdout_phandle;
206
207 void
208 ofppc_bootstrap_console(void)
209 {
210 int chosen;
211 char data[4];
212
213 chosen = OF_finddevice("/chosen");
214
215 if (OF_getprop(chosen, "stdin", data, sizeof(data)) != sizeof(int))
216 goto nocons;
217 ofppc_stdin_ihandle = of_decode_int(data);
218 ofppc_stdin_phandle = OF_instance_to_package(ofppc_stdin_ihandle);
219
220 if (OF_getprop(chosen, "stdout", data, sizeof(data)) != sizeof(int))
221 goto nocons;
222 ofppc_stdout_ihandle = of_decode_int(data);
223 ofppc_stdout_phandle = OF_instance_to_package(ofppc_stdout_ihandle);
224
225 cn_tab = &ofppc_bootcons;
226
227 nocons:
228 return;
229 }
230
231 int
232 ofppc_cngetc(dev_t dev)
233 {
234 u_char ch = '\0';
235 int l;
236
237 while ((l = OF_read(ofppc_stdin_ihandle, &ch, 1)) != 1)
238 if (l != -2 && l != 0)
239 return (-1);
240
241 return (ch);
242 }
243
244 void
245 ofppc_cnputc(dev_t dev, int c)
246 {
247 char ch = c;
248
249 OF_write(ofppc_stdout_ihandle, &ch, 1);
250 }
251
252 /*
253 * Crash dump handling.
254 */
255
256 /*
257 * Stray interrupts.
258 */
259 void
260 strayintr(irq)
261 int irq;
262 {
263 log(LOG_ERR, "stray interrupt %d\n", irq);
264 }
265
266 /*
267 * Halt or reboot the machine after syncing/dumping according to howto.
268 */
269 void
270 cpu_reboot(howto, what)
271 int howto;
272 char *what;
273 {
274 static int syncing;
275 static char str[256];
276 char *ap = str, *ap1 = ap;
277
278 boothowto = howto;
279 if (!cold && !(howto & RB_NOSYNC) && !syncing) {
280 syncing = 1;
281 vfs_shutdown(); /* sync */
282 resettodr(); /* set wall clock */
283 }
284 splhigh();
285 if (howto & RB_HALT) {
286 doshutdownhooks();
287 printf("halted\n\n");
288 ppc_exit();
289 }
290 if (!cold && (howto & RB_DUMP))
291 mpc6xx_dumpsys();
292 doshutdownhooks();
293 printf("rebooting\n\n");
294 if (what && *what) {
295 if (strlen(what) > sizeof str - 5)
296 printf("boot string too large, ignored\n");
297 else {
298 strcpy(str, what);
299 ap1 = ap = str + strlen(str);
300 *ap++ = ' ';
301 }
302 }
303 *ap++ = '-';
304 if (howto & RB_SINGLE)
305 *ap++ = 's';
306 if (howto & RB_KDB)
307 *ap++ = 'd';
308 *ap++ = 0;
309 if (ap[-2] == '-')
310 *ap1 = 0;
311 ppc_boot(str);
312 }
313
314 #ifdef notyet
315 /*
316 * OpenFirmware callback routine
317 */
318 void
319 callback(p)
320 void *p;
321 {
322 panic("callback"); /* for now XXX */
323 }
324 #endif
325
326 /*
327 * Perform an `splx()' for locore.
328 */
329 int
330 lcsplx(int ipl)
331 {
332
333 return (_spllower(ipl));
334 }
335
336 /*
337 * Initial Machine Interface.
338 */
339 static int
340 fake_spl(int new)
341 {
342 int scratch;
343
344 asm volatile ("mfmsr %0; andi. %0,%0,%1; mtmsr %0; isync"
345 : "=r"(scratch) : "K"((u_short)~(PSL_EE|PSL_ME)));
346 return (-1);
347 }
348
349 static void
350 fake_setsoft(int ipl)
351 {
352 /* Do nothing */
353 }
354
355 static void
356 fake_splx(new)
357 int new;
358 {
359
360 (void) fake_spl(0);
361 }
362
363 static void
364 fake_clock_return(frame, nticks)
365 struct clockframe *frame;
366 int nticks;
367 {
368 /* Do nothing */
369 }
370
371 static void *
372 fake_intr_establish(irq, level, ist, handler, arg)
373 int irq, level, ist;
374 int (*handler) __P((void *));
375 void *arg;
376 {
377
378 panic("fake_intr_establish");
379 }
380
381 static void
382 fake_intr_disestablish(cookie)
383 void *cookie;
384 {
385
386 panic("fake_intr_disestablish");
387 }
388