xref: /netbsd/sys/arch/bebox/bebox/machdep.c (revision c4a72b64)
1 /*	$NetBSD: machdep.c,v 1.74 2002/09/25 22:21:06 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 #include "opt_ipkdb.h"
37 
38 #include <sys/param.h>
39 #include <sys/buf.h>
40 #include <sys/conf.h>
41 #include <sys/device.h>
42 #include <sys/exec.h>
43 #include <sys/kernel.h>
44 #include <sys/malloc.h>
45 #include <sys/mbuf.h>
46 #include <sys/mount.h>
47 #include <sys/msgbuf.h>
48 #include <sys/proc.h>
49 #include <sys/reboot.h>
50 #include <sys/syscallargs.h>
51 #include <sys/syslog.h>
52 #include <sys/systm.h>
53 #include <sys/user.h>
54 
55 #ifdef DDB
56 #include <machine/db_machdep.h>
57 #include <ddb/db_extern.h>
58 #endif
59 
60 #include <uvm/uvm_extern.h>
61 
62 #include <net/netisr.h>
63 
64 #include <powerpc/mpc6xx/bat.h>
65 #include <machine/bootinfo.h>
66 #include <machine/autoconf.h>
67 #define _POWERPC_BUS_DMA_PRIVATE
68 #include <machine/bus.h>
69 #include <machine/intr.h>
70 #include <machine/pmap.h>
71 #include <machine/powerpc.h>
72 #include <machine/trap.h>
73 
74 #include <dev/cons.h>
75 
76 #include "pfb.h"
77 
78 #include "pc.h"
79 #if (NPC > 0)
80 #include <machine/pccons.h>
81 #endif
82 
83 #include "vga.h"
84 #if (NVGA > 0)
85 #include <dev/ic/mc6845reg.h>
86 #include <dev/ic/pcdisplayvar.h>
87 #include <dev/ic/vgareg.h>
88 #include <dev/ic/vgavar.h>
89 #endif
90 
91 #include "pckbc.h"
92 #if (NPCKBC > 0)
93 #include <dev/isa/isareg.h>
94 #include <dev/ic/i8042reg.h>
95 #include <dev/ic/pckbcvar.h>
96 #endif
97 
98 #include "com.h"
99 #if (NCOM > 0)
100 #include <sys/termios.h>
101 #include <dev/ic/comreg.h>
102 #include <dev/ic/comvar.h>
103 #endif
104 
105 /*
106  * Global variables used here and there
107  */
108 char bootinfo[BOOTINFO_MAXSIZE];
109 
110 paddr_t bebox_mb_reg;		/* BeBox MotherBoard register */
111 
112 #define	OFMEMREGIONS	32
113 struct mem_region physmemr[OFMEMREGIONS], availmemr[OFMEMREGIONS];
114 
115 char *bootpath;
116 
117 paddr_t avail_end;			/* XXX temporary */
118 
119 extern void *startsym, *endsym;
120 
121 void
122 initppc(startkernel, endkernel, args, btinfo)
123 	u_int startkernel, endkernel, args;
124 	void *btinfo;
125 {
126 	extern void consinit __P((void));
127 	extern void ext_intr __P((void));
128 
129 	/*
130 	 * copy bootinfo
131 	 */
132 	memcpy(bootinfo, btinfo, sizeof (bootinfo));
133 
134 	/*
135 	 * BeBox memory region set
136 	 */
137 	{
138 		struct btinfo_memory *meminfo;
139 
140 		meminfo =
141 			(struct btinfo_memory *)lookup_bootinfo(BTINFO_MEMORY);
142 		if (!meminfo)
143 			panic("not found memory information in bootinfo");
144 		physmemr[0].start = 0;
145 		physmemr[0].size = meminfo->memsize & ~PGOFSET;
146 		availmemr[0].start = (endkernel + PGOFSET) & ~PGOFSET;
147 		availmemr[0].size = meminfo->memsize - availmemr[0].start;
148 	}
149 	avail_end = physmemr[0].start + physmemr[0].size;    /* XXX temporary */
150 
151 	/*
152 	 * Get CPU clock
153 	 */
154 	{
155 		struct btinfo_clock *clockinfo;
156 		extern u_long ticks_per_sec, ns_per_tick;
157 
158 		clockinfo =
159 			(struct btinfo_clock *)lookup_bootinfo(BTINFO_CLOCK);
160 		if (!clockinfo)
161 			panic("not found clock information in bootinfo");
162 		ticks_per_sec = clockinfo->ticks_per_sec;
163 		ns_per_tick = 1000000000 / ticks_per_sec;
164 	}
165 
166 	/*
167 	 * BeBox MotherBoard's Register
168 	 *  Interrupt Mask Reset
169 	 */
170 	*(volatile u_int *)(MOTHER_BOARD_REG + CPU0_INT_MASK) = 0x0ffffffc;
171 	*(volatile u_int *)(MOTHER_BOARD_REG + CPU0_INT_MASK) = 0x80000023;
172 	*(volatile u_int *)(MOTHER_BOARD_REG + CPU1_INT_MASK) = 0x0ffffffc;
173 
174 	/*
175 	 * boothowto
176 	 */
177 	boothowto = args;
178 
179 	/*
180 	 * Init the I/O stuff before the console
181 	 */
182 	bebox_bus_space_init();
183 
184 	/*
185 	 * i386 port says, that this shouldn't be here,
186 	 * but I really think the console should be initialized
187 	 * as early as possible.
188 	 */
189 	consinit();
190 
191 	/*
192 	 * Set up initial BAT table
193 	 */
194 	mpc6xx_batinit(
195 	    BEBOX_BUS_SPACE_IO,  BAT_BL_256M,
196 	    BEBOX_BUS_SPACE_MEM, BAT_BL_256M,
197 	    0);
198 
199 	/*
200 	 * Initialize the vector table and interrupt routine.
201 	 */
202 	mpc6xx_init(ext_intr);
203 
204         /*
205 	 * Set the page size.
206 	 */
207 	uvm_setpagesize();
208 
209 	/*
210 	 * Initialize pmap module.
211 	 */
212 	pmap_bootstrap(startkernel, endkernel, NULL);
213 
214 #ifdef DDB
215 	ddb_init((int)((u_int)endsym - (u_int)startsym), startsym, endsym);
216 #endif
217 #ifdef IPKDB
218 	/*
219 	 * Now trap to IPKDB
220 	 */
221 	ipkdb_init();
222 	if (boothowto & RB_KDB)
223 		ipkdb_connect(0);
224 #endif
225 }
226 
227 void
228 mem_regions(mem, avail)
229 	struct mem_region **mem, **avail;
230 {
231 	*mem = physmemr;
232 	*avail = availmemr;
233 }
234 
235 /*
236  * Machine dependent startup code.
237  */
238 void
239 cpu_startup()
240 {
241 	/*
242 	 * BeBox Mother Board's Register Mapping
243 	 */
244 	bebox_mb_reg = (vaddr_t) mapiodev(MOTHER_BOARD_REG, NBPG);
245 	if (!bebox_mb_reg)
246 		panic("cpu_startup: no room for interrupt register");
247 
248 	/*
249 	 * Do common VM initialization
250 	 */
251 	mpc6xx_startup(NULL);
252 
253 	/*
254 	 * Now that we have VM, malloc's are OK in bus_space.
255 	 */
256 	bebox_bus_space_mallocok();
257 
258 	/*
259 	 * Now allow hardware interrupts.
260 	 */
261 	{
262 		int msr;
263 
264 		splhigh();
265 		__asm __volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0"
266 			      : "=r"(msr) : "K"(PSL_EE));
267 	}
268 }
269 
270 /*
271  * lookup_bootinfo:
272  * Look up information in bootinfo of boot loader.
273  */
274 void *
275 lookup_bootinfo(type)
276 	int type;
277 {
278 	struct btinfo_common *bt;
279 	struct btinfo_common *help = (struct btinfo_common *)bootinfo;
280 
281 	do {
282 		bt = help;
283 		if (bt->type == type)
284 			return (help);
285 		help = (struct btinfo_common *)((char*)help + bt->next);
286 	} while (bt->next &&
287 		(size_t)help < (size_t)bootinfo + sizeof (bootinfo));
288 
289 	return (NULL);
290 }
291 
292 /*
293  * consinit
294  * Initialize system console.
295  */
296 void
297 consinit()
298 {
299 	struct btinfo_console *consinfo;
300 	static int initted;
301 
302 	if (initted)
303 		return;
304 	initted = 1;
305 
306 	consinfo = (struct btinfo_console *)lookup_bootinfo(BTINFO_CONSOLE);
307 	if (!consinfo)
308 		panic("not found console information in bootinfo");
309 
310 #if (NPFB > 0)
311 	if (!strcmp(consinfo->devname, "be")) {
312 		pfb_cnattach(consinfo->addr);
313 #if (NPCKBC > 0)
314 		pckbc_cnattach(&bebox_isa_io_bs_tag, IO_KBD, KBCMDP,
315 		    PCKBC_KBD_SLOT);
316 #endif
317 		return;
318 	}
319 #endif
320 
321 #if (NPC > 0) || (NVGA > 0)
322 	if (!strcmp(consinfo->devname, "vga")) {
323 #if (NVGA > 0)
324 		if (!vga_cnattach(&bebox_io_bs_tag, &bebox_mem_bs_tag,
325 				  -1, 1))
326 			goto dokbd;
327 #endif
328 #if (NPC > 0)
329 		pccnattach();
330 #endif
331 dokbd:
332 #if (NPCKBC > 0)
333 		pckbc_cnattach(&bebox_isa_io_bs_tag, IO_KBD, KBCMDP,
334 		    PCKBC_KBD_SLOT);
335 #endif
336 		return;
337 	}
338 #endif /* PC | VGA */
339 
340 #if (NCOM > 0)
341 	if (!strcmp(consinfo->devname, "com")) {
342 		bus_space_tag_t tag = &bebox_isa_io_bs_tag;
343 
344 		if(comcnattach(tag, consinfo->addr, consinfo->speed, COM_FREQ,
345 		    ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8)))
346 			panic("can't init serial console");
347 
348 		return;
349 	}
350 #endif
351 	panic("invalid console device %s", consinfo->devname);
352 }
353 
354 #if (NPCKBC > 0) && (NPCKBD == 0)
355 /*
356  * glue code to support old console code with the
357  * mi keyboard controller driver
358  */
359 int
360 pckbc_machdep_cnattach(kbctag, kbcslot)
361 	pckbc_tag_t kbctag;
362 	pckbc_slot_t kbcslot;
363 {
364 #if (NPC > 0)
365 	return (pcconskbd_cnattach(kbctag, kbcslot));
366 #else
367 	return (ENXIO);
368 #endif
369 }
370 #endif
371 
372 /*
373  * Stray interrupts.
374  */
375 void
376 strayintr(irq)
377 	int irq;
378 {
379 	log(LOG_ERR, "stray interrupt %d\n", irq);
380 }
381 
382 /*
383  * Halt or reboot the machine after syncing/dumping according to howto.
384  */
385 void
386 cpu_reboot(howto, what)
387 	int howto;
388 	char *what;
389 {
390 	static int syncing;
391 	static char str[256];
392 	char *ap = str, *ap1 = ap;
393 
394 	boothowto = howto;
395 	if (!cold && !(howto & RB_NOSYNC) && !syncing) {
396 		syncing = 1;
397 		vfs_shutdown();		/* sync */
398 		resettodr();		/* set wall clock */
399 	}
400 	splhigh();
401 	if (howto & RB_HALT) {
402 		doshutdownhooks();
403 		printf("halted\n\n");
404 #if 0
405 		ppc_exit();
406 #endif
407 	}
408 	if (!cold && (howto & RB_DUMP))
409 		mpc6xx_dumpsys();
410 	doshutdownhooks();
411 	printf("rebooting\n\n");
412 	if (what && *what) {
413 		if (strlen(what) > sizeof str - 5)
414 			printf("boot string too large, ignored\n");
415 		else {
416 			strcpy(str, what);
417 			ap1 = ap = str + strlen(str);
418 			*ap++ = ' ';
419 		}
420 	}
421 	*ap++ = '-';
422 	if (howto & RB_SINGLE)
423 		*ap++ = 's';
424 	if (howto & RB_KDB)
425 		*ap++ = 'd';
426 	*ap++ = 0;
427 	if (ap[-2] == '-')
428 		*ap1 = 0;
429 #if 0
430 	ppc_boot(str);
431 #endif
432 	while (1);
433 }
434 
435 void
436 lcsplx(ipl)
437 	int ipl;
438 {
439 	splx(ipl);
440 }
441