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