xref: /netbsd/sys/arch/news68k/news68k/machdep.c (revision dc398f1e)
1 /*	$NetBSD: machdep.c,v 1.110 2021/10/09 20:00:42 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.110 2021/10/09 20:00:42 tsutsui Exp $");
43 
44 #include "opt_ddb.h"
45 #include "opt_compat_netbsd.h"
46 #include "opt_modular.h"
47 
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/buf.h>
51 #include <sys/conf.h>
52 #include <sys/kernel.h>
53 #include <sys/device.h>
54 #include <sys/malloc.h>
55 #include <sys/mbuf.h>
56 #include <sys/mount.h>
57 #include <sys/msgbuf.h>
58 #include <sys/proc.h>
59 #include <sys/reboot.h>
60 #include <sys/tty.h>
61 #include <sys/exec.h>
62 #include <sys/exec_aout.h>		/* for MID_* */
63 #include <sys/core.h>
64 #include <sys/kcore.h>
65 #include <sys/ksyms.h>
66 #include <sys/module.h>
67 #include <sys/cpu.h>
68 
69 #ifdef DDB
70 #include <machine/db_machdep.h>
71 #include <ddb/db_sym.h>
72 #include <ddb/db_extern.h>
73 #endif
74 #ifdef __ELF__
75 #include <sys/exec_elf.h>
76 #endif
77 
78 #include <machine/autoconf.h>
79 #include <machine/cpu.h>
80 #include <machine/reg.h>
81 #include <machine/pcb.h>
82 #include <machine/pte.h>
83 #include <machine/intr.h>
84 
85 #include <machine/kcore.h>	/* XXX should be pulled in by sys/kcore.h */
86 
87 #include <dev/cons.h>
88 #include <dev/mm.h>
89 
90 #define MAXMEM	64*1024		/* XXX - from cmap.h */
91 #include <uvm/uvm_extern.h>
92 
93 #include <sys/sysctl.h>
94 
95 #include <news68k/news68k/machid.h>
96 #include <news68k/news68k/isr.h>
97 
98 #include "le.h"
99 #include "kb.h"
100 #include "ms.h"
101 #include "si.h"
102 #include "ksyms.h"
103 #include "romcons.h"
104 /* XXX etc. etc. */
105 
106 /* the following is used externally (sysctl_hw) */
107 char	machine[] = MACHINE;	/* from <machine/param.h> */
108 
109 /* Our exported CPU info; we can have only one. */
110 struct cpu_info cpu_info_store;
111 
112 struct vm_map *phys_map = NULL;
113 
114 int	maxmem;			/* max memory per process */
115 
116 extern paddr_t avail_start, avail_end;
117 extern int end, *esym;
118 extern u_int lowram;
119 extern u_int ctrl_led_phys;
120 
121 /* prototypes for local functions */
122 static void identifycpu(void);
123 static void initcpu(void);
124 static int cpu_dumpsize(void);
125 static int cpu_dump(int (*)(dev_t, daddr_t, void *, size_t), daddr_t *);
126 static void cpu_init_kcore_hdr(void);
127 
128 #ifdef news1700
129 static void news1700_init(void);
130 static void parityenable(void);
131 static void parityerror(void);
132 #endif
133 #ifdef news1200
134 static void news1200_init(void);
135 #endif
136 
137 /* functions called from locore.s */
138 void dumpsys(void);
139 void news68k_init(void);
140 void straytrap(int, u_short);
141 
142 /*
143  * Machine-dependent crash dump header info.
144  */
145 cpu_kcore_hdr_t cpu_kcore_hdr;
146 
147 /*
148  * Note that the value of delay_divisor is roughly
149  * 2048 / cpuspeed (where cpuspeed is in MHz) on 68020
150  * and 68030 systems.
151  */
152 int	cpuspeed = 25;		/* relative CPU speed; XXX skewed on 68040 */
153 int	delay_divisor = 82;	/* delay constant */
154 
155 /*
156  * Early initialization, before main() is called.
157  */
158 void
news68k_init(void)159 news68k_init(void)
160 {
161 	int i;
162 
163 	/*
164 	 * Tell the VM system about available physical memory.  The
165 	 * news68k only has one segment.
166 	 */
167 	uvm_page_physload(atop(avail_start), atop(avail_end),
168 	    atop(avail_start), atop(avail_end), VM_FREELIST_DEFAULT);
169 
170 	/* Initialize system variables. */
171 	switch (systype) {
172 #ifdef news1700
173 	case NEWS1700:
174 		news1700_init();
175 		break;
176 #endif
177 #ifdef news1200
178 	case NEWS1200:
179 		news1200_init();
180 		break;
181 #endif
182 	default:
183 		panic("impossible system type");
184 	}
185 
186 	/*
187 	 * Initialize error message buffer (at end of core).
188 	 * avail_end was pre-decremented in pmap_bootstrap to compensate.
189 	 */
190 	for (i = 0; i < btoc(MSGBUFSIZE); i++)
191 		pmap_kenter_pa((vaddr_t)msgbufaddr + i * PAGE_SIZE,
192 		    avail_end + i * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, 0);
193 	pmap_update(pmap_kernel());
194 	initmsgbuf(msgbufaddr, m68k_round_page(MSGBUFSIZE));
195 }
196 
197 /*
198  * cpu_startup: allocate memory for variable-sized tables,
199  * initialize CPU, and do autoconfiguration.
200  */
201 void
cpu_startup(void)202 cpu_startup(void)
203 {
204 	vaddr_t minaddr, maxaddr;
205 	char pbuf[9];
206 #ifdef DEBUG
207 	extern int pmapdebug;
208 	int opmapdebug = pmapdebug;
209 
210 	pmapdebug = 0;
211 #endif
212 
213 	if (fputype != FPU_NONE)
214 		m68k_make_fpu_idle_frame();
215 
216 	/*
217 	 * Initialize the kernel crash dump header.
218 	 */
219 	cpu_init_kcore_hdr();
220 
221 	/*
222 	 * Good {morning,afternoon,evening,night}.
223 	 */
224 	printf("%s%s", copyright, version);
225 	identifycpu();
226 	format_bytes(pbuf, sizeof(pbuf), ctob(physmem));
227 	printf("total memory = %s\n", pbuf);
228 
229 	minaddr = 0;
230 
231 	/*
232 	 * Allocate a submap for physio
233 	 */
234 	phys_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr,
235 	    VM_PHYS_SIZE, 0, false, NULL);
236 
237 #ifdef DEBUG
238 	pmapdebug = opmapdebug;
239 #endif
240 	format_bytes(pbuf, sizeof(pbuf), ptoa(uvm_availmem(false)));
241 	printf("avail memory = %s\n", pbuf);
242 
243 	/*
244 	 * Set up CPU-specific registers, cache, etc.
245 	 */
246 	initcpu();
247 }
248 
249 int news_machine_id;
250 
251 static void
identifycpu(void)252 identifycpu(void)
253 {
254 
255 	printf("SONY NET WORK STATION, Model %s, ", cpu_getmodel());
256 	printf("Machine ID #%d\n", news_machine_id);
257 
258 	delay_divisor = (20480 / cpuspeed + 5) / 10; /* XXX */
259 }
260 
261 /*
262  * machine dependent system variables.
263  */
264 SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
265 {
266 
267 	sysctl_createv(clog, 0, NULL, NULL,
268 	    CTLFLAG_PERMANENT,
269 	    CTLTYPE_NODE, "machdep", NULL,
270 	    NULL, 0, NULL, 0,
271 	    CTL_MACHDEP, CTL_EOL);
272 
273 	sysctl_createv(clog, 0, NULL, NULL,
274 	    CTLFLAG_PERMANENT,
275 	    CTLTYPE_STRUCT, "console_device", NULL,
276 	    sysctl_consdev, 0, NULL, sizeof(dev_t),
277 	    CTL_MACHDEP, CPU_CONSDEV, CTL_EOL);
278 }
279 
280 int	waittime = -1;
281 
282 void
cpu_reboot(int howto,char * bootstr)283 cpu_reboot(int howto, char *bootstr)
284 {
285 	struct pcb *pcb = lwp_getpcb(curlwp);
286 
287 	/* take a snap shot before clobbering any registers */
288 	if (pcb != NULL)
289 		savectx(pcb);
290 
291 	/* If system is cold, just halt. */
292 	if (cold) {
293 		howto |= RB_HALT;
294 		goto haltsys;
295 	}
296 
297 	boothowto = howto;
298 	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
299 		waittime = 0;
300 		vfs_shutdown();
301 		/*
302 		 * If we've been adjusting the clock, the todr
303 		 * will be out of synch; adjust it now.
304 		 */
305 		resettodr();
306 	}
307 
308 	/* Disable interrupts. */
309 	splhigh();
310 
311 	/* If rebooting and a dump is requested, do it. */
312 	if (howto & RB_DUMP)
313 		dumpsys();
314 
315  haltsys:
316 	/* Run any shutdown hooks. */
317 	doshutdownhooks();
318 
319 	pmf_system_shutdown(boothowto);
320 
321 #if defined(PANICWAIT) && !defined(DDB)
322 	if ((howto & RB_HALT) == 0 && panicstr) {
323 		printf("hit any key to reboot...\n");
324 		cnpollc(1);
325 		(void)cngetc();
326 		cnpollc(0);
327 		printf("\n");
328 	}
329 #endif
330 
331 	/* Finally, halt/reboot the system. */
332 	if ((howto & RB_POWERDOWN) == RB_POWERDOWN) {
333 		DELAY(1000000);
334 		doboot(RB_POWERDOWN);
335 		/* NOTREACHED */
336 	}
337 
338 	if (howto & RB_HALT) {
339 		printf("System halted.\n\n");
340 		doboot(RB_HALT);
341 		/* NOTREACHED */
342 	}
343 
344 	printf("rebooting...\n");
345 	DELAY(1000000);
346 	doboot(RB_AUTOBOOT);
347 	/* NOTREACHED */
348 }
349 
350 /*
351  * Initialize the kernel crash dump header.
352  */
353 static void
cpu_init_kcore_hdr(void)354 cpu_init_kcore_hdr(void)
355 {
356 	cpu_kcore_hdr_t *h = &cpu_kcore_hdr;
357 	struct m68k_kcore_hdr *m = &h->un._m68k;
358 
359 	memset(&cpu_kcore_hdr, 0, sizeof(cpu_kcore_hdr));
360 
361 	/*
362 	 * Initialize the `dispatcher' portion of the header.
363 	 */
364 	strcpy(h->name, machine);
365 	h->page_size = PAGE_SIZE;
366 	h->kernbase = KERNBASE;
367 
368 	/*
369 	 * Fill in information about our MMU configuration.
370 	 */
371 	m->mmutype	= mmutype;
372 	m->sg_v		= SG_V;
373 	m->sg_frame	= SG_FRAME;
374 	m->sg_ishift	= SG_ISHIFT;
375 	m->sg_pmask	= SG_PMASK;
376 	m->sg40_shift1	= SG4_SHIFT1;
377 	m->sg40_mask2	= SG4_MASK2;
378 	m->sg40_shift2	= SG4_SHIFT2;
379 	m->sg40_mask3	= SG4_MASK3;
380 	m->sg40_shift3	= SG4_SHIFT3;
381 	m->sg40_addr1	= SG4_ADDR1;
382 	m->sg40_addr2	= SG4_ADDR2;
383 	m->pg_v		= PG_V;
384 	m->pg_frame	= PG_FRAME;
385 
386 	/*
387 	 * Initialize pointer to kernel segment table.
388 	 */
389 	m->sysseg_pa = (uint32_t)(pmap_kernel()->pm_stpa);
390 
391 	/*
392 	 * Initialize relocation value such that:
393 	 *
394 	 *	pa = (va - KERNBASE) + reloc
395 	 */
396 	m->reloc = lowram;
397 
398 	/*
399 	 * Define the end of the relocatable range.
400 	 */
401 	m->relocend = (uint32_t)&end;
402 
403 	/*
404 	 * news68k has one contiguous memory segment.
405 	 */
406 	m->ram_segs[0].start = lowram;
407 	m->ram_segs[0].size  = ctob(physmem);
408 }
409 
410 /*
411  * Compute the size of the machine-dependent crash dump header.
412  * Returns size in disk blocks.
413  */
414 
415 #define CHDRSIZE (ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)))
416 #define MDHDRSIZE roundup(CHDRSIZE, dbtob(1))
417 
418 static int
cpu_dumpsize(void)419 cpu_dumpsize(void)
420 {
421 
422 	return btodb(MDHDRSIZE);
423 }
424 
425 /*
426  * Called by dumpsys() to dump the machine-dependent header.
427  */
428 static int
cpu_dump(int (* dump)(dev_t,daddr_t,void *,size_t),daddr_t * blknop)429 cpu_dump(int (*dump)(dev_t, daddr_t, void *, size_t), daddr_t *blknop)
430 {
431 	int buf[MDHDRSIZE / sizeof(int)];
432 	cpu_kcore_hdr_t *chdr;
433 	kcore_seg_t *kseg;
434 	int error;
435 
436 	kseg = (kcore_seg_t *)buf;
437 	chdr = (cpu_kcore_hdr_t *)&buf[ALIGN(sizeof(kcore_seg_t)) /
438 	    sizeof(int)];
439 
440 	/* Create the segment header. */
441 	CORE_SETMAGIC(*kseg, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
442 	kseg->c_size = MDHDRSIZE - ALIGN(sizeof(kcore_seg_t));
443 
444 	memcpy(chdr, &cpu_kcore_hdr, sizeof(cpu_kcore_hdr_t));
445 	error = (*dump)(dumpdev, *blknop, (void *)buf, sizeof(buf));
446 	*blknop += btodb(sizeof(buf));
447 	return error;
448 }
449 
450 /*
451  * These variables are needed by /sbin/savecore
452  */
453 uint32_t dumpmag = 0x8fca0101;	/* magic number */
454 int	dumpsize = 0;		/* pages */
455 long	dumplo = 0;		/* blocks */
456 
457 /*
458  * This is called by main to set dumplo and dumpsize.
459  * Dumps always skip the first PAGE_SIZE of disk space
460  * in case there might be a disk label stored there.
461  * If there is extra space, put dump at the end to
462  * reduce the chance that swapping trashes it.
463  */
464 void
cpu_dumpconf(void)465 cpu_dumpconf(void)
466 {
467 	int chdrsize;	/* size of dump header */
468 	int nblks;	/* size of dump area */
469 
470 	if (dumpdev == NODEV)
471 		return;
472 	nblks = bdev_size(dumpdev);
473 	chdrsize = cpu_dumpsize();
474 
475 	dumpsize = btoc(cpu_kcore_hdr.un._m68k.ram_segs[0].size);
476 
477 	/*
478 	 * Check do see if we will fit.  Note we always skip the
479 	 * first PAGE_SIZE in case there is a disk label there.
480 	 */
481 	if (nblks < (ctod(dumpsize) + chdrsize + ctod(1))) {
482 		dumpsize = 0;
483 		dumplo = -1;
484 		return;
485 	}
486 
487 	/*
488 	 * Put dump at the end of the partition.
489 	 */
490 	dumplo = (nblks - 1) - ctod(dumpsize) - chdrsize;
491 }
492 
493 /*
494  * Dump physical memory onto the dump device.  Called by cpu_reboot().
495  */
496 void
dumpsys(void)497 dumpsys(void)
498 {
499 	const struct bdevsw *bdev;
500 	daddr_t blkno;		/* current block to write */
501 				/* dump routine */
502 	int (*dump)(dev_t, daddr_t, void *, size_t);
503 	int pg;			/* page being dumped */
504 	paddr_t maddr;		/* PA being dumped */
505 	int error;		/* error code from (*dump)() */
506 
507 	/* XXX initialized here because of gcc lossage */
508 	maddr = lowram;
509 	pg = 0;
510 
511 	/* Make sure dump device is valid. */
512 	if (dumpdev == NODEV)
513 		return;
514 	bdev = bdevsw_lookup(dumpdev);
515 	if (bdev == NULL)
516 		return;
517 	if (dumpsize == 0) {
518 		cpu_dumpconf();
519 		if (dumpsize == 0)
520 			return;
521 	}
522 	if (dumplo <= 0) {
523 		printf("\ndump to dev %u,%u not possible\n",
524 		    major(dumpdev), minor(dumpdev));
525 		return;
526 	}
527 	dump = bdev->d_dump;
528 	blkno = dumplo;
529 
530 	printf("\ndumping to dev %u,%u offset %ld\n",
531 	    major(dumpdev), minor(dumpdev), dumplo);
532 
533 	printf("dump ");
534 
535 	/* Write the dump header. */
536 	error = cpu_dump(dump, &blkno);
537 	if (error)
538 		goto bad;
539 
540 	for (pg = 0; pg < dumpsize; pg++) {
541 #define NPGMB	(1024*1024/PAGE_SIZE)
542 		/* print out how many MBs we have dumped */
543 		if (pg && (pg % NPGMB) == 0)
544 			printf_nolog("%d ", pg / NPGMB);
545 #undef NPGMB
546 		pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr,
547 		    VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
548 
549 		pmap_update(pmap_kernel());
550 		error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE);
551  bad:
552 		switch (error) {
553 		case 0:
554 			maddr += PAGE_SIZE;
555 			blkno += btodb(PAGE_SIZE);
556 			break;
557 
558 		case ENXIO:
559 			printf("device bad\n");
560 				return;
561 
562 		case EFAULT:
563 			printf("device not ready\n");
564 			return;
565 
566 		case EINVAL:
567 			printf("area improper\n");
568 			return;
569 
570 		case EIO:
571 			printf("i/o error\n");
572 			return;
573 
574 		case EINTR:
575 			printf("aborted from console\n");
576 			return;
577 
578 		default:
579 			printf("error %d\n", error);
580 			return;
581 		}
582 	}
583 	printf("succeeded\n");
584 }
585 
586 static void
initcpu(void)587 initcpu(void)
588 {
589 }
590 
591 void
straytrap(int pc,u_short evec)592 straytrap(int pc, u_short evec)
593 {
594 
595 	printf("unexpected trap (vector offset %x) from %x\n",
596 	    evec & 0xFFF, pc);
597 }
598 
599 /* XXX should change the interface, and make one badaddr() function */
600 
601 int	*nofault;
602 
603 int
badaddr(void * addr,int nbytes)604 badaddr(void *addr, int nbytes)
605 {
606 	int i;
607 	label_t	faultbuf;
608 
609 #ifdef lint
610 	i = *addr; if (i) return 0;
611 #endif
612 
613 	nofault = (int *) &faultbuf;
614 	if (setjmp((label_t *)nofault)) {
615 		nofault = (int *) 0;
616 		return 1;
617 	}
618 	switch (nbytes) {
619 	case 1:
620 		i = *(volatile char *)addr;
621 		break;
622 
623 	case 2:
624 		i = *(volatile short *)addr;
625 		break;
626 
627 	case 4:
628 		i = *(volatile int *)addr;
629 		break;
630 
631 	default:
632 		panic("badaddr: bad request");
633 	}
634 	__USE(i);
635 	nofault = (int *) 0;
636 	return 0;
637 }
638 
639 int
badbaddr(void * addr)640 badbaddr(void *addr)
641 {
642 	int i;
643 	label_t	faultbuf;
644 
645 	nofault = (int *) &faultbuf;
646 	if (setjmp((label_t *)nofault)) {
647 		nofault = (int *) 0;
648 		return 1;
649 	}
650 	i = *(volatile char *)addr;
651 	__USE(i);
652 	nofault = (int *) 0;
653 	return 0;
654 }
655 
656 /*
657  * cpu_exec_aout_makecmds():
658  *	CPU-dependent a.out format hook for execve().
659  *
660  * Determine of the given exec package refers to something which we
661  * understand and, if so, set up the vmcmds for it.
662  *
663  * XXX what are the special cases for the hp300?
664  * XXX why is this COMPAT_NOMID?  was something generating
665  *	hp300 binaries with an a_mid of 0?  i thought that was only
666  *	done on little-endian machines...  -- cgd
667  */
668 int
cpu_exec_aout_makecmds(struct lwp * l,struct exec_package * epp)669 cpu_exec_aout_makecmds(struct lwp *l, struct exec_package *epp)
670 {
671 #if defined(COMPAT_NOMID) || defined(COMPAT_44)
672 	u_long midmag, magic;
673 	u_short mid;
674 	int error;
675 	struct exec *execp = epp->ep_hdr;
676 
677 	midmag = ntohl(execp->a_midmag);
678 	mid = (midmag >> 16) & 0xffff;
679 	magic = midmag & 0xffff;
680 
681 	midmag = mid << 16 | magic;
682 
683 	switch (midmag) {
684 #ifdef COMPAT_NOMID
685 	case (MID_ZERO << 16) | ZMAGIC:
686 		error = exec_aout_prep_oldzmagic(l, epp);
687 		return(error);
688 #endif
689 #ifdef COMPAT_44
690 	case (MID_HP300 << 16) | ZMAGIC:
691 		error = exec_aout_prep_oldzmagic(l, epp);
692 		return error;
693 #endif
694 	}
695 #endif /* !(defined(COMPAT_NOMID) || defined(COMPAT_44)) */
696 
697 	return ENOEXEC;
698 }
699 
700 /*
701  *  System dependent initilization
702  */
703 
704 static volatile uint8_t *dip_switch, *int_status;
705 
706 const uint8_t *idrom_addr;
707 volatile uint8_t *ctrl_ast, *ctrl_int2;
708 volatile uint8_t *ctrl_led;
709 uint32_t sccport0a, lance_mem_phys;
710 
711 #ifdef news1700
712 static volatile u_char *ctrl_parity, *ctrl_parity_clr, *parity_vector;
713 
714 struct news68k_model {
715 	const int id;
716 	const char *name;
717 };
718 
719 static const struct news68k_model news68k_models[] = {
720 	{ ICK001,	"ICK001"	},	/*  1 */
721 	{ ICK00X,	"ICK00X"	},	/*  2 */
722 	{ NWS799,	"NWS-799"	},	/*  3 */
723 	{ NWS800,	"NWS-800"	},	/*  4 */
724 	{ NWS801,	"NWS-801"	},	/*  5 */
725 	{ NWS802,	"NWS-802"	},	/*  6 */
726 	{ NWS711,	"NWS-711"	},	/*  7 */
727 	{ NWS721,	"NWS-721"	},	/*  8 */
728 	{ NWS1850,	"NWS-1850"	},	/*  9 */
729 	{ NWS810,	"NWS-810"	},	/* 10 */
730 	{ NWS811,	"NWS-811"	},	/* 11 */
731 	{ NWS1830,	"NWS-1830"	},	/* 12 */
732 	{ NWS1750,	"NWS-1750"	},	/* 13 */
733 	{ NWS1720,	"NWS-1720"	},	/* 14 */
734 	{ NWS1930,	"NWS-1930"	},	/* 15 */
735 	{ NWS1960,	"NWS-1960"	},	/* 16 */
736 	{ NWS712,	"NWS-712"	},	/* 17 */
737 	{ NWS1860,	"NWS-1860"	},	/* 18 */
738 	{ PWS1630,	"PWS-1630"	},	/* 19 */
739 	{ NWS820,	"NWS-820"	},	/* 20 */
740 	{ NWS821,	"NWS-821"	},	/* 21 */
741 	{ NWS1760,	"NWS-1760"	},	/* 22 */
742 	{ NWS1710,	"NWS-1710"	},	/* 23 */
743 	{ NWS830,	"NWS-830"	},	/* 30 */
744 	{ NWS831,	"NWS-831"	},	/* 31 */
745 	{ NWS841,	"NWS-841"	},	/* 41 */
746 	{ PWS1570,	"PWS-1570"	},	/* 52 */
747 	{ PWS1590,	"PWS-1590"	},	/* 54 */
748 	{ NWS1520,	"NWS-1520"	},	/* 56 */
749 	{ PWS1550,	"PWS-1550"	},	/* 73 */
750 	{ PWS1520,	"PWS-1520"	},	/* 74 */
751 	{ PWS1560,	"PWS-1560"	},	/* 75 */
752 	{ NWS1530,	"NWS-1530"	},	/* 76 */
753 	{ NWS1580,	"NWS-1580"	},	/* 77 */
754 	{ NWS1510,	"NWS-1510"	},	/* 78 */
755 	{ NWS1410,	"NWS-1410"	},	/* 81 */
756 	{ NWS1450,	"NWS-1450"	},	/* 85 */
757 	{ NWS1460,	"NWS-1460"	},	/* 86 */
758 	{ NWS891,	"NWS-891"	},	/* 91 */
759 	{ NWS911,	"NWS-911"	},	/* 111 */
760 	{ NWS921,	"NWS-921"	},	/* 121 */
761 	{ 0,		NULL		}
762 };
763 
764 static void
news1700_init(void)765 news1700_init(void)
766 {
767 	struct oidrom idrom;
768 	const char *t;
769 	const uint8_t *p;
770 	uint8_t *q;
771 	u_int i;
772 
773 	dip_switch	= (uint8_t *)(0xe1c00100);
774 	int_status	= (uint8_t *)(0xe1c00200);
775 
776 	idrom_addr	= (uint8_t *)(0xe1c00000);
777 	ctrl_ast	= (uint8_t *)(0xe1280000);
778 	ctrl_int2	= (uint8_t *)(0xe1180000);
779 	ctrl_led	= (uint8_t *)(ctrl_led_phys);
780 
781 	sccport0a	= (0xe0d40002);
782 	lance_mem_phys	= 0xe0e00000;
783 
784 	p = idrom_addr;
785 	q = (uint8_t *)&idrom;
786 
787 	for (i = 0; i < sizeof(idrom); i++, p += 2)
788 		*q++ = ((*p & 0x0f) << 4) | (*(p + 1) & 0x0f);
789 
790 	t = NULL;
791 	for (i = 0; news68k_models[i].name != NULL; i++) {
792 		if (news68k_models[i].id == idrom.id_model) {
793 			t = news68k_models[i].name;
794 		}
795 	}
796 	if (t == NULL)
797 		panic("unexpected system model.");
798 
799 	cpu_setmodel("%s", t);
800 	news_machine_id = (idrom.id_serial[0] << 8) + idrom.id_serial[1];
801 
802 	ctrl_parity	= (uint8_t *)(0xe1080000);
803 	ctrl_parity_clr	= (uint8_t *)(0xe1a00000);
804 	parity_vector	= (uint8_t *)(0xe1c00200);
805 
806 	parityenable();
807 
808 	cpuspeed = 25;
809 }
810 
811 /*
812  * parity error handling (vectored NMI?)
813  */
814 
815 static void
parityenable(void)816 parityenable(void)
817 {
818 
819 #define PARITY_VECT 0xc0
820 #define PARITY_PRI 7
821 
822 	*parity_vector = PARITY_VECT;
823 
824 	isrlink_vectored((int (*)(void *))parityerror, NULL,
825 	    PARITY_PRI, PARITY_VECT);
826 
827 	*ctrl_parity_clr = 1;
828 	*ctrl_parity = 1;
829 
830 #ifdef DEBUG
831 	printf("enable parity check\n");
832 #endif
833 }
834 
835 static int innmihand;	/* simple mutex */
836 
837 static void
parityerror(void)838 parityerror(void)
839 {
840 
841 	/* Prevent unwanted recursion. */
842 	if (innmihand)
843 		return;
844 	innmihand = 1;
845 
846 #if 0 /* XXX need to implement XXX */
847 	panic("parity error");
848 #else
849 	printf("parity error detected.\n");
850 	*ctrl_parity_clr = 1;
851 #endif
852 	innmihand = 0;
853 }
854 #endif /* news1700 */
855 
856 #ifdef news1200
857 static void
news1200_init(void)858 news1200_init(void)
859 {
860 	struct idrom idrom;
861 	const uint8_t *p;
862 	uint8_t *q;
863 	int i;
864 
865 	dip_switch	= (uint8_t *)0xe1680000;
866 	int_status	= (uint8_t *)0xe1200000;
867 
868 	idrom_addr	= (uint8_t *)0xe1400000;
869 	ctrl_ast	= (uint8_t *)0xe1100000;
870 	ctrl_int2	= (uint8_t *)0xe10c0000;
871 	ctrl_led	= (uint8_t *)ctrl_led_phys;
872 
873 	sccport0a	= 0xe1780002;
874 	lance_mem_phys	= 0xe1a00000;
875 
876 	p = idrom_addr;
877 	q = (uint8_t *)&idrom;
878 	for (i = 0; i < sizeof(idrom); i++, p += 2)
879 		*q++ = ((*p & 0x0f) << 4) | (*(p + 1) & 0x0f);
880 
881 	cpu_setmodel("%s", idrom.id_model);
882 	news_machine_id = idrom.id_serial;
883 
884 	cpuspeed = 25;
885 }
886 #endif /* news1200 */
887 
888 /*
889  * interrupt handlers
890  * XXX should do better handling XXX
891  */
892 
893 void intrhand_lev3(void);
894 void intrhand_lev4(void);
895 
896 void
intrhand_lev3(void)897 intrhand_lev3(void)
898 {
899 	int stat;
900 
901 	stat = *int_status;
902 	intrcnt[3]++;
903 	curcpu()->ci_data.cpu_nintr++;
904 #if 1
905 	printf("level 3 interrupt: INT_STATUS = 0x%02x\n", stat);
906 #endif
907 }
908 
909 extern int leintr(int);
910 extern int si_intr(int);
911 
912 void
intrhand_lev4(void)913 intrhand_lev4(void)
914 {
915 	int stat;
916 
917 #define INTST_LANCE	0x04
918 #define INTST_SCSI	0x80
919 
920 	stat = *int_status;
921 	intrcnt[4]++;
922 	curcpu()->ci_data.cpu_nintr++;
923 
924 #if NSI > 0
925 	if (stat & INTST_SCSI) {
926 		si_intr(0);
927 	}
928 #endif
929 #if NLE > 0
930 	if (stat & INTST_LANCE) {
931 		leintr(0);
932 	}
933 #endif
934 #if 0
935 	printf("level 4 interrupt\n");
936 #endif
937 }
938 
939 /*
940  * consinit() routines - from newsmips/cpu_cons.c
941  */
942 
943 /*
944  * Console initialization: called early on from main,
945  * before vm init or startup.  Do enough configuration
946  * to choose and initialize a console.
947  * XXX need something better here.
948  */
949 #define SCC_CONSOLE	0
950 #define SW_CONSOLE	0x07
951 #define SW_NWB512	0x04
952 #define SW_NWB225	0x01
953 #define SW_FBPOP	0x02
954 #define SW_FBPOP1	0x06
955 #define SW_FBPOP2	0x03
956 #define SW_AUTOSEL	0x07
957 
958 extern struct consdev consdev_rom, consdev_zs;
959 
960 int tty00_is_console = 0;
961 
962 void
consinit(void)963 consinit(void)
964 {
965 	uint8_t dipsw;
966 
967 	dipsw = *dip_switch;
968 
969 	dipsw = ~dipsw;
970 
971 	switch (dipsw & SW_CONSOLE) {
972 	default: /* XXX no real fb support yet */
973 #if NROMCONS > 0
974 		cn_tab = &consdev_rom;
975 		(*cn_tab->cn_init)(cn_tab);
976 		break;
977 #endif
978 	case 0:
979 		tty00_is_console = 1;
980 		cn_tab = &consdev_zs;
981 		(*cn_tab->cn_init)(cn_tab);
982 		break;
983 	}
984 #if NKSYMS || defined(DDB) || defined(MODULAR)
985 	ksyms_addsyms_elf((int)esym - (int)&end - sizeof(Elf32_Ehdr),
986 	    (void *)&end, esym);
987 #endif
988 #ifdef DDB
989 	if (boothowto & RB_KDB)
990 		Debugger();
991 #endif
992 }
993 
994 int
mm_md_physacc(paddr_t pa,vm_prot_t prot)995 mm_md_physacc(paddr_t pa, vm_prot_t prot)
996 {
997 	paddr_t memend;
998 
999 	/*
1000 	 * news68k has one contiguous memory segment.
1001 	 */
1002 	memend = lowram + ctob(physmem);
1003 
1004 	if (lowram <= pa && pa < memend)
1005 		return 0;
1006 
1007 	return EFAULT;
1008 }
1009 
1010 int
mm_md_kernacc(void * ptr,vm_prot_t prot,bool * handled)1011 mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled)
1012 {
1013 
1014 	*handled = false;
1015 	return ISIIOVA(ptr) ? EFAULT : 0;
1016 }
1017 
1018 #ifdef MODULAR
1019 /*
1020  * Push any modules loaded by the bootloader etc.
1021  */
1022 void
module_init_md(void)1023 module_init_md(void)
1024 {
1025 }
1026 #endif
1027