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