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