xref: /netbsd-src/sys/arch/mvmeppc/mvmeppc/machdep.c (revision de1dfb1250df962f1ff3a011772cf58e605aed11)
1 /*	$NetBSD: machdep.c,v 1.19 2003/10/20 00:12:10 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 <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.19 2003/10/20 00:12:10 matt Exp $");
36 
37 #include "opt_compat_netbsd.h"
38 #include "opt_mvmetype.h"
39 #include "opt_ddb.h"
40 
41 #include <sys/param.h>
42 #include <sys/buf.h>
43 #include <sys/conf.h>
44 #include <sys/device.h>
45 #include <sys/exec.h>
46 #include <sys/extent.h>
47 #include <sys/kernel.h>
48 #include <sys/malloc.h>
49 #include <sys/mbuf.h>
50 #include <sys/mount.h>
51 #include <sys/msgbuf.h>
52 #include <sys/proc.h>
53 #include <sys/reboot.h>
54 #include <sys/sa.h>
55 #include <sys/syscallargs.h>
56 #include <sys/syslog.h>
57 #include <sys/systm.h>
58 #include <sys/user.h>
59 #include <sys/ksyms.h>
60 
61 #include <uvm/uvm_extern.h>
62 
63 #include <sys/sysctl.h>
64 
65 #include <net/netisr.h>
66 
67 #include <machine/autoconf.h>
68 #include <machine/bootinfo.h>
69 #include <machine/bus.h>
70 #include <machine/intr.h>
71 #include <machine/pmap.h>
72 #include <machine/platform.h>
73 #include <machine/powerpc.h>
74 #include <machine/trap.h>
75 
76 #include <powerpc/oea/bat.h>
77 
78 #include <dev/cons.h>
79 
80 #if 0
81 #include "vga.h"
82 #if (NVGA > 0)
83 #include <dev/ic/mc6845reg.h>
84 #include <dev/ic/pcdisplayvar.h>
85 #include <dev/ic/vgareg.h>
86 #include <dev/ic/vgavar.h>
87 #endif
88 
89 #include "pckbc.h"
90 #if (NPCKBC > 0)
91 #include <dev/isa/isareg.h>
92 #include <dev/ic/i8042reg.h>
93 #include <dev/ic/pckbcvar.h>
94 #endif
95 #endif
96 
97 #include "com.h"
98 #if (NCOM > 0)
99 #include <sys/termios.h>
100 #include <dev/ic/comreg.h>
101 #include <dev/ic/comvar.h>
102 void comsoft(void);
103 #endif
104 
105 #ifdef DDB
106 #include <machine/db_machdep.h>
107 #include <ddb/db_extern.h>
108 #endif
109 
110 #include "ksyms.h"
111 
112 void initppc(u_long, u_long, void *);
113 void strayintr(int);
114 int lcsplx(int);
115 void mvmeppc_bus_space_init(void);
116 
117 
118 /*
119  * Global variables used here and there
120  */
121 struct mvmeppc_bootinfo bootinfo;
122 
123 vaddr_t mvmeppc_intr_reg;	/* PReP-compatible  interrupt vector register */
124 
125 struct mem_region physmemr[2], availmemr[2];
126 
127 paddr_t avail_end;			/* XXX temporary */
128 
129 void
130 initppc(startkernel, endkernel, btinfo)
131 	u_long startkernel, endkernel;
132 	void *btinfo;
133 {
134 #if NKSYMS || defined(DDB) || defined(LKM)
135 	extern void *startsym, *endsym;
136 #endif
137 
138 	/*
139 	 * Copy bootinfo.
140 	 */
141 	memcpy(&bootinfo, btinfo, sizeof(bootinfo));
142 
143 	/*
144 	 * Figure out the board family/type.
145 	 */
146 	ident_platform();
147 
148 	if (platform == NULL) {
149 		extern void _mvmeppc_unsup_board(const char *, const char *);
150 		char msg[80];
151 
152 		sprintf(msg, "Unsupported model: MVME%04x",
153 		    bootinfo.bi_modelnumber);
154 		_mvmeppc_unsup_board(msg, &msg[strlen(msg)]);
155 		/* NOTREACHED */
156 	}
157 
158 	/*
159 	 * Set memory region
160 	 */
161 	physmemr[0].start = 0;
162 	physmemr[0].size = bootinfo.bi_memsize & ~PGOFSET;
163 	availmemr[0].start = (endkernel + PGOFSET) & ~PGOFSET;
164 	availmemr[0].size = bootinfo.bi_memsize - availmemr[0].start;
165 	avail_end = physmemr[0].start + physmemr[0].size;    /* XXX temporary */
166 
167 	/*
168 	 * Set CPU clock
169 	 */
170 	{
171 		extern u_long ticks_per_sec, ns_per_tick;
172 
173 		ticks_per_sec = bootinfo.bi_clocktps;
174 		ns_per_tick = 1000000000 / ticks_per_sec;
175 	}
176 
177 	/*
178 	 * Setup fixed BAT registers.
179 	 */
180 	oea_batinit(
181 	    MVMEPPC_PHYS_BASE_IO,  BAT_BL_256M,
182 	    MVMEPPC_PHYS_BASE_MEM, BAT_BL_256M,
183 	    0);
184 
185 	/*
186 	 * Install vectors and interrupt handler.
187 	 */
188 	oea_init(platform->ext_intr);
189 
190 	/*
191 	 * Init bus_space so consinit can work.
192 	 */
193 	mvmeppc_bus_space_init();
194 
195 #ifdef DEBUG
196 	/*
197 	 * The console should be initialized as early as possible.
198 	 */
199 	consinit();
200 #endif
201 
202         /*
203 	 * Set the page size.
204 	 */
205 	uvm_setpagesize();
206 
207 	/*
208 	 * Initialize pmap module.
209 	 */
210 	pmap_bootstrap(startkernel, endkernel);
211 
212 #if NKSYMS || defined(DDB) || defined(LKM)
213 	ksyms_init((int)((u_long)endsym - (u_long)startsym), startsym, endsym);
214 #endif
215 
216 #ifdef DDB
217 	if (boothowto & RB_KDB)
218 		Debugger();
219 #endif
220 }
221 
222 void
223 mem_regions(mem, avail)
224 	struct mem_region **mem, **avail;
225 {
226 
227 	*mem = physmemr;
228 	*avail = availmemr;
229 }
230 
231 /*
232  * Machine dependent startup code.
233  */
234 void
235 cpu_startup()
236 {
237 	char modelbuf[256];
238 
239 	/*
240 	 * Mapping PReP-compatible interrput vector register.
241 	 */
242 	mvmeppc_intr_reg = (vaddr_t) mapiodev(MVMEPPC_INTR_REG, PAGE_SIZE);
243 	if (!mvmeppc_intr_reg)
244 		panic("startup: no room for interrupt register");
245 
246 	sprintf(modelbuf, "%s\nCore Speed: %dMHz, Bus Speed: %dMHz\n",
247 	    platform->model,
248 	    bootinfo.bi_mpuspeed/1000000,
249 	    bootinfo.bi_busspeed/1000000);
250 	oea_startup(modelbuf);
251 
252 	/*
253 	 * Now allow hardware interrupts.
254 	 */
255 	{
256 		int msr;
257 
258 		splraise(-1);
259 		__asm __volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0"
260 			      : "=r"(msr) : "K"(PSL_EE));
261 	}
262 
263 	bus_space_mallocok();
264 }
265 
266 /*
267  * consinit
268  * Initialize system console.
269  */
270 void
271 consinit()
272 {
273 	static int initted = 0;
274 
275 	if (initted)
276 		return;
277 	initted = 1;
278 
279 #if 0
280 
281 #if (NPFB > 0)
282 	if (!strcmp(consinfo->devname, "fb")) {
283 		pfb_cnattach(consinfo->addr);
284 #if (NPCKBC > 0)
285 		pckbc_cnattach(&mvmeppc_isa_io_space_tag, IO_KBD, KBCMDP,
286 		    PCKBC_KBD_SLOT);
287 #endif
288 		return;
289 	}
290 #endif
291 
292 #if (NVGA > 0) || (NGTEN > 0)
293 	if (!strcmp(consinfo->devname, "vga")) {
294 #if (NGTEN > 0)
295 		if (!gten_cnattach(&mvmeppc_mem_space_tag))
296 			goto dokbd;
297 #endif
298 #if (NVGA > 0)
299 		if (!vga_cnattach(&mvmeppc_io_space_tag, &mvmeppc_mem_space_tag,
300 				-1, 1))
301 			goto dokbd;
302 #endif
303 dokbd:
304 #if (NPCKBC > 0)
305 		pckbc_cnattach(&mvmeppc_isa_io_space_tag, IO_KBD, KBCMDP,
306 		    PCKBC_KBD_SLOT);
307 #endif
308 		return;
309 	}
310 #endif /* PC | VGA */
311 
312 #endif
313 
314 #if (NCOM > 0)
315 	if (!strcmp(bootinfo.bi_consoledev, "PC16550")) {
316 		bus_space_tag_t tag = &mvmeppc_isa_io_bs_tag;
317 		static const bus_addr_t caddr[2] = {0x3f8, 0x2f8};
318 		int rv;
319 		rv = comcnattach(tag, caddr[bootinfo.bi_consolechan],
320 		    bootinfo.bi_consolespeed, COM_FREQ, COM_TYPE_NORMAL,
321 		    bootinfo.bi_consolecflag);
322 		if (rv)
323 			panic("can't init serial console");
324 
325 		return;
326 	}
327 #endif
328 	panic("invalid console device %s", bootinfo.bi_consoledev);
329 }
330 
331 /*
332  * Soft tty interrupts.
333  */
334 void
335 softserial()
336 {
337 
338 #if (NCOM > 0)
339 	comsoft();
340 #endif
341 }
342 
343 /*
344  * Stray interrupts.
345  */
346 void
347 strayintr(irq)
348 	int irq;
349 {
350 
351 	log(LOG_ERR, "stray interrupt %d\n", irq);
352 }
353 
354 /*
355  * Halt or reboot the machine after syncing/dumping according to howto.
356  */
357 void
358 cpu_reboot(howto, what)
359 	int howto;
360 	char *what;
361 {
362 	static int syncing;
363 
364 	if (cold) {
365 		howto |= RB_HALT;
366 		goto halt_sys;
367 	}
368 
369 	boothowto = howto;
370 	if ((howto & RB_NOSYNC) == 0 && syncing == 0) {
371 		syncing = 1;
372 		vfs_shutdown();		/* sync */
373 		resettodr();		/* set wall clock */
374 	}
375 
376 	/* Disable intr */
377 	splhigh();
378 
379 	/* Do dump if requested */
380 	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
381 		oea_dumpsys();
382 
383 halt_sys:
384 	doshutdownhooks();
385 
386 	if (howto & RB_HALT) {
387                 printf("\n");
388                 printf("The operating system has halted.\n");
389                 printf("Please press any key to reboot.\n\n");
390                 cnpollc(1);	/* for proper keyboard command handling */
391                 cngetc();
392                 cnpollc(0);
393 	}
394 
395 	printf("rebooting...\n\n");
396 
397 	(*platform->reset)();
398 
399 	printf("Oops! Board reset failed!\n");
400 
401 	for (;;)
402 		continue;
403 	/* NOTREACHED */
404 }
405 
406 /*
407  * lcsplx() is called from locore; it is an open-coded version of
408  * splx() differing in that it returns the previous priority level.
409  */
410 int
411 lcsplx(ipl)
412 	int ipl;
413 {
414 	int oldcpl;
415 
416 	__asm __volatile("sync; eieio\n");	/* reorder protect */
417 	oldcpl = cpl;
418 	cpl = ipl;
419 	if (ipending & ~ipl)
420 		do_pending_int();
421 	__asm __volatile("sync; eieio\n");	/* reorder protect */
422 
423 	return (oldcpl);
424 }
425 
426 
427 struct powerpc_bus_space mvmeppc_isa_io_bs_tag = {
428 	_BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE,
429 	MVMEPPC_PHYS_BASE_IO,	/* 60x-bus address of ISA I/O Space */
430 	0x00000000,		/* Corresponds to ISA-bus I/O address 0x0 */
431 	0x00010000,		/* End of ISA-bus I/O address space, +1 */
432 };
433 
434 struct powerpc_bus_space mvmeppc_pci_io_bs_tag = {
435 	_BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_IO_TYPE,
436 	MVMEPPC_PHYS_BASE_IO,	/* 60x-bus address of PCI I/O Space */
437 	0x00000000,		/* Corresponds to PCI-bus I/O address 0x0 */
438 	MVMEPPC_PHYS_SIZE_IO,	/* End of PCI-bus I/O address space, +1 */
439 };
440 
441 struct powerpc_bus_space mvmeppc_isa_mem_bs_tag = {
442 	_BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE,
443 	MVMEPPC_PHYS_BASE_MEM,	/* 60x-bus address of ISA Memory Space */
444 	0x00000000,		/* Corresponds to ISA-bus Memory addr 0x0 */
445 	0x01000000,		/* End of ISA-bus Memory addr space, +1 */
446 };
447 
448 struct powerpc_bus_space mvmeppc_pci_mem_bs_tag = {
449 	_BUS_SPACE_LITTLE_ENDIAN|_BUS_SPACE_MEM_TYPE,
450 	MVMEPPC_PHYS_BASE_MEM,	/* 60x-bus address of PCI Memory Space */
451 	0x00000000,		/* Corresponds to PCI-bus Memory addr 0x0 */
452 	MVMEPPC_PHYS_SIZE_MEM,	/* End of PCI-bus Memory addr space, +1 */
453 };
454 static char ex_storage[MVMEPPC_BUS_SPACE_NUM_REGIONS][EXTENT_FIXED_STORAGE_SIZE(8)]
455     __attribute__((aligned(8)));
456 
457 
458 void
459 mvmeppc_bus_space_init(void)
460 {
461 
462 	int error;
463 
464 	error = bus_space_init(&mvmeppc_pci_io_bs_tag, "pci_io",
465 	    ex_storage[MVMEPPC_BUS_SPACE_IO],
466 	    sizeof(ex_storage[MVMEPPC_BUS_SPACE_IO]));
467 
468 	if (extent_alloc_region(mvmeppc_pci_io_bs_tag.pbs_extent,
469 	    MVMEPPC_PHYS_RESVD_START_IO, MVMEPPC_PHYS_RESVD_SIZE_IO,
470 	    EX_NOWAIT) != 0)
471 		panic("mvmeppc_bus_space_init: reserving I/O hole");
472 
473 	mvmeppc_isa_io_bs_tag.pbs_extent = mvmeppc_pci_io_bs_tag.pbs_extent;
474 	error = bus_space_init(&mvmeppc_isa_io_bs_tag, "isa_io", NULL, 0);
475 
476 	error = bus_space_init(&mvmeppc_pci_mem_bs_tag, "pci_mem",
477 	    ex_storage[MVMEPPC_BUS_SPACE_MEM],
478 	    sizeof(ex_storage[MVMEPPC_BUS_SPACE_MEM]));
479 
480 	mvmeppc_isa_mem_bs_tag.pbs_extent = mvmeppc_pci_mem_bs_tag.pbs_extent;
481 	error = bus_space_init(&mvmeppc_isa_mem_bs_tag, "isa_mem", NULL, 0);
482 }
483