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