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