Home | History | Annotate | Line # | Download | only in mvme68k
      1 /*	$NetBSD: machdep.c,v 1.165 2024/03/05 14:15:33 thorpej 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.165 2024/03/05 14:15:33 thorpej Exp $");
     43 
     44 #include "opt_ddb.h"
     45 #include "opt_m060sp.h"
     46 #include "opt_modular.h"
     47 #include "opt_panicbutton.h"
     48 #include "opt_m68k_arch.h"
     49 #include "opt_mvmeconf.h"
     50 
     51 #include <sys/param.h>
     52 #include <sys/systm.h>
     53 #include <sys/signalvar.h>
     54 #include <sys/kernel.h>
     55 #include <sys/proc.h>
     56 #include <sys/buf.h>
     57 #include <sys/reboot.h>
     58 #include <sys/conf.h>
     59 #include <sys/file.h>
     60 #include <sys/mbuf.h>
     61 #include <sys/msgbuf.h>
     62 #include <sys/ioctl.h>
     63 #include <sys/tty.h>
     64 #include <sys/mount.h>
     65 #include <sys/exec.h>
     66 #include <sys/exec_aout.h>		/* for MID_* */
     67 #include <sys/core.h>
     68 #include <sys/kcore.h>
     69 #include <sys/vnode.h>
     70 #include <sys/syscallargs.h>
     71 #include <sys/ksyms.h>
     72 #include <sys/module.h>
     73 #include <sys/device.h>
     74 #include <sys/cpu.h>
     75 
     76 #include "ksyms.h"
     77 
     78 #if NKSYMS || defined(DDB) || defined(MODULAR)
     79 #include <sys/exec_elf.h>
     80 #endif
     81 
     82 #include <uvm/uvm_extern.h>
     83 
     84 #include <sys/sysctl.h>
     85 
     86 #include <machine/cpu.h>
     87 #define _MVME68K_BUS_DMA_PRIVATE
     88 #include <machine/bus.h>
     89 #undef _MVME68K_BUS_DMA_PRIVATE
     90 #include <machine/pcb.h>
     91 #include <machine/prom.h>
     92 #include <machine/psl.h>
     93 #include <machine/pte.h>
     94 #include <machine/vmparam.h>
     95 #include <m68k/include/cacheops.h>
     96 #include <dev/cons.h>
     97 #include <dev/mm.h>
     98 
     99 #include <machine/kcore.h>	/* XXX should be pulled in by sys/kcore.h */
    100 
    101 #include <mvme68k/dev/mainbus.h>
    102 #include <mvme68k/mvme68k/seglist.h>
    103 
    104 #ifdef DDB
    105 #include <machine/db_machdep.h>
    106 #include <ddb/db_extern.h>
    107 #include <ddb/db_output.h>
    108 #endif
    109 
    110 #define	MAXMEM	64*1024	/* XXX - from cmap.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 /*
    121  * Model information, filled in by the Bug; see locore.s
    122  */
    123 struct	mvmeprom_brdid  boardid;
    124 
    125 paddr_t msgbufpa;		/* PA of message buffer */
    126 
    127 int	maxmem;			/* max memory per process */
    128 
    129 /*
    130  * The driver for the ethernet chip appropriate to the
    131  * platform (lance or i82586) will use this variable
    132  * to size the chip's packet buffer.
    133  */
    134 #ifndef ETHER_DATA_BUFF_PAGES
    135 #define	ETHER_DATA_BUFF_PAGES	4
    136 #endif
    137 u_long	ether_data_buff_size = ETHER_DATA_BUFF_PAGES * PAGE_SIZE;
    138 uint8_t	mvme_ea[6];
    139 
    140 extern	u_int lowram;
    141 extern	short exframesize[];
    142 
    143 /* prototypes for local functions */
    144 void	identifycpu(void);
    145 void	initcpu(void);
    146 void	dumpsys(void);
    147 
    148 int	cpu_dumpsize(void);
    149 int	cpu_dump(int (*)(dev_t, daddr_t, void *, size_t), daddr_t *);
    150 void	cpu_init_kcore_hdr(void);
    151 u_long	cpu_dump_mempagecnt(void);
    152 int	cpu_exec_aout_makecmds(struct lwp *, struct exec_package *);
    153 void	straytrap(int, u_short);
    154 
    155 /*
    156  * Machine-independent crash dump header info.
    157  */
    158 cpu_kcore_hdr_t cpu_kcore_hdr;
    159 
    160 /*
    161  * Memory segments initialized in locore, which are eventually loaded
    162  * as managed VM pages.
    163  */
    164 phys_seg_list_t phys_seg_list[VM_PHYSSEG_MAX];
    165 
    166 /*
    167  * Memory segments to dump.  This is initialized from the phys_seg_list
    168  * before pages are stolen from it for VM system overhead.  I.e. this
    169  * covers the entire range of physical memory.
    170  */
    171 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
    172 int	mem_cluster_cnt;
    173 
    174 /*
    175  * On the 68020/68030 (mvme14x), the value of delay_divisor is roughly
    176  * 8192 / cpuspeed (where cpuspeed is in MHz).
    177  *
    178  * On the other boards (mvme162 and up), the cpuspeed is passed
    179  * in from the firmware.
    180  */
    181 int	cpuspeed;		/* only used for printing later */
    182 int	delay_divisor = 512;	/* assume some reasonable value to start */
    183 
    184 /* Machine-dependent initialization routines. */
    185 void	mvme68k_init(void);
    186 
    187 #ifdef MVME147
    188 #include <mvme68k/dev/pccreg.h>
    189 void	mvme147_init(void);
    190 #endif
    191 
    192 #if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177)
    193 #include <dev/mvme/pcctworeg.h>
    194 void	mvme1xx_init(void);
    195 #endif
    196 
    197 /*
    198  * Early initialization, right before main is called.
    199  */
    200 void
    201 mvme68k_init(void)
    202 {
    203 	int i;
    204 
    205 	/*
    206 	 * Since mvme68k boards can have anything from 4MB of onboard RAM, we
    207 	 * would rather set the pager_map_size at runtime based on the amount
    208 	 * of onboard RAM.
    209 	 *
    210 	 * Set pager_map_size to half the size of onboard RAM, up to a
    211 	 * maximum of 16MB.
    212 	 * (Note: Just use ps_end here since onboard RAM starts at 0x0)
    213 	 */
    214 	pager_map_size = phys_seg_list[0].ps_end / 2;
    215 	if (pager_map_size > (16 * 1024 * 1024))
    216 		pager_map_size = 16 * 1024 * 1024;
    217 
    218 	/*
    219 	 * Tell the VM system about available physical memory.
    220 	 */
    221 	for (i = 0; i < mem_cluster_cnt; i++) {
    222 		if (phys_seg_list[i].ps_start == phys_seg_list[i].ps_end) {
    223 			/*
    224 			 * Segment has been completely gobbled up.
    225 			 */
    226 			continue;
    227 		}
    228 		/*
    229 		 * Note the index of the mem cluster is the free
    230 		 * list we want to put the memory on (0 == default,
    231 		 * 1 == VME).  There can only be two.
    232 		 */
    233 		uvm_page_physload(atop(phys_seg_list[i].ps_start),
    234 				 atop(phys_seg_list[i].ps_end),
    235 				 atop(phys_seg_list[i].ps_start),
    236 				 atop(phys_seg_list[i].ps_end), i);
    237 	}
    238 
    239 	switch (machineid) {
    240 #ifdef MVME147
    241 	case MVME_147:
    242 		mvme147_init();
    243 		break;
    244 #endif
    245 #ifdef MVME167
    246 	case MVME_167:
    247 #endif
    248 #ifdef MVME162
    249 	case MVME_162:
    250 #endif
    251 #ifdef MVME177
    252 	case MVME_177:
    253 #endif
    254 #ifdef MVME172
    255 	case MVME_172:
    256 #endif
    257 #if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177)
    258 		mvme1xx_init();
    259 		break;
    260 #endif
    261 	default:
    262 		panic("%s: impossible machineid", __func__);
    263 	}
    264 
    265 	/*
    266 	 * Initialize error message buffer (at end of core).
    267 	 */
    268 	for (i = 0; i < btoc(round_page(MSGBUFSIZE)); i++)
    269 		pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * PAGE_SIZE,
    270 		    msgbufpa + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE,
    271 		    VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
    272 	initmsgbuf(msgbufaddr, round_page(MSGBUFSIZE));
    273 	pmap_update(pmap_kernel());
    274 }
    275 
    276 #ifdef MVME147
    277 /*
    278  * MVME-147 specific initialization.
    279  */
    280 void
    281 mvme147_init(void)
    282 {
    283 	bus_space_tag_t bt = &_mainbus_space_tag;
    284 	bus_space_handle_t bh;
    285 
    286 	/*
    287 	 * Set up a temporary mapping to the PCC's registers
    288 	 */
    289 	bus_space_map(bt, intiobase_phys + MAINBUS_PCC_OFFSET, PCCREG_SIZE, 0,
    290 	    &bh);
    291 
    292 	/*
    293 	 * calibrate delay() using the 6.25 usec counter.
    294 	 * we adjust the delay_divisor until we get the result we want.
    295 	 */
    296 	bus_space_write_1(bt, bh, PCCREG_TMR1_CONTROL, PCC_TIMERCLEAR);
    297 	bus_space_write_2(bt, bh, PCCREG_TMR1_PRELOAD, 0);
    298 	bus_space_write_1(bt, bh, PCCREG_TMR1_INTR_CTRL, 0);
    299 
    300 	for (delay_divisor = 512; delay_divisor > 0; delay_divisor--) {
    301 		bus_space_write_1(bt, bh, PCCREG_TMR1_CONTROL, PCC_TIMERSTART);
    302 		delay(10000);
    303 		bus_space_write_1(bt, bh, PCCREG_TMR1_CONTROL, PCC_TIMERSTOP);
    304 
    305 		/* 1600 * 6.25usec == 10000usec */
    306 		if (bus_space_read_2(bt, bh, PCCREG_TMR1_COUNT) > 1600)
    307 			break;	/* got it! */
    308 
    309 		bus_space_write_1(bt, bh, PCCREG_TMR1_CONTROL, PCC_TIMERCLEAR);
    310 		/* retry! */
    311 	}
    312 	/* just in case */
    313 	if (delay_divisor == 0) {
    314 		delay_divisor = 1;
    315 	}
    316 
    317 	bus_space_unmap(bt, bh, PCCREG_SIZE);
    318 
    319 	/* calculate cpuspeed */
    320 	cpuspeed = 8192 / delay_divisor;
    321 	cpuspeed *= 100;
    322 }
    323 #endif /* MVME147 */
    324 
    325 #if defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177)
    326 int	get_cpuspeed(void);
    327 
    328 /*
    329  * MVME-1[67]x specific initialization.
    330  */
    331 void
    332 mvme1xx_init(void)
    333 {
    334 	bus_space_tag_t bt = &_mainbus_space_tag;
    335 	bus_space_handle_t bh;
    336 
    337 	/*
    338 	 * Set up a temporary mapping to the PCCChip2's registers
    339 	 */
    340 	bus_space_map(bt,
    341 	    intiobase_phys + MAINBUS_PCCTWO_OFFSET + PCCTWO_REG_OFF,
    342 	    PCC2REG_SIZE, 0, &bh);
    343 
    344 	bus_space_write_1(bt, bh, PCC2REG_TIMER1_ICSR, 0);
    345 
    346 	for (delay_divisor = (cputype == CPU_68060) ? 20 : 154;
    347 	    delay_divisor > 0; delay_divisor--) {
    348 		bus_space_write_4(bt, bh, PCC2REG_TIMER1_COUNTER, 0);
    349 		bus_space_write_1(bt, bh, PCC2REG_TIMER1_CONTROL,
    350 		    PCCTWO_TT_CTRL_CEN);
    351 		delay(10000);
    352 		bus_space_write_1(bt, bh, PCC2REG_TIMER1_CONTROL, 0);
    353 		if (bus_space_read_4(bt, bh, PCC2REG_TIMER1_COUNTER) > 10000)
    354 			break;	/* got it! */
    355 	}
    356 
    357 	bus_space_unmap(bt, bh, PCC2REG_SIZE);
    358 
    359 	/* calculate cpuspeed */
    360 	cpuspeed = get_cpuspeed();
    361 	if (cpuspeed < 1250 || cpuspeed > 6000) {
    362 		printf("%s: Warning! Firmware has " \
    363 		    "bogus CPU speed: `%s'\n", __func__, boardid.speed);
    364 		cpuspeed = ((cputype == CPU_68060) ? 1000 : 3072) /
    365 		    delay_divisor;
    366 		cpuspeed *= 100;
    367 		printf("%s: Approximating speed using delay_divisor\n",
    368 		    __func__);
    369 	}
    370 }
    371 
    372 /*
    373  * Parse the `speed' field of Bug's boardid structure.
    374  */
    375 int
    376 get_cpuspeed(void)
    377 {
    378 	int rv, i;
    379 
    380 	for (i = 0, rv = 0; i < sizeof(boardid.speed); i++) {
    381 		if (boardid.speed[i] < '0' || boardid.speed[i] > '9')
    382 			return 0;
    383 		rv = (rv * 10) + (boardid.speed[i] - '0');
    384 	}
    385 
    386 	return rv;
    387 }
    388 #endif
    389 
    390 /*
    391  * Console initialization: called early on from main,
    392  * before vm init or startup.  Do enough configuration
    393  * to choose and initialize a console.
    394  */
    395 void
    396 consinit(void)
    397 {
    398 
    399 	/*
    400 	 * Initialize the console before we print anything out.
    401 	 */
    402 	cninit();
    403 
    404 #if NKSYMS || defined(DDB) || defined(MODULAR)
    405 	{
    406 		extern char end[];
    407 		extern int *esym;
    408 
    409 		ksyms_addsyms_elf((int)esym - (int)&end - sizeof(Elf32_Ehdr),
    410 		    (void *)&end, esym);
    411 	}
    412 #endif
    413 #ifdef DDB
    414 	if (boothowto & RB_KDB)
    415 		Debugger();
    416 #endif
    417 }
    418 
    419 /*
    420  * cpu_startup: allocate memory for variable-sized tables,
    421  * initialize CPU, and do autoconfiguration.
    422  */
    423 void
    424 cpu_startup(void)
    425 {
    426 	u_quad_t vmememsize;
    427 	vaddr_t minaddr, maxaddr;
    428 	char pbuf[9];
    429 	u_int i;
    430 #ifdef DEBUG
    431 	extern int pmapdebug;
    432 	int opmapdebug = pmapdebug;
    433 
    434 	pmapdebug = 0;
    435 #endif
    436 
    437 	/*
    438 	 * If we have an FPU, initialise the cached idle frame
    439 	 */
    440 	if (fputype != FPU_NONE)
    441 		m68k_make_fpu_idle_frame();
    442 
    443 	/*
    444 	 * Initialize the kernel crash dump header.
    445 	 */
    446 	cpu_init_kcore_hdr();
    447 
    448 	/*
    449 	 * Good {morning,afternoon,evening,night}.
    450 	 */
    451 	printf("%s%s", copyright, version);
    452 	identifycpu();
    453 	format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
    454 	printf("total memory = %s", pbuf);
    455 
    456 	for (vmememsize = 0, i = 1; i < mem_cluster_cnt; i++)
    457 		vmememsize += mem_clusters[i].size;
    458 	if (vmememsize != 0) {
    459 		format_bytes(pbuf, sizeof(pbuf), mem_clusters[0].size);
    460 		printf(" (%s on-board", pbuf);
    461 		format_bytes(pbuf, sizeof(pbuf), vmememsize);
    462 		printf(", %s VMEbus)", pbuf);
    463 	}
    464 
    465 	printf("\n");
    466 
    467 	minaddr = 0;
    468 	/*
    469 	 * Allocate a submap for physio
    470 	 */
    471 	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
    472 	    VM_PHYS_SIZE, 0, false, NULL);
    473 
    474 #ifdef DEBUG
    475 	pmapdebug = opmapdebug;
    476 #endif
    477 	format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false)));
    478 	printf("avail memory = %s\n", pbuf);
    479 
    480 	/*
    481 	 * Set up CPU-specific registers, cache, etc.
    482 	 */
    483 	initcpu();
    484 }
    485 
    486 void
    487 identifycpu(void)
    488 {
    489 	char board_str[16];
    490 	const char *cpu_str, *mmu_str, *fpu_str, *cache_str;
    491 
    492 	/* Fill in the CPU string. */
    493 	switch (cputype) {
    494 #ifdef M68020
    495 	case CPU_68020:
    496 		cpu_str = "MC68020 CPU";
    497 		fpu_str = ", MC68881 FPU";	/* XXX */
    498 		break;
    499 #endif
    500 
    501 #ifdef M68030
    502 	case CPU_68030:
    503 		cpu_str = "MC68030 CPU+MMU";
    504 		fpu_str = ", MC68882 FPU";	/* XXX */
    505 		break;
    506 #endif
    507 
    508 #ifdef M68040
    509 	case CPU_68040:
    510 		cpu_str = "MC68040 CPU+MMU+FPU";
    511 		fpu_str = "";
    512 		break;
    513 #endif
    514 
    515 #ifdef M68060
    516 	case CPU_68060:
    517 		cpu_str = "MC68060 CPU+MMU+FPU";
    518 		fpu_str = "";
    519 		break;
    520 #endif
    521 
    522 	default:
    523 		printf("unknown CPU type");
    524 		panic("startup");
    525 	}
    526 
    527 	/* Fill in the MMU string; only need to handle one case. */
    528 	switch (mmutype) {
    529 	case MMU_68851:
    530 		mmu_str = ", MC68851 MMU";
    531 		break;
    532 	default:
    533 		mmu_str = "";
    534 		break;
    535 	}
    536 
    537 	/* Fill in board model string. */
    538 	switch (machineid) {
    539 #if defined(MVME_147) || defined(MVME162) || defined(MVME167) || defined(MVME172) || defined(MVME177)
    540 	case MVME_147:
    541 	case MVME_162:
    542 	case MVME_167:
    543 	case MVME_172:
    544 	case MVME_177:
    545 	    {
    546 		char *suffix = (char *)&boardid.suffix;
    547 		int len = snprintf(board_str, sizeof(board_str), "%x",
    548 		    machineid);
    549 		if (suffix[0] != '\0' && len > 0 &&
    550 		    len + 3 < sizeof(board_str)) {
    551 			board_str[len++] = suffix[0];
    552 			if (suffix[1] != '\0')
    553 				board_str[len++] = suffix[1];
    554 			board_str[len] = '\0';
    555 		}
    556 		break;
    557 	    }
    558 #endif
    559 	default:
    560 		printf("unknown machine type: 0x%x\n", machineid);
    561 		panic("startup");
    562 	}
    563 
    564 	switch (cputype) {
    565 #if defined(M68040)
    566 	case CPU_68040:
    567 		cache_str = ", 4k+4k on-chip physical I/D caches";
    568 		break;
    569 #endif
    570 #if defined(M68060)
    571 	case CPU_68060:
    572 		cache_str = ", 8k+8k on-chip physical I/D caches";
    573 		break;
    574 #endif
    575 	default:
    576 		cache_str = "";
    577 		break;
    578 	}
    579 
    580 	cpu_setmodel("Motorola MVME-%s: %d.%dMHz %s%s%s%s",
    581 	    board_str, cpuspeed / 100, (cpuspeed % 100) / 10, cpu_str,
    582 	    mmu_str, fpu_str, cache_str);
    583 
    584 	cpuspeed /= 100;
    585 
    586 	printf("%s\n", cpu_getmodel());
    587 }
    588 
    589 /*
    590  * machine dependent system variables.
    591  */
    592 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
    593 {
    594 
    595 	sysctl_createv(clog, 0, NULL, NULL,
    596 		       CTLFLAG_PERMANENT,
    597 		       CTLTYPE_NODE, "machdep", NULL,
    598 		       NULL, 0, NULL, 0,
    599 		       CTL_MACHDEP, CTL_EOL);
    600 
    601 	sysctl_createv(clog, 0, NULL, NULL,
    602 		       CTLFLAG_PERMANENT,
    603 		       CTLTYPE_STRUCT, "console_device", NULL,
    604 		       sysctl_consdev, 0, NULL, sizeof(dev_t),
    605 		       CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
    606 }
    607 
    608 /* See: sig_machdep.c */
    609 
    610 int	waittime = -1;
    611 
    612 void
    613 cpu_reboot(int howto, char *bootstr)
    614 {
    615 	struct pcb *pcb = lwp_getpcb(curlwp);
    616 
    617 	/* take a snap shot before clobbering any registers */
    618 	if (pcb != NULL)
    619 		savectx(pcb);
    620 
    621 	/* Save the RB_SBOOT flag. */
    622 	howto |= (boothowto & RB_SBOOT);
    623 
    624 	/* If system is hold, just halt. */
    625 	if (cold) {
    626 		howto |= RB_HALT;
    627 		goto haltsys;
    628 	}
    629 
    630 	boothowto = howto;
    631 	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
    632 		waittime = 0;
    633 		vfs_shutdown();
    634 	}
    635 
    636 	/* Disable interrupts. */
    637 	splhigh();
    638 
    639 	/* If rebooting and a dump is requested, do it. */
    640 	if (howto & RB_DUMP)
    641 		dumpsys();
    642 
    643  haltsys:
    644 	/* Run any shutdown hooks. */
    645 	doshutdownhooks();
    646 
    647 	pmf_system_shutdown(boothowto);
    648 
    649 #if defined(PANICWAIT) && !defined(DDB)
    650 	if ((howto & RB_HALT) == 0 && panicstr) {
    651 		printf("hit any key to reboot...\n");
    652 		cnpollc(1);
    653 		(void)cngetc();
    654 		cnpollc(0);
    655 		printf("\n");
    656 	}
    657 #endif
    658 
    659 	/* Finally, halt/reboot the system. */
    660 	if (howto & RB_HALT) {
    661 		printf("halted\n\n");
    662 		doboot(RB_HALT);
    663 		/* NOTREACHED */
    664 	}
    665 
    666 	printf("rebooting...\n");
    667 	delay(1000000);
    668 	doboot(RB_AUTOBOOT);
    669 	/*NOTREACHED*/
    670 }
    671 
    672 /*
    673  * Initialize the kernel crash dump header.
    674  */
    675 void
    676 cpu_init_kcore_hdr(void)
    677 {
    678 	cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
    679 	struct m68k_kcore_hdr *m = &h->un._m68k;
    680 	int i;
    681 	extern char end[];
    682 
    683 	memset(&cpu_kcore_hdr, 0, sizeof(cpu_kcore_hdr));
    684 
    685 	/*
    686 	 * Initialize the `dispatcher' portion of the header.
    687 	 */
    688 	strcpy(h->name, machine);
    689 	h->page_size = PAGE_SIZE;
    690 	h->kernbase = KERNBASE;
    691 
    692 	/*
    693 	 * Fill in information about our MMU configuration.
    694 	 */
    695 	m->mmutype	= mmutype;
    696 	m->sg_v		= SG_V;
    697 	m->sg_frame	= SG_FRAME;
    698 	m->sg_ishift	= SG_ISHIFT;
    699 	m->sg_pmask	= SG_PMASK;
    700 	m->sg40_shift1	= SG4_SHIFT1;
    701 	m->sg40_mask2	= SG4_MASK2;
    702 	m->sg40_shift2	= SG4_SHIFT2;
    703 	m->sg40_mask3	= SG4_MASK3;
    704 	m->sg40_shift3	= SG4_SHIFT3;
    705 	m->sg40_addr1	= SG4_ADDR1;
    706 	m->sg40_addr2	= SG4_ADDR2;
    707 	m->pg_v		= PG_V;
    708 	m->pg_frame	= PG_FRAME;
    709 
    710 	/*
    711 	 * Initialize pointer to kernel segment table.
    712 	 */
    713 	m->sysseg_pa = (uint32_t)(pmap_kernel()->pm_stpa);
    714 
    715 	/*
    716 	 * Initialize relocation value such that:
    717 	 *
    718 	 *	pa = (va - KERNBASE) + reloc
    719 	 *
    720 	 * Since we're linked and loaded at the same place,
    721 	 * and the kernel is mapped va == pa, this is 0.
    722 	 */
    723 	m->reloc = 0;
    724 
    725 	/*
    726 	 * Define the end of the relocatable range.
    727 	 */
    728 	m->relocend = (uint32_t)end;
    729 
    730 	/*
    731 	 * The mvme68k has one or two memory segments.
    732 	 */
    733 	for (i = 0; i < mem_cluster_cnt; i++) {
    734 		m->ram_segs[i].start = mem_clusters[i].start;
    735 		m->ram_segs[i].size  = mem_clusters[i].size;
    736 	}
    737 }
    738 
    739 /*
    740  * Compute the size of the machine-dependent crash dump header.
    741  * Returns size in disk blocks.
    742  */
    743 
    744 #define CHDRSIZE (ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)))
    745 #define MDHDRSIZE roundup(CHDRSIZE, dbtob(1))
    746 
    747 int
    748 cpu_dumpsize(void)
    749 {
    750 
    751 	return btodb(MDHDRSIZE);
    752 }
    753 
    754 /*
    755  * Calculate size of RAM (in pages) to be dumped.
    756  */
    757 u_long
    758 cpu_dump_mempagecnt(void)
    759 {
    760 	u_long i, n;
    761 
    762 	n = 0;
    763 	for (i = 0; i < mem_cluster_cnt; i++)
    764 		n += atop(mem_clusters[i].size);
    765 	return n;
    766 }
    767 
    768 /*
    769  * Called by dumpsys() to dump the machine-dependent header.
    770  */
    771 int
    772 cpu_dump(int (*dump)(dev_t, daddr_t, void *, size_t), daddr_t *blknop)
    773 {
    774 	int buf[MDHDRSIZE / sizeof(int)];
    775 	cpu_kcore_hdr_t *chdr;
    776 	kcore_seg_t *kseg;
    777 	int error;
    778 
    779 	kseg = (kcore_seg_t *)buf;
    780 	chdr = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) /
    781 	    sizeof(int)];
    782 
    783 	/* Create the segment header. */
    784 	CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
    785 	kseg->c_size = MDHDRSIZE - ALIGN(sizeof(kcore_seg_t));
    786 
    787 	memcpy(chdr, &cpu_kcore_hdr, sizeof(cpu_kcore_hdr_t));
    788 	error = (*dump)(dumpdev, *blknop, (void *)buf, sizeof(buf));
    789 	*blknop += btodb(sizeof(buf));
    790 	return error;
    791 }
    792 
    793 /*
    794  * These variables are needed by /sbin/savecore
    795  */
    796 uint32_t dumpmag = 0x8fca0101;	/* magic number */
    797 int	dumpsize = 0;		/* pages */
    798 long	dumplo = 0;		/* blocks */
    799 
    800 /*
    801  * This is called by main to set dumplo and dumpsize.
    802  * Dumps always skip the first PAGE_SIZE of disk space
    803  * in case there might be a disk label stored there.
    804  * If there is extra space, put dump at the end to
    805  * reduce the chance that swapping trashes it.
    806  */
    807 void
    808 cpu_dumpconf(void)
    809 {
    810 	int nblks, dumpblks;	/* size of dump area */
    811 
    812 	if (dumpdev == NODEV)
    813 		goto bad;
    814 	nblks = bdev_size(dumpdev);
    815 	if (nblks <= ctod(1))
    816 		goto bad;
    817 
    818 	dumpblks = cpu_dumpsize();
    819 	if (dumpblks < 0)
    820 		goto bad;
    821 	dumpblks += ctod(cpu_dump_mempagecnt());
    822 
    823 	/* If dump won't fit (incl. room for possible label), punt. */
    824 	if (dumpblks > (nblks - ctod(1)))
    825 		goto bad;
    826 
    827 	/* Put dump at end of partition */
    828 	dumplo = nblks - dumpblks;
    829 
    830 	/* dumpsize is in page units, and doesn't include headers. */
    831 	dumpsize = cpu_dump_mempagecnt();
    832 	return;
    833 
    834  bad:
    835 	dumpsize = 0;
    836 }
    837 
    838 /*
    839  * Dump physical memory onto the dump device.  Called by cpu_reboot().
    840  */
    841 void
    842 dumpsys(void)
    843 {
    844 	const struct bdevsw *bdev;
    845 	u_long totalbytesleft, bytes, i, n, memcl;
    846 	u_long maddr;
    847 	int psize;
    848 	daddr_t blkno;
    849 	int (*dump)(dev_t, daddr_t, void *, size_t);
    850 	int error;
    851 
    852 	/* XXX Should save registers. */
    853 
    854 	if (dumpdev == NODEV)
    855 		return;
    856 	bdev = bdevsw_lookup(dumpdev);
    857 	if (bdev == NULL || bdev->d_psize == NULL)
    858 		return;
    859 
    860 	/*
    861 	 * For dumps during autoconfiguration,
    862 	 * if dump device has already configured...
    863 	 */
    864 	if (dumpsize == 0)
    865 		cpu_dumpconf();
    866 	if (dumplo <= 0) {
    867 		printf("\ndump to dev %u,%u not possible\n",
    868 		    major(dumpdev), minor(dumpdev));
    869 		return;
    870 	}
    871 	printf("\ndumping to dev %u,%u offset %ld\n",
    872 	    major(dumpdev), minor(dumpdev), dumplo);
    873 
    874 	psize = bdev_size(dumpdev);
    875 	printf("dump ");
    876 	if (psize == -1) {
    877 		printf("area unavailable\n");
    878 		return;
    879 	}
    880 
    881 	/* XXX should purge all outstanding keystrokes. */
    882 
    883 	dump = bdev->d_dump;
    884 	blkno = dumplo;
    885 
    886 	if ((error = cpu_dump(dump, &blkno)) != 0)
    887 		goto err;
    888 
    889 	totalbytesleft = ptoa(cpu_dump_mempagecnt());
    890 
    891 	for (memcl = 0; memcl < mem_cluster_cnt; memcl++) {
    892 		maddr = mem_clusters[memcl].start;
    893 		bytes = mem_clusters[memcl].size;
    894 
    895 		for (i = 0; i < bytes; i += n, totalbytesleft -= n) {
    896 
    897 			/* Print out how many MBs we have left to go. */
    898 			if ((totalbytesleft % (1024*1024)) == 0)
    899 				printf_nolog("%ld ",
    900 				    totalbytesleft / (1024 * 1024));
    901 
    902 			/* Limit size for next transfer. */
    903 			n = bytes - i;
    904 			if (n > PAGE_SIZE)
    905 				n = PAGE_SIZE;
    906 
    907 			pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr,
    908 			    VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
    909 			pmap_update(pmap_kernel());
    910 
    911 			error = (*dump)(dumpdev, blkno, vmmap, n);
    912 			if (error)
    913 				goto err;
    914 			maddr += n;
    915 			blkno += btodb(n);
    916 		}
    917 	}
    918 
    919  err:
    920 	switch (error) {
    921 
    922 	case ENXIO:
    923 		printf("device bad\n");
    924 		break;
    925 
    926 	case EFAULT:
    927 		printf("device not ready\n");
    928 		break;
    929 
    930 	case EINVAL:
    931 		printf("area improper\n");
    932 		break;
    933 
    934 	case EIO:
    935 		printf("i/o error\n");
    936 		break;
    937 
    938 	case EINTR:
    939 		printf("aborted from console\n");
    940 		break;
    941 
    942 	case 0:
    943 		printf("succeeded\n");
    944 		break;
    945 
    946 	default:
    947 		printf("error %d\n", error);
    948 		break;
    949 	}
    950 	printf("\n\n");
    951 	delay(5000);
    952 }
    953 
    954 void
    955 initcpu(void)
    956 {
    957 	/* Nothing to do. */
    958 }
    959 
    960 void
    961 straytrap(int pc, u_short evec)
    962 {
    963 
    964 	printf("unexpected trap (vector offset %x) from %x\n",
    965 	    evec & 0xFFF, pc);
    966 }
    967 
    968 /*
    969  * Level 7 interrupts are caused by e.g. the ABORT switch.
    970  *
    971  * If we have DDB, then break into DDB on ABORT.  In a production
    972  * environment, bumping the ABORT switch would be bad, so we enable
    973  * panic'ing on ABORT with the kernel option "PANICBUTTON".
    974  */
    975 int
    976 nmihand(void *arg)
    977 {
    978 
    979 	mvme68k_abort("ABORT SWITCH");
    980 
    981 	return 1;
    982 }
    983 
    984 /*
    985  * Common code for handling ABORT signals from buttons, switches,
    986  * serial lines, etc.
    987  */
    988 void
    989 mvme68k_abort(const char *cp)
    990 {
    991 
    992 #ifdef DDB
    993 	db_printf("%s\n", cp);
    994 	Debugger();
    995 #else
    996 #ifdef PANICBUTTON
    997 	panic(cp);
    998 #else
    999 	printf("%s ignored\n", cp);
   1000 #endif /* PANICBUTTON */
   1001 #endif /* DDB */
   1002 }
   1003 
   1004 /*
   1005  * cpu_exec_aout_makecmds():
   1006  *	CPU-dependent a.out format hook for execve().
   1007  *
   1008  * Determine of the given exec package refers to something which we
   1009  * understand and, if so, set up the vmcmds for it.
   1010  */
   1011 int
   1012 cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp)
   1013 {
   1014 
   1015     return ENOEXEC;
   1016 }
   1017 
   1018 #ifdef MODULAR
   1019 /*
   1020  * Push any modules loaded by the bootloader etc.
   1021  */
   1022 void
   1023 module_init_md(void)
   1024 {
   1025 }
   1026 #endif
   1027 
   1028 int
   1029 mm_md_physacc(paddr_t pa, vm_prot_t prot)
   1030 {
   1031 
   1032 	return (pa < lowram || pa >= 0xfffffffc) ? EFAULT : 0;
   1033 }
   1034