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