xref: /original-bsd/sys/pmax/pmax/machdep.c (revision e49f9654)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1992, 1993
4  *	The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Systems Programming Group of the University of Utah Computer
8  * Science Department, The Mach Operating System project at
9  * Carnegie-Mellon University and Ralph Campbell.
10  *
11  * %sccs.include.redist.c%
12  *
13  *	@(#)machdep.c	8.5 (Berkeley) 06/02/95
14  */
15 
16 /* from: Utah $Hdr: machdep.c 1.63 91/04/24$ */
17 
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/signalvar.h>
21 #include <sys/kernel.h>
22 #include <sys/map.h>
23 #include <sys/proc.h>
24 #include <sys/buf.h>
25 #include <sys/reboot.h>
26 #include <sys/conf.h>
27 #include <sys/file.h>
28 #include <sys/clist.h>
29 #include <sys/callout.h>
30 #include <sys/malloc.h>
31 #include <sys/mbuf.h>
32 #include <sys/msgbuf.h>
33 #include <sys/ioctl.h>
34 #include <sys/tty.h>
35 #include <sys/user.h>
36 #include <sys/exec.h>
37 #include <sys/sysctl.h>
38 #include <sys/mount.h>
39 #include <sys/syscallargs.h>
40 #ifdef SYSVSHM
41 #include <sys/shm.h>
42 #endif
43 
44 #include <vm/vm_kern.h>
45 
46 #include <machine/cpu.h>
47 #include <machine/reg.h>
48 #include <machine/psl.h>
49 #include <machine/pte.h>
50 #include <machine/dc7085cons.h>
51 
52 #include <pmax/stand/dec_prom.h>
53 
54 #include <pmax/dev/device.h>
55 #include <pmax/dev/sccreg.h>
56 #include <pmax/dev/ascreg.h>
57 
58 #include <pmax/pmax/clockreg.h>
59 #include <pmax/pmax/kn01.h>
60 #include <pmax/pmax/kn02.h>
61 #include <pmax/pmax/kmin.h>
62 #include <pmax/pmax/maxine.h>
63 #include <pmax/pmax/kn03.h>
64 #include <pmax/pmax/asic.h>
65 #include <pmax/pmax/turbochannel.h>
66 #include <pmax/pmax/pmaxtype.h>
67 #include <pmax/pmax/cons.h>
68 
69 #include <pm.h>
70 #include <cfb.h>
71 #include <mfb.h>
72 #include <xcfb.h>
73 #include <dc.h>
74 #include <dtop.h>
75 #include <scc.h>
76 #include <le.h>
77 #include <asc.h>
78 
79 #if NDC > 0
80 extern int dcGetc(), dcparam();
81 extern void dcPutc();
82 #endif
83 #if NDTOP > 0
84 extern int dtopKBDGetc();
85 #endif
86 #if NSCC > 0
87 extern int sccGetc(), sccparam();
88 extern void sccPutc();
89 #endif
90 extern int KBDGetc();
91 extern void fbPutc();
92 extern struct consdev cn_tab;
93 
94 /* Will scan from max to min, inclusive */
95 static int tc_max_slot = KN02_TC_MAX;
96 static int tc_min_slot = KN02_TC_MIN;
97 static u_int tc_slot_phys_base [TC_MAX_SLOTS] = {
98 	/* use 3max for default values */
99 	KN02_PHYS_TC_0_START, KN02_PHYS_TC_1_START,
100 	KN02_PHYS_TC_2_START, KN02_PHYS_TC_3_START,
101 	KN02_PHYS_TC_4_START, KN02_PHYS_TC_5_START,
102 	KN02_PHYS_TC_6_START, KN02_PHYS_TC_7_START
103 };
104 
105 /* the following is used externally (sysctl_hw) */
106 char	machine[] = "DEC";	/* cpu "architecture" */
107 char	cpu_model[30];
108 
109 vm_map_t buffer_map;
110 
111 /*
112  * Declare these as initialized data so we can patch them.
113  */
114 int	nswbuf = 0;
115 #ifdef	NBUF
116 int	nbuf = NBUF;
117 #else
118 int	nbuf = 0;
119 #endif
120 #ifdef	BUFPAGES
121 int	bufpages = BUFPAGES;
122 #else
123 int	bufpages = 0;
124 #endif
125 int	msgbufmapped = 0;	/* set when safe to use msgbuf */
126 int	maxmem;			/* max memory per process */
127 int	physmem;		/* max supported memory, changes to actual */
128 int	pmax_boardtype;		/* Mother board type */
129 u_long	le_iomem;		/* 128K for lance chip via. ASIC */
130 u_long	asc_iomem;		/* and 7 * 8K buffers for the scsi */
131 u_long	asic_base;		/* Base address of I/O asic */
132 const	struct callback *callv;	/* pointer to PROM entry points */
133 
134 void	(*tc_enable_interrupt)();
135 extern	int (*pmax_hardware_intr)();
136 void	pmax_slot_hand_fill();
137 int	kn02_intr(), kmin_intr(), xine_intr(), pmax_intr();
138 #ifdef DS5000_240
139 int	kn03_intr();
140 #endif
141 extern	int Mach_spl0(), Mach_spl1(), Mach_spl2(), Mach_spl3(), splhigh();
142 int	(*Mach_splnet)() = splhigh;
143 int	(*Mach_splbio)() = splhigh;
144 int	(*Mach_splimp)() = splhigh;
145 int	(*Mach_spltty)() = splhigh;
146 int	(*Mach_splclock)() = splhigh;
147 int	(*Mach_splstatclock)() = splhigh;
148 void	(*tc_slot_hand_fill)();
149 extern	volatile struct chiptime *Mach_clock_addr;
150 u_long	kmin_tc3_imask, xine_tc3_imask;
151 #ifdef DS5000_240
152 u_long	kn03_tc3_imask;
153 #endif
154 tc_option_t tc_slot_info[TC_MAX_LOGICAL_SLOTS];
155 static	void asic_init();
156 extern	void RemconsInit();
157 #ifdef DS5000
158 void	kn02_enable_intr(), kn02_slot_hand_fill(),
159 	kmin_enable_intr(), kmin_slot_hand_fill(),
160 	xine_enable_intr(), xine_slot_hand_fill(),
161 	tc_find_all_options();
162 #ifdef DS5000_240
163 void	kn03_enable_intr(), kn03_slot_hand_fill();
164 #endif
165 #endif /* DS5000 */
166 
167 /*
168  * safepri is a safe priority for sleep to set for a spin-wait
169  * during autoconfiguration or after a panic.
170  */
171 int	safepri = PSL_LOWIPL;
172 
173 struct	user *proc0paddr;
174 struct	proc nullproc;		/* for use by swtch_exit() */
175 
176 /*
177  * Do all the stuff that locore normally does before calling main().
178  * Process arguments passed to us by the prom monitor.
179  * Return the first page address following the system.
180  */
181 mach_init(argc, argv, code, cv)
182 	int argc;
183 	char *argv[];
184 	u_int code;
185 	const struct callback *cv;
186 {
187 	register char *cp;
188 	register int i;
189 	register unsigned firstaddr;
190 	register caddr_t v;
191 	caddr_t start;
192 	extern char edata[], end[];
193 	extern char MachUTLBMiss[], MachUTLBMissEnd[];
194 	extern char MachException[], MachExceptionEnd[];
195 
196 	/* clear the BSS segment */
197 	v = (caddr_t)pmax_round_page(end);
198 	bzero(edata, v - edata);
199 
200 	/* check for direct boot from DS5000 PROM */
201 	if (argc > 0 && strcmp(argv[0], "boot") == 0) {
202 		argc--;
203 		argv++;
204 	}
205 
206 	/* look at argv[0] and compute bootdev */
207 	makebootdev(argv[0]);
208 
209 	/*
210 	 * Look at arguments passed to us and compute boothowto.
211 	 */
212 #ifdef GENERIC
213 	boothowto = RB_SINGLE | RB_ASKNAME;
214 #else
215 	boothowto = RB_SINGLE;
216 #endif
217 #ifdef KADB
218 	boothowto |= RB_KDB;
219 #endif
220 	if (argc > 1) {
221 		for (i = 1; i < argc; i++) {
222 			for (cp = argv[i]; *cp; cp++) {
223 				switch (*cp) {
224 				case 'a': /* autoboot */
225 					boothowto &= ~RB_SINGLE;
226 					break;
227 
228 				case 'd': /* use compiled in default root */
229 					boothowto |= RB_DFLTROOT;
230 					break;
231 
232 				case 'm': /* mini root present in memory */
233 					boothowto |= RB_MINIROOT;
234 					break;
235 
236 				case 'n': /* ask for names */
237 					boothowto |= RB_ASKNAME;
238 					break;
239 
240 				case 'N': /* don't ask for names */
241 					boothowto &= ~RB_ASKNAME;
242 				}
243 			}
244 		}
245 	}
246 
247 #ifdef MFS
248 	/*
249 	 * Check to see if a mini-root was loaded into memory. It resides
250 	 * at the start of the next page just after the end of BSS.
251 	 */
252 	if (boothowto & RB_MINIROOT) {
253 		boothowto |= RB_DFLTROOT;
254 		v += mfs_initminiroot(v);
255 	}
256 #endif
257 
258 	/*
259 	 * Init mapping for u page(s) for proc[0], pm_tlbpid 1.
260 	 */
261 	start = v;
262 	curproc->p_addr = proc0paddr = (struct user *)v;
263 	curproc->p_md.md_regs = proc0paddr->u_pcb.pcb_regs;
264 	firstaddr = MACH_CACHED_TO_PHYS(v);
265 	for (i = 0; i < UPAGES; i++) {
266 		MachTLBWriteIndexed(i,
267 			(UADDR + (i << PGSHIFT)) | (1 << VMMACH_TLB_PID_SHIFT),
268 			curproc->p_md.md_upte[i] = firstaddr | PG_V | PG_M);
269 		firstaddr += NBPG;
270 	}
271 	v += UPAGES * NBPG;
272 	MachSetPID(1);
273 
274 	/*
275 	 * init nullproc for swtch_exit().
276 	 * init mapping for u page(s), pm_tlbpid 0
277 	 * This could be used for an idle process.
278 	 */
279 	nullproc.p_addr = (struct user *)v;
280 	nullproc.p_md.md_regs = nullproc.p_addr->u_pcb.pcb_regs;
281 	bcopy("nullproc", nullproc.p_comm, sizeof("nullproc"));
282 	for (i = 0; i < UPAGES; i++) {
283 		nullproc.p_md.md_upte[i] = firstaddr | PG_V | PG_M;
284 		firstaddr += NBPG;
285 	}
286 	v += UPAGES * NBPG;
287 
288 	/* clear pages for u areas */
289 	bzero(start, v - start);
290 
291 	/*
292 	 * Copy down exception vector code.
293 	 */
294 	if (MachUTLBMissEnd - MachUTLBMiss > 0x80)
295 		panic("startup: UTLB code too large");
296 	bcopy(MachUTLBMiss, (char *)MACH_UTLB_MISS_EXC_VEC,
297 		MachUTLBMissEnd - MachUTLBMiss);
298 	bcopy(MachException, (char *)MACH_GEN_EXC_VEC,
299 		MachExceptionEnd - MachException);
300 
301 	/*
302 	 * Clear out the I and D caches.
303 	 */
304 	MachConfigCache();
305 	MachFlushCache();
306 
307 	/*
308 	 * Determine what model of computer we are running on.
309 	 */
310 	if (code == DEC_PROM_MAGIC) {
311 		callv = cv;
312 		i = (*cv->getsysid)();
313 		cp = "";
314 	} else {
315 		callv = &callvec;
316 		if (cp = (*callv->getenv)("systype"))
317 			i = atoi(cp);
318 		else {
319 			cp = "";
320 			i = 0;
321 		}
322 	}
323 	/* check for MIPS based platform */
324 	if (((i >> 24) & 0xFF) != 0x82) {
325 		printf("Unknown System type '%s' 0x%x\n", cp, i);
326 		boot(RB_HALT | RB_NOSYNC);
327 	}
328 
329 	/* check what model platform we are running on */
330 	pmax_boardtype = ((i >> 16) & 0xff);
331 	switch (pmax_boardtype) {
332 	case DS_PMAX:	/* DS3100 Pmax */
333 		/*
334 		 * Set up interrupt handling and I/O addresses.
335 		 */
336 		pmax_hardware_intr = pmax_intr;
337 		Mach_splnet = Mach_spl1;
338 		Mach_splbio = Mach_spl0;
339 		Mach_splimp = Mach_spl1;
340 		Mach_spltty = Mach_spl2;
341 		Mach_splclock = Mach_spl3;
342 		Mach_splstatclock = Mach_spl3;
343 		Mach_clock_addr = (volatile struct chiptime *)
344 			MACH_PHYS_TO_UNCACHED(KN01_SYS_CLOCK);
345 		pmax_slot_hand_fill();
346 		strcpy(cpu_model, "3100");
347 		break;
348 
349 #ifdef DS5000
350 	case DS_3MAX:	/* DS5000/200 3max */
351 		{
352 		volatile int *csr_addr =
353 			(volatile int *)MACH_PHYS_TO_UNCACHED(KN02_SYS_CSR);
354 
355 		/*
356 		 * Enable ECC memory correction, turn off LEDs, and
357 		 * disable all TURBOchannel interrupts.
358 		 */
359 		i = *csr_addr;
360 		*csr_addr = (i & ~(KN02_CSR_WRESERVED | KN02_CSR_IOINTEN)) |
361 			KN02_CSR_CORRECT | 0xff;
362 
363 		tc_slot_hand_fill = kn02_slot_hand_fill;
364 		pmax_hardware_intr = kn02_intr;
365 		tc_enable_interrupt = kn02_enable_intr;
366 		Mach_splnet = Mach_spl0;
367 		Mach_splbio = Mach_spl0;
368 		Mach_splimp = Mach_spl0;
369 		Mach_spltty = Mach_spl0;
370 		Mach_splclock = Mach_spl1;
371 		Mach_splstatclock = Mach_spl1;
372 		Mach_clock_addr = (volatile struct chiptime *)
373 			MACH_PHYS_TO_UNCACHED(KN02_SYS_CLOCK);
374 
375 		/*
376 		 * Probe the TURBOchannel to see what controllers are present.
377 		 */
378 		tc_find_all_options();
379 
380 		/* clear any memory errors from probes */
381 		*(unsigned *)MACH_PHYS_TO_UNCACHED(KN02_SYS_ERRADR) = 0;
382 		}
383 		strcpy(cpu_model, "5000/200");
384 		break;
385 
386 	case DS_3MIN:	/* DS5000/1xx 3min */
387 		tc_max_slot = KMIN_TC_MAX;
388 		tc_min_slot = KMIN_TC_MIN;
389 		tc_slot_phys_base[0] = KMIN_PHYS_TC_0_START;
390 		tc_slot_phys_base[1] = KMIN_PHYS_TC_1_START;
391 		tc_slot_phys_base[2] = KMIN_PHYS_TC_2_START;
392 		asic_base = MACH_PHYS_TO_UNCACHED(KMIN_SYS_ASIC);
393 		tc_slot_hand_fill = kmin_slot_hand_fill;
394 		pmax_hardware_intr = kmin_intr;
395 		tc_enable_interrupt = kmin_enable_intr;
396 		kmin_tc3_imask = (KMIN_INTR_CLOCK | KMIN_INTR_PSWARN |
397 			KMIN_INTR_TIMEOUT);
398 
399 		/*
400 		 * Since all the motherboard interrupts come through the
401 		 * I/O ASIC, it has to be turned off for all the spls and
402 		 * since we don't know what kinds of devices are in the
403 		 * turbochannel option slots, just splhigh().
404 		 */
405 		Mach_splnet = splhigh;
406 		Mach_splbio = splhigh;
407 		Mach_splimp = splhigh;
408 		Mach_spltty = splhigh;
409 		Mach_splclock = splhigh;
410 		Mach_splstatclock = splhigh;
411 		Mach_clock_addr = (volatile struct chiptime *)
412 			MACH_PHYS_TO_UNCACHED(KMIN_SYS_CLOCK);
413 
414 		/*
415 		 * Probe the TURBOchannel to see what controllers are present.
416 		 */
417 		tc_find_all_options();
418 
419 		/*
420 		 * Initialize interrupts.
421 		 */
422 		*(u_int *)ASIC_REG_IMSK(asic_base) = KMIN_IM0;
423 		*(u_int *)ASIC_REG_INTR(asic_base) = 0;
424 		/* clear any memory errors from probes */
425 		*(unsigned *)MACH_PHYS_TO_UNCACHED(KMIN_REG_TIMEOUT) = 0;
426 		strcpy(cpu_model, "5000/1xx");
427 		break;
428 
429 	case DS_MAXINE:	/* DS5000/xx maxine */
430 		tc_max_slot = XINE_TC_MAX;
431 		tc_min_slot = XINE_TC_MIN;
432 		tc_slot_phys_base[0] = XINE_PHYS_TC_0_START;
433 		tc_slot_phys_base[1] = XINE_PHYS_TC_1_START;
434 		asic_base = MACH_PHYS_TO_UNCACHED(XINE_SYS_ASIC);
435 		tc_slot_hand_fill = xine_slot_hand_fill;
436 		pmax_hardware_intr = xine_intr;
437 		tc_enable_interrupt = xine_enable_intr;
438 		Mach_splnet = Mach_spl3;
439 		Mach_splbio = Mach_spl3;
440 		Mach_splimp = Mach_spl3;
441 		Mach_spltty = Mach_spl3;
442 		Mach_splclock = Mach_spl1;
443 		Mach_splstatclock = Mach_spl1;
444 		Mach_clock_addr = (volatile struct chiptime *)
445 			MACH_PHYS_TO_UNCACHED(XINE_SYS_CLOCK);
446 
447 		/*
448 		 * Probe the TURBOchannel to see what controllers are present.
449 		 */
450 		tc_find_all_options();
451 
452 		/*
453 		 * Initialize interrupts.
454 		 */
455 		*(u_int *)ASIC_REG_IMSK(asic_base) = XINE_IM0;
456 		*(u_int *)ASIC_REG_INTR(asic_base) = 0;
457 		/* clear any memory errors from probes */
458 		*(unsigned *)MACH_PHYS_TO_UNCACHED(XINE_REG_TIMEOUT) = 0;
459 		strcpy(cpu_model, "5000/25");
460 		break;
461 
462 #ifdef DS5000_240
463 	case DS_3MAXPLUS:	/* DS5000/240 3max+ UNTESTED!! */
464 		tc_max_slot = KN03_TC_MAX;
465 		tc_min_slot = KN03_TC_MIN;
466 		tc_slot_phys_base[0] = KN03_PHYS_TC_0_START;
467 		tc_slot_phys_base[1] = KN03_PHYS_TC_1_START;
468 		tc_slot_phys_base[2] = KN03_PHYS_TC_2_START;
469 		asic_base = MACH_PHYS_TO_UNCACHED(KN03_SYS_ASIC);
470 		tc_slot_hand_fill = kn03_slot_hand_fill;
471 		pmax_hardware_intr = kn03_intr;
472 		tc_enable_interrupt = kn03_enable_intr;
473 		kn03_tc3_imask = KN03_INTR_PSWARN;
474 
475 		Mach_splnet = Mach_spl0;
476 		Mach_splbio = Mach_spl0;
477 		Mach_splimp = Mach_spl0;
478 		Mach_spltty = Mach_spl0;
479 		Mach_splclock = Mach_spl1;
480 		Mach_splstatclock = Mach_spl1;
481 		Mach_clock_addr = (volatile struct chiptime *)
482 			MACH_PHYS_TO_UNCACHED(KN03_SYS_CLOCK);
483 
484 		/*
485 		 * Probe the TURBOchannel to see what controllers are present.
486 		 */
487 		tc_find_all_options();
488 
489 		/*
490 		 * Initialize interrupts.
491 		 */
492 		*(u_int *)ASIC_REG_IMSK(asic_base) = KN03_IM0;
493 		*(u_int *)ASIC_REG_INTR(asic_base) = 0;
494 		/* clear any memory errors from probes */
495 		*(unsigned *)MACH_PHYS_TO_UNCACHED(KN03_SYS_ERRADR) = 0;
496 		strcpy(cpu_model, "5000/240");
497 		break;
498 #endif /* DS5000_240 */
499 #endif /* DS5000 */
500 
501 	default:
502 		printf("kernel not configured for systype 0x%x\n", i);
503 		boot(RB_HALT | RB_NOSYNC);
504 	}
505 
506 	/*
507 	 * Find out how much memory is available.
508 	 * Be careful to save and restore the original contents for msgbuf.
509 	 */
510 	physmem = btoc(v - KERNBASE);
511 	cp = (char *)MACH_PHYS_TO_UNCACHED(physmem << PGSHIFT);
512 	while (cp < (char *)MACH_MAX_MEM_ADDR) {
513 		if (badaddr(cp, 4))
514 			break;
515 		i = *(int *)cp;
516 		*(int *)cp = 0xa5a5a5a5;
517 		/*
518 		 * Data will persist on the bus if we read it right away.
519 		 * Have to be tricky here.
520 		 */
521 		((int *)cp)[4] = 0x5a5a5a5a;
522 		MachEmptyWriteBuffer();
523 		if (*(int *)cp != 0xa5a5a5a5)
524 			break;
525 		*(int *)cp = i;
526 		cp += NBPG;
527 		physmem++;
528 	}
529 
530 	maxmem = physmem;
531 
532 #if NLE > 0
533 	/*
534 	 * Grab 128K at the top of physical memory for the lance chip
535 	 * on machines where it does dma through the I/O ASIC.
536 	 * It must be physically contiguous and aligned on a 128K boundary.
537 	 */
538 	if (pmax_boardtype == DS_3MIN || pmax_boardtype == DS_MAXINE ||
539 		pmax_boardtype == DS_3MAXPLUS) {
540 		maxmem -= btoc(128 * 1024);
541 		le_iomem = (maxmem << PGSHIFT);
542 	}
543 #endif /* NLE */
544 #if NASC > 0
545 	/*
546 	 * Ditto for the scsi chip. There is probably a way to make asc.c
547 	 * do dma without these buffers, but it would require major
548 	 * re-engineering of the asc driver.
549 	 * They must be 8K in size and page aligned.
550 	 */
551 	if (pmax_boardtype == DS_3MIN || pmax_boardtype == DS_MAXINE ||
552 		pmax_boardtype == DS_3MAXPLUS) {
553 		maxmem -= btoc(ASC_NCMD * 8192);
554 		asc_iomem = (maxmem << PGSHIFT);
555 	}
556 #endif /* NASC */
557 
558 	/*
559 	 * Initialize error message buffer (at end of core).
560 	 */
561 	maxmem -= btoc(sizeof (struct msgbuf));
562 	msgbufp = (struct msgbuf *)(MACH_PHYS_TO_CACHED(maxmem << PGSHIFT));
563 	msgbufmapped = 1;
564 
565 	/*
566 	 * Allocate space for system data structures.
567 	 * The first available kernel virtual address is in "v".
568 	 * As pages of kernel virtual memory are allocated, "v" is incremented.
569 	 *
570 	 * These data structures are allocated here instead of cpu_startup()
571 	 * because physical memory is directly addressable. We don't have
572 	 * to map these into virtual address space.
573 	 */
574 	start = v;
575 
576 #define	valloc(name, type, num) \
577 	    (name) = (type *)v; v = (caddr_t)((name)+(num))
578 #define	valloclim(name, type, num, lim) \
579 	    (name) = (type *)v; v = (caddr_t)((lim) = ((name)+(num)))
580 	valloc(cfree, struct cblock, nclist);
581 	valloc(callout, struct callout, ncallout);
582 	valloc(swapmap, struct map, nswapmap = maxproc * 2);
583 #ifdef SYSVSHM
584 	valloc(shmsegs, struct shmid_ds, shminfo.shmmni);
585 #endif
586 
587 	/*
588 	 * Determine how many buffers to allocate.
589 	 * We allocate more buffer space than the BSD standard of
590 	 * using 10% of memory for the first 2 Meg, 5% of remaining.
591 	 * We just allocate a flat 10%.  Ensure a minimum of 16 buffers.
592 	 * We allocate 1/2 as many swap buffer headers as file i/o buffers.
593 	 */
594 	if (bufpages == 0)
595 		bufpages = physmem / 10 / CLSIZE;
596 	if (nbuf == 0) {
597 		nbuf = bufpages;
598 		if (nbuf < 16)
599 			nbuf = 16;
600 	}
601 	if (nswbuf == 0) {
602 		nswbuf = (nbuf / 2) &~ 1;	/* force even */
603 		if (nswbuf > 256)
604 			nswbuf = 256;		/* sanity */
605 	}
606 	valloc(swbuf, struct buf, nswbuf);
607 	valloc(buf, struct buf, nbuf);
608 
609 	/*
610 	 * Clear allocated memory.
611 	 */
612 	bzero(start, v - start);
613 
614 	/*
615 	 * Initialize the virtual memory system.
616 	 */
617 	pmap_bootstrap((vm_offset_t)v);
618 }
619 
620 /*
621  * Console initialization: called early on from main,
622  * before vm init or startup.  Do enough configuration
623  * to choose and initialize a console.
624  */
625 consinit()
626 {
627 	register int kbd, crt;
628 	register char *oscon;
629 
630 	/*
631 	 * First get the "osconsole" environment variable.
632 	 */
633 	oscon = (*callv->getenv)("osconsole");
634 	crt = kbd = -1;
635 	if (oscon && *oscon >= '0' && *oscon <= '9') {
636 		kbd = *oscon - '0';
637 		cn_tab.cn_screen = 0;
638 		while (*++oscon) {
639 			if (*oscon == ',')
640 				cn_tab.cn_screen = 1;
641 			else if (cn_tab.cn_screen &&
642 			    *oscon >= '0' && *oscon <= '9') {
643 				crt = kbd;
644 				kbd = *oscon - '0';
645 				break;
646 			}
647 		}
648 	}
649 	if (pmax_boardtype == DS_PMAX && kbd == 1)
650 		cn_tab.cn_screen = 1;
651 	/*
652 	 * The boot program uses PMAX ROM entrypoints so the ROM sets
653 	 * osconsole to '1' like the PMAX.
654 	 */
655 	if (pmax_boardtype == DS_3MAX && crt == -1 && kbd == 1) {
656 		cn_tab.cn_screen = 1;
657 		crt = 0;
658 		kbd = 7;
659 	}
660 
661 	/*
662 	 * First try the keyboard/crt cases then fall through to the
663 	 * remote serial lines.
664 	 */
665 	if (cn_tab.cn_screen) {
666 	    switch (pmax_boardtype) {
667 	    case DS_PMAX:
668 #if NDC > 0 && NPM > 0
669 		if (pminit()) {
670 			cn_tab.cn_dev = makedev(DCDEV, DCKBD_PORT);
671 			cn_tab.cn_getc = KBDGetc;
672 			cn_tab.cn_kbdgetc = dcGetc;
673 			cn_tab.cn_putc = fbPutc;
674 			cn_tab.cn_disabled = 0;
675 			return;
676 		}
677 #endif /* NDC and NPM */
678 		goto remcons;
679 
680 	    case DS_MAXINE:
681 #if NDTOP > 0
682 		if (kbd == 3) {
683 			cn_tab.cn_dev = makedev(DTOPDEV, 0);
684 			cn_tab.cn_getc = dtopKBDGetc;
685 			cn_tab.cn_putc = fbPutc;
686 		} else
687 #endif /* NDTOP */
688 			goto remcons;
689 #if NXCFB > 0
690 		if (crt == 3 && xcfbinit()) {
691 			cn_tab.cn_disabled = 0;
692 			return;
693 		}
694 #endif /* XCFB */
695 		break;
696 
697 	    case DS_3MAX:
698 #if NDC > 0
699 		if (kbd == 7) {
700 			cn_tab.cn_dev = makedev(DCDEV, DCKBD_PORT);
701 			cn_tab.cn_getc = KBDGetc;
702 			cn_tab.cn_kbdgetc = dcGetc;
703 			cn_tab.cn_putc = fbPutc;
704 		} else
705 #endif /* NDC */
706 			goto remcons;
707 		break;
708 
709 	    case DS_3MIN:
710 	    case DS_3MAXPLUS:
711 #if NSCC > 0
712 		if (kbd == 3) {
713 			cn_tab.cn_dev = makedev(SCCDEV, SCCKBD_PORT);
714 			cn_tab.cn_getc = KBDGetc;
715 			cn_tab.cn_kbdgetc = sccGetc;
716 			cn_tab.cn_putc = fbPutc;
717 		} else
718 #endif /* NSCC */
719 			goto remcons;
720 		break;
721 
722 	    default:
723 		goto remcons;
724 	    };
725 
726 	    /*
727 	     * Check for a suitable turbochannel frame buffer.
728 	     */
729 	    if (tc_slot_info[crt].driver_name) {
730 #if NMFB > 0
731 		if (strcmp(tc_slot_info[crt].driver_name, "mfb") == 0 &&
732 		    mfbinit(tc_slot_info[crt].k1seg_address)) {
733 			cn_tab.cn_disabled = 0;
734 			return;
735 		}
736 #endif /* NMFB */
737 #if NCFB > 0
738 		if (strcmp(tc_slot_info[crt].driver_name, "cfb") == 0 &&
739 		    cfbinit(tc_slot_info[crt].k1seg_address)) {
740 			cn_tab.cn_disabled = 0;
741 			return;
742 		}
743 #endif /* NCFB */
744 		printf("crt: %s not supported as console device\n",
745 			tc_slot_info[crt].driver_name);
746 	    } else
747 		printf("No crt console device in slot %d\n", crt);
748 	}
749 remcons:
750 	/*
751 	 * Configure a serial port as a remote console.
752 	 */
753 	cn_tab.cn_screen = 0;
754 	switch (pmax_boardtype) {
755 	case DS_PMAX:
756 #if NDC > 0
757 		if (kbd == 4)
758 			cn_tab.cn_dev = makedev(DCDEV, DCCOMM_PORT);
759 		else
760 			cn_tab.cn_dev = makedev(DCDEV, DCPRINTER_PORT);
761 		cn_tab.cn_getc = dcGetc;
762 		cn_tab.cn_putc = dcPutc;
763 #endif /* NDC */
764 		break;
765 
766 	case DS_3MAX:
767 #if NDC > 0
768 		cn_tab.cn_dev = makedev(DCDEV, DCPRINTER_PORT);
769 		cn_tab.cn_getc = dcGetc;
770 		cn_tab.cn_putc = dcPutc;
771 #endif /* NDC */
772 		break;
773 
774 	case DS_3MIN:
775 	case DS_3MAXPLUS:
776 #if NSCC > 0
777 		cn_tab.cn_dev = makedev(SCCDEV, SCCCOMM3_PORT);
778 		cn_tab.cn_getc = sccGetc;
779 		cn_tab.cn_putc = sccPutc;
780 #endif /* NSCC */
781 		break;
782 
783 	case DS_MAXINE:
784 #if NSCC > 0
785 		cn_tab.cn_dev = makedev(SCCDEV, SCCCOMM2_PORT);
786 		cn_tab.cn_getc = sccGetc;
787 		cn_tab.cn_putc = sccPutc;
788 #endif /* NSCC */
789 		break;
790 	};
791 	if (cn_tab.cn_dev == NODEV)
792 		printf("Can't configure console!\n");
793 }
794 
795 /*
796  * cpu_startup: allocate memory for variable-sized tables,
797  * initialize cpu, and do autoconfiguration.
798  */
799 cpu_startup()
800 {
801 	register unsigned i;
802 	register caddr_t v;
803 	int base, residual;
804 	vm_offset_t minaddr, maxaddr;
805 	vm_size_t size;
806 #ifdef DEBUG
807 	extern int pmapdebug;
808 	int opmapdebug = pmapdebug;
809 
810 	pmapdebug = 0;
811 #endif
812 
813 	/*
814 	 * Good {morning,afternoon,evening,night}.
815 	 */
816 	printf(version);
817 	printf("real mem = %d\n", ctob(physmem));
818 
819 	/*
820 	 * Allocate virtual address space for file I/O buffers.
821 	 * Note they are different than the array of headers, 'buf',
822 	 * and usually occupy more virtual memory than physical.
823 	 */
824 	size = MAXBSIZE * nbuf;
825 	buffer_map = kmem_suballoc(kernel_map, (vm_offset_t *)&buffers,
826 				   &maxaddr, size, TRUE);
827 	minaddr = (vm_offset_t)buffers;
828 	if (vm_map_find(buffer_map, vm_object_allocate(size), (vm_offset_t)0,
829 			&minaddr, size, FALSE) != KERN_SUCCESS)
830 		panic("startup: cannot allocate buffers");
831 	base = bufpages / nbuf;
832 	residual = bufpages % nbuf;
833 	for (i = 0; i < nbuf; i++) {
834 		vm_size_t curbufsize;
835 		vm_offset_t curbuf;
836 
837 		/*
838 		 * First <residual> buffers get (base+1) physical pages
839 		 * allocated for them.  The rest get (base) physical pages.
840 		 *
841 		 * The rest of each buffer occupies virtual space,
842 		 * but has no physical memory allocated for it.
843 		 */
844 		curbuf = (vm_offset_t)buffers + i * MAXBSIZE;
845 		curbufsize = CLBYTES * (i < residual ? base+1 : base);
846 		vm_map_pageable(buffer_map, curbuf, curbuf+curbufsize, FALSE);
847 		vm_map_simplify(buffer_map, curbuf);
848 	}
849 	/*
850 	 * Allocate a submap for exec arguments.  This map effectively
851 	 * limits the number of processes exec'ing at any time.
852 	 */
853 	exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
854 				 16 * NCARGS, TRUE);
855 	/*
856 	 * Allocate a submap for physio
857 	 */
858 	phys_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr,
859 				 VM_PHYS_SIZE, TRUE);
860 
861 	/*
862 	 * Finally, allocate mbuf pool.  Since mclrefcnt is an off-size
863 	 * we use the more space efficient malloc in place of kmem_alloc.
864 	 */
865 	mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES,
866 				   M_MBUF, M_NOWAIT);
867 	bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES);
868 	mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr,
869 			       VM_MBUF_SIZE, FALSE);
870 	/*
871 	 * Initialize callouts
872 	 */
873 	callfree = callout;
874 	for (i = 1; i < ncallout; i++)
875 		callout[i-1].c_next = &callout[i];
876 	callout[i-1].c_next = NULL;
877 
878 #ifdef DEBUG
879 	pmapdebug = opmapdebug;
880 #endif
881 	printf("avail mem = %d\n", ptoa(cnt.v_free_count));
882 	printf("using %d buffers containing %d bytes of memory\n",
883 		nbuf, bufpages * CLBYTES);
884 	/*
885 	 * Set up CPU-specific registers, cache, etc.
886 	 */
887 	initcpu();
888 
889 	/*
890 	 * Set up buffers, so they can be used to read disk labels.
891 	 */
892 	bufinit();
893 
894 	/*
895 	 * Configure the system.
896 	 */
897 	configure();
898 }
899 
900 /*
901  * machine dependent system variables.
902  */
903 cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
904 	int *name;
905 	u_int namelen;
906 	void *oldp;
907 	size_t *oldlenp;
908 	void *newp;
909 	size_t newlen;
910 	struct proc *p;
911 {
912 
913 	/* all sysctl names at this level are terminal */
914 	if (namelen != 1)
915 		return (ENOTDIR);		/* overloaded */
916 
917 	switch (name[0]) {
918 	case CPU_CONSDEV:
919 		return (sysctl_rdstruct(oldp, oldlenp, newp, &cn_tab.cn_dev,
920 		    sizeof cn_tab.cn_dev));
921 	default:
922 		return (EOPNOTSUPP);
923 	}
924 	/* NOTREACHED */
925 }
926 
927 /*
928  * Set registers on exec.
929  * Clear all registers except sp, pc.
930  */
931 setregs(p, entry, retval)
932 	register struct proc *p;
933 	u_long entry;
934 	register_t retval[2];
935 {
936 	int sp = p->p_md.md_regs[SP];
937 	extern struct proc *machFPCurProcPtr;
938 
939 	bzero((caddr_t)p->p_md.md_regs, (FSR + 1) * sizeof(int));
940 	p->p_md.md_regs[SP] = sp;
941 	p->p_md.md_regs[PC] = entry & ~3;
942 	p->p_md.md_regs[PS] = PSL_USERSET;
943 	p->p_md.md_flags & ~MDP_FPUSED;
944 	if (machFPCurProcPtr == p)
945 		machFPCurProcPtr = (struct proc *)0;
946 }
947 
948 /*
949  * WARNING: code in locore.s assumes the layout shown for sf_signum
950  * thru sf_handler so... don't screw with them!
951  */
952 struct sigframe {
953 	int	sf_signum;		/* signo for handler */
954 	int	sf_code;		/* additional info for handler */
955 	struct	sigcontext *sf_scp;	/* context ptr for handler */
956 	sig_t	sf_handler;		/* handler addr for u_sigc */
957 	struct	sigcontext sf_sc;	/* actual context */
958 };
959 
960 #ifdef DEBUG
961 int sigdebug = 0;
962 int sigpid = 0;
963 #define SDB_FOLLOW	0x01
964 #define SDB_KSTACK	0x02
965 #define SDB_FPSTATE	0x04
966 #endif
967 
968 /*
969  * Send an interrupt to process.
970  */
971 void
972 sendsig(catcher, sig, mask, code)
973 	sig_t catcher;
974 	int sig, mask;
975 	u_long code;
976 {
977 	register struct proc *p = curproc;
978 	register struct sigframe *fp;
979 	register int *regs;
980 	register struct sigacts *psp = p->p_sigacts;
981 	int oonstack, fsize;
982 	struct sigcontext ksc;
983 	extern char sigcode[], esigcode[];
984 
985 	regs = p->p_md.md_regs;
986 	oonstack = psp->ps_sigstk.ss_flags & SA_ONSTACK;
987 	/*
988 	 * Allocate and validate space for the signal handler
989 	 * context. Note that if the stack is in data space, the
990 	 * call to grow() is a nop, and the copyout()
991 	 * will fail if the process has not already allocated
992 	 * the space with a `brk'.
993 	 */
994 	fsize = sizeof(struct sigframe);
995 	if ((psp->ps_flags & SAS_ALTSTACK) &&
996 	    (psp->ps_sigstk.ss_flags & SA_ONSTACK) == 0 &&
997 	    (psp->ps_sigonstack & sigmask(sig))) {
998 		fp = (struct sigframe *)(psp->ps_sigstk.ss_base +
999 					 psp->ps_sigstk.ss_size - fsize);
1000 		psp->ps_sigstk.ss_flags |= SA_ONSTACK;
1001 	} else
1002 		fp = (struct sigframe *)(regs[SP] - fsize);
1003 	if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize))
1004 		(void)grow(p, (unsigned)fp);
1005 #ifdef DEBUG
1006 	if ((sigdebug & SDB_FOLLOW) ||
1007 	    (sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
1008 		printf("sendsig(%d): sig %d ssp %x usp %x scp %x\n",
1009 		       p->p_pid, sig, &oonstack, fp, &fp->sf_sc);
1010 #endif
1011 	/*
1012 	 * Build the signal context to be used by sigreturn.
1013 	 */
1014 	ksc.sc_onstack = oonstack;
1015 	ksc.sc_mask = mask;
1016 	ksc.sc_pc = regs[PC];
1017 	ksc.sc_regs[ZERO] = 0xACEDBADE;		/* magic number */
1018 	bcopy((caddr_t)&regs[1], (caddr_t)&ksc.sc_regs[1],
1019 		sizeof(ksc.sc_regs) - sizeof(int));
1020 	ksc.sc_fpused = p->p_md.md_flags & MDP_FPUSED;
1021 	if (ksc.sc_fpused) {
1022 		extern struct proc *machFPCurProcPtr;
1023 
1024 		/* if FPU has current state, save it first */
1025 		if (p == machFPCurProcPtr)
1026 			MachSaveCurFPState(p);
1027 		bcopy((caddr_t)&p->p_md.md_regs[F0], (caddr_t)ksc.sc_fpregs,
1028 			sizeof(ksc.sc_fpregs));
1029 	}
1030 	if (copyout((caddr_t)&ksc, (caddr_t)&fp->sf_sc, sizeof(ksc))) {
1031 		/*
1032 		 * Process has trashed its stack; give it an illegal
1033 		 * instruction to halt it in its tracks.
1034 		 */
1035 		SIGACTION(p, SIGILL) = SIG_DFL;
1036 		sig = sigmask(SIGILL);
1037 		p->p_sigignore &= ~sig;
1038 		p->p_sigcatch &= ~sig;
1039 		p->p_sigmask &= ~sig;
1040 		psignal(p, SIGILL);
1041 		return;
1042 	}
1043 	/*
1044 	 * Build the argument list for the signal handler.
1045 	 */
1046 	regs[A0] = sig;
1047 	regs[A1] = code;
1048 	regs[A2] = (int)&fp->sf_sc;
1049 	regs[A3] = (int)catcher;
1050 
1051 	regs[PC] = (int)catcher;
1052 	regs[SP] = (int)fp;
1053 	/*
1054 	 * Signal trampoline code is at base of user stack.
1055 	 */
1056 	regs[RA] = (int)PS_STRINGS - (esigcode - sigcode);
1057 #ifdef DEBUG
1058 	if ((sigdebug & SDB_FOLLOW) ||
1059 	    (sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
1060 		printf("sendsig(%d): sig %d returns\n",
1061 		       p->p_pid, sig);
1062 #endif
1063 }
1064 
1065 /*
1066  * System call to cleanup state after a signal
1067  * has been taken.  Reset signal mask and
1068  * stack state from context left by sendsig (above).
1069  * Return to previous pc and psl as specified by
1070  * context left by sendsig. Check carefully to
1071  * make sure that the user has not modified the
1072  * psl to gain improper priviledges or to cause
1073  * a machine fault.
1074  */
1075 /* ARGSUSED */
1076 sigreturn(p, uap, retval)
1077 	struct proc *p;
1078 	struct sigreturn_args /* {
1079 		syscallarg(struct sigcontext *) sigcntxp;
1080 	} */ *uap;
1081 	register_t *retval;
1082 {
1083 	register struct sigcontext *scp;
1084 	register int *regs;
1085 	struct sigcontext ksc;
1086 	int error;
1087 
1088 	scp = SCARG(uap, sigcntxp);
1089 #ifdef DEBUG
1090 	if (sigdebug & SDB_FOLLOW)
1091 		printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
1092 #endif
1093 	regs = p->p_md.md_regs;
1094 	/*
1095 	 * Test and fetch the context structure.
1096 	 * We grab it all at once for speed.
1097 	 */
1098 	error = copyin((caddr_t)scp, (caddr_t)&ksc, sizeof(ksc));
1099 	if (error || ksc.sc_regs[ZERO] != 0xACEDBADE) {
1100 #ifdef DEBUG
1101 		if (!(sigdebug & SDB_FOLLOW))
1102 			printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
1103 		printf("  old sp %x ra %x pc %x\n",
1104 			regs[SP], regs[RA], regs[PC]);
1105 		printf("  new sp %x ra %x pc %x err %d z %x\n",
1106 			ksc.sc_regs[SP], ksc.sc_regs[RA], ksc.sc_regs[PC],
1107 			error, ksc.sc_regs[ZERO]);
1108 #endif
1109 		return (EINVAL);
1110 	}
1111 	scp = &ksc;
1112 	/*
1113 	 * Restore the user supplied information
1114 	 */
1115 	if (scp->sc_onstack & 01)
1116 		p->p_sigacts->ps_sigstk.ss_flags |= SA_ONSTACK;
1117 	else
1118 		p->p_sigacts->ps_sigstk.ss_flags &= ~SA_ONSTACK;
1119 	p->p_sigmask = scp->sc_mask &~ sigcantmask;
1120 	regs[PC] = scp->sc_pc;
1121 	bcopy((caddr_t)&scp->sc_regs[1], (caddr_t)&regs[1],
1122 		sizeof(scp->sc_regs) - sizeof(int));
1123 	if (scp->sc_fpused)
1124 		bcopy((caddr_t)scp->sc_fpregs, (caddr_t)&p->p_md.md_regs[F0],
1125 			sizeof(scp->sc_fpregs));
1126 	return (EJUSTRETURN);
1127 }
1128 
1129 int	waittime = -1;
1130 
1131 boot(howto)
1132 	register int howto;
1133 {
1134 	struct proc *p = curproc;	/* XXX */
1135 
1136 	/* take a snap shot before clobbering any registers */
1137 	if (curproc)
1138 		savectx(curproc->p_addr, 0);
1139 
1140 #ifdef DEBUG
1141 	if (panicstr)
1142 		stacktrace();
1143 #endif
1144 
1145 	boothowto = howto;
1146 	if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
1147 		register struct buf *bp;
1148 		int iter, nbusy;
1149 
1150 		waittime = 0;
1151 		(void) spl0();
1152 		printf("syncing disks... ");
1153 		/*
1154 		 * Release vnodes held by texts before sync.
1155 		 */
1156 		if (panicstr == 0)
1157 			vnode_pager_umount(NULL);
1158 #ifdef notdef
1159 #include "fd.h"
1160 #if NFD > 0
1161 		fdshutdown();
1162 #endif
1163 #endif
1164 		sync(p, (void *)NULL, (int *)NULL);
1165 		/*
1166 		 * Unmount filesystems
1167 		 */
1168 		if (panicstr == 0)
1169 			vfs_unmountall();
1170 
1171 		for (iter = 0; iter < 20; iter++) {
1172 			nbusy = 0;
1173 			for (bp = &buf[nbuf]; --bp >= buf; )
1174 				if ((bp->b_flags & (B_BUSY|B_INVAL)) == B_BUSY)
1175 					nbusy++;
1176 			if (nbusy == 0)
1177 				break;
1178 			printf("%d ", nbusy);
1179 			DELAY(40000 * iter);
1180 		}
1181 		if (nbusy)
1182 			printf("giving up\n");
1183 		else
1184 			printf("done\n");
1185 		/*
1186 		 * If we've been adjusting the clock, the todr
1187 		 * will be out of synch; adjust it now.
1188 		 */
1189 		resettodr();
1190 	}
1191 	(void) splhigh();		/* extreme priority */
1192 	if (callv != &callvec) {
1193 		if (howto & RB_HALT)
1194 			(*callv->rex)('h');
1195 		else {
1196 			if (howto & RB_DUMP)
1197 				dumpsys();
1198 			(*callv->rex)('b');
1199 		}
1200 	} else if (howto & RB_HALT) {
1201 		volatile void (*f)() = (volatile void (*)())DEC_PROM_REINIT;
1202 
1203 		(*f)();	/* jump back to prom monitor */
1204 	} else {
1205 		volatile void (*f)() = (volatile void (*)())DEC_PROM_AUTOBOOT;
1206 
1207 		if (howto & RB_DUMP)
1208 			dumpsys();
1209 		(*f)();	/* jump back to prom monitor and do 'auto' cmd */
1210 	}
1211 	/*NOTREACHED*/
1212 }
1213 
1214 int	dumpmag = (int)0x8fca0101;	/* magic number for savecore */
1215 int	dumpsize = 0;		/* also for savecore */
1216 long	dumplo = 0;
1217 
1218 dumpconf()
1219 {
1220 	int nblks;
1221 
1222 	dumpsize = physmem;
1223 	if (dumpdev != NODEV && bdevsw[major(dumpdev)].d_psize) {
1224 		nblks = (*bdevsw[major(dumpdev)].d_psize)(dumpdev);
1225 		if (dumpsize > btoc(dbtob(nblks - dumplo)))
1226 			dumpsize = btoc(dbtob(nblks - dumplo));
1227 		else if (dumplo == 0)
1228 			dumplo = nblks - btodb(ctob(physmem));
1229 	}
1230 	/*
1231 	 * Don't dump on the first CLBYTES (why CLBYTES?)
1232 	 * in case the dump device includes a disk label.
1233 	 */
1234 	if (dumplo < btodb(CLBYTES))
1235 		dumplo = btodb(CLBYTES);
1236 }
1237 
1238 /*
1239  * Doadump comes here after turning off memory management and
1240  * getting on the dump stack, either when called above, or by
1241  * the auto-restart code.
1242  */
1243 dumpsys()
1244 {
1245 	int error;
1246 
1247 	msgbufmapped = 0;
1248 	if (dumpdev == NODEV)
1249 		return;
1250 	/*
1251 	 * For dumps during autoconfiguration,
1252 	 * if dump device has already configured...
1253 	 */
1254 	if (dumpsize == 0)
1255 		dumpconf();
1256 	if (dumplo < 0)
1257 		return;
1258 	printf("\ndumping to dev %x, offset %d\n", dumpdev, dumplo);
1259 	printf("dump ");
1260 	switch (error = (*bdevsw[major(dumpdev)].d_dump)(dumpdev)) {
1261 
1262 	case ENXIO:
1263 		printf("device bad\n");
1264 		break;
1265 
1266 	case EFAULT:
1267 		printf("device not ready\n");
1268 		break;
1269 
1270 	case EINVAL:
1271 		printf("area improper\n");
1272 		break;
1273 
1274 	case EIO:
1275 		printf("i/o error\n");
1276 		break;
1277 
1278 	default:
1279 		printf("error %d\n", error);
1280 		break;
1281 
1282 	case 0:
1283 		printf("succeeded\n");
1284 	}
1285 }
1286 
1287 /*
1288  * Return the best possible estimate of the time in the timeval
1289  * to which tvp points.  Unfortunately, we can't read the hardware registers.
1290  * We guarantee that the time will be greater than the value obtained by a
1291  * previous call.
1292  */
1293 void
1294 microtime(tvp)
1295 	struct timeval *tvp;
1296 {
1297 	int s = splclock();
1298 	static struct timeval lasttime;
1299 
1300 	*tvp = time;
1301 #ifdef notdef
1302 	tvp->tv_usec += clkread();
1303 	while (tvp->tv_usec > 1000000) {
1304 		tvp->tv_sec++;
1305 		tvp->tv_usec -= 1000000;
1306 	}
1307 #endif
1308 	if (tvp->tv_sec == lasttime.tv_sec &&
1309 	    tvp->tv_usec <= lasttime.tv_usec &&
1310 	    (tvp->tv_usec = lasttime.tv_usec + 1) > 1000000) {
1311 		tvp->tv_sec++;
1312 		tvp->tv_usec -= 1000000;
1313 	}
1314 	lasttime = *tvp;
1315 	splx(s);
1316 }
1317 
1318 initcpu()
1319 {
1320 	register volatile struct chiptime *c;
1321 	int i;
1322 
1323 	/* disable clock interrupts (until startrtclock()) */
1324 	c = Mach_clock_addr;
1325 	c->regb = REGB_DATA_MODE | REGB_HOURS_FORMAT;
1326 	i = c->regc;
1327 	spl0();		/* safe to turn interrupts on now */
1328 	return (i);
1329 }
1330 
1331 /*
1332  * Convert an ASCII string into an integer.
1333  */
1334 int
1335 atoi(s)
1336 	char *s;
1337 {
1338 	int c;
1339 	unsigned base = 10, d;
1340 	int neg = 0, val = 0;
1341 
1342 	if (s == 0 || (c = *s++) == 0)
1343 		goto out;
1344 
1345 	/* skip spaces if any */
1346 	while (c == ' ' || c == '\t')
1347 		c = *s++;
1348 
1349 	/* parse sign, allow more than one (compat) */
1350 	while (c == '-') {
1351 		neg = !neg;
1352 		c = *s++;
1353 	}
1354 
1355 	/* parse base specification, if any */
1356 	if (c == '0') {
1357 		c = *s++;
1358 		switch (c) {
1359 		case 'X':
1360 		case 'x':
1361 			base = 16;
1362 			break;
1363 		case 'B':
1364 		case 'b':
1365 			base = 2;
1366 			break;
1367 		default:
1368 			base = 8;
1369 		}
1370 	}
1371 
1372 	/* parse number proper */
1373 	for (;;) {
1374 		if (c >= '0' && c <= '9')
1375 			d = c - '0';
1376 		else if (c >= 'a' && c <= 'z')
1377 			d = c - 'a' + 10;
1378 		else if (c >= 'A' && c <= 'Z')
1379 			d = c - 'A' + 10;
1380 		else
1381 			break;
1382 		val *= base;
1383 		val += d;
1384 		c = *s++;
1385 	}
1386 	if (neg)
1387 		val = -val;
1388 out:
1389 	return val;
1390 }
1391 
1392 /*
1393  * Fill in the pmax addresses by hand.
1394  */
1395 static struct pmax_address {
1396 	char	*pmax_name;
1397 	char	*pmax_addr;
1398 	int	pmax_pri;
1399 } pmax_addresses[] = {
1400 	{ "pm",	(char *)MACH_PHYS_TO_CACHED(KN01_PHYS_FBUF_START),	3 },
1401 	{ "dc",	(char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_DZ),		2 },
1402 	{ "le",	(char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_LANCE),		1 },
1403 	{ "sii",(char *)MACH_PHYS_TO_UNCACHED(KN01_SYS_SII),		0 },
1404 	{ (char *)0, },
1405 };
1406 
1407 void
1408 pmax_slot_hand_fill()
1409 {
1410 	register struct pmax_ctlr *cp;
1411 	register struct driver *drp;
1412 	register struct pmax_address *pmap;
1413 
1414 	/*
1415 	 * Find the device driver entry and fill in the address.
1416 	 */
1417 	for (cp = pmax_cinit; drp = cp->pmax_driver; cp++) {
1418 		for (pmap = pmax_addresses; pmap->pmax_name; pmap++) {
1419 			if (strcmp(drp->d_name, pmap->pmax_name))
1420 				continue;
1421 			if (cp->pmax_addr == (char *)QUES) {
1422 				cp->pmax_addr = pmap->pmax_addr;
1423 				cp->pmax_pri = pmap->pmax_pri;
1424 				continue;
1425 			}
1426 		}
1427 	}
1428 }
1429 
1430 #ifdef DS5000
1431 /*
1432  * Mach Operating System
1433  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
1434  * All Rights Reserved.
1435  *
1436  * Permission to use, copy, modify and distribute this software and its
1437  * documentation is hereby granted, provided that both the copyright
1438  * notice and this permission notice appear in all copies of the
1439  * software, derivative works or modified versions, and any portions
1440  * thereof, and that both notices appear in supporting documentation.
1441  *
1442  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
1443  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
1444  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1445  *
1446  * Carnegie Mellon requests users of this software to return to
1447  *
1448  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
1449  *  School of Computer Science
1450  *  Carnegie Mellon University
1451  *  Pittsburgh PA 15213-3890
1452  *
1453  * any improvements or extensions that they make and grant Carnegie the
1454  * rights to redistribute these changes.
1455  */
1456 
1457 
1458 /*
1459  * Driver map: associates a device driver to an option type.
1460  * Drivers name are (arbitrarily) defined in each driver and
1461  * used in the various config tables.
1462  */
1463 struct drivers_map {
1464 	char	module_name[TC_ROM_LLEN];	/* from ROM, literally! */
1465 	char	*driver_name;			/* in bus_??_init[] tables */
1466 } tc_drivers_map[] = {
1467 	{ "KN02    ",	"dc"},		/* (*) 3max system board (with DC) */
1468 	{ "PMAD-AA ",	"le"},		/* Ether */
1469 	{ "PMAZ-AA ",	"asc"},		/* SCSI */
1470 	{ "PMAG-AA ",	"mfb"},		/* Mono Frame Buffer */
1471 	{ "PMAG-BA ",	"cfb"},		/* Color Frame Buffer */
1472 	{ "PMAGB-BA",	"sfb"},		/* Smart Frame Buffer */
1473 	{ "PMAG-CA ",	"ga"},		/* 2D graphic board */
1474 	{ "PMAG-DA ",	"gq"},		/* 3D graphic board (LM) */
1475 	{ "PMAG-FA ",	"gq"},		/* 3D graphic board (HE) */
1476 	{ "PMAG-DV ",	"xcfb"},	/* (*) maxine Color Frame Buffer */
1477 	{ "Z8530   ",	"scc"},		/* (*) 3min/maxine serial lines */
1478 	{ "ASIC    ",	"asic"},	/* (*) 3min/maxine DMA controller */
1479 	{ "XINE-FDC",	"fdc"},		/* (*) maxine floppy controller */
1480 	{ "DTOP    ",	"dtop"},	/* (*) maxine desktop bus */
1481 	{ "AMD79c30",	"isdn"},	/* (*) maxine ISDN chip */
1482 	{ "XINE-FRC",	"frc"},		/* (*) maxine free-running counter */
1483 	{ "PMAF-AA ",   "fza"},		/* slow FDDI */
1484 	{ "T3PKT   ",   "tt"},		/* DECWRL turbochannel T3 */
1485 	{ "T1D4PKT ",   "ds"},		/* DECWRL turbochannel T1 */
1486 	{ "FORE_ATM",   "fa"},		/* Fore t??-100 ATM */
1487 	{ "LoFi    ",	"lofi"},	/* DEC audio board */
1488 	{ "AV01A-AA",	"lofi"},	/* DEC audio board */
1489 	{ "AV01B-AA",	"lofi"},	/* DEC audio board */
1490 	{ "", 0}			/* list end */
1491 };
1492 
1493 /*
1494  * Identify an option on the TC.  Looks at the mandatory
1495  * info in the option's ROM and checks it.
1496  */
1497 #ifdef DEBUG
1498 int tc_verbose = 0;
1499 #endif
1500 
1501 static int
1502 tc_identify_option(addr, slot, complain)
1503 	tc_rommap_t	*addr;
1504 	tc_option_t	*slot;
1505 	int		complain;
1506 {
1507 	register int	i;
1508 	unsigned char   width;
1509 	char            firmwr[TC_ROM_LLEN+1], vendor[TC_ROM_LLEN+1],
1510 			module[TC_ROM_LLEN+1], host_type[TC_ROM_SLEN+1];
1511 
1512 	/*
1513 	 * We do not really use the 'width' info, but take advantage
1514 	 * of the restriction that the spec impose on the portion
1515 	 * of the ROM that maps between +0x3e0 and +0x470, which
1516 	 * is the only piece we need to look at.
1517 	 */
1518 	width = addr->rom_width.value;
1519 	switch (width) {
1520 	case 1:
1521 	case 2:
1522 	case 4:
1523 		break;
1524 
1525 	default:
1526 #ifdef DEBUG
1527 		if (tc_verbose && complain)
1528 			printf("%s (x%x) at x%x\n", "Invalid ROM width",
1529 			       width, addr);
1530 #endif
1531 		return (0);
1532 	}
1533 
1534 	if (addr->rom_stride.value != 4) {
1535 #ifdef DEBUG
1536 		if (tc_verbose && complain)
1537 			printf("%s (x%x) at x%x\n", "Invalid ROM stride",
1538 			       addr->rom_stride.value, addr);
1539 #endif
1540 		return (0);
1541 	}
1542 
1543 	if ((addr->test_data[0] != 0x55) ||
1544 	    (addr->test_data[4] != 0x00) ||
1545 	    (addr->test_data[8] != 0xaa) ||
1546 	    (addr->test_data[12] != 0xff)) {
1547 #ifdef DEBUG
1548 		if (tc_verbose && complain)
1549 			printf("%s x%x\n", "Test pattern failed, option at",
1550 			       addr);
1551 #endif
1552 		return (0);
1553 	}
1554 
1555 	for (i = 0; i < TC_ROM_LLEN; i++) {
1556 		firmwr[i] = addr->firmware_rev[i].value;
1557 		vendor[i] = addr->vendor_name[i].value;
1558 		module[i] = addr->module_name[i].value;
1559 		if (i >= TC_ROM_SLEN)
1560 			continue;
1561 		host_type[i] = addr->host_firmware_type[i].value;
1562 	}
1563 	firmwr[TC_ROM_LLEN] = vendor[TC_ROM_LLEN] =
1564 	module[TC_ROM_LLEN] = host_type[TC_ROM_SLEN] = '\0';
1565 
1566 #ifdef DEBUG
1567 	if (tc_verbose)
1568 		printf("%s %s '%s' at 0x%x\n %s %s %s '%s'\n %s %d %s %d %s\n",
1569 		"Found a", vendor, module, addr,
1570 		"Firmware rev.", firmwr,
1571 		"diagnostics for a", host_type,
1572 		"ROM size is", addr->rom_size.value << 3,
1573 		"Kbytes, uses", addr->slot_size.value, "TC slot(s)");
1574 #endif
1575 
1576 	bcopy(module, slot->module_name, TC_ROM_LLEN);
1577 	bcopy(vendor, slot->module_id, TC_ROM_LLEN);
1578 	bcopy(firmwr, &slot->module_id[TC_ROM_LLEN], TC_ROM_LLEN);
1579 	slot->slot_size = addr->slot_size.value;
1580 	slot->rom_width = width;
1581 
1582 	return (1);
1583 }
1584 
1585 /*
1586  * TURBOchannel autoconf procedure.  Finds in one sweep what is
1587  * hanging on the bus and fills in the tc_slot_info array.
1588  * This is only the first part of the autoconf scheme, at this
1589  * time we are basically only looking for a graphics board to
1590  * use as system console (all workstations).
1591  */
1592 
1593 void
1594 tc_find_all_options()
1595 {
1596 	register int i;
1597 	u_long addr;
1598 	int found;
1599 	register tc_option_t *sl;
1600 	struct drivers_map *map;
1601 	register struct pmax_ctlr *cp;
1602 	register struct driver *drp;
1603 
1604 	/*
1605 	 * Take a look at the bus
1606 	 */
1607 	bzero(tc_slot_info, sizeof(tc_slot_info));
1608 	for (i = tc_max_slot; i >= tc_min_slot;) {
1609 		addr = MACH_PHYS_TO_UNCACHED(tc_slot_phys_base[i]);
1610 		found = tc_probe_slot(addr, &tc_slot_info[i]);
1611 
1612 		if (found) {
1613 			/*
1614 			 * Found a slot, make a note of it
1615 			 */
1616 			tc_slot_info[i].present = 1;
1617 			tc_slot_info[i].k1seg_address = addr;
1618 		}
1619 
1620 		i -= tc_slot_info[i].slot_size;
1621 	}
1622 
1623 	/*
1624 	 * Some slots (e.g. the system slot on 3max) might require
1625 	 * hand-filling.  If so, do it now.
1626 	 */
1627 	if (tc_slot_hand_fill)
1628 		(*tc_slot_hand_fill) (tc_slot_info);
1629 
1630 	/*
1631 	 * Now for each alive slot see if we have a device driver that
1632 	 * handles it.  This is done in "priority order", meaning that
1633 	 * always present devices are at higher slot numbers on all
1634 	 * current TC machines, and option slots are at lowest numbers.
1635 	 */
1636 	for (i = TC_MAX_LOGICAL_SLOTS - 1; i >= 0; i--) {
1637 		sl = &tc_slot_info[i];
1638 		if (!sl->present)
1639 			continue;
1640 		found = FALSE;
1641 		for (map = tc_drivers_map; map->driver_name; map++) {
1642 			if (bcmp(sl->module_name, map->module_name, TC_ROM_LLEN))
1643 				continue;
1644 			sl->driver_name = map->driver_name;
1645 			found = TRUE;
1646 			break;
1647 		}
1648 		if (!found) {
1649 			printf("%s %s %s\n",
1650 				"Cannot associate a device driver to",
1651 				sl->module_name, ". Will (try to) ignore it.");
1652 			sl->present = 0;
1653 			continue;
1654 		}
1655 
1656 		/*
1657 		 * Find the device driver entry and fill in the address.
1658 		 */
1659 		for (cp = pmax_cinit; drp = cp->pmax_driver; cp++) {
1660 			if (strcmp(drp->d_name, map->driver_name))
1661 				continue;
1662 			if (cp->pmax_alive)
1663 				continue;
1664 			if (cp->pmax_addr == (char *)QUES) {
1665 				cp->pmax_addr = (char *)sl->k1seg_address;
1666 				cp->pmax_pri = i;
1667 				/*
1668 				 * Only enable interrupts if there is an
1669 				 * interrupt handler for it. (e.g., PMAG-BA
1670 				 * can't disable the vertical retrace interrupt
1671 				 * and we might want to ignore it).
1672 				 */
1673 				if (drp->d_intr)
1674 					(*tc_enable_interrupt)(i, 1);
1675 				cp->pmax_alive = 1;
1676 				break;
1677 			}
1678 			if (cp->pmax_addr != (char *)sl->k1seg_address) {
1679 				cp->pmax_addr = (char *)QUES;
1680 				printf("%s: device not at configued address (expected at %x, found at %x)\n",
1681 					drp->d_name,
1682 					cp->pmax_addr, sl->k1seg_address);
1683 			}
1684 		}
1685 	}
1686 }
1687 
1688 /*
1689  * Probe a slot in the TURBOchannel. Return TRUE if a valid option
1690  * is present, FALSE otherwise. A side-effect is to fill the slot
1691  * descriptor with the size of the option, whether it is
1692  * recognized or not.
1693  */
1694 int
1695 tc_probe_slot(addr, slot)
1696 	caddr_t addr;
1697 	tc_option_t *slot;
1698 {
1699 	int i;
1700 	static unsigned tc_offset_rom[] = {
1701 		TC_OFF_PROTO_ROM, TC_OFF_ROM
1702 	};
1703 #define TC_N_OFFSETS	sizeof(tc_offset_rom)/sizeof(unsigned)
1704 
1705 	slot->slot_size = 1;
1706 
1707 	for (i = 0; i < TC_N_OFFSETS; i++) {
1708 		if (badaddr(addr + tc_offset_rom[i], 4))
1709 			continue;
1710 		/* complain only on last chance */
1711 		if (tc_identify_option((tc_rommap_t *)(addr + tc_offset_rom[i]),
1712 		    slot, i == (TC_N_OFFSETS-1)))
1713 			return (1);
1714 	}
1715 	return (0);
1716 #undef TC_N_OFFSETS
1717 }
1718 
1719 /*
1720  * Enable/Disable interrupts for a TURBOchannel slot.
1721  */
1722 void
1723 kn02_enable_intr(slotno, on)
1724 	register int slotno;
1725 	int on;
1726 {
1727 	register volatile int *p_csr =
1728 		(volatile int *)MACH_PHYS_TO_UNCACHED(KN02_SYS_CSR);
1729 	int csr;
1730 	int s;
1731 
1732 	slotno = 1 << (slotno + KN02_CSR_IOINTEN_SHIFT);
1733 	s = Mach_spl0();
1734 	csr = *p_csr & ~(KN02_CSR_WRESERVED | 0xFF);
1735 	if (on)
1736 		*p_csr = csr | slotno;
1737 	else
1738 		*p_csr = csr & ~slotno;
1739 	splx(s);
1740 }
1741 
1742 /*
1743  *	Object:
1744  *		kmin_enable_intr		EXPORTED function
1745  *
1746  *	Enable/Disable interrupts from a TURBOchannel slot.
1747  *
1748  *	We pretend we actually have 8 slots even if we really have
1749  *	only 4: TCslots 0-2 maps to slots 0-2, TCslot3 maps to
1750  *	slots 3-7 (see kmin_slot_hand_fill).
1751  */
1752 void
1753 kmin_enable_intr(slotno, on)
1754 	register unsigned int slotno;
1755 	int on;
1756 {
1757 	register unsigned mask;
1758 
1759 	switch (slotno) {
1760 	case 0:
1761 	case 1:
1762 	case 2:
1763 		return;
1764 	case KMIN_SCSI_SLOT:
1765 		mask = (KMIN_INTR_SCSI | KMIN_INTR_SCSI_PTR_LOAD |
1766 			KMIN_INTR_SCSI_OVRUN | KMIN_INTR_SCSI_READ_E);
1767 		break;
1768 	case KMIN_LANCE_SLOT:
1769 		mask = KMIN_INTR_LANCE;
1770 		break;
1771 	case KMIN_SCC0_SLOT:
1772 		mask = KMIN_INTR_SCC_0;
1773 		break;
1774 	case KMIN_SCC1_SLOT:
1775 		mask = KMIN_INTR_SCC_1;
1776 		break;
1777 	case KMIN_ASIC_SLOT:
1778 		mask = KMIN_INTR_ASIC;
1779 		break;
1780 	default:
1781 		return;
1782 	}
1783 	if (on)
1784 		kmin_tc3_imask |= mask;
1785 	else
1786 		kmin_tc3_imask &= ~mask;
1787 }
1788 
1789 /*
1790  *	Object:
1791  *		xine_enable_intr		EXPORTED function
1792  *
1793  *	Enable/Disable interrupts from a TURBOchannel slot.
1794  *
1795  *	We pretend we actually have 11 slots even if we really have
1796  *	only 3: TCslots 0-1 maps to slots 0-1, TCslot 2 is used for
1797  *	the system (TCslot3), TCslot3 maps to slots 3-10
1798  *	(see xine_slot_hand_fill).
1799  *	Note that all these interrupts come in via the IMR.
1800  */
1801 void
1802 xine_enable_intr(slotno, on)
1803 	register unsigned int slotno;
1804 	int on;
1805 {
1806 	register unsigned mask;
1807 
1808 	switch (slotno) {
1809 	case 0:			/* a real slot, but  */
1810 		mask = XINE_INTR_TC_0;
1811 		break;
1812 	case 1:			/* a real slot, but */
1813 		mask = XINE_INTR_TC_1;
1814 		break;
1815 	case XINE_FLOPPY_SLOT:
1816 		mask = XINE_INTR_FLOPPY;
1817 		break;
1818 	case XINE_SCSI_SLOT:
1819 		mask = (XINE_INTR_SCSI | XINE_INTR_SCSI_PTR_LOAD |
1820 			XINE_INTR_SCSI_OVRUN | XINE_INTR_SCSI_READ_E);
1821 		break;
1822 	case XINE_LANCE_SLOT:
1823 		mask = XINE_INTR_LANCE;
1824 		break;
1825 	case XINE_SCC0_SLOT:
1826 		mask = XINE_INTR_SCC_0;
1827 		break;
1828 	case XINE_DTOP_SLOT:
1829 		mask = XINE_INTR_DTOP_RX;
1830 		break;
1831 	case XINE_ISDN_SLOT:
1832 		mask = XINE_INTR_ISDN;
1833 		break;
1834 	case XINE_ASIC_SLOT:
1835 		mask = XINE_INTR_ASIC;
1836 		break;
1837 	default:
1838 		return;/* ignore */
1839 	}
1840 	if (on)
1841 		xine_tc3_imask |= mask;
1842 	else
1843 		xine_tc3_imask &= ~mask;
1844 }
1845 
1846 #ifdef DS5000_240
1847 /*
1848  * UNTESTED!!
1849  *	Object:
1850  *		kn03_enable_intr		EXPORTED function
1851  *
1852  *	Enable/Disable interrupts from a TURBOchannel slot.
1853  *
1854  *	We pretend we actually have 8 slots even if we really have
1855  *	only 4: TCslots 0-2 maps to slots 0-2, TCslot3 maps to
1856  *	slots 3-7 (see kn03_slot_hand_fill).
1857  */
1858 void
1859 kn03_enable_intr(slotno, on)
1860 	register unsigned int slotno;
1861 	int on;
1862 {
1863 	register unsigned mask;
1864 
1865 	switch (slotno) {
1866 	case 0:
1867 		mask = KN03_INTR_TC_0;
1868 		break;
1869 	case 1:
1870 		mask = KN03_INTR_TC_1;
1871 		break;
1872 	case 2:
1873 		mask = KN03_INTR_TC_2;
1874 		break;
1875 	case KN03_SCSI_SLOT:
1876 		mask = (KN03_INTR_SCSI | KN03_INTR_SCSI_PTR_LOAD |
1877 			KN03_INTR_SCSI_OVRUN | KN03_INTR_SCSI_READ_E);
1878 		break;
1879 	case KN03_LANCE_SLOT:
1880 		mask = KN03_INTR_LANCE;
1881 		break;
1882 	case KN03_SCC0_SLOT:
1883 		mask = KN03_INTR_SCC_0;
1884 		break;
1885 	case KN03_SCC1_SLOT:
1886 		mask = KN03_INTR_SCC_1;
1887 		break;
1888 	case KN03_ASIC_SLOT:
1889 		mask = KN03_INTR_ASIC;
1890 		break;
1891 	default:
1892 		return;
1893 	}
1894 	if (on)
1895 		kn03_tc3_imask |= mask;
1896 	else
1897 		kn03_tc3_imask &= ~mask;
1898 }
1899 #endif /* DS5000_240 */
1900 
1901 /*
1902  *	Object:
1903  *		kn02_slot_hand_fill		EXPORTED function
1904  *
1905  *	Fill in by hand the info for TC slots that are non-standard.
1906  *	This is basically just the system slot on a 3max, it does not
1907  *	look to me like it follows the TC rules although some of the
1908  *	required info is indeed there.
1909  *
1910  */
1911 void
1912 kn02_slot_hand_fill(slot)
1913 	tc_option_t *slot;
1914 {
1915 	slot[7].present = 1;
1916 	slot[7].slot_size = 1;
1917 	slot[7].rom_width = 1;
1918 #if unsafe
1919 	bcopy(0xbffc0410, slot[7].module_name, TC_ROM_LLEN+1);
1920 #endif
1921 	bcopy("KN02    ", slot[7].module_name, TC_ROM_LLEN+1);
1922 	bcopy("DEC xxxx", slot[7].module_id, TC_ROM_LLEN+1);
1923 	slot[7].k1seg_address = MACH_PHYS_TO_UNCACHED(KN02_SYS_DZ);
1924 }
1925 
1926 /*
1927  *	Object:
1928  *		kmin_slot_hand_fill		EXPORTED function
1929  *
1930  *	Fill in by hand the info for TC slots that are non-standard.
1931  *	This is the system slot on a 3min, which we think of as a
1932  *	set of non-regular size TC slots.
1933  *
1934  */
1935 void
1936 kmin_slot_hand_fill(slot)
1937 	tc_option_t *slot;
1938 {
1939 	register int i;
1940 
1941 	for (i = KMIN_SCSI_SLOT; i < KMIN_ASIC_SLOT+1; i++) {
1942 		slot[i].present = 1;
1943 		slot[i].slot_size = 1;
1944 		slot[i].rom_width = 1;
1945 		slot[i].unit = 0;
1946 		bcopy("DEC KMIN", slot[i].module_id, TC_ROM_LLEN+1);
1947 	}
1948 
1949 	/* scsi */
1950 	bcopy("PMAZ-AA ", slot[KMIN_SCSI_SLOT].module_name, TC_ROM_LLEN+1);
1951 	slot[KMIN_SCSI_SLOT].k1seg_address =
1952 		MACH_PHYS_TO_UNCACHED(KMIN_SYS_SCSI);
1953 
1954 	/* lance */
1955 	bcopy("PMAD-AA ", slot[KMIN_LANCE_SLOT].module_name, TC_ROM_LLEN+1);
1956 	slot[KMIN_LANCE_SLOT].k1seg_address = 0;
1957 
1958 	/* scc */
1959 	bcopy("Z8530   ", slot[KMIN_SCC0_SLOT].module_name, TC_ROM_LLEN+1);
1960 	slot[KMIN_SCC0_SLOT].k1seg_address =
1961 		MACH_PHYS_TO_UNCACHED(KMIN_SYS_SCC_0);
1962 
1963 	slot[KMIN_SCC1_SLOT].unit = 1;
1964 	bcopy("Z8530   ", slot[KMIN_SCC1_SLOT].module_name, TC_ROM_LLEN+1);
1965 	slot[KMIN_SCC1_SLOT].k1seg_address =
1966 		MACH_PHYS_TO_UNCACHED(KMIN_SYS_SCC_1);
1967 
1968 	/* asic */
1969 	bcopy("ASIC    ", slot[KMIN_ASIC_SLOT].module_name, TC_ROM_LLEN+1);
1970 	slot[KMIN_ASIC_SLOT].k1seg_address =
1971 		MACH_PHYS_TO_UNCACHED(KMIN_SYS_ASIC);
1972 	asic_init(0);
1973 }
1974 
1975 /*
1976  *	Object:
1977  *		xine_slot_hand_fill		EXPORTED function
1978  *
1979  *	Fill in by hand the info for TC slots that are non-standard.
1980  *	This is the system slot on a 3min, which we think of as a
1981  *	set of non-regular size TC slots.
1982  *
1983  */
1984 void
1985 xine_slot_hand_fill(slot)
1986 	tc_option_t *slot;
1987 {
1988 	register int i;
1989 
1990 	for (i = XINE_FLOPPY_SLOT; i < XINE_FRC_SLOT+1; i++) {
1991 		slot[i].present = 1;
1992 		slot[i].slot_size = 1;
1993 		slot[i].rom_width = 1;
1994 		slot[i].unit = 0;
1995 		bcopy("DEC XINE", slot[i].module_id, TC_ROM_LLEN+1);
1996 	}
1997 
1998 	/* floppy */
1999 	bcopy("XINE-FDC", slot[XINE_FLOPPY_SLOT].module_name, TC_ROM_LLEN+1);
2000 	slot[XINE_FLOPPY_SLOT].k1seg_address =
2001 		MACH_PHYS_TO_UNCACHED(XINE_SYS_FLOPPY);
2002 
2003 	/* scsi */
2004 	bcopy("PMAZ-AA ", slot[XINE_SCSI_SLOT].module_name, TC_ROM_LLEN+1);
2005 	slot[XINE_SCSI_SLOT].k1seg_address =
2006 		MACH_PHYS_TO_UNCACHED(XINE_SYS_SCSI);
2007 
2008 	/* lance */
2009 	bcopy("PMAD-AA ", slot[XINE_LANCE_SLOT].module_name, TC_ROM_LLEN+1);
2010 	slot[XINE_LANCE_SLOT].k1seg_address =
2011 		MACH_PHYS_TO_UNCACHED(XINE_SYS_LANCE);
2012 
2013 	/* scc */
2014 	bcopy("Z8530   ", slot[XINE_SCC0_SLOT].module_name, TC_ROM_LLEN+1);
2015 	slot[XINE_SCC0_SLOT].k1seg_address =
2016 		MACH_PHYS_TO_UNCACHED(XINE_SYS_SCC_0);
2017 
2018 	/* Desktop */
2019 	bcopy("DTOP    ", slot[XINE_DTOP_SLOT].module_name, TC_ROM_LLEN+1);
2020 	slot[XINE_DTOP_SLOT].k1seg_address =
2021 		MACH_PHYS_TO_UNCACHED(XINE_SYS_DTOP+0x20000); /* why? */
2022 
2023 	/* ISDN */
2024 	bcopy("AMD79c30", slot[XINE_ISDN_SLOT].module_name, TC_ROM_LLEN+1);
2025 	slot[XINE_ISDN_SLOT].k1seg_address =
2026 		MACH_PHYS_TO_UNCACHED(XINE_SYS_ISDN);
2027 
2028 	/* Video */
2029 	bcopy("PMAG-DV ", slot[XINE_CFB_SLOT].module_name, TC_ROM_LLEN+1);
2030 	slot[XINE_CFB_SLOT].k1seg_address =
2031 		MACH_PHYS_TO_CACHED(XINE_PHYS_CFB_START);
2032 
2033 	/* asic */
2034 	bcopy("ASIC    ", slot[XINE_ASIC_SLOT].module_name, TC_ROM_LLEN+1);
2035 	slot[XINE_ASIC_SLOT].k1seg_address =
2036 		MACH_PHYS_TO_UNCACHED(XINE_SYS_ASIC);
2037 
2038 	/* free-running counter (high resolution mapped time) */
2039 	bcopy("XINE-FRC", slot[XINE_FRC_SLOT].module_name, TC_ROM_LLEN+1);
2040 	slot[XINE_FRC_SLOT].k1seg_address =
2041 		MACH_PHYS_TO_UNCACHED(XINE_REG_FCTR);
2042 	asic_init(1);
2043 }
2044 
2045 #ifdef DS5000_240
2046 /*
2047  * UNTESTED!!
2048  *	Object:
2049  *		kn03_slot_hand_fill		EXPORTED function
2050  *
2051  *	Fill in by hand the info for TC slots that are non-standard.
2052  *	This is the system slot on a 3max+, which we think of as a
2053  *	set of non-regular size TC slots.
2054  *
2055  */
2056 void
2057 kn03_slot_hand_fill(slot)
2058 	tc_option_t *slot;
2059 {
2060 	register int i;
2061 
2062 	for (i = KN03_SCSI_SLOT; i < KN03_ASIC_SLOT+1; i++) {
2063 		slot[i].present = 1;
2064 		slot[i].slot_size = 1;
2065 		slot[i].rom_width = 1;
2066 		slot[i].unit = 0;
2067 		bcopy("DEC KN03", slot[i].module_id, TC_ROM_LLEN+1);
2068 	}
2069 
2070 	/* scsi */
2071 	bcopy("PMAZ-AA ", slot[KN03_SCSI_SLOT].module_name, TC_ROM_LLEN+1);
2072 	slot[KN03_SCSI_SLOT].k1seg_address =
2073 		MACH_PHYS_TO_UNCACHED(KN03_SYS_SCSI);
2074 
2075 	/* lance */
2076 	bcopy("PMAD-AA ", slot[KN03_LANCE_SLOT].module_name, TC_ROM_LLEN+1);
2077 	slot[KN03_LANCE_SLOT].k1seg_address = 0;
2078 
2079 	/* scc */
2080 	bcopy("Z8530   ", slot[KN03_SCC0_SLOT].module_name, TC_ROM_LLEN+1);
2081 	slot[KN03_SCC0_SLOT].k1seg_address =
2082 		MACH_PHYS_TO_UNCACHED(KN03_SYS_SCC_0);
2083 
2084 	slot[KN03_SCC1_SLOT].unit = 1;
2085 	bcopy("Z8530   ", slot[KN03_SCC1_SLOT].module_name, TC_ROM_LLEN+1);
2086 	slot[KN03_SCC1_SLOT].k1seg_address =
2087 		MACH_PHYS_TO_UNCACHED(KN03_SYS_SCC_1);
2088 
2089 	/* asic */
2090 	bcopy("ASIC    ", slot[KN03_ASIC_SLOT].module_name, TC_ROM_LLEN+1);
2091 	slot[KN03_ASIC_SLOT].k1seg_address =
2092 		MACH_PHYS_TO_UNCACHED(KN03_SYS_ASIC);
2093 	asic_init(0);
2094 }
2095 #endif /* DS5000_240 */
2096 
2097 /*
2098  * Initialize the I/O asic
2099  */
2100 static void
2101 asic_init(isa_maxine)
2102 	int isa_maxine;
2103 {
2104 	volatile u_int *decoder;
2105 
2106 	/* These are common between 3min and maxine */
2107 	decoder = (volatile u_int *)ASIC_REG_LANCE_DECODE(asic_base);
2108 	*decoder = KMIN_LANCE_CONFIG;
2109 }
2110 #endif /* DS5000 */
2111