xref: /netbsd-src/sys/arch/luna68k/luna68k/machdep.c (revision f36002f244a49908fef9cba8789032bdbf48d572)
1 /* $NetBSD: machdep.c,v 1.112 2024/03/05 14:15:32 thorpej Exp $ */
2 
3 /*-
4  * Copyright (c) 2000 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Tohru Nishimura.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
33 
34 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.112 2024/03/05 14:15:32 thorpej Exp $");
35 
36 #include "opt_ddb.h"
37 #include "opt_kgdb.h"
38 #include "opt_compat_sunos.h"
39 #include "opt_modular.h"
40 #include "opt_panicbutton.h"
41 #include "opt_m68k_arch.h"
42 
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/kernel.h>
46 #include <sys/proc.h>
47 #include <sys/buf.h>
48 #include <sys/reboot.h>
49 #include <sys/conf.h>
50 #include <sys/file.h>
51 #include <sys/device.h>
52 #include <sys/mbuf.h>
53 #include <sys/msgbuf.h>
54 #include <sys/ioctl.h>
55 #include <sys/tty.h>
56 #include <sys/mount.h>
57 #include <sys/exec.h>
58 #include <sys/exec_aout.h>		/* for MID_* */
59 #include <sys/core.h>
60 #include <sys/kauth.h>
61 #include <sys/kcore.h>
62 #include <sys/vnode.h>
63 #include <sys/syscallargs.h>
64 #include <sys/ksyms.h>
65 #include <sys/module.h>
66 #ifdef	KGDB
67 #include <sys/kgdb.h>
68 #endif
69 #include <sys/boot_flag.h>
70 #include <sys/exec_elf.h>
71 #include <sys/cpu.h>
72 
73 #include <uvm/uvm_extern.h>
74 
75 #include <sys/sysctl.h>
76 
77 #include <machine/bootinfo.h>
78 #include <machine/board.h>
79 #include <machine/cpu.h>
80 #include <machine/reg.h>
81 #include <machine/pcb.h>
82 #include <machine/psl.h>
83 #include <machine/pte.h>
84 #include <machine/kcore.h>	/* XXX should be pulled in by sys/kcore.h */
85 
86 #include <luna68k/dev/siottyvar.h>
87 
88 #include <dev/cons.h>
89 #include <dev/mm.h>
90 
91 #if defined(DDB)
92 #include <machine/db_machdep.h>
93 #include <ddb/db_sym.h>
94 #include <ddb/db_extern.h>
95 #endif
96 
97 #include "ksyms.h"
98 
99 /*
100  * Info for CTL_HW
101  */
102 char	machine[] = MACHINE;
103 
104 /* Our exported CPU info; we can have only one. */
105 struct cpu_info cpu_info_store;
106 
107 struct vm_map *phys_map = NULL;
108 
109 int	maxmem;			/* max memory per process */
110 
111 extern	u_int lowram;
112 
113 void luna68k_init(void);
114 void identifycpu(void);
115 void dumpsys(void);
116 
117 void straytrap(int, u_short);
118 void nmihand(struct frame);
119 
120 int  cpu_dumpsize(void);
121 int  cpu_dump(int (*)(dev_t, daddr_t, void *, size_t), daddr_t *);
122 void cpu_init_kcore_hdr(void);
123 
124 #if NKSYMS || defined(DDB) || defined(MODULAR)
125 vsize_t symtab_size(vaddr_t);
126 #endif
127 extern char end[];
128 extern void *esym;
129 
130 /*
131  * Machine-independent crash dump header info.
132  */
133 cpu_kcore_hdr_t cpu_kcore_hdr;
134 
135 int	machtype;	/* model: 1 for LUNA-1, 2 for LUNA-2 */
136 int	sysconsole;	/* console: 0 for ttya, 1 for video */
137 
138 extern void omfb_cnattach(void);
139 extern void ws_cnattach(void);
140 
141 /*
142  * On the 68020/68030, the value of delay_divisor is roughly
143  * 2048 / cpuspeed (where cpuspeed is in MHz).
144  *
145  * On the 68040/68060(?), the value of delay_divisor is roughly
146  * 759 / cpuspeed (where cpuspeed is in MHz).
147  * XXX -- is the above formula correct?
148  */
149 int	cpuspeed = 25;		/* only used for printing later */
150 int	delay_divisor = 30;	/* for delay() loop count */
151 
152 /*
153  * Early initialization, before main() is called.
154  */
155 void
luna68k_init(void)156 luna68k_init(void)
157 {
158 	volatile uint8_t *pio0 = (void *)OBIO_PIO0_BASE;
159 	int sw1, i;
160 	char *cp;
161 	extern char bootarg[64];
162 
163 	extern paddr_t avail_start, avail_end;
164 
165 	/* initialize cn_tab for early console */
166 #if 1
167 	cn_tab = &siottycons;
168 #else
169 	cn_tab = &romcons;
170 #endif
171 
172 	/*
173 	 * Tell the VM system about available physical memory.  The
174 	 * luna68k only has one segment.
175 	 */
176 	uvm_page_physload(atop(avail_start), atop(avail_end),
177 	    atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT);
178 
179 	/*
180 	 * Initialize error message buffer (at end of core).
181 	 * avail_end was pre-decremented in pmap_bootstrap to compensate.
182 	 */
183 	for (i = 0; i < btoc(MSGBUFSIZE); i++)
184 		pmap_kenter_pa((vaddr_t)msgbufaddr + i * PAGE_SIZE,
185 		    avail_end + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, 0);
186 	pmap_update(pmap_kernel());
187 	initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE));
188 
189 
190 	pio0[3] = 0xb6;
191 	pio0[2] = 1 << 6;		/* enable parity check */
192 	pio0[3] = 0xb6;
193 	sw1 = pio0[0];			/* dip sw1 value */
194 	sw1 ^= 0xff;
195 	sysconsole = !(sw1 & 0x2);	/* console selection */
196 
197 	/*
198 	 * Check if boothowto and bootdev values are passed by our bootloader.
199 	 */
200 	if ((bootdev & B_MAGICMASK) == B_DEVMAGIC) {
201 		/* Valid value is set; no need to parse bootarg. */
202 		return;
203 	}
204 
205 	/*
206 	 * No valid bootdev value is set.
207 	 * Assume we are booted by ROM monitor directly using a.out kernel
208 	 * and we have to parse bootarg passed from the monitor to set
209 	 * proper boothowto and check netboot.
210 	 */
211 
212 	/* set default to "sd0a" with no howto flags */
213 	bootdev = MAKEBOOTDEV(0, LUNA68K_BOOTADPT_SPC, 0, 0, 0);
214 	boothowto = 0;
215 
216 	/*
217 	 * 'bootarg' on LUNA has:
218 	 *   "<args of x command> ENADDR=<addr> HOST=<host> SERVER=<name>"
219 	 * where <addr> is MAC address of which network loader used (not
220 	 * necessarily same as one at 0x4101.FFE0), <host> and <name>
221 	 * are the values of HOST and SERVER environment variables.
222 	 *
223 	 * 'bootarg' on LUNA-II has "<args of x command>" only.
224 	 *
225 	 * NetBSD/luna68k cares only the first argument; any of "sda".
226 	 */
227 	bootarg[63] = '\0';
228 	for (cp = bootarg; *cp != '\0'; cp++) {
229 		if (*cp == '-') {
230 			char c;
231 			while ((c = *cp) != '\0' && c != ' ') {
232 				BOOT_FLAG(c, boothowto);
233 				cp++;
234 			}
235 		} else if (*cp == 'E' && memcmp("ENADDR=", cp, 7) == 0) {
236 			bootdev =
237 			    MAKEBOOTDEV(0, LUNA68K_BOOTADPT_LANCE, 0, 0, 0);
238 		}
239 	}
240 }
241 
242 /*
243  * Console initialization: called early on from main,
244  */
245 void
consinit(void)246 consinit(void)
247 {
248 
249 	if (sysconsole == 0) {
250 		cn_tab = &siottycons;
251 		(*cn_tab->cn_init)(cn_tab);
252 	} else {
253 		omfb_cnattach();
254 		ws_cnattach();
255 	}
256 
257 #if NKSYMS || defined(DDB) || defined(MODULAR)
258 	ksyms_addsyms_elf((esym != NULL) ? 1 : 0, (void *)&end, esym);
259 #endif
260 #ifdef DDB
261 	if (boothowto & RB_KDB)
262 		cpu_Debugger();
263 #endif
264 }
265 
266 #if NKSYMS || defined(DDB) || defined(MODULAR)
267 
268 /*
269  * Check and compute size of DDB symbols and strings.
270  *
271  * Note this function could be called from locore.s before MMU is turned on
272  * so we should avoid global variables and function calls.
273  */
274 vsize_t
symtab_size(vaddr_t hdr)275 symtab_size(vaddr_t hdr)
276 {
277 	int i;
278 	Elf_Ehdr *ehdr;
279 	Elf_Shdr *shp;
280 	vaddr_t maxsym;
281 
282 	/*
283 	 * Check the ELF headers.
284 	 */
285 
286 	ehdr = (void *)hdr;
287 	if (ehdr->e_ident[EI_MAG0] != ELFMAG0 ||
288 	    ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
289 	    ehdr->e_ident[EI_MAG2] != ELFMAG2 ||
290 	    ehdr->e_ident[EI_MAG3] != ELFMAG3 ||
291 	    ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
292 		return 0;
293 	}
294 
295 	/*
296 	 * Find the end of the symbols and strings.
297 	 */
298 
299 	maxsym = 0;
300 	shp = (Elf_Shdr *)(hdr + ehdr->e_shoff);
301 	for (i = 0; i < ehdr->e_shnum; i++) {
302 		if (shp[i].sh_type != SHT_SYMTAB &&
303 		    shp[i].sh_type != SHT_STRTAB) {
304 			continue;
305 		}
306 		maxsym = uimax(maxsym, shp[i].sh_offset + shp[i].sh_size);
307 	}
308 
309 	return maxsym;
310 }
311 #endif /* NKSYMS || defined(DDB) || defined(MODULAR) */
312 
313 /*
314  * cpu_startup: allocate memory for variable-sized tables.
315  */
316 void
cpu_startup(void)317 cpu_startup(void)
318 {
319 	vaddr_t minaddr, maxaddr;
320 	char pbuf[9];
321 
322 	if (fputype != FPU_NONE)
323 		m68k_make_fpu_idle_frame();
324 
325 	/*
326 	 * Initialize the kernel crash dump header.
327 	 */
328 	cpu_init_kcore_hdr();
329 
330 	/*
331 	 * Good {morning,afternoon,evening,night}.
332 	 */
333 	printf("%s%s", copyright, version);
334 	identifycpu();
335 
336 	format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
337 	printf("total memory = %s\n", pbuf);
338 
339 	minaddr = 0;
340 
341 	/*
342 	 * Allocate a submap for physio
343 	 */
344 	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
345 	    VM_PHYS_SIZE, 0, false, NULL);
346 
347 	format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false)));
348 	printf("avail memory = %s\n", pbuf);
349 }
350 
351 void
identifycpu(void)352 identifycpu(void)
353 {
354 	extern int cputype;
355 	const char *model, *fpu;
356 
357 	switch (cputype) {
358 	case CPU_68030:
359 		model ="LUNA-I";
360 		switch (fputype) {
361 		case FPU_68881:
362 			fpu = "MC68881";
363 			break;
364 		case FPU_68882:
365 			fpu = "MC68882";
366 			break;
367 		case FPU_NONE:
368 			fpu = "no";
369 			break;
370 		default:
371 			fpu = "unknown";
372 			break;
373 		}
374 		cpu_setmodel("%s (MC68030 CPU+MMU, %s FPU)", model, fpu);
375 		machtype = LUNA_I;
376 		/* 20MHz 68030 */
377 		cpuspeed = 20;
378 		delay_divisor = 102;
379 		hz = 60;
380 		break;
381 #if defined(M68040)
382 	case CPU_68040:
383 		model ="LUNA-II";
384 		cpu_setmodel(
385 		    "%s (MC68040 CPU+MMU+FPU, 4k on-chip physical I/D caches)",
386 		    model);
387 		machtype = LUNA_II;
388 		/* 25MHz 68040 */
389 		cpuspeed = 25;
390 		delay_divisor = 30;
391 		/* hz = 100 on LUNA-II */
392 		break;
393 #endif
394 	default:
395 		panic("unknown CPU type");
396 	}
397 	printf("%s\n", cpu_getmodel());
398 }
399 
400 /*
401  * machine dependent system variables.
402  */
403 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
404 {
405 
406 	sysctl_createv(clog, 0, NULL, NULL,
407 		       CTLFLAG_PERMANENT,
408 		       CTLTYPE_NODE, "machdep", NULL,
409 		       NULL, 0, NULL, 0,
410 		       CTL_MACHDEP, CTL_EOL);
411 
412 	sysctl_createv(clog, 0, NULL, NULL,
413 		       CTLFLAG_PERMANENT,
414 		       CTLTYPE_STRUCT, "console_device", NULL,
415 		       sysctl_consdev, 0, NULL, sizeof(dev_t),
416 		       CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
417 }
418 
419 int	waittime = -1;
420 
421 void
cpu_reboot(int howto,char * bootstr)422 cpu_reboot(int howto, char *bootstr)
423 {
424 	struct pcb *pcb = lwp_getpcb(curlwp);
425 	extern void doboot(void);
426 
427 	/* take a snap shot before clobbering any registers */
428 	if (pcb != NULL)
429 		savectx(pcb);
430 
431 	/* If system is hold, just halt. */
432 	if (cold) {
433 		howto |= RB_HALT;
434 		goto haltsys;
435 	}
436 
437 	boothowto = howto;
438 	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
439 		waittime = 0;
440 		vfs_shutdown();
441 	}
442 
443 	/* Disable interrupts. */
444 	splhigh();
445 
446 	/* If rebooting and a dump is requested, do it. */
447 	if (howto & RB_DUMP)
448 		dumpsys();
449 
450 haltsys:
451 	/* Run any shutdown hooks. */
452 	doshutdownhooks();
453 
454 	pmf_system_shutdown(boothowto);
455 
456 	/* Finally, halt/reboot the system. */
457 	if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
458 		volatile uint8_t *pio = (void *)OBIO_PIO1_BASE;
459 
460 		printf("power is going down.\n");
461 		DELAY(100000);
462 		pio[3] = 0x94;
463 		pio[2] = 0 << 4;
464 		for (;;)
465 			/* NOP */;
466 	}
467 	if (howto & RB_HALT) {
468 		printf("System halted.	Hit any key to reboot.\n\n");
469 		cnpollc(1);
470 		(void)cngetc();
471 		cnpollc(0);
472 	}
473 
474 	printf("rebooting...\n");
475 	DELAY(100000);
476 	doboot();
477 	/*NOTREACHED*/
478 	for (;;)
479 		;
480 }
481 
482 /*
483  * Initialize the kernel crash dump header.
484  */
485 void
cpu_init_kcore_hdr(void)486 cpu_init_kcore_hdr(void)
487 {
488 	cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
489 	struct m68k_kcore_hdr *m = &h->un._m68k;
490 
491 	memset(&cpu_kcore_hdr, 0, sizeof(cpu_kcore_hdr));
492 
493 	/*
494 	 * Initialize the `dispatcher' portion of the header.
495 	 */
496 	strcpy(h->name, machine);
497 	h->page_size = PAGE_SIZE;
498 	h->kernbase = KERNBASE;
499 
500 	/*
501 	 * Fill in information about our MMU configuration.
502 	 */
503 	m->mmutype	= mmutype;
504 	m->sg_v		= SG_V;
505 	m->sg_frame	= SG_FRAME;
506 	m->sg_ishift	= SG_ISHIFT;
507 	m->sg_pmask	= SG_PMASK;
508 	m->sg40_shift1	= SG4_SHIFT1;
509 	m->sg40_mask2	= SG4_MASK2;
510 	m->sg40_shift2	= SG4_SHIFT2;
511 	m->sg40_mask3	= SG4_MASK3;
512 	m->sg40_shift3	= SG4_SHIFT3;
513 	m->sg40_addr1	= SG4_ADDR1;
514 	m->sg40_addr2	= SG4_ADDR2;
515 	m->pg_v		= PG_V;
516 	m->pg_frame	= PG_FRAME;
517 
518 	/*
519 	 * Initialize pointer to kernel segment table.
520 	 */
521 	m->sysseg_pa = (uint32_t)(pmap_kernel()->pm_stpa);
522 
523 	/*
524 	 * Initialize relocation value such that:
525 	 *
526 	 *	pa = (va - KERNBASE) + reloc
527 	 *
528 	 * Since we're linked and loaded at the same place,
529 	 * and the kernel is mapped va == pa, this is 0.
530 	 */
531 	m->reloc = 0;
532 
533 	/*
534 	 * Define the end of the relocatable range.
535 	 */
536 	m->relocend = (uint32_t)end;
537 
538 	/*
539 	 * The luna68k has one contiguous memory segment.
540 	 */
541 	m->ram_segs[0].start = 0 /* lowram */;
542 	m->ram_segs[0].size  = ctob(physmem);
543 }
544 
545 /*
546  * Compute the size of the machine-dependent crash dump header.
547  * Returns size in disk blocks.
548  */
549 
550 #define CHDRSIZE (ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)))
551 #define MDHDRSIZE roundup(CHDRSIZE, dbtob(1))
552 
553 int
cpu_dumpsize(void)554 cpu_dumpsize(void)
555 {
556 
557 	return btodb(MDHDRSIZE);
558 }
559 
560 /*
561  * Called by dumpsys() to dump the machine-dependent header.
562  */
563 int
cpu_dump(int (* dump)(dev_t,daddr_t,void *,size_t),daddr_t * blknop)564 cpu_dump(int (*dump)(dev_t, daddr_t, void *, size_t), daddr_t *blknop)
565 {
566 	int buf[MDHDRSIZE / sizeof(int)];
567 	cpu_kcore_hdr_t *chdr;
568 	kcore_seg_t *kseg;
569 	int error;
570 
571 	kseg = (kcore_seg_t *)buf;
572 	chdr = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) /
573 	    sizeof(int)];
574 
575 	/* Create the segment header. */
576 	CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
577 	kseg->c_size = MDHDRSIZE - ALIGN(sizeof(kcore_seg_t));
578 
579 	memcpy(chdr, &cpu_kcore_hdr, sizeof(cpu_kcore_hdr_t));
580 	error = (*dump)(dumpdev, *blknop, (void *)buf, sizeof(buf));
581 	*blknop += btodb(sizeof(buf));
582 	return error;
583 }
584 
585 /*
586  * These variables are needed by /sbin/savecore
587  */
588 uint32_t dumpmag = 0x8fca0101;	/* magic number */
589 int	dumpsize = 0;		/* pages */
590 long	dumplo = 0;		/* blocks */
591 
592 /*
593  * This is called by main to set dumplo and dumpsize.
594  * Dumps always skip the first PAGE_SIZE of disk space
595  * in case there might be a disk label stored there.
596  * If there is extra space, put dump at the end to
597  * reduce the chance that swapping trashes it.
598  */
599 void
cpu_dumpconf(void)600 cpu_dumpconf(void)
601 {
602 	int chdrsize;	/* size of dump header */
603 	int nblks;	/* size of dump area */
604 
605 	if (dumpdev == NODEV)
606 		return;
607 	nblks = bdev_size(dumpdev);
608 	chdrsize = cpu_dumpsize();
609 
610 	dumpsize = btoc(cpu_kcore_hdr.un._m68k.ram_segs[0].size);
611 
612 	/*
613 	 * Check do see if we will fit.  Note we always skip the
614 	 * first PAGE_SIZE in case there is a disk label there.
615 	 */
616 	if (nblks < (ctod(dumpsize) + chdrsize + ctod(1))) {
617 		dumpsize = 0;
618 		dumplo = -1;
619 		return;
620 	}
621 
622 	/*
623 	 * Put dump at the end of the partition.
624 	 */
625 	dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize;
626 }
627 
628 /*
629  * Dump physical memory onto the dump device.  Called by cpu_reboot().
630  */
631 void
dumpsys(void)632 dumpsys(void)
633 {
634 	const struct bdevsw *bdev;
635 	daddr_t blkno;		/* current block to write */
636 				/* dump routine */
637 	int (*dump)(dev_t, daddr_t, void *, size_t);
638 	int pg;			/* page being dumped */
639 	paddr_t maddr;		/* PA being dumped */
640 	int error;		/* error code from (*dump)() */
641 
642 	/* XXX initialized here because of gcc lossage */
643 	maddr = 0 /* lowram */;
644 	pg = 0;
645 
646 	/* Make sure dump device is valid. */
647 	if (dumpdev == NODEV)
648 		return;
649 	bdev = bdevsw_lookup(dumpdev);
650 	if (bdev == NULL)
651 		return;
652 	if (dumpsize == 0) {
653 		cpu_dumpconf();
654 		if (dumpsize == 0)
655 			return;
656 	}
657 	if (dumplo <= 0) {
658 		printf("\ndump to dev %u,%u  not possible\n",
659 		    major(dumpdev), minor(dumpdev));
660 		return;
661 	}
662 	dump = bdev->d_dump;
663 	blkno = dumplo;
664 
665 	printf("\ndumping to dev %u,%u offset %ld\n",
666 	    major(dumpdev), minor(dumpdev), dumplo);
667 
668 	printf("dump ");
669 
670 	/* Write the dump header. */
671 	error = cpu_dump(dump, &blkno);
672 	if (error)
673 		goto bad;
674 
675 	for (pg = 0; pg < dumpsize; pg++) {
676 #define NPGMB	(1024*1024/PAGE_SIZE)
677 		/* print out how many MBs we have dumped */
678 		if (pg && (pg % NPGMB) == 0)
679 			printf("%d ", pg / NPGMB);
680 #undef NPGMB
681 		pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr,
682 		    VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
683 
684 		pmap_update(pmap_kernel());
685 		error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE);
686  bad:
687 		switch (error) {
688 		case 0:
689 			maddr += PAGE_SIZE;
690 			blkno += btodb(PAGE_SIZE);
691 			break;
692 
693 		case ENXIO:
694 			printf("device bad\n");
695 			return;
696 
697 		case EFAULT:
698 			printf("device not ready\n");
699 			return;
700 
701 		case EINVAL:
702 			printf("area improper\n");
703 			return;
704 
705 		case EIO:
706 			printf("i/o error\n");
707 			return;
708 
709 		case EINTR:
710 			printf("aborted from console\n");
711 			return;
712 
713 		default:
714 			printf("error %d\n", error);
715 			return;
716 		}
717 	}
718 	printf("succeeded\n");
719 }
720 
721 void
straytrap(int pc,u_short evec)722 straytrap(int pc, u_short evec)
723 {
724 
725 	printf("unexpected trap (vector offset %x) from %x\n",
726 	    evec & 0xFFF, pc);
727 }
728 
729 int	*nofault;
730 
731 int
badaddr(register void * addr,int nbytes)732 badaddr(register void *addr, int nbytes)
733 {
734 	int i;
735 	label_t faultbuf;
736 
737 	nofault = (int *)&faultbuf;
738 	if (setjmp((label_t *)nofault)) {
739 		nofault = (int *)0;
740 		return 1;
741 	}
742 
743 	switch (nbytes) {
744 	case 1:
745 		i = *(volatile int8_t *)addr;
746 		break;
747 
748 	case 2:
749 		i = *(volatile int16_t *)addr;
750 		break;
751 
752 	case 4:
753 		i = *(volatile int32_t *)addr;
754 		break;
755 
756 	default:
757 		panic("badaddr: bad request");
758 	}
759 	__USE(i);
760 	nofault = (int *)0;
761 	return 0;
762 }
763 
764 void luna68k_abort(const char *);
765 
766 static int innmihand;	/* simple mutex */
767 
768 /*
769  * Level 7 interrupts are caused by e.g. the ABORT switch.
770  *
771  * If we have DDB, then break into DDB on ABORT.  In a production
772  * environment, bumping the ABORT switch would be bad, so we enable
773  * panic'ing on ABORT with the kernel option "PANICBUTTON".
774  */
775 void
nmihand(struct frame frame)776 nmihand(struct frame frame)
777 {
778 
779 	/* Prevent unwanted recursion */
780 	if (innmihand)
781 		return;
782 	innmihand = 1;
783 
784 	luna68k_abort("ABORT SWITCH");
785 
786 	innmihand = 0;
787 }
788 
789 /*
790  * Common code for handling ABORT signals from buttons, switches,
791  * serial lines, etc.
792  */
793 void
luna68k_abort(const char * cp)794 luna68k_abort(const char *cp)
795 {
796 
797 #ifdef DDB
798 	printf("%s\n", cp);
799 	cpu_Debugger();
800 #else
801 #ifdef PANICBUTTON
802 	panic(cp);
803 #else
804 	printf("%s ignored\n", cp);
805 #endif /* PANICBUTTON */
806 #endif /* DDB */
807 }
808 
809 /*
810  * cpu_exec_aout_makecmds():
811  *	CPU-dependent a.out format hook for execve().
812  *
813  * Determine of the given exec package refers to something which we
814  * understand and, if so, set up the vmcmds for it.
815  */
816 int
cpu_exec_aout_makecmds(struct lwp * l,struct exec_package * epp)817 cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp)
818 {
819 	return ENOEXEC;
820 }
821 
822 #ifdef MODULAR
823 /*
824  * Push any modules loaded by the bootloader etc.
825  */
826 void
module_init_md(void)827 module_init_md(void)
828 {
829 }
830 #endif
831 
832 #ifdef notyet
833 /*
834  * romcons is useful until m68k TC register is initialized.
835  */
836 int  romcngetc(dev_t);
837 void romcnputc(dev_t, int);
838 
839 struct consdev romcons = {
840 	NULL,
841 	NULL,
842 	romcngetc,
843 	romcnputc,
844 	nullcnpollc,
845 	makedev(7, 0), /* XXX */
846 	CN_DEAD,
847 };
848 
849 #define __		((int **)PROM_ADDR)
850 #define GETC()		(*(int (*)())__[6])()
851 #define PUTC(x)		(*(void (*)())__[7])(x)
852 
853 #define ROMPUTC(x) \
854 ({					\
855 	register _r;			\
856 	__asm volatile ("			\
857 		movc	%%vbr,%0	; \
858 		movel	%0,%%sp@-	; \
859 		clrl	%0		; \
860 		movc	%0,%%vbr"	\
861 		: "=r" (_r));		\
862 	PUTC(x);			\
863 	__asm volatile ("			\
864 		movel	%%sp@+,%0	; \
865 		movc	%0,%%vbr"	\
866 		: "=r" (_r));		\
867 })
868 
869 #define ROMGETC() \
870 ({					\
871 	register _r, _c;		\
872 	__asm volatile ("			\
873 		movc	%%vbr,%0	; \
874 		movel	%0,%%sp@-	; \
875 		clrl	%0		; \
876 		movc	%0,%%vbr"	\
877 		: "=r" (_r));		\
878 	_c = GETC();			\
879 	__asm volatile ("			\
880 		movel	%%sp@+,%0	; \
881 		movc	%0,%%vbr"	\
882 		: "=r" (_r));		\
883 	_c;				\
884 })
885 
886 void
romcnputc(dev_t dev,int c)887 romcnputc(dev_t dev, int c)
888 {
889 	int s;
890 
891 	s = splhigh();
892 	ROMPUTC(c);
893 	splx(s);
894 }
895 
896 int
romcngetc(dev_t dev)897 romcngetc(dev_t dev)
898 {
899 	int s, c;
900 
901 	do {
902 		s = splhigh();
903 		c = ROMGETC();
904 		splx(s);
905 	} while (c == -1);
906 	return c;
907 }
908 #endif
909 
910 int
mm_md_physacc(paddr_t pa,vm_prot_t prot)911 mm_md_physacc(paddr_t pa, vm_prot_t prot)
912 {
913 
914 	return (pa < lowram || pa >= 0xfffffffc) ? EFAULT : 0;
915 }
916