autoconf.c revision 1.11
1/*
2 * Copyright (c) 1988 University of Utah.
3 * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * the Systems Programming Group of the University of Utah Computer
8 * Science Department.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *	This product includes software developed by the University of
21 *	California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * from: Utah $Hdr: autoconf.c 1.31 91/01/21$
39 *
40 *	@(#)autoconf.c	7.5 (Berkeley) 5/7/91
41 *	$Id: autoconf.c,v 1.11 1994/03/08 10:48:49 chopps Exp $
42 */
43
44/*
45 * Setup the system to run on the current machine.
46 *
47 * Configure() is called at boot time.  Available
48 * devices are determined (from possibilities mentioned in ioconf.c),
49 * and the drivers are initialized.
50 */
51
52#include <sys/param.h>
53#include <sys/systm.h>
54#include <sys/buf.h>
55#include <sys/dkstat.h>
56#include <sys/conf.h>
57#include <sys/dmap.h>
58#include <sys/reboot.h>
59
60#include <vm/vm.h>		/* XXXX Kludge for IVS Vector - mlh */
61
62#include <machine/vmparam.h>
63#include <machine/cpu.h>
64#include <machine/pte.h>
65#include <amiga/dev/device.h>
66
67#include <amiga/amiga/configdev.h>
68#include <amiga/amiga/custom.h>
69
70/*
71 * The following several variables are related to
72 * the configuration process, and are used in initializing
73 * the machine.
74 */
75int	cold;		    /* if 1, still working on cold-start */
76int	dkn;		    /* number of iostat dk numbers assigned so far */
77int	cpuspeed = MHZ_8;   /* relative cpu speed */
78struct	amiga_hw sc_table[MAXCTLRS];
79
80/* set up in amiga_init.c */
81extern caddr_t ZORRO2ADDR;
82
83/* maps a zorro2 and/or A3000 builtin address into the mapped kva address */
84#define zorro2map(pa) ((caddr_t) ((u_int)ZORRO2ADDR - ZORRO2BASE + (u_int)pa))
85
86/* tests whether the address lies in our zorro2 space */
87#define iszorro2kva(kva) \
88    ((u_int)kva >= (u_int)ZORRO2ADDR && \
89    (u_int)kva < ((u_int)ZORRO2ADDR + (u_int)ZORRO2TOP - (u_int)ZORRO2BASE))
90
91#define iszorro2pa(pa) ((u_int)pa >= ZORRO2BASE && (u_int)pa <= ZORRO2TOP)
92
93#ifdef DEBUG
94int	acdebug = 0;
95#endif
96
97void setroot __P((void));
98void swapconf __P((void));
99void configure __P((void));
100void find_devs __P((void));
101void find_slaves __P((struct amiga_ctlr *));
102void find_busslaves __P((struct amiga_ctlr *, int));
103
104/*
105 * Determine mass storage and memory configuration for a machine.
106 */
107void
108configure()
109{
110	register struct amiga_hw *hw;
111	int found;
112
113	/* XXXX I HATE IT XXXX */
114	custom.intena = INTF_INTEN;
115
116	/*
117	 * Look over each hardware device actually found and attempt
118	 * to match it with an ioconf.c table entry.
119	 */
120	for (hw = sc_table; hw->hw_type; hw++) {
121		if (HW_ISCTLR(hw))
122			found = find_controller(hw);
123		else
124			found = find_device(hw);
125#ifdef DEBUG
126		if (!found && acdebug)
127			printf("unconfigured device %d/%d\n",
128			    hw->hw_manufacturer, hw->hw_product);
129
130#endif
131	}
132
133#if GENERIC
134	if ((boothowto & RB_ASKNAME) == 0)
135		setroot();
136	setconf();
137#else
138	setroot();
139#endif
140	swapconf();
141	cold = 0;
142
143	custom.intena = INTF_SETCLR | INTF_INTEN;
144}
145
146#define dr_type(d, s) (strcmp((d)->d_name, (s)) == 0)
147
148#define same_hw_ctlr(hw, ac) \
149    (HW_ISFLOPPY(hw) && dr_type((ac)->amiga_driver, "floppy") || \
150    HW_ISSCSI(hw) && (dr_type((ac)->amiga_driver, "a3000scsi") \
151    || dr_type((ac)->amiga_driver, "a2091scsi") \
152    || dr_type((ac)->amiga_driver, "GVPIIscsi") \
153    || dr_type((ac)->amiga_driver, "Zeusscsi") \
154    || dr_type((ac)->amiga_driver, "Magnumscsi") \
155    || dr_type((ac)->amiga_driver, "Mlhscsi") \
156    || dr_type((ac)->amiga_driver, "Csa12gscsi") \
157    || dr_type((ac)->amiga_driver, "Suprascsi") \
158    || dr_type((ac)->amiga_driver, "IVSscsi")))
159
160int
161find_controller(hw)
162	register struct amiga_hw *hw;
163{
164	register struct amiga_ctlr *ac;
165	struct amiga_ctlr *match_c;
166	caddr_t oaddr;
167	int sc;
168
169#ifdef DEBUG
170	if (acdebug)
171		printf("find_controller: hw: [%d/%d] (%x), type %x...",
172		    hw->hw_manufacturer, hw->hw_product,
173		    hw->hw_kva, hw->hw_type);
174#endif
175	sc = (hw->hw_manufacturer << 16) | hw->hw_product;
176	match_c = NULL;
177
178	for (ac = amiga_cinit; ac->amiga_driver; ac++) {
179		if (ac->amiga_alive)
180			continue;
181		/*
182		 * Make sure we are looking at the right
183		 * controller type.
184		 */
185		if (!same_hw_ctlr(hw, ac))
186			continue;
187		/*
188		 * Exact match; all done
189		 */
190		if ((int)ac->amiga_addr == sc) {
191			match_c = ac;
192			break;
193		}
194		/*
195		 * Wildcard; possible match so remember first instance
196		 * but continue looking for exact match.
197		 */
198		if (ac->amiga_addr == NULL && match_c == NULL)
199			match_c = ac;
200	}
201#ifdef DEBUG
202	if (acdebug) {
203		if (match_c)
204			printf("found %s%d\n",
205			    match_c->amiga_driver->d_name,
206			    match_c->amiga_unit);
207		else
208			printf("not found\n");
209	}
210#endif
211	/*
212	 * Didn't find an ioconf entry for this piece of hardware,
213	 * just ignore it.
214	 */
215	if (match_c == NULL)
216		return(0);
217	/*
218	 * Found a match, attempt to initialize and configure all attached
219	 * slaves.  Note, we can still fail if HW won't initialize.
220	 */
221	ac = match_c;
222	oaddr = ac->amiga_addr;
223	ac->amiga_addr = hw->hw_kva;
224	if (0 == (*ac->amiga_driver->d_init)(ac))
225		ac->amiga_addr = oaddr;
226	else {
227		ac->amiga_alive = 1;
228		printf("%s%d", ac->amiga_driver->d_name, ac->amiga_unit);
229		printf(" [%d/%d]", hw->hw_manufacturer, hw->hw_product);
230		if (ac->amiga_flags)
231			printf(", flags 0x%x", ac->amiga_flags);
232		printf("\n");
233		find_slaves(ac);
234	}
235	return(1);
236}
237
238int
239find_device(hw)
240	register struct amiga_hw *hw;
241{
242	register struct amiga_device *ad;
243	struct amiga_device *match_d;
244	caddr_t oaddr;
245	int sc;
246
247#ifdef DEBUG
248	if (acdebug)
249		printf("find_device: hw: [%d/%d] (%x), type %x...",
250		    hw->hw_manufacturer, hw->hw_product,
251		    hw->hw_kva, hw->hw_type);
252#endif
253	match_d = NULL;
254
255	for (ad = amiga_dinit; ad->amiga_driver; ad++) {
256		if (ad->amiga_alive)
257			continue;
258		/* Must not be a slave */
259		if (ad->amiga_cdriver)
260			continue;
261
262		/*
263		 * XXX: A graphics device that was found as part of the
264		 * console init will have the amiga_addr field already set
265		 * (i.e. no longer the select code).  Gotta perform a
266		 * slightly different check for an exact match.
267		 */
268		if (HW_ISDEV(hw, D_BITMAP) && iszorro2kva(ad->amiga_addr)) {
269			if (ad->amiga_addr == hw->hw_kva) {
270				match_d = ad;
271				break;
272			}
273			continue;
274		}
275		sc = (int) ad->amiga_addr;
276		/*
277		 * Exact match; all done.
278		 */
279		if (sc > 0 &&
280		    sc == ((hw->hw_manufacturer << 16) | hw->hw_product)) {
281			match_d = ad;
282			break;
283		}
284		/*
285		 * Wildcard; possible match so remember first instance
286		 * but continue looking for exact match.
287		 */
288		if (sc == 0 && same_hw_device(hw, ad) && match_d == NULL)
289			match_d = ad;
290	}
291#ifdef DEBUG
292	if (acdebug) {
293		if (match_d)
294			printf("found %s%d\n",
295			       match_d->amiga_driver->d_name,
296			       match_d->amiga_unit);
297		else
298			printf("not found\n");
299	}
300#endif
301	/*
302	 * Didn't find an ioconf entry for this piece
303	 * of hardware, just ignore it.
304	 */
305	if (match_d == NULL)
306		return(0);
307	/*
308	 * Found a match, attempt to initialize.
309	 * Note, we can still fail if HW won't initialize.
310	 */
311	ad = match_d;
312	oaddr = ad->amiga_addr;
313	ad->amiga_addr = hw->hw_kva;
314	ad->amiga_serno = hw->hw_serno;
315	ad->amiga_size = hw->hw_size;
316
317	if (0 == (*ad->amiga_driver->d_init)(ad))
318		ad->amiga_addr = oaddr;
319	else {
320		ad->amiga_alive = 1;
321		printf("%s%d", ad->amiga_driver->d_name, ad->amiga_unit);
322		printf(" [%d/%d]", hw->hw_manufacturer, hw->hw_product);
323		if (ad->amiga_flags)
324			printf(", flags 0x%x", ad->amiga_flags);
325		printf("\n");
326	}
327	return(1);
328}
329
330void
331find_slaves(ac)
332	struct amiga_ctlr *ac;
333{
334	if (dr_type(ac->amiga_driver, "floppy"))
335		find_busslaves(ac, 4);
336	else if (dr_type(ac->amiga_driver, "a3000scsi")
337            || dr_type(ac->amiga_driver, "a2091scsi")
338	    || dr_type(ac->amiga_driver, "GVPIIscsi")
339	    || dr_type(ac->amiga_driver, "Zeusscsi")
340	    || dr_type(ac->amiga_driver, "Magnumscsi")
341	    || dr_type(ac->amiga_driver, "Mlhscsi")
342	    || dr_type(ac->amiga_driver, "Csa12gscsi")
343	    || dr_type(ac->amiga_driver, "Suprascsi")
344	    || dr_type(ac->amiga_driver, "IVSscsi"))
345		find_busslaves(ac, 7);
346}
347
348/*
349 */
350void
351find_busslaves(ac, maxslaves)
352	register struct amiga_ctlr *ac;
353	int maxslaves;
354{
355	register int s;
356	register struct amiga_device *ad;
357	struct amiga_device *match_s;
358	int new_s, new_c, old_s, old_c;
359	int rescan;
360
361#ifdef DEBUG
362	if (acdebug)
363		printf("find_busslaves: for %s%d\n",
364		       ac->amiga_driver->d_name, ac->amiga_unit);
365#endif
366	for (s = 0; s < maxslaves; s++) {
367		rescan = 1;
368		match_s = NULL;
369		for (ad = amiga_dinit; ad->amiga_driver; ad++) {
370			/*
371			 * Rule out the easy ones:
372			 * 1. slave already assigned or not a slave
373			 * 2. not of the proper type
374			 * 3. controller specified but not this one
375			 * 4. slave specified but not this one
376			 */
377			if (ad->amiga_alive || ad->amiga_cdriver == NULL)
378				continue;
379			else if (0 == dr_type(ac->amiga_driver,
380			    ad->amiga_cdriver->d_name))
381				continue;
382			else if (ad->amiga_ctlr >= 0 &&
383			    ad->amiga_ctlr != ac->amiga_unit)
384				continue;
385			else if (ad->amiga_slave >= 0 && ad->amiga_slave != s)
386				continue;
387			/*
388			 * Case 0: first possible match.
389			 * Remember it and keep looking for better.
390			 */
391			if (match_s == NULL) {
392				match_s = ad;
393				new_c = ac->amiga_unit;
394				new_s = s;
395				continue;
396			}
397			/*
398			 * Case 1: exact match.
399			 * All done.  Note that we do not attempt any other
400			 * matches if this one fails.  This allows us to
401			 * "reserve" locations for dynamic addition of
402			 * disk/tape drives by fully qualifing the location.
403			 */
404			if (ad->amiga_slave == s &&
405			    ad->amiga_ctlr == ac->amiga_unit) {
406				match_s = ad;
407				rescan = 0;
408				break;
409			}
410			/*
411			 * Case 2: right controller, wildcarded slave.
412			 * Remember first and keep looking for an exact match.
413			 */
414			if (ad->amiga_ctlr == ac->amiga_unit &&
415			    match_s->amiga_ctlr < 0) {
416				match_s = ad;
417				new_s = s;
418				continue;
419			}
420			/*
421			 * Case 3: right slave, wildcarded controller.
422			 * Remember and keep looking for a better match.
423			 */
424			if (ad->amiga_slave == s &&
425			    match_s->amiga_ctlr < 0 &&
426			    match_s->amiga_slave < 0) {
427				match_s = ad;
428				new_c = ac->amiga_unit;
429				continue;
430			}
431			/*
432			 * OW: we had a totally wildcarded spec.
433			 * If we got this far, we have found a possible
434			 * match already (match_s != NULL) so there is no
435			 * reason to remember this one.
436			 */
437			continue;
438		}
439		/*
440		 * Found a match.  We need to set
441		 * amiga_ctlr/amiga_slave properly for the init
442		 * routines but we also need to remember all the old
443		 * values in case this doesn't pan out.
444		 */
445		if (match_s) {
446			ad = match_s;
447			old_c = ad->amiga_ctlr;
448			old_s = ad->amiga_slave;
449			if (ad->amiga_ctlr < 0)
450				ad->amiga_ctlr = new_c;
451			if (ad->amiga_slave < 0)
452				ad->amiga_slave = new_s;
453#ifdef DEBUG
454			if (acdebug)
455				printf("looking for %s%d at slave %d...",
456				       ad->amiga_driver->d_name,
457				       ad->amiga_unit, ad->amiga_slave);
458#endif
459
460			if ((*ad->amiga_driver->d_init)(ad)) {
461#ifdef DEBUG
462				if (acdebug)
463					printf("found\n");
464#endif
465				printf("%s%d at %s%d, slave %d",
466				       ad->amiga_driver->d_name,
467				       ad->amiga_unit,
468				       ac->amiga_driver->d_name,
469				       ad->amiga_ctlr,ad->amiga_slave);
470				if (ad->amiga_flags)
471					printf(" flags 0x%x",ad->amiga_flags);
472				printf("\n");
473
474				ad->amiga_alive = 1;
475				if (ad->amiga_dk && dkn < DK_NDRIVE)
476					ad->amiga_dk = dkn++;
477				else
478					ad->amiga_dk = -1;
479				rescan = 1;
480				/*
481				 * The init on this unit suceeded, so
482				 * we need to mark the same
483				 * device/unit on other hardware
484				 * controllers as "alive" since we
485				 * can't reuse the same unit for that
486				 * device driver. mlh
487				 */
488				for (ad = amiga_dinit; ad->amiga_driver;
489				     ad++) {
490					if (ad->amiga_driver ==
491					    match_s->amiga_driver &&
492					    ad->amiga_unit ==
493					    match_s->amiga_unit)
494						ad->amiga_alive = 2;
495				}
496			} else {
497#ifdef DEBUG
498				if (acdebug)
499					printf("not found\n");
500#endif
501				ad->amiga_ctlr = old_c;
502				ad->amiga_slave = old_s;
503			}
504			/*
505			 * XXX: This should be handled better.
506			 * Re-scan a slave.  There are two reasons to do this.
507			 * 1. It is possible to have both a tape and disk
508			 *    (e.g. 7946) or two disks (e.g. 9122) at the
509			 *    same slave address.  Here we need to rescan
510			 *    looking only at entries with a different
511			 *    physical unit number (amiga_flags).
512			 * 2. It is possible that an init failed because the
513			 *    slave was there but of the wrong type.  In this
514			 *    case it may still be possible to match the slave
515			 *    to another ioconf entry of a different type.
516			 *    Here we need to rescan looking only at entries
517			 *    of different types.
518			 * In both cases we avoid looking at undesirable
519			 * ioconf entries of the same type by setting their
520			 * alive fields to -1.
521			 */
522			if (rescan) {
523				for (ad = amiga_dinit; ad->amiga_driver;
524				    ad++) {
525					if (ad->amiga_alive)
526						continue;
527					else if (match_s->amiga_alive == 1) {
528						if (ad->amiga_flags ==
529						    match_s->amiga_flags)
530							ad->amiga_alive = -1;
531					} else { /* 2 */
532						if (ad->amiga_driver ==
533						    match_s->amiga_driver)
534							ad->amiga_alive = -1;
535					}
536				}
537				s--;
538				continue;
539			}
540		}
541		/*
542		 * Reset bogon alive fields prior to attempting next slave
543		 */
544		for (ad = amiga_dinit; ad->amiga_driver; ad++)
545			if (ad->amiga_alive == -1)
546				ad->amiga_alive = 0;
547	}
548}
549
550int
551same_hw_device(hw, ad)
552	struct amiga_hw *hw;
553	struct amiga_device *ad;
554{
555	int found;
556
557	found = 0;
558
559	switch (hw->hw_type & ~B_MASK) {
560	case C_FLOPPY:
561		found = dr_type(ad->amiga_driver, "floppy");
562		break;
563	case C_SCSI:
564		found = (dr_type(ad->amiga_driver, "a3000scsi")
565			 || dr_type(ad->amiga_driver, "a2091scsi")
566			 || dr_type(ad->amiga_driver, "GVPIIscsi")
567			 || dr_type(ad->amiga_driver, "Zeusscsi")
568			 || dr_type(ad->amiga_driver, "Magnumscsi")
569			 || dr_type(ad->amiga_driver, "Mlhscsi")
570			 || dr_type(ad->amiga_driver, "Csa12gscsi")
571			 || dr_type(ad->amiga_driver, "Suprascsi")
572			 || dr_type(ad->amiga_driver, "IVSscsi"));
573		break;
574	case D_BITMAP:
575		found = dr_type(ad->amiga_driver, "grf");
576		break;
577	case D_LAN:
578		found = dr_type(ad->amiga_driver, "le");
579		break;
580	case D_COMMSER:
581		found = dr_type(ad->amiga_driver, "ser");
582		break;
583	case D_CLOCK:
584		found = dr_type(ad->amiga_driver, "rtclock");
585		break;
586	case D_PPORT:
587		found = dr_type(ad->amiga_driver, "par");
588		break;
589	default:
590		break;
591	}
592	return(found);
593}
594
595char notmappedmsg[] = "WARNING: no space to map IO card, ignored\n";
596
597/*
598 * Scan the IO space looking for devices.
599 */
600void
601find_devs()
602{
603  extern int num_ConfigDev;
604  extern struct ConfigDev *ConfigDev;
605  short sc;
606  u_char *id_reg;
607  register caddr_t addr;
608  register struct amiga_hw *hw;
609  int didmap, sctop;
610  struct ConfigDev *cd;
611
612#if 0
613  /*
614   * Initialize IO resource map for iomap().
615   */
616  rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16);
617#endif
618  hw = sc_table;
619
620  /* first enter builtin devices */
621
622  if (is_a4000 ())
623    {
624      /* The A4000 appears to use the same realtime clock as the A3000.
625         Add the IDE controller when that information becomes available.
626	 */
627
628      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
629      hw->hw_size	  = NBPG;
630      hw->hw_kva	  = zorro2map (0xdc0000);
631      hw->hw_manufacturer = MANUF_BUILTIN;
632      hw->hw_product      = PROD_BUILTIN_CLOCK;
633      hw->hw_type	  = B_BUILTIN | D_CLOCK;
634      hw->hw_serno	  = 0;
635      hw++;
636    }
637  else if (is_a3000 ())
638    {
639      /* hm, this doesn't belong here... */
640      volatile u_char *magic_reset_reg = zorro2map (0xde0002);
641      /* this bit makes the next reset look like a powerup reset, Amiga
642	 Unix sets this bit, and perhaps it will enable 16M machines to
643	 boot again... */
644      *magic_reset_reg   |= 0x80;
645
646      hw->hw_pa		  = (caddr_t) 0xdd0000;
647      hw->hw_size	  = NBPG;
648      hw->hw_kva	  = zorro2map (0xdd0000);
649      hw->hw_manufacturer = MANUF_BUILTIN;
650      hw->hw_product      = PROD_BUILTIN_SCSI;
651      hw->hw_type	  = B_BUILTIN | C_SCSI;
652      hw->hw_serno	  = 0;
653      hw++;
654
655      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
656      hw->hw_size	  = NBPG;
657      hw->hw_kva	  = zorro2map (0xdc0000);
658      hw->hw_manufacturer = MANUF_BUILTIN;
659      hw->hw_product      = PROD_BUILTIN_CLOCK;
660      hw->hw_type	  = B_BUILTIN | D_CLOCK;
661      hw->hw_serno	  = 0;
662      hw++;
663    }
664  else
665    {
666      /* what about other Amigas? Oh well.. */
667      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
668      hw->hw_size	  = NBPG;
669      hw->hw_kva	  = zorro2map (0xdc0000);
670      hw->hw_manufacturer = MANUF_BUILTIN;
671      hw->hw_product      = PROD_BUILTIN_CLOCK2;
672      hw->hw_type	  = B_BUILTIN | D_CLOCK;
673      hw->hw_serno	  = 0;
674      hw++;
675    }
676
677  hw->hw_pa	      = 0;
678  hw->hw_size	      = 0;
679  hw->hw_kva	      = (caddr_t) CUSTOMbase;
680  hw->hw_manufacturer = MANUF_BUILTIN;
681  hw->hw_product      = PROD_BUILTIN_FLOPPY;
682  hw->hw_type	      = B_BUILTIN | C_FLOPPY;
683  hw->hw_serno	      = 0;
684  hw++;
685
686  hw->hw_pa	      = 0;
687  hw->hw_size	      = 0;
688  hw->hw_kva	      = (caddr_t) CUSTOMbase;
689  hw->hw_manufacturer = MANUF_BUILTIN;
690  hw->hw_product      = PROD_BUILTIN_KEYBOARD;
691  hw->hw_type	      = B_BUILTIN | D_KEYBOARD;
692  hw->hw_serno	      = 0;
693  hw++;
694
695  hw->hw_pa	      = 0;
696  hw->hw_size	      = 0;
697  hw->hw_kva	      = (caddr_t) CUSTOMbase;
698  hw->hw_manufacturer = MANUF_BUILTIN;
699  hw->hw_product      = PROD_BUILTIN_PPORT;
700  hw->hw_type	      = B_BUILTIN | D_PPORT;
701  hw->hw_serno	      = 0;
702  hw++;
703
704  hw->hw_pa	      = 0;
705  hw->hw_size	      = 0;
706  hw->hw_kva	      = (caddr_t) CUSTOMbase;
707  hw->hw_manufacturer = MANUF_BUILTIN;
708  hw->hw_product      = PROD_BUILTIN_DISPLAY;
709  hw->hw_type	      = B_BUILTIN | D_BITMAP;
710  hw->hw_serno	      = 0;
711  hw++;
712
713  hw->hw_pa	      = 0;
714  hw->hw_size	      = 0;
715  hw->hw_kva	      = (caddr_t) CUSTOMbase;
716  hw->hw_manufacturer = MANUF_BUILTIN;
717  hw->hw_product      = PROD_BUILTIN_RS232;
718  hw->hw_type	      = B_BUILTIN | D_COMMSER;
719  hw->hw_serno	      = 0;
720  hw++;
721
722  /* and afterwards add Zorro II/III devices passed by the loader */
723
724  for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++)
725    {
726      hw->hw_pa		  = cd->cd_BoardAddr;
727      hw->hw_size	  = cd->cd_BoardSize;
728      /* ADD ZORRO3 SUPPORT HERE !! */
729      hw->hw_kva	  = iszorro2pa(cd->cd_BoardAddr) ? zorro2map (cd->cd_BoardAddr) : 0;
730      hw->hw_manufacturer = cd->cd_Rom.er_Manufacturer;
731      hw->hw_product	  = cd->cd_Rom.er_Product;
732      hw->hw_serno	  = cd->cd_Rom.er_SerialNumber;
733
734      switch (hw->hw_manufacturer)
735        {
736        case MANUF_CBM_1:
737          switch (hw->hw_product)
738            {
739            case PROD_CBM_1_A2088:
740              hw->hw_type = B_ZORROII | D_MISC;
741              break;
742
743            default:
744              continue;
745            }
746          break;
747
748	case MANUF_CBM_2:
749	  switch (hw->hw_product)
750	    {
751	    case PROD_CBM_2_A2091:
752	      hw->hw_type = B_ZORROII | C_SCSI;
753	      break;
754
755	    case PROD_CBM_2_A2065:
756	      hw->hw_type = B_ZORROII | D_LAN;
757              /* the ethernet board uses bytes 1 to 3 for ID, set byte 0 to indicate
758                 whether Commodore or Ameristar board. */
759              hw->hw_serno = (hw->hw_serno & 0x00ffffff) | 0x01000000;
760	      break;
761
762	    default:
763	      continue;
764	    }
765	  break;
766
767	case MANUF_AMERISTAR:
768	  switch (hw->hw_product)
769	    {
770	    case PROD_AMERISTAR_ETHER:
771	      hw->hw_type = B_ZORROII | D_LAN;
772              /* the ethernet board uses bytes 1 to 3 for ID, set byte 0 to indicate
773                 whether Commodore or Ameristar board. */
774              hw->hw_serno = (hw->hw_serno & 0x00ffffff) | 0x02000000;
775	      break;
776
777	    default:
778	      continue;
779	    }
780	  break;
781
782        case MANUF_UNILOWELL:
783          switch (hw->hw_product)
784            {
785            case PROD_UNILOWELL_A2410:
786              hw->hw_type = B_ZORROII | D_BITMAP;
787              break;
788
789            default:
790              continue;
791            }
792          break;
793
794	case MANUF_MACROSYSTEM:
795	  switch (hw->hw_product)
796	    {
797	    case PROD_MACROSYSTEM_RETINA:
798	      hw->hw_type = B_ZORROII | D_BITMAP;
799	      break;
800
801	    default:
802	      continue;
803	    }
804	  break;
805
806	case MANUF_GVP:
807	  switch (hw->hw_product)
808	    {
809	    case PROD_GVP_SERIES_I:
810	      /* XXX need to pass product code to driver */
811	      hw->hw_type = B_ZORROII | C_SCSI;
812	      break;
813
814	    case PROD_GVP_SERIES_II:
815	      /* Figure out what kind of board this is */
816	      id_reg = (u_char *)hw->hw_kva + 0x8001;
817	      switch (*id_reg & 0xf8)
818		{
819		case PROD_GVP_X_GF40_SCSI:
820		case PROD_GVP_X_COMBO4_SCSI:
821		case PROD_GVP_X_GF30_SCSI:
822		case PROD_GVP_X_COMBO3_SCSI:
823		case PROD_GVP_X_SCSI_II:
824		  hw->hw_type = B_ZORROII | C_SCSI;
825		  break;
826		case PROD_GVP_X_IOEXTEND:
827		  hw->hw_type = B_ZORROII | D_COMMSER;
828		  break;
829		}
830	      break;
831
832	    case PROD_GVP_IV24:
833	      hw->hw_type = B_ZORROII | D_BITMAP;
834	      break;
835
836	    default:
837	      continue;
838	    }
839	  break;
840
841	case MANUF_PPI:
842	  switch (hw->hw_product)
843	    {
844	    case PROD_PPI_ZEUS:
845	      hw->hw_type = B_ZORROII | C_SCSI;
846	      break;
847
848	    default:
849	      continue;
850	    }
851	  break;
852
853	case MANUF_CSA:
854	  switch (hw->hw_product)
855	    {
856	    case PROD_CSA_MAGNUM:
857	    case PROD_CSA_12G:
858	      hw->hw_type = B_ZORROII | C_SCSI;
859	      break;
860
861	    default:
862	      continue;
863	    }
864	  break;
865
866	case MANUF_SUPRA:
867	  switch (hw->hw_product)
868	    {
869	    /* XXXX need to distinguish different controllers with a single driver */
870	    case PROD_SUPRA_WORDSYNC_2:
871	      hw->hw_type = B_ZORROII | C_SCSI;
872	      break;
873
874	    default:
875	      continue;
876	    }
877	  break;
878
879	case MANUF_IVS:
880	  switch (hw->hw_product)
881	    {
882	    /* XXXX need to distinguish different controllers with a single driver */
883	    case PROD_IVS_VECTOR:
884	      /* XXXX Ouch! board addresss isn't Zorro II or Zorro III! */
885	      {
886		if (pmap_extract(zorro2map(0x00f00000)) == 0x00f00000) {
887		  /* remap to Vector pa */
888		}
889	      }
890	      hw->hw_type = B_ZORROII | C_SCSI;
891	      break;
892
893	    default:
894	      continue;
895	    }
896	  break;
897
898	case MANUF_HACKER:
899	  switch (hw->hw_product)
900	    {
901	    case PROD_HACKER_MLH:
902	      hw->hw_type = B_ZORROII | C_SCSI;
903	      break;
904
905	    default:
906	      continue;
907	    }
908	  break;
909
910        default:
911          continue;
912	}
913
914      hw++;
915    }
916}
917
918/*
919 * Configure swap space and related parameters.
920 */
921void
922swapconf()
923{
924	register struct swdevt *swp;
925	register int nblks;
926
927	for (swp = swdevt; swp->sw_dev; swp++) {
928		if (bdevsw[major(swp->sw_dev)].d_psize) {
929			nblks =
930			    bdevsw[major(swp->sw_dev)].d_psize(swp->sw_dev);
931			if (nblks != -1 &&
932			    (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) {
933				swp->sw_nblks = nblks;
934			}
935		}
936	}
937	dumpconf();
938	printf ("\n");
939}
940
941#define	DOSWAP			/* Change swdevt and dumpdev too */
942u_long	bootdev;		/* should be dev_t, but not until 32 bits */
943
944static	char devname[][2] = {
945	0,0,		/* 0 = ct */
946	0,0,		/* 1 = xx */
947	'r','d',	/* 2 = rd */
948	0,0,		/* 3 = sw */
949	's','d',	/* 4 = sd */
950};
951
952#define	PARTITIONMASK	0x7
953#define	PARTITIONSHIFT	3
954
955/*
956 * Attempt to find the device from which we were booted.
957 * If we can do so, and not instructed not to do so,
958 * change rootdev to correspond to the load device.
959 */
960void
961setroot()
962{
963	register struct amiga_ctlr *ac;
964	register struct amiga_device *ad;
965	int  majdev, mindev, unit, part, adaptor;
966	dev_t temp, orootdev;
967	struct swdevt *swp;
968
969#ifdef DEBUG
970	if (acdebug > 1)
971		printf("setroot: boothowto = 0x%x, bootdev = 0x%x\n",
972			boothowto, bootdev);
973#endif
974
975	if (boothowto & RB_DFLTROOT ||
976	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) {
977#ifdef DEBUG
978		if (acdebug > 1)
979			printf("returning due to: bad boothowto\n");
980#endif
981		return;
982	}
983	majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
984	if (majdev > sizeof(devname) / sizeof(devname[0])) {
985#ifdef DEBUG
986		if (acdebug > 1)
987			printf("returning due to: majdev(%d) > maxdevs(%d)\n",
988			    majdev, sizeof(devname) / sizeof(devname[0]));
989#endif
990		return;
991	}
992
993	adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
994	part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
995	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
996
997	/*
998	 * First, find the controller type which support this device.
999	 * Can have more than one controller for the same device, with
1000	 * just one of them configured, so test for
1001	 * ad->amiga_cdriver != 0 too.
1002	 */
1003	for (ad = amiga_dinit; ad->amiga_driver; ad++) {
1004		if (ad->amiga_driver->d_name[0] != devname[majdev][0]
1005		    || ad->amiga_driver->d_name[1] != devname[majdev][1])
1006			continue;
1007
1008		/*
1009		 * Next, find the controller of that type corresponding to
1010		 * the adaptor number.
1011		 */
1012		for (ac = amiga_cinit; ac->amiga_driver; ac++)
1013			if (ac->amiga_alive && ac->amiga_unit == adaptor &&
1014			    ac->amiga_driver == ad->amiga_cdriver)
1015				goto found_it;
1016	}
1017
1018	/* could also place after test, but I'd like to be on the safe side */
1019found_it:
1020	if (ad->amiga_driver == 0) {
1021#ifdef DEBUG
1022		if (acdebug > 1)
1023			printf("returning due to: amiga_driver == 0\n");
1024#endif
1025		return;
1026	}
1027
1028	/*
1029	 * Finally, find the device in question attached to that controller.
1030	 */
1031	for (ad = amiga_dinit; ad->amiga_driver; ad++)
1032		if (ad->amiga_alive && ad->amiga_slave == unit &&
1033		    ad->amiga_cdriver == ac->amiga_driver &&
1034		    ad->amiga_ctlr == ac->amiga_unit)
1035			break;
1036	if (ad->amiga_driver == 0) {
1037#ifdef DEBUG
1038		if (acdebug > 1)
1039			printf("returning due to: no device\n");
1040#endif
1041		return;
1042	}
1043	mindev = ad->amiga_unit;
1044
1045	/*
1046	 * Form a new rootdev
1047	 */
1048	mindev = (mindev << PARTITIONSHIFT) + part;
1049	orootdev = rootdev;
1050	rootdev = makedev(majdev, mindev);
1051
1052	/*
1053	 * If the original rootdev is the same as the one
1054	 * just calculated, don't need to adjust the swap configuration.
1055	 */
1056	if (rootdev == orootdev) {
1057#ifdef DEBUG
1058		if (acdebug > 1)
1059			printf("returning due to: new root == old root\n");
1060#endif
1061		return;
1062	}
1063
1064	printf("Changing root device to %c%c%d%c\n",
1065		devname[majdev][0], devname[majdev][1],
1066		mindev >> PARTITIONSHIFT, part + 'a');
1067
1068#ifdef DOSWAP
1069	mindev &= ~PARTITIONMASK;
1070	for (swp = swdevt; swp->sw_dev; swp++) {
1071		if (majdev == major(swp->sw_dev) &&
1072		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
1073			temp = swdevt[0].sw_dev;
1074			swdevt[0].sw_dev = swp->sw_dev;
1075			swp->sw_dev = temp;
1076			break;
1077		}
1078	}
1079	if (swp->sw_dev == 0)
1080		return;
1081
1082	/*
1083	 * If dumpdev was the same as the old primary swap
1084	 * device, move it to the new primary swap device.
1085	 */
1086	if (temp == dumpdev)
1087		dumpdev = swdevt[0].sw_dev;
1088#endif
1089}
1090
1091/*
1092 * Try to determine, of this machine is an A3000, which has a builtin
1093 * realtime clock and scsi controller, so that this hardware is only
1094 * included as "configured" if this IS an A3000
1095 */
1096
1097int a3000_flag = 1;		/* patchable */
1098#ifdef A4000
1099int a4000_flag = 1;		/* patchable - default to A4000 */
1100#else
1101int a4000_flag = 0;		/* patchable */
1102#endif
1103
1104int
1105is_a3000()
1106{
1107	/* this is a dirty kludge.. but how do you do this RIGHT ? :-) */
1108	extern long orig_fastram_start;
1109	extern int num_ConfigDev;
1110	extern struct ConfigDev *ConfigDev;
1111	short sc;
1112	struct ConfigDev *cd;
1113
1114	/* where is fastram on the A4000 ?? */
1115	/* if fastram is below 0x07000000, assume it's not an A3000 */
1116	if (orig_fastram_start < 0x07000000)
1117		return (0);
1118
1119	/*
1120	 * OK, fastram starts at or above 0x07000000, check specific
1121	 * machines
1122	 */
1123	for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++) {
1124		switch (cd->cd_Rom.er_Manufacturer) {
1125		case MANUF_PPI:		/* Progressive Peripherals, Inc */
1126			switch (cd->cd_Rom.er_Product) {
1127			case PROD_PPI_MERCURY:	/* PPI Mercury - A3000 */
1128			case PROD_PPI_A3000_040:/* PP&S A3000 '040 */
1129				return (1);
1130			case PROD_PPI_ZEUS:	/* PPI Zeus - it's an A2000 */
1131			case PROD_PPI_A2000_040:/* PP&S A2000 '040 */
1132			case PROD_PPI_A500_040:	/* PP&S A500 '040 */
1133				return (0);
1134			}
1135			break;
1136
1137		case MANUF_IVS:			/* IVS */
1138			switch (cd->cd_Rom.er_Product) {
1139			case PROD_IVS_VECTOR_ACC:
1140				return (0); /* A2000 accelerator? */
1141			}
1142			break;
1143		}
1144	}
1145	/* XXX assume it's an A3000 */
1146	return (a3000_flag);
1147}
1148
1149int
1150is_a4000()
1151{
1152	return (a4000_flag);		/* XXX */
1153}
1154