xref: /netbsd/sys/arch/hp300/hp300/machdep.c (revision bf9ec67e)
1 /*	$NetBSD: machdep.c,v 1.158 2002/05/23 03:05:30 gmcgarry Exp $	*/
2 
3 /*
4  * Copyright (c) 1988 University of Utah.
5  * Copyright (c) 1982, 1986, 1990, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * the Systems Programming Group of the University of Utah Computer
10  * Science Department.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *	This product includes software developed by the University of
23  *	California, Berkeley and its contributors.
24  * 4. Neither the name of the University nor the names of its contributors
25  *    may be used to endorse or promote products derived from this software
26  *    without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38  * SUCH DAMAGE.
39  *
40  * from: Utah $Hdr: machdep.c 1.74 92/12/20$
41  *
42  *	@(#)machdep.c	8.10 (Berkeley) 4/20/94
43  */
44 
45 #include <sys/cdefs.h>
46 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.158 2002/05/23 03:05:30 gmcgarry Exp $");
47 
48 #include "opt_ddb.h"
49 #include "opt_compat_hpux.h"
50 #include "opt_compat_netbsd.h"
51 #include "hil.h"
52 
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/callout.h>
56 #include <sys/buf.h>
57 #include <sys/clist.h>
58 #include <sys/conf.h>
59 #include <sys/exec.h>
60 #include <sys/file.h>
61 #include <sys/ioctl.h>
62 #include <sys/kernel.h>
63 #include <sys/device.h>
64 #include <sys/malloc.h>
65 #include <sys/map.h>
66 #include <sys/mbuf.h>
67 #include <sys/mount.h>
68 #include <sys/msgbuf.h>
69 #include <sys/proc.h>
70 #include <sys/reboot.h>
71 #include <sys/signalvar.h>
72 #include <sys/syscallargs.h>
73 #include <sys/tty.h>
74 #include <sys/user.h>
75 #include <sys/exec.h>
76 #include <sys/core.h>
77 #include <sys/kcore.h>
78 #include <sys/vnode.h>
79 
80 #ifdef DDB
81 #include <machine/db_machdep.h>
82 #include <ddb/db_sym.h>
83 #include <ddb/db_extern.h>
84 #ifdef __ELF__
85 #include <sys/exec_elf.h>
86 #endif
87 #endif /* DDB */
88 
89 #include <machine/autoconf.h>
90 #include <machine/bootinfo.h>
91 #include <machine/bus.h>
92 #include <machine/cpu.h>
93 #include <machine/hp300spu.h>
94 #include <machine/reg.h>
95 #include <machine/psl.h>
96 #include <machine/pte.h>
97 
98 #include <machine/kcore.h>	/* XXX should be pulled in by sys/kcore.h */
99 
100 #include <dev/cons.h>
101 
102 #define	MAXMEM	64*1024	/* XXX - from cmap.h */
103 #include <uvm/uvm_extern.h>
104 
105 #include <sys/sysctl.h>
106 
107 #include "opt_useleds.h"
108 
109 #include <hp300/dev/hilreg.h>
110 #include <hp300/dev/hilioctl.h>
111 #include <hp300/dev/hilvar.h>
112 #ifdef USELEDS
113 #include <hp300/hp300/leds.h>
114 #endif
115 
116 /* the following is used externally (sysctl_hw) */
117 char	machine[] = MACHINE;	/* from <machine/param.h> */
118 
119 /* Our exported CPU info; we can have only one. */
120 struct cpu_info cpu_info_store;
121 
122 struct vm_map *exec_map = NULL;
123 struct vm_map *mb_map = NULL;
124 struct vm_map *phys_map = NULL;
125 
126 extern paddr_t avail_end;
127 
128 /*
129  * bootinfo base (physical and virtual).  The bootinfo is placed, by
130  * the boot loader, into the first page of kernel text, which is zero
131  * filled (see locore.s) and not mapped at 0.  It is remapped to a
132  * different address in pmap_bootstrap().
133  */
134 paddr_t	bootinfo_pa;
135 vaddr_t	bootinfo_va;
136 
137 caddr_t	msgbufaddr;
138 int	maxmem;			/* max memory per process */
139 int	physmem = MAXMEM;	/* max supported memory, changes to actual */
140 /*
141  * safepri is a safe priority for sleep to set for a spin-wait
142  * during autoconfiguration or after a panic.
143  */
144 int	safepri = PSL_LOWIPL;
145 
146 extern	u_int lowram;
147 extern	short exframesize[];
148 
149 #ifdef COMPAT_HPUX
150 extern struct emul emul_hpux;
151 #endif
152 
153 /* prototypes for local functions */
154 void	parityenable __P((void));
155 int	parityerror __P((struct frame *));
156 int	parityerrorfind __P((void));
157 void    identifycpu __P((void));
158 void    initcpu __P((void));
159 
160 int	cpu_dumpsize __P((void));
161 int	cpu_dump __P((int (*)(dev_t, daddr_t, caddr_t, size_t), daddr_t *));
162 void	cpu_init_kcore_hdr __P((void));
163 
164 /* functions called from locore.s */
165 void    dumpsys __P((void));
166 void	hp300_init __P((void));
167 void    straytrap __P((int, u_short));
168 void	nmihand __P((struct frame));
169 
170 /*
171  * Machine-dependent crash dump header info.
172  */
173 cpu_kcore_hdr_t cpu_kcore_hdr;
174 
175 /*
176  * Note that the value of delay_divisor is roughly
177  * 2048 / cpuspeed (where cpuspeed is in MHz) on 68020
178  * and 68030 systems.  See clock.c for the delay
179  * calibration algorithm.
180  */
181 int	cpuspeed;		/* relative cpu speed; XXX skewed on 68040 */
182 int	delay_divisor;		/* delay constant */
183 
184 /*
185  * Early initialization, before main() is called.
186  */
187 void
188 hp300_init()
189 {
190 	struct btinfo_magic *bt_mag;
191 	int i;
192 
193 	extern paddr_t avail_start, avail_end;
194 
195 	/*
196 	 * Tell the VM system about available physical memory.  The
197 	 * hp300 only has one segment.
198 	 */
199 	uvm_page_physload(atop(avail_start), atop(avail_end),
200 	    atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT);
201 
202 	/* Initialize the interrupt handlers. */
203 	intr_init();
204 
205 	/* Calibrate the delay loop. */
206 	hp300_calibrate_delay();
207 
208 	/*
209 	 * Initialize error message buffer (at end of core).
210 	 * avail_end was pre-decremented in pmap_bootstrap to compensate.
211 	 */
212 	for (i = 0; i < btoc(MSGBUFSIZE); i++)
213 		pmap_kenter_pa((vaddr_t)msgbufaddr + i * NBPG,
214 		    avail_end + i * NBPG, VM_PROT_READ|VM_PROT_WRITE);
215 	pmap_update(pmap_kernel());
216 	initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE));
217 
218 	/*
219 	 * Map in the bootinfo page, and make sure the bootinfo
220 	 * exists by searching for the MAGIC record.  If it's not
221 	 * there, disable bootinfo.
222 	 */
223 	pmap_enter(pmap_kernel(), bootinfo_va, bootinfo_pa,
224 	    VM_PROT_READ|VM_PROT_WRITE,
225 	    VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
226 	pmap_update(pmap_kernel());
227 	bt_mag = lookup_bootinfo(BTINFO_MAGIC);
228 	if (bt_mag == NULL ||
229 	    bt_mag->magic1 != BOOTINFO_MAGIC1 ||
230 	    bt_mag->magic2 != BOOTINFO_MAGIC2) {
231 		pmap_remove(pmap_kernel(), bootinfo_va, bootinfo_va + NBPG);
232 		pmap_update(pmap_kernel());
233 		bootinfo_va = 0;
234 	}
235 }
236 
237 /*
238  * Console initialization: called early on from main,
239  * before vm init or startup.  Do enough configuration
240  * to choose and initialize a console.
241  */
242 void
243 consinit()
244 {
245 	extern struct map extiomap[];
246 
247 	/*
248 	 * Initialize the DIO resource map.
249 	 */
250 	rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16);
251 
252 	/*
253 	 * Initialize the console before we print anything out.
254 	 */
255 
256 	hp300_cninit();
257 
258 	/*
259 	 * Issue a warning if the boot loader didn't provide bootinfo.
260 	 */
261 	if (bootinfo_va == 0)
262 		printf("WARNING: boot loader did not provide bootinfo\n");
263 
264 #ifdef DDB
265 	{
266 		extern int end;
267 		extern int *esym;
268 
269 #ifndef __ELF__
270 		ddb_init(*(int *)&end, ((int *)&end) + 1, esym);
271 #else
272 		ddb_init((int)esym - (int)&end - sizeof(Elf32_Ehdr),
273 		    (void *)&end, esym);
274 #endif
275 	}
276 	if (boothowto & RB_KDB)
277 		Debugger();
278 #endif
279 }
280 
281 /*
282  * cpu_startup: allocate memory for variable-sized tables,
283  * initialize cpu
284  */
285 void
286 cpu_startup()
287 {
288 	extern char *etext;
289 	unsigned i;
290 	caddr_t v;
291 	int base, residual;
292 	vaddr_t minaddr, maxaddr;
293 	vsize_t size;
294 	char pbuf[9];
295 #ifdef DEBUG
296 	extern int pmapdebug;
297 	int opmapdebug = pmapdebug;
298 
299 	pmapdebug = 0;
300 #endif
301 
302 	/*
303 	 * Initialize the kernel crash dump header.
304 	 */
305 	cpu_init_kcore_hdr();
306 
307 	/*
308 	 * Good {morning,afternoon,evening,night}.
309 	 */
310 	printf(version);
311 	identifycpu();
312 	format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
313 	printf("total memory = %s\n", pbuf);
314 
315 	/*
316 	 * Find out how much space we need, allocate it,
317 	 * and the give everything true virtual addresses.
318 	 */
319 	size = (vsize_t)allocsys(NULL, NULL);
320 	if ((v = (caddr_t)uvm_km_zalloc(kernel_map, round_page(size))) == 0)
321 		panic("startup: no room for tables");
322 	if ((allocsys(v, NULL) - v) != size)
323 		panic("startup: table size inconsistency");
324 
325 	/*
326 	 * Now allocate buffers proper.  They are different than the above
327 	 * in that they usually occupy more virtual memory than physical.
328 	 */
329 	size = MAXBSIZE * nbuf;
330 	if (uvm_map(kernel_map, (vaddr_t *) &buffers, round_page(size),
331 		    NULL, UVM_UNKNOWN_OFFSET, 0,
332 		    UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE,
333 				UVM_ADV_NORMAL, 0)) != 0)
334 		panic("startup: cannot allocate VM for buffers");
335 	minaddr = (vaddr_t)buffers;
336 	base = bufpages / nbuf;
337 	residual = bufpages % nbuf;
338 	for (i = 0; i < nbuf; i++) {
339 		vsize_t curbufsize;
340 		vaddr_t curbuf;
341 		struct vm_page *pg;
342 
343 		/*
344 		 * Each buffer has MAXBSIZE bytes of VM space allocated.  Of
345 		 * that MAXBSIZE space, we allocate and map (base+1) pages
346 		 * for the first "residual" buffers, and then we allocate
347 		 * "base" pages for the rest.
348 		 */
349 		curbuf = (vaddr_t) buffers + (i * MAXBSIZE);
350 		curbufsize = NBPG * ((i < residual) ? (base+1) : base);
351 
352 		while (curbufsize) {
353 			pg = uvm_pagealloc(NULL, 0, NULL, 0);
354 			if (pg == NULL)
355 				panic("cpu_startup: not enough memory for "
356 				    "buffer cache");
357 			pmap_kenter_pa(curbuf, VM_PAGE_TO_PHYS(pg),
358 					VM_PROT_READ|VM_PROT_WRITE);
359 			curbuf += PAGE_SIZE;
360 			curbufsize -= PAGE_SIZE;
361 		}
362 	}
363 	pmap_update(pmap_kernel());
364 
365 	/*
366 	 * Allocate a submap for exec arguments.  This map effectively
367 	 * limits the number of processes exec'ing at any time.
368 	 */
369 	exec_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
370 				   16*NCARGS, VM_MAP_PAGEABLE, FALSE, NULL);
371 
372 	/*
373 	 * Allocate a submap for physio
374 	 */
375 	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
376 				   VM_PHYS_SIZE, 0, FALSE, NULL);
377 
378 	/*
379 	 * Finally, allocate mbuf cluster submap.
380 	 */
381 	mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
382 				 nmbclusters * mclbytes, VM_MAP_INTRSAFE,
383 				 FALSE, NULL);
384 
385 #ifdef DEBUG
386 	pmapdebug = opmapdebug;
387 #endif
388 	format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free));
389 	printf("avail memory = %s\n", pbuf);
390 	format_bytes(pbuf, sizeof(pbuf), bufpages * NBPG);
391 	printf("using %d buffers containing %s of memory\n", nbuf, pbuf);
392 
393 	/*
394 	 * Tell the VM system that page 0 isn't mapped.
395 	 *
396 	 * XXX This is bogus; should just fix KERNBASE and
397 	 * XXX VM_MIN_KERNEL_ADDRESS, but not right now.
398 	 */
399 	if (uvm_map_protect(kernel_map, 0, NBPG, UVM_PROT_NONE, TRUE) != 0)
400 		panic("can't mark page 0 off-limits");
401 
402 	/*
403 	 * Tell the VM system that writing to kernel text isn't allowed.
404 	 * If we don't, we might end up COW'ing the text segment!
405 	 *
406 	 * XXX Should be m68k_trunc_page(&kernel_text) instead
407 	 * XXX of NBPG.
408 	 */
409 	if (uvm_map_protect(kernel_map, NBPG, m68k_round_page(&etext),
410 	    UVM_PROT_READ|UVM_PROT_EXEC, TRUE) != 0)
411 		panic("can't protect kernel text");
412 
413 	/*
414 	 * Set up CPU-specific registers, cache, etc.
415 	 */
416 	initcpu();
417 
418 	/*
419 	 * Set up buffers, so they can be used to read disk labels.
420 	 */
421 	bufinit();
422 }
423 
424 /*
425  * Set registers on exec.
426  */
427 void
428 setregs(p, pack, stack)
429 	struct proc *p;
430 	struct exec_package *pack;
431 	u_long stack;
432 {
433 	struct frame *frame = (struct frame *)p->p_md.md_regs;
434 
435 	frame->f_sr = PSL_USERSET;
436 	frame->f_pc = pack->ep_entry & ~1;
437 	frame->f_regs[D0] = 0;
438 	frame->f_regs[D1] = 0;
439 	frame->f_regs[D2] = 0;
440 	frame->f_regs[D3] = 0;
441 	frame->f_regs[D4] = 0;
442 	frame->f_regs[D5] = 0;
443 	frame->f_regs[D6] = 0;
444 	frame->f_regs[D7] = 0;
445 	frame->f_regs[A0] = 0;
446 	frame->f_regs[A1] = 0;
447 	frame->f_regs[A2] = (int)p->p_psstr;
448 	frame->f_regs[A3] = 0;
449 	frame->f_regs[A4] = 0;
450 	frame->f_regs[A5] = 0;
451 	frame->f_regs[A6] = 0;
452 	frame->f_regs[SP] = stack;
453 
454 	/* restore a null state frame */
455 	p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0;
456 	if (fputype)
457 		m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
458 }
459 
460 /*
461  * Info for CTL_HW
462  */
463 char	cpu_model[120];
464 
465 struct hp300_model {
466 	int id;
467 	int mmuid;
468 	const char *name;
469 	const char *speed;
470 };
471 
472 const struct hp300_model hp300_models[] = {
473 	{ HP_320,	-1,		"320",		"16.67"	},
474 	{ HP_330,	-1,		"318/319/330",	"16.67"	},
475 	{ HP_340,	-1,		"340",		"16.67"	},
476 	{ HP_345,	-1,		"345",		"50"	},
477 	{ HP_350,	-1,		"350",		"25"	},
478 	{ HP_360,	-1,		"360",		"25"	},
479 	{ HP_370,	-1,		"370",		"33.33"	},
480 	{ HP_375,	-1,		"375",		"50"	},
481 	{ HP_380,	-1,		"380",		"25"	},
482 	{ HP_385,	-1,		"385",		"33"	},
483 	{ HP_400,	-1,		"400",		"50"	},
484 	{ HP_425,	MMUID_425_T,	"425t",		"25"	},
485 	{ HP_425,	MMUID_425_S,	"425s",		"25"	},
486 	{ HP_425,	MMUID_425_E,	"425e",		"25"	},
487 	{ HP_425,	-1,		"425",		"25"	},
488 	{ HP_433,	MMUID_433_T,	"433t",		"33"	},
489 	{ HP_433,	MMUID_433_S,	"433s",		"33"	},
490 	{ HP_433,	-1,		"433",		"33"	},
491 	{ 0,		-1,		NULL,		NULL	},
492 };
493 
494 void
495 identifycpu()
496 {
497 	const char *t, *mc, *s;
498 	int i, len;
499 
500 	/*
501 	 * Find the model number.
502 	 */
503 	for (t = s = NULL, i = 0; hp300_models[i].name != NULL; i++) {
504 		if (hp300_models[i].id == machineid) {
505 			if (hp300_models[i].mmuid != -1 &&
506 			    hp300_models[i].mmuid != mmuid)
507 				continue;
508 			t = hp300_models[i].name;
509 			s = hp300_models[i].speed;
510 			break;
511 		}
512 	}
513 	if (t == NULL) {
514 		printf("\nunknown machineid %d\n", machineid);
515 		goto lose;
516 	}
517 
518 	/*
519 	 * ...and the CPU type.
520 	 */
521 	switch (cputype) {
522 	case CPU_68040:
523 		mc = "40";
524 		break;
525 	case CPU_68030:
526 		mc = "30";
527 		break;
528 	case CPU_68020:
529 		mc = "20";
530 		break;
531 	default:
532 		printf("\nunknown cputype %d\n", cputype);
533 		goto lose;
534 	}
535 
536 	sprintf(cpu_model, "HP 9000/%s (%sMHz MC680%s CPU", t, s, mc);
537 
538 	/*
539 	 * ...and the MMU type.
540 	 */
541 	switch (mmutype) {
542 	case MMU_68040:
543 	case MMU_68030:
544 		strcat(cpu_model, "+MMU");
545 		break;
546 	case MMU_68851:
547 		strcat(cpu_model, ", MC68851 MMU");
548 		break;
549 	case MMU_HP:
550 		strcat(cpu_model, ", HP MMU");
551 		break;
552 	default:
553 		printf("%s\nunknown MMU type %d\n", cpu_model, mmutype);
554 		panic("startup");
555 	}
556 
557 	len = strlen(cpu_model);
558 
559 	/*
560 	 * ...and the FPU type.
561 	 */
562 	switch (fputype) {
563 	case FPU_68040:
564 		len += sprintf(cpu_model + len, "+FPU");
565 		break;
566 	case FPU_68882:
567 		len += sprintf(cpu_model + len, ", %sMHz MC68882 FPU", s);
568 		break;
569 	case FPU_68881:
570 		len += sprintf(cpu_model + len, ", %sMHz MC68881 FPU",
571 		    machineid == HP_350 ? "20" : "16.67");
572 		break;
573 	default:
574 		len += sprintf(cpu_model + len, ", unknown FPU");
575 	}
576 
577 	/*
578 	 * ...and finally, the cache type.
579 	 */
580 	if (cputype == CPU_68040)
581 		sprintf(cpu_model + len, ", 4k on-chip physical I/D caches");
582 	else {
583 		switch (ectype) {
584 		case EC_VIRT:
585 			sprintf(cpu_model + len,
586 			    ", %dK virtual-address cache",
587 			    machineid == HP_320 ? 16 : 32);
588 			break;
589 		case EC_PHYS:
590 			sprintf(cpu_model + len,
591 			    ", %dK physical-address cache",
592 			    machineid == HP_370 ? 64 : 32);
593 			break;
594 		}
595 	}
596 
597 	strcat(cpu_model, ")");
598 	printf("%s\n", cpu_model);
599 #ifdef DIAGNOSTIC
600 	printf("cpu: delay divisor %d", delay_divisor);
601 	if (mmuid)
602 		printf(", mmuid %d", mmuid);
603 	printf("\n");
604 #endif
605 
606 	/*
607 	 * Now that we have told the user what they have,
608 	 * let them know if that machine type isn't configured.
609 	 */
610 	switch (machineid) {
611 	case -1:		/* keep compilers happy */
612 #if !defined(HP320)
613 	case HP_320:
614 #endif
615 #if !defined(HP330)
616 	case HP_330:
617 #endif
618 #if !defined(HP340)
619 	case HP_340:
620 #endif
621 #if !defined(HP345)
622 	case HP_345:
623 #endif
624 #if !defined(HP350)
625 	case HP_350:
626 #endif
627 #if !defined(HP360)
628 	case HP_360:
629 #endif
630 #if !defined(HP370)
631 	case HP_370:
632 #endif
633 #if !defined(HP375)
634 	case HP_375:
635 #endif
636 #if !defined(HP380)
637 	case HP_380:
638 #endif
639 #if !defined(HP385)
640 	case HP_385:
641 #endif
642 #if !defined(HP400)
643 	case HP_400:
644 #endif
645 #if !defined(HP425)
646 	case HP_425:
647 #endif
648 #if !defined(HP433)
649 	case HP_433:
650 #endif
651 		panic("SPU type not configured");
652 	default:
653 		break;
654 	}
655 
656 	return;
657  lose:
658 	panic("startup");
659 }
660 
661 /*
662  * machine dependent system variables.
663  */
664 int
665 cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
666 	int *name;
667 	u_int namelen;
668 	void *oldp;
669 	size_t *oldlenp;
670 	void *newp;
671 	size_t newlen;
672 	struct proc *p;
673 {
674 	dev_t consdev;
675 
676 	/* all sysctl names at this level are terminal */
677 	if (namelen != 1)
678 		return (ENOTDIR);		/* overloaded */
679 
680 	switch (name[0]) {
681 	case CPU_CONSDEV:
682 		if (cn_tab != NULL)
683 			consdev = cn_tab->cn_dev;
684 		else
685 			consdev = NODEV;
686 		return (sysctl_rdstruct(oldp, oldlenp, newp, &consdev,
687 		    sizeof consdev));
688 	default:
689 		return (EOPNOTSUPP);
690 	}
691 	/* NOTREACHED */
692 }
693 
694 int	waittime = -1;
695 
696 void
697 cpu_reboot(howto, bootstr)
698 	int howto;
699 	char *bootstr;
700 {
701 
702 #if __GNUC__	/* XXX work around lame compiler problem (gcc 2.7.2) */
703 	(void)&howto;
704 #endif
705 	/* take a snap shot before clobbering any registers */
706 	if (curproc && curproc->p_addr)
707 		savectx(&curproc->p_addr->u_pcb);
708 
709 	/* If system is cold, just halt. */
710 	if (cold) {
711 		howto |= RB_HALT;
712 		goto haltsys;
713 	}
714 
715 	boothowto = howto;
716 	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
717 		waittime = 0;
718 		vfs_shutdown();
719 		/*
720 		 * If we've been adjusting the clock, the todr
721 		 * will be out of synch; adjust it now.
722 		 */
723 		resettodr();
724 	}
725 
726 	/* Disable interrupts. */
727 	splhigh();
728 
729 	/* If rebooting and a dump is requested do it. */
730 	if (howto & RB_DUMP)
731 		dumpsys();
732 
733  haltsys:
734 	/* Run any shutdown hooks. */
735 	doshutdownhooks();
736 
737 #if defined(PANICWAIT) && !defined(DDB)
738 	if ((howto & RB_HALT) == 0 && panicstr) {
739 		printf("hit any key to reboot...\n");
740 		(void)cngetc();
741 		printf("\n");
742 	}
743 #endif
744 
745 	/* Finally, halt/reboot the system. */
746 	if (howto & RB_HALT) {
747 		printf("System halted.  Hit any key to reboot.\n\n");
748 		(void)cngetc();
749 	}
750 
751 	printf("rebooting...\n");
752 	DELAY(1000000);
753 	doboot();
754 	/*NOTREACHED*/
755 }
756 
757 /*
758  * Initialize the kernel crash dump header.
759  */
760 void
761 cpu_init_kcore_hdr()
762 {
763 	cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
764 	struct m68k_kcore_hdr *m = &h->un._m68k;
765 	extern int end;
766 
767 	memset(&cpu_kcore_hdr, 0, sizeof(cpu_kcore_hdr));
768 
769 	/*
770 	 * Initialize the `dispatcher' portion of the header.
771 	 */
772 	strcpy(h->name, machine);
773 	h->page_size = NBPG;
774 	h->kernbase = KERNBASE;
775 
776 	/*
777 	 * Fill in information about our MMU configuration.
778 	 */
779 	m->mmutype	= mmutype;
780 	m->sg_v		= SG_V;
781 	m->sg_frame	= SG_FRAME;
782 	m->sg_ishift	= SG_ISHIFT;
783 	m->sg_pmask	= SG_PMASK;
784 	m->sg40_shift1	= SG4_SHIFT1;
785 	m->sg40_mask2	= SG4_MASK2;
786 	m->sg40_shift2	= SG4_SHIFT2;
787 	m->sg40_mask3	= SG4_MASK3;
788 	m->sg40_shift3	= SG4_SHIFT3;
789 	m->sg40_addr1	= SG4_ADDR1;
790 	m->sg40_addr2	= SG4_ADDR2;
791 	m->pg_v		= PG_V;
792 	m->pg_frame	= PG_FRAME;
793 
794 	/*
795 	 * Initialize pointer to kernel segment table.
796 	 */
797 	m->sysseg_pa = (u_int32_t)(pmap_kernel()->pm_stpa);
798 
799 	/*
800 	 * Initialize relocation value such that:
801 	 *
802 	 *	pa = (va - KERNBASE) + reloc
803 	 */
804 	m->reloc = lowram;
805 
806 	/*
807 	 * Define the end of the relocatable range.
808 	 */
809 	m->relocend = (u_int32_t)&end;
810 
811 	/*
812 	 * hp300 has one contiguous memory segment.
813 	 */
814 	m->ram_segs[0].start = lowram;
815 	m->ram_segs[0].size  = ctob(physmem);
816 }
817 
818 /*
819  * Compute the size of the machine-dependent crash dump header.
820  * Returns size in disk blocks.
821  */
822 int
823 cpu_dumpsize()
824 {
825 	int size;
826 
827 	size = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
828 	return (btodb(roundup(size, dbtob(1))));
829 }
830 
831 /*
832  * Called by dumpsys() to dump the machine-dependent header.
833  */
834 int
835 cpu_dump(dump, blknop)
836 	int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
837 	daddr_t *blknop;
838 {
839 	int buf[dbtob(1) / sizeof(int)];
840 	cpu_kcore_hdr_t *chdr;
841 	kcore_seg_t *kseg;
842 	int error;
843 
844 	kseg = (kcore_seg_t *)buf;
845 	chdr = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) /
846 	    sizeof(int)];
847 
848 	/* Create the segment header. */
849 	CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
850 	kseg->c_size = dbtob(1) - ALIGN(sizeof(kcore_seg_t));
851 
852 	memcpy(chdr, &cpu_kcore_hdr, sizeof(cpu_kcore_hdr_t));
853 	error = (*dump)(dumpdev, *blknop, (caddr_t)buf, sizeof(buf));
854 	*blknop += btodb(sizeof(buf));
855 	return (error);
856 }
857 
858 /*
859  * These variables are needed by /sbin/savecore
860  */
861 u_int32_t dumpmag = 0x8fca0101;	/* magic number */
862 int	dumpsize = 0;		/* pages */
863 long	dumplo = 0;		/* blocks */
864 
865 /*
866  * This is called by main to set dumplo and dumpsize.
867  * Dumps always skip the first NBPG of disk space
868  * in case there might be a disk label stored there.
869  * If there is extra space, put dump at the end to
870  * reduce the chance that swapping trashes it.
871  */
872 void
873 cpu_dumpconf()
874 {
875 	int chdrsize;	/* size of dump header */
876 	int nblks;	/* size of dump area */
877 	int maj;
878 
879 	if (dumpdev == NODEV)
880 		return;
881 	maj = major(dumpdev);
882 	if (maj < 0 || maj >= nblkdev)
883 		panic("dumpconf: bad dumpdev=0x%x", dumpdev);
884 	if (bdevsw[maj].d_psize == NULL)
885 		return;
886 	nblks = (*bdevsw[maj].d_psize)(dumpdev);
887 	chdrsize = cpu_dumpsize();
888 
889 	dumpsize = btoc(cpu_kcore_hdr.un._m68k.ram_segs[0].size);
890 
891 	/*
892 	 * Check do see if we will fit.  Note we always skip the
893 	 * first NBPG in case there is a disk label there.
894 	 */
895 	if (nblks < (ctod(dumpsize) + chdrsize + ctod(1))) {
896 		dumpsize = 0;
897 		dumplo = -1;
898 		return;
899 	}
900 
901 	/*
902 	 * Put dump at the end of the partition.
903 	 */
904 	dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize;
905 }
906 
907 /*
908  * Dump physical memory onto the dump device.  Called by cpu_reboot().
909  */
910 void
911 dumpsys()
912 {
913 	daddr_t blkno;		/* current block to write */
914 				/* dump routine */
915 	int (*dump) __P((dev_t, daddr_t, caddr_t, size_t));
916 	int pg;			/* page being dumped */
917 	paddr_t maddr;		/* PA being dumped */
918 	int error;		/* error code from (*dump)() */
919 
920 	/* XXX initialized here because of gcc lossage */
921 	maddr = lowram;
922 	pg = 0;
923 
924 	/* Make sure dump device is valid. */
925 	if (dumpdev == NODEV)
926 		return;
927 	if (dumpsize == 0) {
928 		cpu_dumpconf();
929 		if (dumpsize == 0)
930 			return;
931 	}
932 	if (dumplo <= 0) {
933 		printf("\ndump to dev %u,%u not possible\n", major(dumpdev),
934 		    minor(dumpdev));
935 		return;
936 	}
937 	dump = bdevsw[major(dumpdev)].d_dump;
938 	blkno = dumplo;
939 
940 	printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev),
941 	    minor(dumpdev), dumplo);
942 
943 	printf("dump ");
944 
945 	/* Write the dump header. */
946 	error = cpu_dump(dump, &blkno);
947 	if (error)
948 		goto bad;
949 
950 	for (pg = 0; pg < dumpsize; pg++) {
951 #define NPGMB	(1024*1024/NBPG)
952 		/* print out how many MBs we have dumped */
953 		if (pg && (pg % NPGMB) == 0)
954 			printf("%d ", pg / NPGMB);
955 #undef NPGMB
956 		pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr,
957 		    VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
958 
959 		pmap_update(pmap_kernel());
960 		error = (*dump)(dumpdev, blkno, vmmap, NBPG);
961  bad:
962 		switch (error) {
963 		case 0:
964 			maddr += NBPG;
965 			blkno += btodb(NBPG);
966 			break;
967 
968 		case ENXIO:
969 			printf("device bad\n");
970 			return;
971 
972 		case EFAULT:
973 			printf("device not ready\n");
974 			return;
975 
976 		case EINVAL:
977 			printf("area improper\n");
978 			return;
979 
980 		case EIO:
981 			printf("i/o error\n");
982 			return;
983 
984 		case EINTR:
985 			printf("aborted from console\n");
986 			return;
987 
988 		default:
989 			printf("error %d\n", error);
990 			return;
991 		}
992 	}
993 	printf("succeeded\n");
994 }
995 
996 void
997 initcpu()
998 {
999 
1000 #ifdef MAPPEDCOPY
1001 	/*
1002 	 * Initialize lower bound for doing copyin/copyout using
1003 	 * page mapping (if not already set).  We don't do this on
1004 	 * VAC machines as it loses big time.
1005 	 */
1006 	if (ectype == EC_VIRT)
1007 		mappedcopysize = -1;	/* in case it was patched */
1008 	else
1009 		mappedcopysize = NBPG;
1010 #endif
1011 	parityenable();
1012 #ifdef USELEDS
1013 	ledinit();
1014 #endif
1015 }
1016 
1017 void
1018 straytrap(pc, evec)
1019 	int pc;
1020 	u_short evec;
1021 {
1022 	printf("unexpected trap (vector offset %x) from %x\n",
1023 	       evec & 0xFFF, pc);
1024 }
1025 
1026 /* XXX should change the interface, and make one badaddr() function */
1027 
1028 int	*nofault;
1029 
1030 int
1031 badaddr(addr)
1032 	caddr_t addr;
1033 {
1034 	int i;
1035 	label_t	faultbuf;
1036 
1037 	nofault = (int *) &faultbuf;
1038 	if (setjmp((label_t *)nofault)) {
1039 		nofault = (int *) 0;
1040 		return(1);
1041 	}
1042 	i = *(volatile short *)addr;
1043 	nofault = (int *) 0;
1044 	return(0);
1045 }
1046 
1047 int
1048 badbaddr(addr)
1049 	caddr_t addr;
1050 {
1051 	int i;
1052 	label_t	faultbuf;
1053 
1054 	nofault = (int *) &faultbuf;
1055 	if (setjmp((label_t *)nofault)) {
1056 		nofault = (int *) 0;
1057 		return(1);
1058 	}
1059 	i = *(volatile char *)addr;
1060 	nofault = (int *) 0;
1061 	return(0);
1062 }
1063 
1064 /*
1065  * lookup_bootinfo:
1066  *
1067  *	Look up information in bootinfo from boot loader.
1068  */
1069 void *
1070 lookup_bootinfo(type)
1071 	int type;
1072 {
1073 	struct btinfo_common *bt;
1074 	char *help = (char *)bootinfo_va;
1075 
1076 	/* Check for a bootinfo record first. */
1077 	if (help == NULL)
1078 		return (NULL);
1079 
1080 	do {
1081 		bt = (struct btinfo_common *)help;
1082 		if (bt->type == type)
1083 			return (help);
1084 		help += bt->next;
1085 	} while (bt->next != 0 &&
1086 		 (size_t)help < (size_t)bootinfo_va + BOOTINFO_SIZE);
1087 
1088 	return (NULL);
1089 }
1090 
1091 #ifdef PANICBUTTON
1092 /*
1093  * Declare these so they can be patched.
1094  */
1095 int panicbutton = 1;	/* non-zero if panic buttons are enabled */
1096 int candbdiv = 2;	/* give em half a second (hz / candbdiv) */
1097 
1098 void	candbtimer __P((void *));
1099 
1100 int crashandburn;
1101 
1102 struct callout candbtimer_ch = CALLOUT_INITIALIZER;
1103 
1104 void
1105 candbtimer(arg)
1106 	void *arg;
1107 {
1108 
1109 	crashandburn = 0;
1110 }
1111 #endif /* PANICBUTTON */
1112 
1113 static int innmihand;	/* simple mutex */
1114 
1115 /*
1116  * Level 7 interrupts can be caused by the keyboard or parity errors.
1117  */
1118 void
1119 nmihand(frame)
1120 	struct frame frame;
1121 {
1122 
1123 	/* Prevent unwanted recursion. */
1124 	if (innmihand)
1125 		return;
1126 	innmihand = 1;
1127 
1128 #if NHIL > 0
1129 	/* Check for keyboard <CRTL>+<SHIFT>+<RESET>. */
1130 	if (kbdnmi()) {
1131 		printf("Got a keyboard NMI");
1132 
1133 		/*
1134 		 * We can:
1135 		 *
1136 		 *	- enter DDB
1137 		 *
1138 		 *	- Start the crashandburn sequence
1139 		 *
1140 		 *	- Ignore it.
1141 		 */
1142 #ifdef DDB
1143 		printf(": entering debugger\n");
1144 		Debugger();
1145 #else
1146 #ifdef PANICBUTTON
1147 		if (panicbutton) {
1148 			if (crashandburn) {
1149 				crashandburn = 0;
1150 				printf(": CRASH AND BURN!\n");
1151 				panic("forced crash");
1152 			} else {
1153 				/* Start the crashandburn sequence */
1154 				printf("\n");
1155 				crashandburn = 1;
1156 				callout_reset(&candbtimer_ch, hz / candbdiv,
1157 				    candbtiner, NULL);
1158 			}
1159 		} else
1160 #endif /* PANICBUTTON */
1161 			printf(": ignoring\n");
1162 #endif /* DDB */
1163 
1164 		goto nmihand_out;	/* no more work to do */
1165 	}
1166 #endif
1167 
1168 	if (parityerror(&frame))
1169 		return;
1170 	/* panic?? */
1171 	printf("unexpected level 7 interrupt ignored\n");
1172 
1173 #if NHIL > 0
1174 nmihand_out:
1175 	innmihand = 0;
1176 #endif
1177 }
1178 
1179 /*
1180  * Parity error section.  Contains magic.
1181  */
1182 #define PARREG		((volatile short *)IIOV(0x5B0000))
1183 static int gotparmem = 0;
1184 #ifdef DEBUG
1185 int ignorekperr = 0;	/* ignore kernel parity errors */
1186 #endif
1187 
1188 /*
1189  * Enable parity detection
1190  */
1191 void
1192 parityenable()
1193 {
1194 	label_t	faultbuf;
1195 
1196 	nofault = (int *) &faultbuf;
1197 	if (setjmp((label_t *)nofault)) {
1198 		nofault = (int *) 0;
1199 		printf("Parity detection disabled\n");
1200 		return;
1201 	}
1202 	*PARREG = 1;
1203 	nofault = (int *) 0;
1204 	gotparmem = 1;
1205 }
1206 
1207 /*
1208  * Determine if level 7 interrupt was caused by a parity error
1209  * and deal with it if it was.  Returns 1 if it was a parity error.
1210  */
1211 int
1212 parityerror(fp)
1213 	struct frame *fp;
1214 {
1215 	if (!gotparmem)
1216 		return(0);
1217 	*PARREG = 0;
1218 	DELAY(10);
1219 	*PARREG = 1;
1220 	if (panicstr) {
1221 		printf("parity error after panic ignored\n");
1222 		return(1);
1223 	}
1224 	if (!parityerrorfind())
1225 		printf("WARNING: transient parity error ignored\n");
1226 	else if (USERMODE(fp->f_sr)) {
1227 		printf("pid %d: parity error\n", curproc->p_pid);
1228 		uprintf("sorry, pid %d killed due to memory parity error\n",
1229 			curproc->p_pid);
1230 		psignal(curproc, SIGKILL);
1231 #ifdef DEBUG
1232 	} else if (ignorekperr) {
1233 		printf("WARNING: kernel parity error ignored\n");
1234 #endif
1235 	} else {
1236 		regdump((struct trapframe *)fp, 128);
1237 		panic("kernel parity error");
1238 	}
1239 	return(1);
1240 }
1241 
1242 /*
1243  * Yuk!  There has got to be a better way to do this!
1244  * Searching all of memory with interrupts blocked can lead to disaster.
1245  */
1246 int
1247 parityerrorfind()
1248 {
1249 	static label_t parcatch;
1250 	static int looking = 0;
1251 	volatile int pg, o, s;
1252 	volatile int *ip;
1253 	int i;
1254 	int found;
1255 
1256 #ifdef lint
1257 	i = o = pg = 0; if (i) return(0);
1258 #endif
1259 	/*
1260 	 * If looking is true we are searching for a known parity error
1261 	 * and it has just occurred.  All we do is return to the higher
1262 	 * level invocation.
1263 	 */
1264 	if (looking)
1265 		longjmp(&parcatch);
1266 	s = splhigh();
1267 	/*
1268 	 * If setjmp returns true, the parity error we were searching
1269 	 * for has just occurred (longjmp above) at the current pg+o
1270 	 */
1271 	if (setjmp(&parcatch)) {
1272 		printf("Parity error at 0x%x\n", ctob(pg)|o);
1273 		found = 1;
1274 		goto done;
1275 	}
1276 	/*
1277 	 * If we get here, a parity error has occurred for the first time
1278 	 * and we need to find it.  We turn off any external caches and
1279 	 * loop thru memory, testing every longword til a fault occurs and
1280 	 * we regain control at setjmp above.  Note that because of the
1281 	 * setjmp, pg and o need to be volatile or their values will be lost.
1282 	 */
1283 	looking = 1;
1284 	ecacheoff();
1285 	for (pg = btoc(lowram); pg < btoc(lowram)+physmem; pg++) {
1286 		pmap_enter(pmap_kernel(), (vaddr_t)vmmap, ctob(pg),
1287 		    VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
1288 		pmap_update(pmap_kernel());
1289 		ip = (int *)vmmap;
1290 		for (o = 0; o < NBPG; o += sizeof(int))
1291 			i = *ip++;
1292 	}
1293 	/*
1294 	 * Getting here implies no fault was found.  Should never happen.
1295 	 */
1296 	printf("Couldn't locate parity error\n");
1297 	found = 0;
1298 done:
1299 	looking = 0;
1300 	pmap_remove(pmap_kernel(), (vaddr_t)vmmap, (vaddr_t)&vmmap[NBPG]);
1301 	pmap_update(pmap_kernel());
1302 	ecacheon();
1303 	splx(s);
1304 	return(found);
1305 }
1306 
1307 /*
1308  * cpu_exec_aout_makecmds():
1309  *	cpu-dependent a.out format hook for execve().
1310  *
1311  * Determine of the given exec package refers to something which we
1312  * understand and, if so, set up the vmcmds for it.
1313  *
1314  * XXX what are the special cases for the hp300?
1315  * XXX why is this COMPAT_NOMID?  was something generating
1316  *	hp300 binaries with an a_mid of 0?  i thought that was only
1317  *	done on little-endian machines...  -- cgd
1318  */
1319 int
1320 cpu_exec_aout_makecmds(p, epp)
1321 	struct proc *p;
1322 	struct exec_package *epp;
1323 {
1324 #if defined(COMPAT_NOMID) || defined(COMPAT_44)
1325 	u_long midmag, magic;
1326 	u_short mid;
1327 	int error;
1328 	struct exec *execp = epp->ep_hdr;
1329 
1330 	midmag = ntohl(execp->a_midmag);
1331 	mid = (midmag >> 16) & 0xffff;
1332 	magic = midmag & 0xffff;
1333 
1334 	midmag = mid << 16 | magic;
1335 
1336 	switch (midmag) {
1337 #ifdef COMPAT_NOMID
1338 	case (MID_ZERO << 16) | ZMAGIC:
1339 		error = exec_aout_prep_oldzmagic(p, epp);
1340 		return(error);
1341 #endif
1342 #ifdef COMPAT_44
1343 	case (MID_HP300 << 16) | ZMAGIC:
1344 		error = exec_aout_prep_oldzmagic(p, epp);
1345 		return(error);
1346 #endif
1347 	}
1348 #endif /* !(defined(COMPAT_NOMID) || defined(COMPAT_44)) */
1349 
1350 	return ENOEXEC;
1351 }
1352