Home | History | Annotate | Line # | Download | only in hp300
      1 /*	$NetBSD: machdep.c,v 1.240 2024/12/21 17:53:21 tsutsui 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. Neither the name of the University nor the names of its contributors
     21  *    may be used to endorse or promote products derived from this software
     22  *    without specific prior written permission.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34  * SUCH DAMAGE.
     35  *
     36  * from: Utah $Hdr: machdep.c 1.74 92/12/20$
     37  *
     38  *	@(#)machdep.c	8.10 (Berkeley) 4/20/94
     39  */
     40 
     41 #include <sys/cdefs.h>
     42 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.240 2024/12/21 17:53:21 tsutsui Exp $");
     43 
     44 #include "opt_ddb.h"
     45 #include "opt_compat_netbsd.h"
     46 #include "opt_fpu_emulate.h"
     47 #include "opt_modular.h"
     48 #include "opt_panicbutton.h"
     49 
     50 #include <sys/param.h>
     51 #include <sys/systm.h>
     52 #include <sys/callout.h>
     53 #include <sys/buf.h>
     54 #include <sys/conf.h>
     55 #include <sys/exec.h>
     56 #include <sys/exec_aout.h>		/* for MID_* */
     57 #include <sys/file.h>
     58 #include <sys/ioctl.h>
     59 #include <sys/kernel.h>
     60 #include <sys/device.h>
     61 #include <sys/malloc.h>
     62 #include <sys/mbuf.h>
     63 #include <sys/mount.h>
     64 #include <sys/msgbuf.h>
     65 #include <sys/proc.h>
     66 #include <sys/reboot.h>
     67 #include <sys/signalvar.h>
     68 #include <sys/syscallargs.h>
     69 #include <sys/tty.h>
     70 #include <sys/core.h>
     71 #include <sys/kcore.h>
     72 #include <sys/vnode.h>
     73 #include <sys/ksyms.h>
     74 #include <sys/module.h>
     75 #include <sys/cpu.h>
     76 
     77 #ifdef DDB
     78 #include <machine/db_machdep.h>
     79 #include <ddb/db_sym.h>
     80 #include <ddb/db_extern.h>
     81 #endif /* DDB */
     82 #include <sys/exec_elf.h>
     83 
     84 #include <machine/autoconf.h>
     85 #include <machine/bootinfo.h>
     86 #include <machine/bus.h>
     87 #include <machine/cpu.h>
     88 #include <machine/hp300spu.h>
     89 #include <machine/reg.h>
     90 #include <machine/pcb.h>
     91 #include <machine/psl.h>
     92 #include <machine/pte.h>
     93 
     94 #include <machine/kcore.h>	/* XXX should be pulled in by sys/kcore.h */
     95 
     96 #include <dev/cons.h>
     97 #include <dev/mm.h>
     98 
     99 #define	MAXMEM	64*1024	/* XXX - from cmap.h */
    100 #include <uvm/uvm_extern.h>
    101 
    102 #include <sys/sysctl.h>
    103 
    104 #include "opt_useleds.h"
    105 
    106 #ifdef USELEDS
    107 #include <hp300/hp300/leds.h>
    108 #endif
    109 
    110 #include "ksyms.h"
    111 
    112 /* the following is used externally (sysctl_hw) */
    113 char	machine[] = MACHINE;	/* from <machine/param.h> */
    114 
    115 /* Our exported CPU info; we can have only one. */
    116 struct cpu_info cpu_info_store;
    117 
    118 struct vm_map *phys_map = NULL;
    119 
    120 extern paddr_t avail_end;
    121 
    122 /*
    123  * bootinfo base (physical and virtual).  The bootinfo is placed, by
    124  * the boot loader, into the first page of kernel text, which is zero
    125  * filled (see locore.s) and not mapped at 0.  It is remapped to a
    126  * different address in pmap_bootstrap().
    127  */
    128 paddr_t	bootinfo_pa;
    129 vaddr_t	bootinfo_va;
    130 
    131 int	maxmem;			/* max memory per process */
    132 
    133 extern	u_int lowram;
    134 extern	short exframesize[];
    135 
    136 /* prototypes for local functions */
    137 static void	parityenable(void);
    138 static int	parityerror(struct frame *);
    139 static int	parityerrorfind(void);
    140 static void	identifycpu(void);
    141 static void	initcpu(void);
    142 
    143 static int	cpu_dumpsize(void);
    144 static int	cpu_dump(int (*)(dev_t, daddr_t, void *, size_t), daddr_t *);
    145 static void	cpu_init_kcore_hdr(void);
    146 
    147 /* functions called from locore.s */
    148 void    dumpsys(void);
    149 void	hp300_init(void);
    150 void    straytrap(int, u_short);
    151 void	nmihand(struct frame);
    152 
    153 /*
    154  * Machine-dependent crash dump header info.
    155  */
    156 static cpu_kcore_hdr_t cpu_kcore_hdr;
    157 
    158 /*
    159  * Note that the value of delay_divisor is roughly
    160  * 2048 / cpuspeed (where cpuspeed is in MHz) on 68020
    161  * and 68030 systems.  See clock.c for the delay
    162  * calibration algorithm.
    163  */
    164 int	cpuspeed;		/* relative CPU speed; XXX skewed on 68040 */
    165 int	delay_divisor;		/* delay constant */
    166 
    167 /*
    168  * Early initialization, before main() is called.
    169  */
    170 void
    171 hp300_init(void)
    172 {
    173 	struct btinfo_magic *bt_mag;
    174 	int i;
    175 
    176 	extern paddr_t avail_start, avail_end;
    177 
    178 #ifdef CACHE_HAVE_VAC
    179 	/*
    180 	 * Determine VA aliasing distance if any
    181 	 */
    182 	switch (machineid) {
    183 	case HP_320:
    184 		pmap_aliasmask = 0x3fff;	/* 16KB */
    185 		break;
    186 	case HP_350:
    187 		pmap_aliasmask = 0x7fff;	/* 32KB */
    188 		break;
    189 	default:
    190 		break;
    191 	}
    192 #endif
    193 
    194 	/*
    195 	 * Tell the VM system about available physical memory.  The
    196 	 * hp300 only has one segment.
    197 	 */
    198 	uvm_page_physload(atop(avail_start), atop(avail_end),
    199 	    atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT);
    200 
    201 	/* Calibrate the delay loop. */
    202 	hp300_calibrate_delay();
    203 
    204 	/*
    205 	 * Initialize error message buffer (at end of core).
    206 	 * avail_end was pre-decremented in pmap_bootstrap to compensate.
    207 	 */
    208 	for (i = 0; i < btoc(MSGBUFSIZE); i++)
    209 		pmap_kenter_pa((vaddr_t)msgbufaddr + i * PAGE_SIZE,
    210 		    avail_end + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, 0);
    211 	pmap_update(pmap_kernel());
    212 	initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE));
    213 
    214 	/*
    215 	 * Map in the bootinfo page, and make sure the bootinfo
    216 	 * exists by searching for the MAGIC record.  If it's not
    217 	 * there, disable bootinfo.
    218 	 */
    219 	bootinfo_va = virtual_avail;
    220 	virtual_avail += PAGE_SIZE;
    221 	pmap_enter(pmap_kernel(), bootinfo_va, bootinfo_pa,
    222 	    VM_PROT_READ|VM_PROT_WRITE,
    223 	    VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
    224 	pmap_update(pmap_kernel());
    225 	bt_mag = lookup_bootinfo(BTINFO_MAGIC);
    226 	if (bt_mag == NULL ||
    227 	    bt_mag->magic1 != BOOTINFO_MAGIC1 ||
    228 	    bt_mag->magic2 != BOOTINFO_MAGIC2) {
    229 		pmap_remove(pmap_kernel(), bootinfo_va,
    230 		    bootinfo_va + PAGE_SIZE);
    231 		pmap_update(pmap_kernel());
    232 		virtual_avail -= PAGE_SIZE;
    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(void)
    244 {
    245 
    246 	/*
    247 	 * Initialize the external I/O extent map.
    248 	 */
    249 	iomap_init();
    250 
    251 	/*
    252 	 * Initialize the console before we print anything out.
    253 	 */
    254 
    255 	hp300_cninit();
    256 
    257 	/*
    258 	 * Issue a warning if the boot loader didn't provide bootinfo.
    259 	 */
    260 	if (bootinfo_va != 0)
    261 		printf("bootinfo found at 0x%08lx\n", bootinfo_pa);
    262 	else
    263 		printf("WARNING: boot loader did not provide bootinfo\n");
    264 
    265 #if NKSYMS || defined(DDB) || defined(MODULAR)
    266 	{
    267 		extern int end;
    268 		extern int *esym;
    269 
    270 		ksyms_addsyms_elf((int)esym - (int)&end - sizeof(Elf32_Ehdr),
    271 		    (void *)&end, esym);
    272 	}
    273 #endif
    274 #ifdef DDB
    275 	if (boothowto & RB_KDB)
    276 		Debugger();
    277 #endif
    278 }
    279 
    280 /*
    281  * cpu_startup: allocate memory for variable-sized tables,
    282  * initialize CPU
    283  */
    284 void
    285 cpu_startup(void)
    286 {
    287 	vaddr_t minaddr, maxaddr;
    288 	char pbuf[9];
    289 #ifdef DEBUG
    290 	extern int pmapdebug;
    291 	int opmapdebug = pmapdebug;
    292 
    293 	pmapdebug = 0;
    294 #endif
    295 
    296 	hp300_cninit_deferred();
    297 
    298 	if (fputype != FPU_NONE)
    299 		m68k_make_fpu_idle_frame();
    300 
    301 	/*
    302 	 * Initialize the kernel crash dump header.
    303 	 */
    304 	cpu_init_kcore_hdr();
    305 
    306 	/*
    307 	 * Good {morning,afternoon,evening,night}.
    308 	 */
    309 	printf("%s%s", copyright, version);
    310 	identifycpu();
    311 	format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
    312 	printf("total memory = %s\n", pbuf);
    313 
    314 	minaddr = 0;
    315 
    316 	/*
    317 	 * Allocate a submap for physio
    318 	 */
    319 	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
    320 	    VM_PHYS_SIZE, 0, false, NULL);
    321 
    322 #ifdef DEBUG
    323 	pmapdebug = opmapdebug;
    324 #endif
    325 	format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false)));
    326 	printf("avail memory = %s\n", pbuf);
    327 
    328 	/*
    329 	 * Set up CPU-specific registers, cache, etc.
    330 	 */
    331 	initcpu();
    332 
    333 	/* Safe to use malloc for extio_ex now. */
    334 	extio_ex_malloc_safe = 1;
    335 }
    336 
    337 struct hp300_model {
    338 	int id;
    339 	int mmuid;
    340 	const char *name;
    341 	const char *speed;
    342 };
    343 
    344 static const struct hp300_model hp300_models[] = {
    345 	{ HP_320,	-1,		"320",		"16.67"	},
    346 	{ HP_330,	-1,		"318/319/330",	"16.67"	},
    347 	{ HP_340,	-1,		"340",		"16.67"	},
    348 	{ HP_345,	-1,		"345",		"50"	},
    349 	{ HP_350,	-1,		"350",		"25"	},
    350 	{ HP_360,	-1,		"360",		"25"	},
    351 	{ HP_362,	-1,		"362",		"25"	},
    352 	{ HP_370,	-1,		"370",		"33.33"	},
    353 	{ HP_375,	-1,		"375",		"50"	},
    354 	{ HP_380,	-1,		"380",		"25"	},
    355 	{ HP_382,	-1,		"382",		"25"	},
    356 	{ HP_385,	-1,		"385",		"33"	},
    357 	{ HP_400,	-1,		"400",		"50"	},
    358 	{ HP_425,	MMUID_425_T,	"425t",		"25"	},
    359 	{ HP_425,	MMUID_425_S,	"425s",		"25"	},
    360 	{ HP_425,	MMUID_425_E,	"425e",		"25"	},
    361 	{ HP_425,	-1,		"425",		"25"	},
    362 	{ HP_433,	MMUID_433_T,	"433t",		"33"	},
    363 	{ HP_433,	MMUID_433_S,	"433s",		"33"	},
    364 	{ HP_433,	-1,		"433",		"33"	},
    365 	{ 0,		-1,		NULL,		NULL	},
    366 };
    367 
    368 static void
    369 identifycpu(void)
    370 {
    371 	const char *t, *cpu, *s, *mmu;
    372 	int i;
    373 	char fpu[64], cache[64];
    374 
    375 	/*
    376 	 * Find the model number.
    377 	 */
    378 	for (t = s = NULL, i = 0; hp300_models[i].name != NULL; i++) {
    379 		if (hp300_models[i].id == machineid) {
    380 			if (hp300_models[i].mmuid != -1 &&
    381 			    hp300_models[i].mmuid != mmuid)
    382 				continue;
    383 			t = hp300_models[i].name;
    384 			s = hp300_models[i].speed;
    385 			break;
    386 		}
    387 	}
    388 	if (t == NULL) {
    389 		printf("\nunknown machineid %d\n", machineid);
    390 		goto lose;
    391 	}
    392 
    393 	/*
    394 	 * ...and the CPU type.
    395 	 */
    396 	switch (cputype) {
    397 	case CPU_68040:
    398 		cpu = "MC68040";
    399 		break;
    400 	case CPU_68030:
    401 		cpu = "MC68030";
    402 		break;
    403 	case CPU_68020:
    404 		cpu = "MC68020";
    405 		break;
    406 	default:
    407 		printf("\nunknown cputype %d\n", cputype);
    408 		goto lose;
    409 	}
    410 
    411 
    412 	/*
    413 	 * ...and the MMU type.
    414 	 */
    415 	switch (mmutype) {
    416 	case MMU_68040:
    417 	case MMU_68030:
    418 		mmu = "+MMU";
    419 		break;
    420 	case MMU_68851:
    421 		mmu = ", MC68851 MMU";
    422 		break;
    423 	case MMU_HP:
    424 		mmu = ", HP MMU";
    425 		break;
    426 	default:
    427 		printf("%s\nunknown MMU type %d\n", cpu, mmutype);
    428 		panic("startup");
    429 	}
    430 
    431 	/*
    432 	 * ...and the FPU type.
    433 	 */
    434 	fpu[0] = '\0';
    435 	switch (fputype) {
    436 	case FPU_68040:
    437 		strlcpy(fpu, "+FPU", sizeof(fpu));
    438 		break;
    439 	case FPU_68882:
    440 		snprintf(fpu, sizeof(fpu), ", %sMHz MC68882 FPU", s);
    441 		break;
    442 	case FPU_68881:
    443 		snprintf(fpu, sizeof(fpu), ", %sMHz MC68881 FPU",
    444 		    machineid == HP_350 ? "20" : "16.67");
    445 		break;
    446 	case FPU_NONE:
    447 #ifdef FPU_EMULATE
    448 		strlcpy(fpu, ", emulated FPU", sizeof(fpu));
    449 #else
    450 		strlcpy(fpu, ", no FPU", sizeof(fpu));
    451 #endif
    452 		break;
    453 	default:
    454 		strlcpy(fpu, ", unknown FPU", sizeof(fpu));
    455 	}
    456 
    457 	/*
    458 	 * ...and finally, the cache type.
    459 	 */
    460 	cache[0] = '\0';
    461 	if (cputype == CPU_68040)
    462 		snprintf(cache, sizeof(cache),
    463 		    ", 4k on-chip physical I/D caches");
    464 	else {
    465 		switch (ectype) {
    466 		case EC_VIRT:
    467 			snprintf(cache, sizeof(cache),
    468 			    ", %dK virtual-address cache",
    469 			    machineid == HP_320 ? 16 : 32);
    470 			break;
    471 		case EC_PHYS:
    472 			snprintf(cache, sizeof(cache),
    473 			    ", %dK physical-address cache",
    474 			    machineid == HP_370 ? 64 : 32);
    475 			break;
    476 		}
    477 	}
    478 
    479 	cpu_setmodel("HP 9000/%s (%sMHz %s CPU%s%s%s)", t, s, cpu,
    480 	    mmu, fpu, cache);
    481 	printf("%s\n", cpu_getmodel());
    482 #ifdef DIAGNOSTIC
    483 	printf("cpu: delay divisor %d", delay_divisor);
    484 	if (mmuid)
    485 		printf(", mmuid %d", mmuid);
    486 	printf("\n");
    487 #endif
    488 
    489 	/*
    490 	 * Now that we have told the user what they have,
    491 	 * let them know if that machine type isn't configured.
    492 	 */
    493 	switch (machineid) {
    494 	case -1:		/* keep compilers happy */
    495 #if !defined(HP320)
    496 	case HP_320:
    497 #endif
    498 #if !defined(HP330)
    499 	case HP_330:
    500 #endif
    501 #if !defined(HP340)
    502 	case HP_340:
    503 #endif
    504 #if !defined(HP345)
    505 	case HP_345:
    506 #endif
    507 #if !defined(HP350)
    508 	case HP_350:
    509 #endif
    510 #if !defined(HP360)
    511 	case HP_360:
    512 #endif
    513 #if !defined(HP362)
    514 	case HP_362:
    515 #endif
    516 #if !defined(HP370)
    517 	case HP_370:
    518 #endif
    519 #if !defined(HP375)
    520 	case HP_375:
    521 #endif
    522 #if !defined(HP380)
    523 	case HP_380:
    524 #endif
    525 #if !defined(HP382)
    526 	case HP_382:
    527 #endif
    528 #if !defined(HP385)
    529 	case HP_385:
    530 #endif
    531 #if !defined(HP400)
    532 	case HP_400:
    533 #endif
    534 #if !defined(HP425)
    535 	case HP_425:
    536 #endif
    537 #if !defined(HP433)
    538 	case HP_433:
    539 #endif
    540 		panic("SPU type not configured");
    541 	default:
    542 		break;
    543 	}
    544 
    545 	return;
    546  lose:
    547 	panic("startup");
    548 }
    549 
    550 /*
    551  * machine dependent system variables.
    552  */
    553 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
    554 {
    555 
    556 	sysctl_createv(clog, 0, NULL, NULL,
    557 	    CTLFLAG_PERMANENT,
    558 	    CTLTYPE_NODE, "machdep", NULL,
    559 	    NULL, 0, NULL, 0,
    560 	    CTL_MACHDEP, CTL_EOL);
    561 
    562 	sysctl_createv(clog, 0, NULL, NULL,
    563 	    CTLFLAG_PERMANENT,
    564 	    CTLTYPE_STRUCT, "console_device", NULL,
    565 	    sysctl_consdev, 0, NULL, sizeof(dev_t),
    566 	    CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
    567 }
    568 
    569 int	waittime = -1;
    570 
    571 void
    572 cpu_reboot(int howto, char *bootstr)
    573 {
    574 	struct pcb *pcb = lwp_getpcb(curlwp);
    575 
    576 	/* take a snap shot before clobbering any registers */
    577 	if (pcb != NULL)
    578 		savectx(pcb);
    579 
    580 	/* If system is cold, just halt. */
    581 	if (cold) {
    582 		howto |= RB_HALT;
    583 		goto haltsys;
    584 	}
    585 
    586 	boothowto = howto;
    587 	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
    588 		waittime = 0;
    589 		vfs_shutdown();
    590 	}
    591 
    592 	/* Disable interrupts. */
    593 	splhigh();
    594 
    595 	/* If rebooting and a dump is requested do it. */
    596 	if (howto & RB_DUMP)
    597 		dumpsys();
    598 
    599  haltsys:
    600 	/* Run any shutdown hooks. */
    601 	doshutdownhooks();
    602 
    603 	pmf_system_shutdown(boothowto);
    604 
    605 #if defined(PANICWAIT) && !defined(DDB)
    606 	if ((howto & RB_HALT) == 0 && panicstr) {
    607 		printf("hit any key to reboot...\n");
    608 		cnpollc(1);
    609 		(void)cngetc();
    610 		cnpollc(0);
    611 		printf("\n");
    612 	}
    613 #endif
    614 
    615 	/* Finally, halt/reboot the system. */
    616 	if (howto & RB_HALT) {
    617 		printf("System halted.  Hit any key to reboot.\n\n");
    618 		cnpollc(1);
    619 		(void)cngetc();
    620 		cnpollc(0);
    621 	}
    622 
    623 	printf("rebooting...\n");
    624 	DELAY(1000000);
    625 	doboot();
    626 	/* NOTREACHED */
    627 }
    628 
    629 /*
    630  * Initialize the kernel crash dump header.
    631  */
    632 static void
    633 cpu_init_kcore_hdr(void)
    634 {
    635 	cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
    636 	struct m68k_kcore_hdr *m = &h->un._m68k;
    637 	extern int end;
    638 
    639 	memset(&cpu_kcore_hdr, 0, sizeof(cpu_kcore_hdr));
    640 
    641 	/*
    642 	 * Initialize the `dispatcher' portion of the header.
    643 	 */
    644 	strcpy(h->name, machine);
    645 	h->page_size = PAGE_SIZE;
    646 	h->kernbase = KERNBASE;
    647 
    648 	/*
    649 	 * Fill in information about our MMU configuration.
    650 	 */
    651 	m->mmutype	= mmutype;
    652 	m->sg_v		= SG_V;
    653 	m->sg_frame	= SG_FRAME;
    654 	m->sg_ishift	= SG_ISHIFT;
    655 	m->sg_pmask	= SG_PMASK;
    656 	m->sg40_shift1	= SG4_SHIFT1;
    657 	m->sg40_mask2	= SG4_MASK2;
    658 	m->sg40_shift2	= SG4_SHIFT2;
    659 	m->sg40_mask3	= SG4_MASK3;
    660 	m->sg40_shift3	= SG4_SHIFT3;
    661 	m->sg40_addr1	= SG4_ADDR1;
    662 	m->sg40_addr2	= SG4_ADDR2;
    663 	m->pg_v		= PG_V;
    664 	m->pg_frame	= PG_FRAME;
    665 
    666 	/*
    667 	 * Initialize pointer to kernel segment table.
    668 	 */
    669 	m->sysseg_pa = (uint32_t)(pmap_kernel()->pm_stpa);
    670 
    671 	/*
    672 	 * Initialize relocation value such that:
    673 	 *
    674 	 *	pa = (va - KERNBASE) + reloc
    675 	 */
    676 	m->reloc = lowram;
    677 
    678 	/*
    679 	 * Define the end of the relocatable range.
    680 	 */
    681 	m->relocend = (uint32_t)&end;
    682 
    683 	/*
    684 	 * hp300 has one contiguous memory segment.
    685 	 */
    686 	m->ram_segs[0].start = lowram;
    687 	m->ram_segs[0].size  = ctob(physmem);
    688 }
    689 
    690 /*
    691  * Compute the size of the machine-dependent crash dump header.
    692  * Returns size in disk blocks.
    693  */
    694 
    695 #define CHDRSIZE (ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)))
    696 #define MDHDRSIZE roundup(CHDRSIZE, dbtob(1))
    697 
    698 static int
    699 cpu_dumpsize(void)
    700 {
    701 
    702 	return btodb(MDHDRSIZE);
    703 }
    704 
    705 /*
    706  * Called by dumpsys() to dump the machine-dependent header.
    707  */
    708 static int
    709 cpu_dump(int (*dump)(dev_t, daddr_t, void *, size_t), daddr_t *blknop)
    710 {
    711 	int buf[MDHDRSIZE / sizeof(int)];
    712 	cpu_kcore_hdr_t *chdr;
    713 	kcore_seg_t *kseg;
    714 	int error;
    715 
    716 	kseg = (kcore_seg_t *)buf;
    717 	chdr = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) /
    718 	    sizeof(int)];
    719 
    720 	/* Create the segment header. */
    721 	CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
    722 	kseg->c_size = MDHDRSIZE - ALIGN(sizeof(kcore_seg_t));
    723 
    724 	memcpy(chdr, &cpu_kcore_hdr, sizeof(cpu_kcore_hdr_t));
    725 	error = (*dump)(dumpdev, *blknop, (void *)buf, sizeof(buf));
    726 	*blknop += btodb(sizeof(buf));
    727 	return error;
    728 }
    729 
    730 /*
    731  * These variables are needed by /sbin/savecore
    732  */
    733 uint32_t dumpmag = 0x8fca0101;	/* magic number */
    734 int	dumpsize = 0;		/* pages */
    735 long	dumplo = 0;		/* blocks */
    736 
    737 /*
    738  * This is called by main to set dumplo and dumpsize.
    739  * Dumps always skip the first PAGE_SIZE of disk space
    740  * in case there might be a disk label stored there.
    741  * If there is extra space, put dump at the end to
    742  * reduce the chance that swapping trashes it.
    743  */
    744 void
    745 cpu_dumpconf(void)
    746 {
    747 	int chdrsize;	/* size of dump header */
    748 	int nblks;	/* size of dump area */
    749 
    750 	if (dumpdev == NODEV)
    751 		return;
    752 	nblks = bdev_size(dumpdev);
    753 	chdrsize = cpu_dumpsize();
    754 
    755 	dumpsize = btoc(cpu_kcore_hdr.un._m68k.ram_segs[0].size);
    756 
    757 	/*
    758 	 * Check do see if we will fit.  Note we always skip the
    759 	 * first PAGE_SIZE in case there is a disk label there.
    760 	 */
    761 	if (nblks < (ctod(dumpsize) + chdrsize + ctod(1))) {
    762 		dumpsize = 0;
    763 		dumplo = -1;
    764 		return;
    765 	}
    766 
    767 	/*
    768 	 * Put dump at the end of the partition.
    769 	 */
    770 	dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize;
    771 }
    772 
    773 /*
    774  * Dump physical memory onto the dump device.  Called by cpu_reboot().
    775  */
    776 void
    777 dumpsys(void)
    778 {
    779 	const struct bdevsw *bdev;
    780 	daddr_t blkno;		/* current block to write */
    781 				/* dump routine */
    782 	int (*dump)(dev_t, daddr_t, void *, size_t);
    783 	int pg;			/* page being dumped */
    784 	paddr_t maddr;		/* PA being dumped */
    785 	int error;		/* error code from (*dump)() */
    786 
    787 	/* XXX initialized here because of gcc lossage */
    788 	maddr = lowram;
    789 	pg = 0;
    790 
    791 	/* Make sure dump device is valid. */
    792 	if (dumpdev == NODEV)
    793 		return;
    794 	bdev = bdevsw_lookup(dumpdev);
    795 	if (bdev == NULL)
    796 		return;
    797 	if (dumpsize == 0) {
    798 		cpu_dumpconf();
    799 		if (dumpsize == 0)
    800 			return;
    801 	}
    802 	if (dumplo <= 0) {
    803 		printf("\ndump to dev %u,%u not possible\n",
    804 		    major(dumpdev), minor(dumpdev));
    805 		return;
    806 	}
    807 	dump = bdev->d_dump;
    808 	blkno = dumplo;
    809 
    810 	printf("\ndumping to dev %u,%u offset %ld\n",
    811 	    major(dumpdev), minor(dumpdev), dumplo);
    812 
    813 	printf("dump ");
    814 
    815 	/* Write the dump header. */
    816 	error = cpu_dump(dump, &blkno);
    817 	if (error)
    818 		goto bad;
    819 
    820 	for (pg = 0; pg < dumpsize; pg++) {
    821 #define NPGMB	(1024*1024/PAGE_SIZE)
    822 		/* print out how many MBs we have dumped */
    823 		if (pg && (pg % NPGMB) == 0)
    824 			printf("%d ", pg / NPGMB);
    825 #undef NPGMB
    826 		pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr,
    827 		    VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
    828 
    829 		pmap_update(pmap_kernel());
    830 		error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE);
    831  bad:
    832 		switch (error) {
    833 		case 0:
    834 			maddr += PAGE_SIZE;
    835 			blkno += btodb(PAGE_SIZE);
    836 			break;
    837 
    838 		case ENXIO:
    839 			printf("device bad\n");
    840 			return;
    841 
    842 		case EFAULT:
    843 			printf("device not ready\n");
    844 			return;
    845 
    846 		case EINVAL:
    847 			printf("area improper\n");
    848 			return;
    849 
    850 		case EIO:
    851 			printf("i/o error\n");
    852 			return;
    853 
    854 		case EINTR:
    855 			printf("aborted from console\n");
    856 			return;
    857 
    858 		default:
    859 			printf("error %d\n", error);
    860 			return;
    861 		}
    862 	}
    863 	printf("succeeded\n");
    864 }
    865 
    866 static void
    867 initcpu(void)
    868 {
    869 
    870 	parityenable();
    871 #ifdef USELEDS
    872 	ledinit();
    873 #endif
    874 }
    875 
    876 void
    877 straytrap(int pc, u_short evec)
    878 {
    879 	printf("unexpected trap (vector offset %x) from %x\n",
    880 	       evec & 0xFFF, pc);
    881 }
    882 
    883 /* XXX should change the interface, and make one badaddr() function */
    884 
    885 int	*nofault;
    886 
    887 int
    888 badaddr(void *addr)
    889 {
    890 	int i;
    891 	label_t	faultbuf;
    892 
    893 	nofault = (int *)&faultbuf;
    894 	if (setjmp((label_t *)nofault)) {
    895 		nofault = (int *)0;
    896 		return 1;
    897 	}
    898 	i = *(volatile short *)addr;
    899 	__USE(i);
    900 	nofault = (int *)0;
    901 	return 0;
    902 }
    903 
    904 int
    905 badbaddr(void *addr)
    906 {
    907 	int i;
    908 	label_t	faultbuf;
    909 
    910 	nofault = (int *)&faultbuf;
    911 	if (setjmp((label_t *)nofault)) {
    912 		nofault = (int *)0;
    913 		return 1;
    914 	}
    915 	i = *(volatile char *)addr;
    916 	__USE(i);
    917 	nofault = (int *) 0;
    918 	return 0;
    919 }
    920 
    921 /*
    922  * lookup_bootinfo:
    923  *
    924  *	Look up information in bootinfo from boot loader.
    925  */
    926 void *
    927 lookup_bootinfo(int type)
    928 {
    929 	struct btinfo_common *bt;
    930 	char *help = (char *)bootinfo_va;
    931 
    932 	/* Check for a bootinfo record first. */
    933 	if (help == NULL)
    934 		return NULL;
    935 
    936 	do {
    937 		bt = (struct btinfo_common *)help;
    938 		if (bt->type == type)
    939 			return help;
    940 		help += bt->next;
    941 	} while (bt->next != 0 &&
    942 		 (size_t)help < (size_t)bootinfo_va + BOOTINFO_SIZE);
    943 
    944 	return NULL;
    945 }
    946 
    947 #if defined(PANICBUTTON) && !defined(DDB)
    948 /*
    949  * Declare these so they can be patched.
    950  */
    951 int panicbutton = 1;	/* non-zero if panic buttons are enabled */
    952 int candbdiv = 2;	/* give em half a second (hz / candbdiv) */
    953 
    954 static void	candbtimer(void *);
    955 
    956 int crashandburn;
    957 
    958 callout_t candbtimer_ch;
    959 
    960 void
    961 candbtimer(void *arg)
    962 {
    963 
    964 	crashandburn = 0;
    965 }
    966 #endif /* PANICBUTTON & !DDB */
    967 
    968 static int innmihand;	/* simple mutex */
    969 
    970 /*
    971  * Level 7 interrupts can be caused by HIL keyboards (in cooked mode only,
    972  * but we run them in raw mode) or parity errors.
    973  */
    974 void
    975 nmihand(struct frame frame)
    976 {
    977 
    978 	/* Prevent unwanted recursion. */
    979 	if (innmihand)
    980 		return;
    981 	innmihand = 1;
    982 
    983 	if (parityerror(&frame))
    984 		return;
    985 	/* panic?? */
    986 	printf("unexpected level 7 interrupt ignored\n");
    987 
    988 	innmihand = 0;
    989 }
    990 
    991 /*
    992  * Parity error section.  Contains magic.
    993  */
    994 #define PARREG		((volatile short *)IIOV(0x5B0000))
    995 static int gotparmem = 0;
    996 #ifdef DEBUG
    997 int ignorekperr = 0;	/* ignore kernel parity errors */
    998 #endif
    999 
   1000 /*
   1001  * Enable parity detection
   1002  */
   1003 static void
   1004 parityenable(void)
   1005 {
   1006 	label_t	faultbuf;
   1007 
   1008 	nofault = (int *)&faultbuf;
   1009 	if (setjmp((label_t *)nofault)) {
   1010 		nofault = (int *)0;
   1011 		printf("Parity detection disabled\n");
   1012 		return;
   1013 	}
   1014 	*PARREG = 1;
   1015 	nofault = (int *)0;
   1016 	gotparmem = 1;
   1017 }
   1018 
   1019 /*
   1020  * Determine if level 7 interrupt was caused by a parity error
   1021  * and deal with it if it was.  Returns 1 if it was a parity error.
   1022  */
   1023 static int
   1024 parityerror(struct frame *fp)
   1025 {
   1026 	if (!gotparmem)
   1027 		return 0;
   1028 	*PARREG = 0;
   1029 	DELAY(10);
   1030 	*PARREG = 1;
   1031 	if (panicstr) {
   1032 		printf("parity error after panic ignored\n");
   1033 		return 1;
   1034 	}
   1035 	if (!parityerrorfind())
   1036 		printf("WARNING: transient parity error ignored\n");
   1037 	else if (USERMODE(fp->f_sr)) {
   1038 		printf("pid %d: parity error\n", curproc->p_pid);
   1039 		uprintf("sorry, pid %d killed due to memory parity error\n",
   1040 		    curproc->p_pid);
   1041 		psignal(curproc, SIGKILL);
   1042 #ifdef DEBUG
   1043 	} else if (ignorekperr) {
   1044 		printf("WARNING: kernel parity error ignored\n");
   1045 #endif
   1046 	} else {
   1047 		regdump((struct trapframe *)fp, 128);
   1048 		panic("kernel parity error");
   1049 	}
   1050 	return 1;
   1051 }
   1052 
   1053 /*
   1054  * Yuk!  There has got to be a better way to do this!
   1055  * Searching all of memory with interrupts blocked can lead to disaster.
   1056  */
   1057 static int
   1058 parityerrorfind(void)
   1059 {
   1060 	static label_t parcatch;
   1061 	static int looking = 0;
   1062 	volatile int pg, o, s;
   1063 	volatile int *ip;
   1064 	int i;
   1065 	int found;
   1066 
   1067 	/*
   1068 	 * If looking is true we are searching for a known parity error
   1069 	 * and it has just occurred.  All we do is return to the higher
   1070 	 * level invocation.
   1071 	 */
   1072 	if (looking)
   1073 		longjmp(&parcatch);
   1074 	s = splhigh();
   1075 	/*
   1076 	 * If setjmp returns true, the parity error we were searching
   1077 	 * for has just occurred (longjmp above) at the current pg+o
   1078 	 */
   1079 	if (setjmp(&parcatch)) {
   1080 		printf("Parity error at 0x%x\n", ctob(pg)|o);
   1081 		found = 1;
   1082 		goto done;
   1083 	}
   1084 	/*
   1085 	 * If we get here, a parity error has occurred for the first time
   1086 	 * and we need to find it.  We turn off any external caches and
   1087 	 * loop thru memory, testing every longword til a fault occurs and
   1088 	 * we regain control at setjmp above.  Note that because of the
   1089 	 * setjmp, pg and o need to be volatile or their values will be lost.
   1090 	 */
   1091 	looking = 1;
   1092 	ecacheoff();
   1093 	for (pg = btoc(lowram); pg < btoc(lowram)+physmem; pg++) {
   1094 		pmap_enter(pmap_kernel(), (vaddr_t)vmmap, ctob(pg),
   1095 		    VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
   1096 		pmap_update(pmap_kernel());
   1097 		ip = (int *)vmmap;
   1098 		for (o = 0; o < PAGE_SIZE; o += sizeof(int))
   1099 			i = *ip++;
   1100 	}
   1101 	__USE(i);
   1102 	/*
   1103 	 * Getting here implies no fault was found.  Should never happen.
   1104 	 */
   1105 	printf("Couldn't locate parity error\n");
   1106 	found = 0;
   1107  done:
   1108 	looking = 0;
   1109 	pmap_remove(pmap_kernel(), (vaddr_t)vmmap, (vaddr_t)&vmmap[PAGE_SIZE]);
   1110 	pmap_update(pmap_kernel());
   1111 	ecacheon();
   1112 	splx(s);
   1113 	return found;
   1114 }
   1115 
   1116 /*
   1117  * cpu_exec_aout_makecmds():
   1118  *	CPU-dependent a.out format hook for execve().
   1119  *
   1120  * Determine of the given exec package refers to something which we
   1121  * understand and, if so, set up the vmcmds for it.
   1122  *
   1123  * XXX what are the special cases for the hp300?
   1124  * XXX why is this COMPAT_NOMID?  was something generating
   1125  *	hp300 binaries with an a_mid of 0?  i thought that was only
   1126  *	done on little-endian machines...  -- cgd
   1127  */
   1128 int
   1129 cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp)
   1130 {
   1131 #if defined(COMPAT_NOMID) || defined(COMPAT_44)
   1132 	u_long midmag, magic;
   1133 	u_short mid;
   1134 	int error;
   1135 	struct exec *execp = epp->ep_hdr;
   1136 
   1137 	midmag = ntohl(execp->a_midmag);
   1138 	mid = (midmag >> 16) & 0xffff;
   1139 	magic = midmag & 0xffff;
   1140 
   1141 	midmag = mid << 16 | magic;
   1142 
   1143 	switch (midmag) {
   1144 #ifdef COMPAT_NOMID
   1145 	case (MID_ZERO << 16) | ZMAGIC:
   1146 		error = exec_aout_prep_oldzmagic(l, epp);
   1147 		return error;
   1148 #endif
   1149 #ifdef COMPAT_44
   1150 	case (MID_HP300 << 16) | ZMAGIC:
   1151 		error = exec_aout_prep_oldzmagic(l, epp);
   1152 		return error;
   1153 #endif
   1154 	}
   1155 #endif /* !(defined(COMPAT_NOMID) || defined(COMPAT_44)) */
   1156 
   1157 	return ENOEXEC;
   1158 }
   1159 
   1160 int
   1161 mm_md_physacc(paddr_t pa, vm_prot_t prot)
   1162 {
   1163 
   1164 	/*
   1165 	 * On the hp300, physical RAM is always located at the end of
   1166 	 * the physical address space, i.e. from 0xffffffff to lowram.
   1167 	 */
   1168 	return (pa < lowram || pa >= 0xfffffffc) ? EFAULT : 0;
   1169 }
   1170 
   1171 int
   1172 mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled)
   1173 {
   1174 
   1175 	/*
   1176 	 * Do not allow reading intio or dio device space.  This could lead
   1177 	 * to corruption of device registers.
   1178 	 */
   1179 	*handled = false;
   1180 	return (ISIIOVA(ptr) || ((uint8_t *)ptr >= extiobase &&
   1181 	    (uint8_t *)ptr < extiobase + (EIOMAPSIZE * PAGE_SIZE)))
   1182 	    ? EFAULT : 0;
   1183 }
   1184 
   1185 #ifdef MODULAR
   1186 /*
   1187  * Push any modules loaded by the bootloader etc.
   1188  */
   1189 void
   1190 module_init_md(void)
   1191 {
   1192 }
   1193 #endif
   1194