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