xref: /netbsd-src/sys/arch/next68k/next68k/machdep.c (revision f36002f244a49908fef9cba8789032bdbf48d572)
1 /*	$NetBSD: machdep.c,v 1.122 2024/03/05 14:15:33 thorpej Exp $	*/
2 
3 /*
4  * Copyright (c) 1998 Darrin B. Jewell
5  * Copyright (c) 1988 University of Utah.
6  * Copyright (c) 1982, 1986, 1990, 1993
7  *	The Regents of the University of California.  All rights reserved.
8  *
9  * This code is derived from software contributed to Berkeley by
10  * the Systems Programming Group of the University of Utah Computer
11  * Science Department.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  * from: Utah $Hdr: machdep.c 1.74 92/12/20$
38  *
39  *	@(#)machdep.c	8.10 (Berkeley) 4/20/94
40  */
41 
42 #include <sys/cdefs.h>
43 __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.122 2024/03/05 14:15:33 thorpej Exp $");
44 
45 #include "opt_ddb.h"
46 #include "opt_kgdb.h"
47 #include "opt_modular.h"
48 
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/signalvar.h>
52 #include <sys/kernel.h>
53 #include <sys/proc.h>
54 #include <sys/buf.h>
55 #include <sys/reboot.h>
56 #include <sys/conf.h>
57 #include <sys/file.h>
58 #include <sys/device.h>
59 #include <sys/mbuf.h>
60 #include <sys/msgbuf.h>
61 #include <sys/ioctl.h>
62 #include <sys/tty.h>
63 #include <sys/mount.h>
64 #include <sys/exec.h>
65 #include <sys/exec_aout.h>		/* for MID_* */
66 #include <sys/core.h>
67 #include <sys/kcore.h>
68 #include <sys/vnode.h>
69 #include <sys/syscallargs.h>
70 #include <sys/ksyms.h>
71 #include <sys/module.h>
72 #ifdef KGDB
73 #include <sys/kgdb.h>
74 #endif
75 #include <sys/boot_flag.h>
76 #include <sys/cpu.h>
77 
78 #include <uvm/uvm_extern.h>
79 
80 #ifdef DDB
81 #include <machine/db_machdep.h>
82 #include <ddb/db_access.h>
83 #include <ddb/db_sym.h>
84 #include <ddb/db_extern.h>
85 #endif
86 
87 #ifdef KGDB
88 /* Is zs configured in? */
89 #include "zsc.h"
90 #if (NZSC > 0)
91 #include <next68k/dev/zs_cons.h>
92 #endif
93 #endif
94 
95 #include <sys/sysctl.h>
96 
97 #include <machine/cpu.h>
98 #include <machine/bus.h>
99 #include <machine/reg.h>
100 #include <machine/pcb.h>
101 #include <machine/psl.h>
102 #include <machine/pte.h>
103 #include <machine/vmparam.h>
104 #include <dev/cons.h>
105 
106 #include <machine/kcore.h>	/* XXX should be pulled in by sys/kcore.h */
107 
108 #include <next68k/next68k/isr.h>
109 #include <next68k/next68k/nextrom.h>
110 #include <next68k/next68k/rtc.h>
111 #include <next68k/next68k/seglist.h>
112 
113 #include <dev/mm.h>
114 
115 #include "ksyms.h"
116 
117 int nsym;
118 char *ssym;
119 extern char *esym;
120 
121 #define	MAXMEM	64*1024	/* XXX - from cmap.h */
122 
123 /* the following is used externally (sysctl_hw) */
124 char	machine[] = MACHINE;	/* from <machine/param.h> */
125 
126 /* Our exported CPU info; we can have only one. */
127 struct cpu_info cpu_info_store;
128 
129 struct vm_map *phys_map = NULL;
130 
131 paddr_t msgbufpa;		/* PA of message buffer */
132 
133 int	maxmem;			/* max memory per process */
134 
135 extern	u_int lowram;
136 extern	short exframesize[];
137 
138 /* prototypes for local functions */
139 void	identifycpu(void);
140 void	initcpu(void);
141 void	dumpsys(void);
142 
143 int	cpu_dumpsize(void);
144 int	cpu_dump(int (*)(dev_t, daddr_t, void *, size_t), daddr_t *);
145 void	cpu_init_kcore_hdr(void);
146 
147 /* functions called from locore.s */
148 void next68k_init(void);
149 void straytrap(int, u_short);
150 
151 /*
152  * Machine-independent crash dump header info.
153  */
154 cpu_kcore_hdr_t cpu_kcore_hdr;
155 
156 /*
157  * Memory segments initialized in locore, which are eventually loaded
158  * as managed VM pages.
159  */
160 phys_seg_list_t phys_seg_list[VM_PHYSSEG_MAX];
161 
162 /*
163  * Memory segments to dump.  This is initialized from the phys_seg_list
164  * before pages are stolen from it for VM system overhead.  I.e. this
165  * covers the entire range of physical memory.
166  */
167 phys_ram_seg_t mem_clusters[VM_PHYSSEG_MAX];
168 int	mem_cluster_cnt;
169 
170 /*
171  * On the 68020/68030, the value of delay_divisor is roughly
172  * 2048 / cpuspeed (where cpuspeed is in MHz).
173  *
174  * On the 68040/68060(?), the value of delay_divisor is roughly
175  * 759 / cpuspeed (where cpuspeed is in MHz).
176  * XXX -- is the above formula correct?
177  */
178 int	cpuspeed = 33;		  /* relative cpu speed; XXX skewed on 68040 */
179 int	delay_divisor = 759 / 33;  /* delay constant; assume fastest 33 MHz */
180 
181 /****************************************************************/
182 
183 /*
184  * Early initialization, before main() is called.
185  */
186 void
next68k_init(void)187 next68k_init(void)
188 {
189 	int i;
190 
191 	/*
192 	 * Tell the VM system about available physical memory.
193 	 */
194 	for (i = 0; i < mem_cluster_cnt; i++) {
195 		if (phys_seg_list[i].ps_start == phys_seg_list[i].ps_end) {
196 			/*
197 			 * Segment has been completely gobbled up.
198 			 */
199 			continue;
200 		}
201 		/*
202 		 * Note the index of the mem cluster is the free
203 		 * list we want to put the memory on.
204 		 */
205 		uvm_page_physload(atop(phys_seg_list[i].ps_start),
206 				  atop(phys_seg_list[i].ps_end),
207 				  atop(phys_seg_list[i].ps_start),
208 				  atop(phys_seg_list[i].ps_end),
209 				  VM_FREELIST_DEFAULT);
210 	}
211 
212 	{
213 		char *p = rom_boot_arg;
214 		boothowto = 0;
215 		if (*p++ == '-') {
216 			for (;*p;p++)
217 				BOOT_FLAG(*p, boothowto);
218 		}
219 	}
220 
221 	/*
222 	 * Initialize error message buffer (at end of core).
223 	 */
224 	for (i = 0; i < btoc(round_page(MSGBUFSIZE)); i++)
225 		pmap_enter(pmap_kernel(), (vaddr_t)msgbufaddr + i * PAGE_SIZE,
226 		    msgbufpa + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE,
227 		    VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
228 	initmsgbuf(msgbufaddr, round_page(MSGBUFSIZE));
229 	pmap_update(pmap_kernel());
230 }
231 
232 /*
233  * Console initialization: called early on from main,
234  * before vm init or startup.  Do enough configuration
235  * to choose and initialize a console.
236  */
237 void
consinit(void)238 consinit(void)
239 {
240 	static int init = 0;
241 
242 	/*
243 	 * Generic console: sys/dev/cons.c
244 	 *	Initializes either ite or ser as console.
245 	 *	Can be called from locore.s and init_main.c.
246 	 */
247 
248 	if (!init) {
249 		cninit();
250 #if defined(KGDB) && (NZSC > 0)
251 		zs_kgdb_init();
252 #endif
253 #if NKSYMS || defined(DDB) || defined(MODULAR)
254 		/* Initialize kernel symbol table, if compiled in. */
255 		ksyms_addsyms_elf(nsym, ssym, esym);
256 #endif
257 		if (boothowto & RB_KDB) {
258 #if defined(KGDB)
259 			kgdb_connect(1);
260 #elif defined(DDB)
261 			Debugger();
262 #endif
263 		}
264 
265 		init = 1;
266 	}
267 }
268 
269 /*
270  * cpu_startup: allocate memory for variable-sized tables,
271  * initialize CPU, and do autoconfiguration.
272  */
273 void
cpu_startup(void)274 cpu_startup(void)
275 {
276 	vaddr_t minaddr, maxaddr;
277 	char pbuf[9];
278 #ifdef DEBUG
279 	extern int pmapdebug;
280 	int opmapdebug = pmapdebug;
281 
282 	pmapdebug = 0;
283 #endif
284 
285 	if (fputype != FPU_NONE)
286 		m68k_make_fpu_idle_frame();
287 
288 	/*
289 	 * Initialize the kernel crash dump header.
290 	 */
291 	cpu_init_kcore_hdr();
292 
293 	/*
294 	 * Good {morning,afternoon,evening,night}.
295 	 */
296 	printf("%s%s", copyright, version);
297 	identifycpu();
298 	format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
299 	printf("total memory = %s\n", pbuf);
300 
301 	minaddr = 0;
302 	/*
303 	 * Allocate a submap for physio
304 	 */
305 	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
306 				 VM_PHYS_SIZE, 0, false, NULL);
307 
308 #ifdef DEBUG
309 	pmapdebug = opmapdebug;
310 #endif
311 	format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false)));
312 	printf("avail memory = %s\n", pbuf);
313 
314 	/*
315 	 * Set up CPU-specific registers, cache, etc.
316 	 */
317 	initcpu();
318 }
319 
320 void
identifycpu(void)321 identifycpu(void)
322 {
323 	const char *cpu_str, *mmu_str, *fpu_str, *cache_str;
324 	extern int turbo;
325 
326 	/*
327 	 * ...and the CPU type.
328 	 */
329 	switch (cputype) {
330 	case CPU_68040:
331 		cpu_str = "MC68040";
332 		cpuspeed = turbo ? 33 : 25;
333 		delay_divisor = 759 / cpuspeed;
334 		break;
335 	case CPU_68030:
336 		cpu_str = "MC68030";
337 		cpuspeed = 25;
338 		delay_divisor = 2048 / cpuspeed;
339 		break;
340 #if 0
341 	case CPU_68020:
342 		cpu_str = "MC68020";
343 		break;
344 #endif
345 	default:
346 		printf("\nunknown cputype %d\n", cputype);
347 		panic("startup");
348 	}
349 
350 	/*
351 	 * ...and the MMU type.
352 	 */
353 	switch (mmutype) {
354 	case MMU_68040:
355 	case MMU_68030:
356 		mmu_str = "+MMU";
357 		break;
358 #if 0
359 	case MMU_68851:
360 		mmu_str = ", MC68851 MMU";
361 		break;
362 #endif
363 	default:
364 		printf("%s: unknown MMU type %d\n", cpu_str, mmutype);
365 		panic("startup");
366 	}
367 
368 	/*
369 	 * ...and the FPU type.
370 	 */
371 	switch (fputype) {
372 	case FPU_68040:
373 		fpu_str = "+FPU";
374 		break;
375 	case FPU_68882:
376 		fpu_str = ", MC68882 FPU";
377 		break;
378 	case FPU_68881:
379 		fpu_str = ", MC68881 FPU";
380 		break;
381 	default:
382 		fpu_str = ", unknown FPU";
383 	}
384 
385 	/*
386 	 * ...and finally, the cache type.
387 	 */
388 	if (cputype == CPU_68040)
389 		cache_str = ", 4k on-chip physical I/D caches";
390 	else
391 		cache_str = "";
392 
393 	cpu_setmodel("NeXT/%s CPU%s%s%s", cpu_str, mmu_str, fpu_str, cache_str);
394 	printf("%s\n", cpu_getmodel());
395 }
396 
397 /*
398  * machine dependent system variables.
399  */
400 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
401 {
402 
403 	sysctl_createv(clog, 0, NULL, NULL,
404 		       CTLFLAG_PERMANENT,
405 		       CTLTYPE_NODE, "machdep", NULL,
406 		       NULL, 0, NULL, 0,
407 		       CTL_MACHDEP, CTL_EOL);
408 
409 #if 0
410 	sysctl_createv(clog, 0, NULL, NULL,
411 		       CTLFLAG_PERMANENT,
412 		       CTLTYPE_STRUCT, "console_device", NULL,
413 		       sysctl_consdev, 0, NULL, sizeof(dev_t),
414 		       CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
415 #endif
416 }
417 
418 /* See: sig_machdep.c */
419 
420 int	waittime = -1;
421 
422 void
cpu_reboot(int howto,char * bootstr)423 cpu_reboot(int howto, char *bootstr)
424 {
425 	struct pcb *pcb = lwp_getpcb(curlwp);
426 
427 	/* take a snap shot before clobbering any registers */
428 	if (pcb != NULL)
429 		savectx(pcb);
430 
431 	/* If system is cold, 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 #if defined(PANICWAIT) && !defined(DDB)
457 	if ((howto & RB_HALT) == 0 && panicstr) {
458 		printf("hit any key to reboot...\n");
459 		cnpollc(1);
460 		(void)cngetc();
461 		cnpollc(0);
462 		printf("\n");
463 	}
464 #endif
465 
466 	if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
467 		poweroff();
468 	}
469 
470 	/* Finally, halt/reboot the system. */
471 	if (howto & RB_HALT) {
472 		monbootflag = 0x2d680000;				/* "-h" */
473 	}
474 
475 	printf("rebooting...\n");
476 	DELAY(1000000);
477 	doboot();
478 	/*NOTREACHED*/
479 }
480 
481 /*
482  * Initialize the kernel crash dump header.
483  */
484 void
cpu_init_kcore_hdr(void)485 cpu_init_kcore_hdr(void)
486 {
487 	cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
488 	struct m68k_kcore_hdr *m = &h->un._m68k;
489 	int i;
490 	extern char end[];
491 
492 	memset(&cpu_kcore_hdr, 0, sizeof(cpu_kcore_hdr));
493 
494 	/*
495 	 * Initialize the `dispatcher' portion of the header.
496 	 */
497 	strcpy(h->name, machine);
498 	h->page_size = PAGE_SIZE;
499 	h->kernbase = KERNBASE;
500 
501 	/*
502 	 * Fill in information about our MMU configuration.
503 	 */
504 	m->mmutype	= mmutype;
505 	m->sg_v		= SG_V;
506 	m->sg_frame	= SG_FRAME;
507 	m->sg_ishift	= SG_ISHIFT;
508 	m->sg_pmask	= SG_PMASK;
509 	m->sg40_shift1	= SG4_SHIFT1;
510 	m->sg40_mask2	= SG4_MASK2;
511 	m->sg40_shift2	= SG4_SHIFT2;
512 	m->sg40_mask3	= SG4_MASK3;
513 	m->sg40_shift3	= SG4_SHIFT3;
514 	m->sg40_addr1	= SG4_ADDR1;
515 	m->sg40_addr2	= SG4_ADDR2;
516 	m->pg_v		= PG_V;
517 	m->pg_frame	= PG_FRAME;
518 
519 	/*
520 	 * Initialize pointer to kernel segment table.
521 	 */
522 	m->sysseg_pa = (uint32_t)(pmap_kernel()->pm_stpa);
523 
524 	/*
525 	 * Initialize relocation value such that:
526 	 *
527 	 *	pa = (va - KERNBASE) + reloc
528 	 */
529 	m->reloc = lowram;
530 
531 	/*
532 	 * Define the end of the relocatable range.
533 	 */
534 	m->relocend = (uint32_t)end;
535 
536 	/*
537 	 * The next68k has multiple memory segments.
538 	 */
539 	for (i = 0; i < mem_cluster_cnt; i++) {
540 		m->ram_segs[i].start = mem_clusters[i].start;
541 		m->ram_segs[i].size  = mem_clusters[i].size;
542 	}
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 	vm_offset_t maddr;	/* PA being dumped */
640 	int error;		/* error code from (*dump)() */
641 
642 	/* XXX initialized here because of gcc lossage */
643 	maddr = lowram;
644 	pg = 0;
645 
646 	/* Don't put dump messages in msgbuf. */
647 	msgbufmapped = 0;
648 
649 	/* Make sure dump device is valid. */
650 	if (dumpdev == NODEV)
651 		return;
652 	bdev = bdevsw_lookup(dumpdev);
653 	if (bdev == NULL)
654 		return;
655 	if (dumpsize == 0) {
656 		cpu_dumpconf();
657 		if (dumpsize == 0)
658 			return;
659 	}
660 	if (dumplo < 0)
661 		return;
662 	dump = bdev->d_dump;
663 	blkno = dumplo;
664 
665 	printf("\ndumping to dev 0x%"PRIx64", offset %ld\n", dumpdev, dumplo);
666 
667 	printf("dump ");
668 
669 	/* Write the dump header. */
670 	error = cpu_dump(dump, &blkno);
671 	if (error)
672 		goto bad;
673 
674 	for (pg = 0; pg < dumpsize; pg++) {
675 #define NPGMB	(1024*1024/PAGE_SIZE)
676 		/* print out how many MBs we have dumped */
677 		if (pg && (pg % NPGMB) == 0)
678 			printf_nolog("%d ", pg / NPGMB);
679 #undef NPGMB
680 		pmap_enter(pmap_kernel(), (vm_offset_t)vmmap, maddr,
681 		    VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
682 		pmap_update(pmap_kernel());
683 
684 		error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE);
685  bad:
686 		switch (error) {
687 		case 0:
688 			maddr += PAGE_SIZE;
689 			blkno += btodb(PAGE_SIZE);
690 			break;
691 
692 		case ENXIO:
693 			printf("device bad\n");
694 			return;
695 
696 		case EFAULT:
697 			printf("device not ready\n");
698 			return;
699 
700 		case EINVAL:
701 			printf("area improper\n");
702 			return;
703 
704 		case EIO:
705 			printf("i/o error\n");
706 			return;
707 
708 		case EINTR:
709 			printf("aborted from console\n");
710 			return;
711 
712 		default:
713 			printf("error %d\n", error);
714 			return;
715 		}
716 	}
717 	printf("succeeded\n");
718 }
719 
720 void
initcpu(void)721 initcpu(void)
722 {
723 }
724 
725 void
straytrap(int pc,u_short evec)726 straytrap(int pc, u_short evec)
727 {
728 	printf("unexpected trap (vector offset %x) from %x\n",
729 	       evec & 0xFFF, pc);
730 
731 	/* XXX kgdb/ddb entry? */
732 }
733 
734 /* XXX should change the interface, and make one badaddr() function */
735 
736 int	*nofault;
737 
738 #if 0
739 int
740 badaddr(void *addr, int nbytes)
741 {
742 	int i;
743 	label_t faultbuf;
744 
745 #ifdef lint
746 	i = *addr; if (i) return (0);
747 #endif
748 
749 	nofault = (int *) &faultbuf;
750 	if (setjmp((label_t *)nofault)) {
751 		nofault = (int *) 0;
752 		return(1);
753 	}
754 
755 	switch (nbytes) {
756 	case 1:
757 		i = *(volatile char *)addr;
758 		break;
759 
760 	case 2:
761 		i = *(volatile short *)addr;
762 		break;
763 
764 	case 4:
765 		i = *(volatile int *)addr;
766 		break;
767 
768 	default:
769 		panic("badaddr: bad request");
770 	}
771 	nofault = NULL;
772 	return (0);
773 }
774 #endif
775 
776 /*
777  * Level 7 interrupts can be caused by the keyboard or parity errors.
778  */
779 int
nmihand(void * frame)780 nmihand(void *frame)
781 {
782 	static int innmihand;	/* simple mutex */
783 
784 	/* Prevent unwanted recursion. */
785 	if (innmihand)
786 		return 0;
787 	innmihand = 1;
788 
789 	printf("Got a NMI");
790 
791 	if (!INTR_OCCURRED(NEXT_I_NMI)) {
792 		printf("But NMI isn't set in intrstat!\n");
793 	}
794 	INTR_DISABLE(NEXT_I_NMI);
795 
796 #if defined(DDB)
797 	printf(": entering debugger\n");
798 	Debugger();
799 	printf("continuing after NMI\n");
800 #elif defined(KGDB)
801 	kgdb_connect(1);
802 #else
803 	printf(": ignoring\n");
804 #endif /* DDB */
805 
806 	INTR_ENABLE(NEXT_I_NMI);
807 
808 	innmihand = 0;
809 
810 	return 0;
811 }
812 
813 
814 /*
815  * cpu_exec_aout_makecmds():
816  *	CPU-dependent a.out format hook for execve().
817  *
818  * Determine of the given exec package refers to something which we
819  * understand and, if so, set up the vmcmds for it.
820  */
821 int
cpu_exec_aout_makecmds(struct lwp * l,struct exec_package * epp)822 cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp)
823 {
824 	return ENOEXEC;
825 }
826 
827 int
mm_md_physacc(paddr_t pa,vm_prot_t prot)828 mm_md_physacc(paddr_t pa, vm_prot_t prot)
829 {
830 
831 	return (pa < lowram || pa >= 0xfffffffc) ? EFAULT : 0;
832 }
833 
834 #ifdef MODULAR
835 /*
836  * Push any modules loaded by the bootloader etc.
837  */
838 void
module_init_md(void)839 module_init_md(void)
840 {
841 }
842 #endif
843