autoconf.c revision 1.7
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				/*
454				 * The init on this unit suceeded, so we need to
455				 * mark the same device/unit on other hardware
456				 * controllers as "alive" since we can't reuse
457				 * the same unit for that device driver. mlh
458				 */
459				for (ad = amiga_dinit; ad->amiga_driver; ad++) {
460					if (ad->amiga_driver == match_s->amiga_driver &&
461					    ad->amiga_unit == match_s->amiga_unit)
462						ad->amiga_alive = 2;
463				}
464			} else {
465#ifdef DEBUG
466				if (acdebug)
467					printf("not found\n");
468#endif
469				ad->amiga_ctlr = old_c;
470				ad->amiga_slave = old_s;
471			}
472			/*
473			 * XXX: This should be handled better.
474			 * Re-scan a slave.  There are two reasons to do this.
475			 * 1. It is possible to have both a tape and disk
476			 *    (e.g. 7946) or two disks (e.g. 9122) at the
477			 *    same slave address.  Here we need to rescan
478			 *    looking only at entries with a different
479			 *    physical unit number (amiga_flags).
480			 * 2. It is possible that an init failed because the
481			 *    slave was there but of the wrong type.  In this
482			 *    case it may still be possible to match the slave
483			 *    to another ioconf entry of a different type.
484			 *    Here we need to rescan looking only at entries
485			 *    of different types.
486			 * In both cases we avoid looking at undesirable
487			 * ioconf entries of the same type by setting their
488			 * alive fields to -1.
489			 */
490			if (rescan) {
491				for (ad = amiga_dinit; ad->amiga_driver; ad++) {
492					if (ad->amiga_alive)
493						continue;
494					if (match_s->amiga_alive == 1) {	/* 1 */
495						if (ad->amiga_flags == match_s->amiga_flags)
496							ad->amiga_alive = -1;
497					} else {			/* 2 */
498						if (ad->amiga_driver == match_s->amiga_driver)
499							ad->amiga_alive = -1;
500					}
501				}
502				s--;
503				continue;
504			}
505		}
506		/*
507		 * Reset bogon alive fields prior to attempting next slave
508		 */
509		for (ad = amiga_dinit; ad->amiga_driver; ad++)
510			if (ad->amiga_alive == -1)
511				ad->amiga_alive = 0;
512	}
513}
514
515same_hw_device(hw, ad)
516	struct amiga_hw *hw;
517	struct amiga_device *ad;
518{
519	int found = 0;
520
521	switch (hw->hw_type & ~B_MASK) {
522	case C_FLOPPY:
523		found = dr_type(ad->amiga_driver, "floppy");
524		break;
525	case C_SCSI:
526		found = (dr_type(ad->amiga_driver, "a3000scsi")
527			 || dr_type(ad->amiga_driver, "a2091scsi")
528			 || dr_type(ad->amiga_driver, "GVPIIscsi")
529			 || dr_type(ad->amiga_driver, "Zeusscsi")
530			 || dr_type(ad->amiga_driver, "Magnumscsi"));
531		break;
532	case D_BITMAP:
533		found = dr_type(ad->amiga_driver, "grf");
534		break;
535	case D_LAN:
536		found = dr_type(ad->amiga_driver, "le");
537		break;
538	case D_COMMSER:
539		found = dr_type(ad->amiga_driver, "ser");
540		break;
541	case D_CLOCK:
542		found = dr_type(ad->amiga_driver, "rtclock");
543		break;
544	case D_PPORT:
545		found = dr_type(ad->amiga_driver, "par");
546		break;
547	default:
548		break;
549	}
550	return(found);
551}
552
553char notmappedmsg[] = "WARNING: no space to map IO card, ignored\n";
554
555/*
556 * Scan the IO space looking for devices.
557 */
558find_devs()
559{
560  short sc;
561  u_char *id_reg;
562  register caddr_t addr;
563  register struct amiga_hw *hw;
564  int didmap, sctop;
565  extern int num_ConfigDev;
566  extern struct ConfigDev *ConfigDev;
567  struct ConfigDev *cd;
568
569#if 0
570  /*
571   * Initialize IO resource map for iomap().
572   */
573  rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16);
574#endif
575  hw = sc_table;
576
577  /* first enter builtin devices */
578
579  if (is_a4000 ())
580    {
581      /* The A4000 appears to use the same realtime clock as the A3000.
582         Add the IDE controller when that information becomes available.
583	 */
584
585      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
586      hw->hw_size	  = NBPG;
587      hw->hw_kva	  = zorro2map (0xdc0000);
588      hw->hw_manufacturer = MANUF_BUILTIN;
589      hw->hw_product      = PROD_BUILTIN_CLOCK;
590      hw->hw_type	  = B_BUILTIN | D_CLOCK;
591      hw->hw_serno	  = 0;
592      hw++;
593    }
594  else if (is_a3000 ())
595    {
596      /* hm, this doesn't belong here... */
597      volatile u_char *magic_reset_reg = zorro2map (0xde0002);
598      /* this bit makes the next reset look like a powerup reset, Amiga
599	 Unix sets this bit, and perhaps it will enable 16M machines to
600	 boot again... */
601      *magic_reset_reg   |= 0x80;
602
603      hw->hw_pa		  = (caddr_t) 0xdd0000;
604      hw->hw_size	  = NBPG;
605      hw->hw_kva	  = zorro2map (0xdd0000);
606      hw->hw_manufacturer = MANUF_BUILTIN;
607      hw->hw_product      = PROD_BUILTIN_SCSI;
608      hw->hw_type	  = B_BUILTIN | C_SCSI;
609      hw->hw_serno	  = 0;
610      hw++;
611
612      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
613      hw->hw_size	  = NBPG;
614      hw->hw_kva	  = zorro2map (0xdc0000);
615      hw->hw_manufacturer = MANUF_BUILTIN;
616      hw->hw_product      = PROD_BUILTIN_CLOCK;
617      hw->hw_type	  = B_BUILTIN | D_CLOCK;
618      hw->hw_serno	  = 0;
619      hw++;
620    }
621  else
622    {
623      /* what about other Amigas? Oh well.. */
624      hw->hw_pa	      	  = (caddr_t) 0xdc0000;
625      hw->hw_size	  = NBPG;
626      hw->hw_kva	  = zorro2map (0xdc0000);
627      hw->hw_manufacturer = MANUF_BUILTIN;
628      hw->hw_product      = PROD_BUILTIN_CLOCK2;
629      hw->hw_type	  = B_BUILTIN | D_CLOCK;
630      hw->hw_serno	  = 0;
631      hw++;
632    }
633
634  hw->hw_pa	      = 0;
635  hw->hw_size	      = 0;
636  hw->hw_kva	      = (caddr_t) CUSTOMbase;
637  hw->hw_manufacturer = MANUF_BUILTIN;
638  hw->hw_product      = PROD_BUILTIN_FLOPPY;
639  hw->hw_type	      = B_BUILTIN | C_FLOPPY;
640  hw->hw_serno	      = 0;
641  hw++;
642
643  hw->hw_pa	      = 0;
644  hw->hw_size	      = 0;
645  hw->hw_kva	      = (caddr_t) CUSTOMbase;
646  hw->hw_manufacturer = MANUF_BUILTIN;
647  hw->hw_product      = PROD_BUILTIN_KEYBOARD;
648  hw->hw_type	      = B_BUILTIN | D_KEYBOARD;
649  hw->hw_serno	      = 0;
650  hw++;
651
652  hw->hw_pa	      = 0;
653  hw->hw_size	      = 0;
654  hw->hw_kva	      = (caddr_t) CUSTOMbase;
655  hw->hw_manufacturer = MANUF_BUILTIN;
656  hw->hw_product      = PROD_BUILTIN_PPORT;
657  hw->hw_type	      = B_BUILTIN | D_PPORT;
658  hw->hw_serno	      = 0;
659  hw++;
660
661  hw->hw_pa	      = 0;
662  hw->hw_size	      = 0;
663  hw->hw_kva	      = (caddr_t) CUSTOMbase;
664  hw->hw_manufacturer = MANUF_BUILTIN;
665  hw->hw_product      = PROD_BUILTIN_DISPLAY;
666  hw->hw_type	      = B_BUILTIN | D_BITMAP;
667  hw->hw_serno	      = 0;
668  hw++;
669
670  hw->hw_pa	      = 0;
671  hw->hw_size	      = 0;
672  hw->hw_kva	      = (caddr_t) CUSTOMbase;
673  hw->hw_manufacturer = MANUF_BUILTIN;
674  hw->hw_product      = PROD_BUILTIN_RS232;
675  hw->hw_type	      = B_BUILTIN | D_COMMSER;
676  hw->hw_serno	      = 0;
677  hw++;
678
679  /* and afterwards add Zorro II/III devices passed by the loader */
680
681  for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++)
682    {
683      hw->hw_pa		  = cd->cd_BoardAddr;
684      hw->hw_size	  = cd->cd_BoardSize;
685      /* ADD ZORRO3 SUPPORT HERE !! */
686      hw->hw_kva	  = iszorro2pa(cd->cd_BoardAddr) ? zorro2map (cd->cd_BoardAddr) : 0;
687      hw->hw_manufacturer = cd->cd_Rom.er_Manufacturer;
688      hw->hw_product	  = cd->cd_Rom.er_Product;
689      hw->hw_serno	  = cd->cd_Rom.er_SerialNumber;
690
691      switch (hw->hw_manufacturer)
692        {
693        case MANUF_CBM_1:
694          switch (hw->hw_product)
695            {
696            case PROD_CBM_1_A2088:
697              hw->hw_type = B_ZORROII | D_MISC;
698              break;
699
700            default:
701              continue;
702            }
703          break;
704
705	case MANUF_CBM_2:
706	  switch (hw->hw_product)
707	    {
708	    case PROD_CBM_2_A2091:
709	      hw->hw_type = B_ZORROII | C_SCSI;
710	      break;
711
712	    case PROD_CBM_2_A2065:
713	      hw->hw_type = B_ZORROII | D_LAN;
714              /* the ethernet board uses bytes 1 to 3 for ID, set byte 0 to indicate
715                 whether Commodore or Ameristar board. */
716              hw->hw_serno = (hw->hw_serno & 0x00ffffff) | 0x01000000;
717	      break;
718
719	    default:
720	      continue;
721	    }
722	  break;
723
724	case MANUF_AMERISTAR:
725	  switch (hw->hw_product)
726	    {
727	    case PROD_AMERISTAR_ETHER:
728	      hw->hw_type = B_ZORROII | D_LAN;
729              /* the ethernet board uses bytes 1 to 3 for ID, set byte 0 to indicate
730                 whether Commodore or Ameristar board. */
731              hw->hw_serno = (hw->hw_serno & 0x00ffffff) | 0x02000000;
732	      break;
733
734	    default:
735	      continue;
736	    }
737	  break;
738
739        case MANUF_UNILOWELL:
740          switch (hw->hw_product)
741            {
742            case PROD_UNILOWELL_A2410:
743              hw->hw_type = B_ZORROII | D_BITMAP;
744              break;
745
746            default:
747              continue;
748            }
749          break;
750
751	case MANUF_MACROSYSTEM:
752	  switch (hw->hw_product)
753	    {
754	    case PROD_MACROSYSTEM_RETINA:
755	      hw->hw_type = B_ZORROII | D_BITMAP;
756	      break;
757
758	    default:
759	      continue;
760	    }
761	  break;
762
763	case MANUF_GVP:
764	  switch (hw->hw_product)
765	    {
766	    case PROD_GVP_SERIES_II:
767	      /* Kludge for I/O extender:
768		 if er_notused != 0, it's a SCSI controller
769		 if er_notused == 0, it's either an I/O extender or might
770		 possibly be a SCSI controller with autoboot disabled */
771	      if (cd->cd_Rom.er_notused)
772	        hw->hw_type = B_ZORROII | C_SCSI;
773	      else
774		hw->hw_type = B_ZORROII | D_COMMSER;
775	      break;
776
777	    case PROD_GVP_IV24:
778	      hw->hw_type = B_ZORROII | D_BITMAP;
779	      break;
780
781	    default:
782	      continue;
783	    }
784	  break;
785
786	case MANUF_PPI:
787	  switch (hw->hw_product)
788	    {
789	    case PROD_PPI_ZEUS:
790	      hw->hw_type = B_ZORROII | C_SCSI;
791	      break;
792
793	    default:
794	      continue;
795	    }
796	  break;
797
798	case MANUF_CSA:
799	  switch (hw->hw_product)
800	    {
801	    case PROD_CSA_MAGNUM:
802	      hw->hw_type = B_ZORROII | C_SCSI;
803	      break;
804
805	    default:
806	      continue;
807	    }
808	  break;
809
810        default:
811          continue;
812	}
813
814      hw++;
815    }
816}
817
818#if 0
819/*
820 * Allocate/deallocate a cache-inhibited range of kernel virtual address
821 * space mapping the indicated physical address range [pa - pa+size)
822 */
823caddr_t
824iomap(pa, size)
825	caddr_t pa;
826	int size;
827{
828	int ix, npf;
829	caddr_t kva;
830
831#ifdef DEBUG
832	if (((int)pa & PGOFSET) || (size & PGOFSET))
833		panic("iomap: unaligned");
834#endif
835	npf = btoc(size);
836	ix = rmalloc(extiomap, npf);
837	if (ix == 0)
838		return(0);
839	kva = extiobase + ctob(ix-1);
840	physaccess(kva, pa, size, PG_RW|PG_CI);
841	return(kva);
842}
843
844iounmap(kva, size)
845	caddr_t kva;
846	int size;
847{
848	int ix;
849
850#ifdef DEBUG
851	if (((int)kva & PGOFSET) || (size & PGOFSET))
852		panic("iounmap: unaligned");
853	if (kva < extiobase || kva >= extiobase + ctob(EIOMAPSIZE))
854		panic("iounmap: bad address");
855#endif
856	physunaccess(kva, size);
857	ix = btoc(kva - extiobase) + 1;
858	rmfree(extiomap, btoc(size), ix);
859}
860#endif
861
862#if NCD > 0
863#include "../dev/cdvar.h"
864
865find_cdevices()
866{
867	register struct cddevice *cd;
868
869	for (cd = cddevice; cd->cd_unit >= 0; cd++) {
870		/*
871		 * XXX
872		 * Assign disk index first so that init routine
873		 * can use it (saves having the driver drag around
874		 * the cddevice pointer just to set up the dk_*
875		 * info in the open routine).
876		 */
877		if (dkn < DK_NDRIVE)
878			cd->cd_dk = dkn++;
879		else
880			cd->cd_dk = -1;
881		if (cdinit(cd))
882			printf("cd%d configured\n", cd->cd_unit);
883		else if (cd->cd_dk >= 0) {
884			cd->cd_dk = -1;
885			dkn--;
886		}
887	}
888}
889#endif
890
891#if 0
892isrinit()
893{
894	register int i;
895
896	for (i = 0; i < NISR; i++)
897		isrqueue[i].isr_forw = isrqueue[i].isr_back = &isrqueue[i];
898}
899
900void
901isrlink(isr)
902	register struct isr *isr;
903{
904	int i = ISRIPL(isr->isr_ipl);
905
906	if (i < 0 || i >= NISR) {
907		printf("bad IPL %d\n", i);
908		panic("configure");
909	}
910	insque(isr, isrqueue[i].isr_back);
911}
912#endif
913
914/*
915 * Configure swap space and related parameters.
916 */
917swapconf()
918{
919	register struct swdevt *swp;
920	register int nblks;
921
922	for (swp = swdevt; swp->sw_dev; swp++)
923	  {
924		if (bdevsw[major(swp->sw_dev)].d_psize) {
925			nblks =
926			  (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
927			if (nblks != -1 &&
928			    (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
929			      {
930				swp->sw_nblks = nblks;
931/*				printf ("swap: dev %x = %d\n", swp->sw_dev, nblks);*/
932			      }
933		}
934	  }
935	dumpconf();
936
937	printf ("\n");
938}
939
940#define	DOSWAP			/* Change swdevt and dumpdev too */
941u_long	bootdev;		/* should be dev_t, but not until 32 bits */
942
943static	char devname[][2] = {
944	0,0,		/* 0 = ct */
945	0,0,		/* 1 = xx */
946	'r','d',	/* 2 = rd */
947	0,0,		/* 3 = sw */
948	's','d',	/* 4 = sd */
949	'r','z',	/* 5 = sz */
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 */
960setroot()
961{
962	register struct amiga_ctlr *ac;
963	register struct amiga_device *ad;
964	int  majdev, mindev, unit, part, adaptor;
965	dev_t temp, orootdev;
966	struct swdevt *swp;
967
968#ifdef DEBUG
969	if (acdebug > 1)
970	  printf ("setroot: boothowto = 0x%x, bootdev = 0x%x\n", boothowto, bootdev);
971#endif
972
973	if (boothowto & RB_DFLTROOT ||
974	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
975	  {
976#ifdef DEBUG
977	    if (acdebug > 1)
978	      printf ("returning due to: bad boothowto\n");
979#endif
980	    return;
981	  }
982	majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
983	if (majdev > sizeof(devname) / sizeof(devname[0]))
984	  {
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	adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
993	part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
994	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
995
996	/* First, find the controller type which support this device.
997
998	   Can have more than one controller for the same device, with
999	   just one of them configured, so test for ad->amiga_cdriver != 0
1000	   too.  */
1001
1002	for (ad = amiga_dinit; ad->amiga_driver; ad++)
1003	  {
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	  {
1022#ifdef DEBUG
1023	    if (acdebug > 1)
1024	      printf ("returning due to: amiga_driver == 0\n");
1025#endif
1026	    return;
1027	  }
1028
1029	/*
1030	 * Finally, find the device in question attached to that controller.
1031	 */
1032	for (ad = amiga_dinit; ad->amiga_driver; ad++)
1033		if (ad->amiga_alive && ad->amiga_slave == unit &&
1034		    ad->amiga_cdriver == ac->amiga_driver &&
1035		    ad->amiga_ctlr == ac->amiga_unit)
1036			break;
1037	if (ad->amiga_driver == 0)
1038	  {
1039#ifdef DEBUG
1040	    if (acdebug > 1)
1041	      printf ("returning due to: no device\n");
1042#endif
1043	    return;
1044	  }
1045	mindev = ad->amiga_unit;
1046	/*
1047	 * Form a new rootdev
1048	 */
1049	mindev = (mindev << PARTITIONSHIFT) + part;
1050	orootdev = rootdev;
1051	rootdev = makedev(majdev, mindev);
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	  {
1058#ifdef DEBUG
1059	    if (acdebug > 1)
1060	      printf ("returning due to: new root == old root\n");
1061#endif
1062	    return;
1063	  }
1064
1065
1066
1067	printf("Changing root device to %c%c%d%c\n",
1068		devname[majdev][0], devname[majdev][1],
1069		mindev >> PARTITIONSHIFT, part + 'a');
1070
1071#ifdef DOSWAP
1072	mindev &= ~PARTITIONMASK;
1073	for (swp = swdevt; swp->sw_dev; swp++) {
1074		if (majdev == major(swp->sw_dev) &&
1075		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
1076			temp = swdevt[0].sw_dev;
1077			swdevt[0].sw_dev = swp->sw_dev;
1078			swp->sw_dev = temp;
1079			break;
1080		}
1081	}
1082	if (swp->sw_dev == 0)
1083		return;
1084
1085	/*
1086	 * If dumpdev was the same as the old primary swap
1087	 * device, move it to the new primary swap device.
1088	 */
1089	if (temp == dumpdev)
1090		dumpdev = swdevt[0].sw_dev;
1091#endif
1092}
1093
1094/* try to determine, of this machine is an A3000, which has a builtin
1095   realtime clock and scsi controller, so that this hardware is only
1096   included as "configured" if this IS an A3000  */
1097
1098int a3000_flag = 1;		/* patchable */
1099#ifdef A4000
1100int a4000_flag = 1;		/* patchable - default to A4000 */
1101#else
1102int a4000_flag = 0;		/* patchable */
1103#endif
1104
1105int
1106is_a3000 ()
1107{
1108  /* this is a dirty kludge.. but how do you do this RIGHT ? :-) */
1109  extern long orig_fastram_start;
1110  short sc;
1111  extern int num_ConfigDev;
1112  extern struct ConfigDev *ConfigDev;
1113  struct ConfigDev *cd;
1114
1115  /* where is fastram on the A4000 ?? */
1116  /* if fastram is below 0x07000000, assume it's not an A3000 */
1117  if (orig_fastram_start < 0x07000000)
1118    return (0);
1119
1120  /* OK, fastram starts at or above 0x07000000, check specific machines */
1121  for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++) {
1122    switch (cd->cd_Rom.er_Manufacturer) {
1123    case MANUF_PPI:			/* Progressive Peripherals, Inc */
1124      switch (cd->cd_Rom.er_Product) {
1125#if 0
1126      case PROD_PPI_MECURY:		/* PPI Mecury - it's an A3000 */
1127        return (1);
1128      case PROD_PPI_2000:
1129      case PROD_PPI_500:
1130#endif
1131      case PROD_PPI_ZEUS:
1132        return (0);
1133      }
1134    }
1135  }
1136  /* assume it's an A3000 */
1137  return (a3000_flag);
1138}
1139
1140int
1141is_a4000 ()
1142{
1143  /* This is a real dirty kludge.. */
1144  return (a4000_flag);
1145}
1146