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