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