xref: /netbsd/sys/arch/mvmeppc/mvmeppc/machdep.c (revision c4a72b64)
1 /*	$NetBSD: machdep.c,v 1.6 2002/09/25 22:21:14 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_mvmetype.h"
36 #include "opt_ddb.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 #include <uvm/uvm_extern.h>
56 
57 #include <sys/sysctl.h>
58 
59 #include <net/netisr.h>
60 
61 #include <machine/autoconf.h>
62 #include <machine/bat.h>
63 #include <machine/bootinfo.h>
64 #include <machine/bus.h>
65 #include <machine/intr.h>
66 #include <machine/pmap.h>
67 #include <machine/platform.h>
68 #include <machine/powerpc.h>
69 #include <machine/trap.h>
70 
71 #include <dev/cons.h>
72 
73 #if 0
74 #include "vga.h"
75 #if (NVGA > 0)
76 #include <dev/ic/mc6845reg.h>
77 #include <dev/ic/pcdisplayvar.h>
78 #include <dev/ic/vgareg.h>
79 #include <dev/ic/vgavar.h>
80 #endif
81 
82 #include "pckbc.h"
83 #if (NPCKBC > 0)
84 #include <dev/isa/isareg.h>
85 #include <dev/ic/i8042reg.h>
86 #include <dev/ic/pckbcvar.h>
87 #endif
88 #endif
89 
90 #include "com.h"
91 #if (NCOM > 0)
92 #include <sys/termios.h>
93 #include <dev/ic/comreg.h>
94 #include <dev/ic/comvar.h>
95 void comsoft(void);
96 #endif
97 
98 #ifdef DDB
99 #include <machine/db_machdep.h>
100 #include <ddb/db_extern.h>
101 #endif
102 
103 void initppc(u_long, u_long, void *);
104 void strayintr(int);
105 int lcsplx(int);
106 
107 
108 /*
109  * Global variables used here and there
110  */
111 struct mvmeppc_bootinfo bootinfo;
112 
113 vaddr_t mvmeppc_intr_reg;	/* PReP-compatible  interrupt vector register */
114 
115 struct mem_region physmemr[2], availmemr[2];
116 
117 paddr_t avail_end;			/* XXX temporary */
118 
119 void
120 initppc(startkernel, endkernel, btinfo)
121 	u_long startkernel, endkernel;
122 	void *btinfo;
123 {
124 #ifdef DDB
125 	extern void *startsym, *endsym;
126 #endif
127 
128 	/*
129 	 * Copy bootinfo.
130 	 */
131 	memcpy(&bootinfo, btinfo, sizeof(bootinfo));
132 
133 	/*
134 	 * Figure out the board family/type.
135 	 */
136 	ident_platform();
137 
138 	if (platform == NULL) {
139 		extern void _mvmeppc_unsup_board(const char *, const char *);
140 		char msg[80];
141 
142 		sprintf(msg, "Unsupported model: MVME%04x",
143 		    bootinfo.bi_modelnumber);
144 		_mvmeppc_unsup_board(msg, &msg[strlen(msg)]);
145 		/* NOTREACHED */
146 	}
147 
148 	/*
149 	 * Set memory region
150 	 */
151 	physmemr[0].start = 0;
152 	physmemr[0].size = bootinfo.bi_memsize & ~PGOFSET;
153 	availmemr[0].start = (endkernel + PGOFSET) & ~PGOFSET;
154 	availmemr[0].size = bootinfo.bi_memsize - availmemr[0].start;
155 	avail_end = physmemr[0].start + physmemr[0].size;    /* XXX temporary */
156 
157 	/*
158 	 * Set CPU clock
159 	 */
160 	{
161 		extern u_long ticks_per_sec, ns_per_tick;
162 
163 		ticks_per_sec = bootinfo.bi_clocktps;
164 		ns_per_tick = 1000000000 / ticks_per_sec;
165 	}
166 
167 	/*
168 	 * boothowto
169 	 */
170 	mpc6xx_batinit(
171 	    MVMEPPC_PHYS_BASE_IO,  BAT_BL_256M,
172 	    MVMEPPC_PHYS_BASE_MEM, BAT_BL_256M,
173 	    0);
174 
175 	/*
176 	 * Install vectors and interrupt handler.
177 	 */
178 	mpc6xx_init(platform->ext_intr);
179 
180 #ifdef DEBUG
181 	/*
182 	 * i386 port says, that this shouldn't be here,
183 	 * but I really think the console should be initialized
184 	 * as early as possible.
185 	 */
186 	consinit();
187 #endif
188         /*
189 	 * Set the page size.
190 	 */
191 	uvm_setpagesize();
192 
193 	/*
194 	 * Initialize pmap module.
195 	 */
196 	pmap_bootstrap(startkernel, endkernel, NULL);
197 
198 #ifdef DDB
199 	ddb_init((int)((u_long)endsym - (u_long)startsym), startsym, endsym);
200 
201 	if (boothowto & RB_KDB)
202 		Debugger();
203 #endif
204 }
205 
206 void
207 mem_regions(mem, avail)
208 	struct mem_region **mem, **avail;
209 {
210 
211 	*mem = physmemr;
212 	*avail = availmemr;
213 }
214 
215 /*
216  * Machine dependent startup code.
217  */
218 void
219 cpu_startup()
220 {
221 	char modelbuf[256];
222 
223 	/*
224 	 * Mapping PReP-compatible interrput vector register.
225 	 */
226 	mvmeppc_intr_reg = (vaddr_t) mapiodev(MVMEPPC_INTR_REG, NBPG);
227 	if (!mvmeppc_intr_reg)
228 		panic("startup: no room for interrupt register");
229 
230 	sprintf(modelbuf, "%s\nCore Speed: %dMHz, Bus Speed: %dMHz\n",
231 	    platform->model,
232 	    bootinfo.bi_mpuspeed/1000000,
233 	    bootinfo.bi_busspeed/1000000);
234 	mpc6xx_startup(modelbuf);
235 
236 	/*
237 	 * Now allow hardware interrupts.
238 	 */
239 	{
240 		int msr;
241 
242 		splraise(-1);
243 		__asm __volatile ("mfmsr %0; ori %0,%0,%1; mtmsr %0"
244 			      : "=r"(msr) : "K"(PSL_EE));
245 	}
246 
247 	mvmeppc_bus_space_init();
248 }
249 
250 /*
251  * consinit
252  * Initialize system console.
253  */
254 void
255 consinit()
256 {
257 	static int initted = 0;
258 
259 	if (initted)
260 		return;
261 	initted = 1;
262 
263 #if 0
264 
265 #if (NPFB > 0)
266 	if (!strcmp(consinfo->devname, "fb")) {
267 		pfb_cnattach(consinfo->addr);
268 #if (NPCKBC > 0)
269 		pckbc_cnattach(&mvmeppc_isa_io_space_tag, IO_KBD, KBCMDP,
270 		    PCKBC_KBD_SLOT);
271 #endif
272 		return;
273 	}
274 #endif
275 
276 #if (NVGA > 0) || (NGTEN > 0)
277 	if (!strcmp(consinfo->devname, "vga")) {
278 #if (NGTEN > 0)
279 		if (!gten_cnattach(&mvmeppc_mem_space_tag))
280 			goto dokbd;
281 #endif
282 #if (NVGA > 0)
283 		if (!vga_cnattach(&mvmeppc_io_space_tag, &mvmeppc_mem_space_tag,
284 				-1, 1))
285 			goto dokbd;
286 #endif
287 dokbd:
288 #if (NPCKBC > 0)
289 		pckbc_cnattach(&mvmeppc_isa_io_space_tag, IO_KBD, KBCMDP,
290 		    PCKBC_KBD_SLOT);
291 #endif
292 		return;
293 	}
294 #endif /* PC | VGA */
295 
296 #endif
297 
298 #if (NCOM > 0)
299 	if (!strcmp(bootinfo.bi_consoledev, "PC16550")) {
300 		bus_space_tag_t tag = &mvmeppc_isa_io_bs_tag;
301 		bus_addr_t caddr[2] = {0x3f8, 0x2f8};
302 		int rv;
303 		rv = comcnattach(tag, caddr[bootinfo.bi_consolechan],
304 		    bootinfo.bi_consolespeed, COM_FREQ,
305 		    bootinfo.bi_consolecflag);
306 		if (rv)
307 			panic("can't init serial console");
308 
309 		return;
310 	}
311 #endif
312 	panic("invalid console device %s", bootinfo.bi_consoledev);
313 }
314 
315 /*
316  * Soft tty interrupts.
317  */
318 void
319 softserial()
320 {
321 
322 #if (NCOM > 0)
323 	comsoft();
324 #endif
325 }
326 
327 /*
328  * Stray interrupts.
329  */
330 void
331 strayintr(irq)
332 	int irq;
333 {
334 
335 	log(LOG_ERR, "stray interrupt %d\n", irq);
336 }
337 
338 /*
339  * Halt or reboot the machine after syncing/dumping according to howto.
340  */
341 void
342 cpu_reboot(howto, what)
343 	int howto;
344 	char *what;
345 {
346 	static int syncing;
347 
348 	if (cold) {
349 		howto |= RB_HALT;
350 		goto halt_sys;
351 	}
352 
353 	boothowto = howto;
354 	if ((howto & RB_NOSYNC) == 0 && syncing == 0) {
355 		syncing = 1;
356 		vfs_shutdown();		/* sync */
357 		resettodr();		/* set wall clock */
358 	}
359 
360 	/* Disable intr */
361 	splhigh();
362 
363 	/* Do dump if requested */
364 	if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP)
365 		mpc6xx_dumpsys();
366 
367 halt_sys:
368 	doshutdownhooks();
369 
370 	if (howto & RB_HALT) {
371                 printf("\n");
372                 printf("The operating system has halted.\n");
373                 printf("Please press any key to reboot.\n\n");
374                 cnpollc(1);	/* for proper keyboard command handling */
375                 cngetc();
376                 cnpollc(0);
377 	}
378 
379 	printf("rebooting...\n\n");
380 
381 #if 0
382 	(*platform->reset)();
383 #endif
384 
385 	for (;;)
386 		continue;
387 	/* NOTREACHED */
388 }
389 
390 /*
391  * lcsplx() is called from locore; it is an open-coded version of
392  * splx() differing in that it returns the previous priority level.
393  */
394 int
395 lcsplx(ipl)
396 	int ipl;
397 {
398 	int oldcpl;
399 
400 	__asm__ volatile("sync; eieio\n");	/* reorder protect */
401 	oldcpl = cpl;
402 	cpl = ipl;
403 	if (ipending & ~ipl)
404 		do_pending_int();
405 	__asm__ volatile("sync; eieio\n");	/* reorder protect */
406 
407 	return (oldcpl);
408 }
409