autoconf.c revision 1.4
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")||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	case D_PPORT:
524		found = dr_type(ad->amiga_driver, "par");
525		break;
526	default:
527		break;
528	}
529	return(found);
530}
531
532char notmappedmsg[] = "WARNING: no space to map IO card, ignored\n";
533
534/*
535 * Scan the IO space looking for devices.
536 */
537find_devs()
538{
539  short sc;
540  u_char *id_reg;
541  register caddr_t addr;
542  register struct amiga_hw *hw;
543  int didmap, sctop;
544  extern int num_ConfigDev;
545  extern struct ConfigDev *ConfigDev;
546  struct ConfigDev *cd;
547
548#if 0
549  /*
550   * Initialize IO resource map for iomap().
551   */
552  rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16);
553#endif
554  hw = sc_table;
555
556  /* first enter builtin devices */
557
558  if (is_a3000 ())
559    {
560      /* hm, this doesn't belong here... */
561      volatile u_char *magic_reset_reg = zorro2map (0xde0002);
562      /* this bit makes the next reset look like a powerup reset, Amiga
563	 Unix sets this bit, and perhaps it will enable 16M machines to
564	 boot again... */
565      *magic_reset_reg   |= 0x80;
566
567      hw->hw_pa		  = 0xdd0000;
568      hw->hw_size	  = NBPG;
569      hw->hw_kva	  = zorro2map (0xdd0000);
570      hw->hw_manufacturer = MANUF_BUILTIN;
571      hw->hw_product      = PROD_BUILTIN_SCSI;
572      hw->hw_type	  = B_BUILTIN | C_SCSI;
573      hw->hw_serno	  = 0;
574      hw++;
575
576      hw->hw_pa	      	  = 0xdc0000;
577      hw->hw_size	  = NBPG;
578      hw->hw_kva	  = zorro2map (0xdc0000);
579      hw->hw_manufacturer = MANUF_BUILTIN;
580      hw->hw_product      = PROD_BUILTIN_CLOCK;
581      hw->hw_type	  = B_BUILTIN | D_CLOCK;
582      hw->hw_serno	  = 0;
583      hw++;
584    }
585  else
586    {
587      /* what about other Amigas? Oh well.. */
588      hw->hw_pa	      	  = 0xdc0000;
589      hw->hw_size	  = NBPG;
590      hw->hw_kva	  = zorro2map (0xdc0000);
591      hw->hw_manufacturer = MANUF_BUILTIN;
592      hw->hw_product      = PROD_BUILTIN_CLOCK2;
593      hw->hw_type	  = B_BUILTIN | D_CLOCK;
594      hw->hw_serno	  = 0;
595      hw++;
596    }
597
598  hw->hw_pa	      = 0;
599  hw->hw_size	      = 0;
600  hw->hw_kva	      = CUSTOMbase;
601  hw->hw_manufacturer = MANUF_BUILTIN;
602  hw->hw_product      = PROD_BUILTIN_FLOPPY;
603  hw->hw_type	      = B_BUILTIN | C_FLOPPY;
604  hw->hw_serno	      = 0;
605  hw++;
606
607  hw->hw_pa	      = 0;
608  hw->hw_size	      = 0;
609  hw->hw_kva	      = CUSTOMbase;
610  hw->hw_manufacturer = MANUF_BUILTIN;
611  hw->hw_product      = PROD_BUILTIN_KEYBOARD;
612  hw->hw_type	      = B_BUILTIN | D_KEYBOARD;
613  hw->hw_serno	      = 0;
614  hw++;
615
616  hw->hw_pa	      = 0;
617  hw->hw_size	      = 0;
618  hw->hw_kva	      = CUSTOMbase;
619  hw->hw_manufacturer = MANUF_BUILTIN;
620  hw->hw_product      = PROD_BUILTIN_PPORT;
621  hw->hw_type	      = B_BUILTIN | D_PPORT;
622  hw->hw_serno	      = 0;
623  hw++;
624
625  hw->hw_pa	      = 0;
626  hw->hw_size	      = 0;
627  hw->hw_kva	      = CUSTOMbase;
628  hw->hw_manufacturer = MANUF_BUILTIN;
629  hw->hw_product      = PROD_BUILTIN_DISPLAY;
630  hw->hw_type	      = B_BUILTIN | D_BITMAP;
631  hw->hw_serno	      = 0;
632  hw++;
633
634  hw->hw_pa	      = 0;
635  hw->hw_size	      = 0;
636  hw->hw_kva	      = CUSTOMbase;
637  hw->hw_manufacturer = MANUF_BUILTIN;
638  hw->hw_product      = PROD_BUILTIN_RS232;
639  hw->hw_type	      = B_BUILTIN | D_COMMSER;
640  hw->hw_serno	      = 0;
641  hw++;
642
643  /* and afterwards add Zorro II/III devices passed by the loader */
644
645  for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++)
646    {
647      hw->hw_pa		  = cd->cd_BoardAddr;
648      hw->hw_size	  = cd->cd_BoardSize;
649      /* ADD ZORRO3 SUPPORT HERE !! */
650      hw->hw_kva	  = iszorro2pa(cd->cd_BoardAddr) ? zorro2map (cd->cd_BoardAddr) : 0;
651      hw->hw_manufacturer = cd->cd_Rom.er_Manufacturer;
652      hw->hw_product	  = cd->cd_Rom.er_Product;
653      hw->hw_serno	  = cd->cd_Rom.er_SerialNumber;
654
655      switch (hw->hw_manufacturer)
656        {
657        case MANUF_CBM_1:
658          switch (hw->hw_product)
659            {
660            case PROD_CBM_1_A2088:
661              hw->hw_type = B_ZORROII | D_MISC;
662              break;
663
664            default:
665              continue;
666            }
667          break;
668
669	case MANUF_CBM_2:
670	  switch (hw->hw_product)
671	    {
672	    case PROD_CBM_2_A2091:
673	      hw->hw_type = B_ZORROII | C_SCSI;
674	      break;
675
676	    case PROD_CBM_2_A2065:
677	      hw->hw_type = B_ZORROII | D_LAN;
678              /* the ethernet board uses bytes 1 to 3 for ID, set byte 0 to indicate
679                 whether Commodore or Ameristar board. */
680              hw->hw_serno = (hw->hw_serno & 0x00ffffff) | 0x01000000;
681	      break;
682
683	    default:
684	      continue;
685	    }
686	  break;
687
688	case MANUF_AMERISTAR:
689	  switch (hw->hw_product)
690	    {
691	    case PROD_AMERISTAR_ETHER:
692	      hw->hw_type = B_ZORROII | D_LAN;
693              /* the ethernet board uses bytes 1 to 3 for ID, set byte 0 to indicate
694                 whether Commodore or Ameristar board. */
695              hw->hw_serno = (hw->hw_serno & 0x00ffffff) | 0x02000000;
696	      break;
697
698	    default:
699	      continue;
700	    }
701	  break;
702
703        case MANUF_UNILOWELL:
704          switch (hw->hw_product)
705            {
706            case PROD_UNILOWELL_A2410:
707              hw->hw_type = B_ZORROII | D_BITMAP;
708              break;
709
710            default:
711              continue;
712            }
713          break;
714
715	case MANUF_MACROSYSTEM:
716	  switch (hw->hw_product)
717	    {
718	    case PROD_MACROSYSTEM_RETINA:
719	      hw->hw_type = B_ZORROII | D_BITMAP;
720	      break;
721
722	    default:
723	      continue;
724	    }
725	  break;
726
727	case MANUF_GVP:
728	  switch (hw->hw_product)
729	    {
730	    case PROD_GVP_SERIES_II:
731	      hw->hw_type = B_ZORROII | C_SCSI;
732	      break;
733
734	    case PROD_GVP_IV24:
735	      hw->hw_type = B_ZORROII | D_BITMAP;
736	      break;
737
738	    default:
739	      continue;
740	    }
741	  break;
742
743
744        default:
745          continue;
746	}
747
748      hw++;
749    }
750}
751
752#if 0
753/*
754 * Allocate/deallocate a cache-inhibited range of kernel virtual address
755 * space mapping the indicated physical address range [pa - pa+size)
756 */
757caddr_t
758iomap(pa, size)
759	caddr_t pa;
760	int size;
761{
762	int ix, npf;
763	caddr_t kva;
764
765#ifdef DEBUG
766	if (((int)pa & PGOFSET) || (size & PGOFSET))
767		panic("iomap: unaligned");
768#endif
769	npf = btoc(size);
770	ix = rmalloc(extiomap, npf);
771	if (ix == 0)
772		return(0);
773	kva = extiobase + ctob(ix-1);
774	physaccess(kva, pa, size, PG_RW|PG_CI);
775	return(kva);
776}
777
778iounmap(kva, size)
779	caddr_t kva;
780	int size;
781{
782	int ix;
783
784#ifdef DEBUG
785	if (((int)kva & PGOFSET) || (size & PGOFSET))
786		panic("iounmap: unaligned");
787	if (kva < extiobase || kva >= extiobase + ctob(EIOMAPSIZE))
788		panic("iounmap: bad address");
789#endif
790	physunaccess(kva, size);
791	ix = btoc(kva - extiobase) + 1;
792	rmfree(extiomap, btoc(size), ix);
793}
794#endif
795
796#if NCD > 0
797#include "../dev/cdvar.h"
798
799find_cdevices()
800{
801	register struct cddevice *cd;
802
803	for (cd = cddevice; cd->cd_unit >= 0; cd++) {
804		/*
805		 * XXX
806		 * Assign disk index first so that init routine
807		 * can use it (saves having the driver drag around
808		 * the cddevice pointer just to set up the dk_*
809		 * info in the open routine).
810		 */
811		if (dkn < DK_NDRIVE)
812			cd->cd_dk = dkn++;
813		else
814			cd->cd_dk = -1;
815		if (cdinit(cd))
816			printf("cd%d configured\n", cd->cd_unit);
817		else if (cd->cd_dk >= 0) {
818			cd->cd_dk = -1;
819			dkn--;
820		}
821	}
822}
823#endif
824
825#if 0
826isrinit()
827{
828	register int i;
829
830	for (i = 0; i < NISR; i++)
831		isrqueue[i].isr_forw = isrqueue[i].isr_back = &isrqueue[i];
832}
833
834void
835isrlink(isr)
836	register struct isr *isr;
837{
838	int i = ISRIPL(isr->isr_ipl);
839
840	if (i < 0 || i >= NISR) {
841		printf("bad IPL %d\n", i);
842		panic("configure");
843	}
844	insque(isr, isrqueue[i].isr_back);
845}
846#endif
847
848/*
849 * Configure swap space and related parameters.
850 */
851swapconf()
852{
853	register struct swdevt *swp;
854	register int nblks;
855
856	for (swp = swdevt; swp->sw_dev; swp++)
857	  {
858		if (bdevsw[major(swp->sw_dev)].d_psize) {
859			nblks =
860			  (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
861			if (nblks != -1 &&
862			    (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
863			      {
864				swp->sw_nblks = nblks;
865/*				printf ("swap: dev %x = %d\n", swp->sw_dev, nblks);*/
866			      }
867		}
868	  }
869	dumpconf();
870
871	printf ("\n");
872}
873
874#define	DOSWAP			/* Change swdevt and dumpdev too */
875u_long	bootdev;		/* should be dev_t, but not until 32 bits */
876
877static	char devname[][2] = {
878	0,0,		/* 0 = ct */
879	0,0,		/* 1 = xx */
880	'r','d',	/* 2 = rd */
881	0,0,		/* 3 = sw */
882	's','d',	/* 4 = sd */
883};
884
885#define	PARTITIONMASK	0x7
886#define	PARTITIONSHIFT	3
887
888/*
889 * Attempt to find the device from which we were booted.
890 * If we can do so, and not instructed not to do so,
891 * change rootdev to correspond to the load device.
892 */
893setroot()
894{
895	register struct amiga_ctlr *ac;
896	register struct amiga_device *ad;
897	int  majdev, mindev, unit, part, adaptor;
898	dev_t temp, orootdev;
899	struct swdevt *swp;
900
901#ifdef DEBUG
902	if (acdebug > 1)
903	  printf ("setroot: boothowto = 0x%x, bootdev = 0x%x\n", boothowto, bootdev);
904#endif
905
906	if (boothowto & RB_DFLTROOT ||
907	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
908	  {
909#ifdef DEBUG
910	    if (acdebug > 1)
911	      printf ("returning due to: bad boothowto\n");
912#endif
913	    return;
914	  }
915	majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
916	if (majdev > sizeof(devname) / sizeof(devname[0]))
917	  {
918#ifdef DEBUG
919	    if (acdebug > 1)
920	      printf ("returning due to: majdev (%d) > maxdevs (%d)\n",
921		      majdev, sizeof(devname) / sizeof(devname[0]));
922#endif
923	    return;
924	  }
925	adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
926	part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
927	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
928
929	/* First, find the controller type which support this device.
930
931	   Can have more than one controller for the same device, with
932	   just one of them configured, so test for ad->amiga_cdriver != 0
933	   too.  */
934
935	for (ad = amiga_dinit; ad->amiga_driver; ad++)
936	  {
937	    if (ad->amiga_driver->d_name[0] != devname[majdev][0]
938		|| ad->amiga_driver->d_name[1] != devname[majdev][1])
939	      continue;
940
941	    /*
942	     * Next, find the controller of that type corresponding to
943	     * the adaptor number.
944	     */
945	    for (ac = amiga_cinit; ac->amiga_driver; ac++)
946	      if (ac->amiga_alive && ac->amiga_unit == adaptor &&
947		  ac->amiga_driver == ad->amiga_cdriver)
948		goto found_it;
949	  }
950
951/* could also place after test, but I'd like to be on the safe side */
952found_it:
953	if (ad->amiga_driver == 0)
954	  {
955#ifdef DEBUG
956	    if (acdebug > 1)
957	      printf ("returning due to: amiga_driver == 0\n");
958#endif
959	    return;
960	  }
961
962	/*
963	 * Finally, find the device in question attached to that controller.
964	 */
965	for (ad = amiga_dinit; ad->amiga_driver; ad++)
966		if (ad->amiga_alive && ad->amiga_slave == unit &&
967		    ad->amiga_cdriver == ac->amiga_driver &&
968		    ad->amiga_ctlr == ac->amiga_unit)
969			break;
970	if (ad->amiga_driver == 0)
971	  {
972#ifdef DEBUG
973	    if (acdebug > 1)
974	      printf ("returning due to: no device\n");
975#endif
976	    return;
977	  }
978	mindev = ad->amiga_unit;
979	/*
980	 * Form a new rootdev
981	 */
982	mindev = (mindev << PARTITIONSHIFT) + part;
983	orootdev = rootdev;
984	rootdev = makedev(majdev, mindev);
985	/*
986	 * If the original rootdev is the same as the one
987	 * just calculated, don't need to adjust the swap configuration.
988	 */
989	if (rootdev == orootdev)
990	  {
991#ifdef DEBUG
992	    if (acdebug > 1)
993	      printf ("returning due to: new root == old root\n");
994#endif
995	    return;
996	  }
997
998
999
1000	printf("Changing root device to %c%c%d%c\n",
1001		devname[majdev][0], devname[majdev][1],
1002		mindev >> PARTITIONSHIFT, part + 'a');
1003
1004#ifdef DOSWAP
1005	mindev &= ~PARTITIONMASK;
1006	for (swp = swdevt; swp->sw_dev; swp++) {
1007		if (majdev == major(swp->sw_dev) &&
1008		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
1009			temp = swdevt[0].sw_dev;
1010			swdevt[0].sw_dev = swp->sw_dev;
1011			swp->sw_dev = temp;
1012			break;
1013		}
1014	}
1015	if (swp->sw_dev == 0)
1016		return;
1017
1018	/*
1019	 * If dumpdev was the same as the old primary swap
1020	 * device, move it to the new primary swap device.
1021	 */
1022	if (temp == dumpdev)
1023		dumpdev = swdevt[0].sw_dev;
1024#endif
1025}
1026
1027/* try to determine, of this machine is an A3000, which has a builtin
1028   realtime clock and scsi controller, so that this hardware is only
1029   included as "configured" if this IS an A3000  */
1030int
1031is_a3000 ()
1032{
1033  /* this is a dirty kludge.. but how do you do this RIGHT ? :-) */
1034  extern long orig_fastram_start;
1035
1036  /* where is fastram on the A4000 ?? */
1037  return orig_fastram_start >= 0x07000000;
1038}
1039