xref: /netbsd/sys/arch/sparc64/sparc64/autoconf.c (revision c4a72b64)
1 /*	$NetBSD: autoconf.c,v 1.68 2002/11/03 01:54:45 mrg Exp $ */
2 
3 /*
4  * Copyright (c) 1996
5  *    The President and Fellows of Harvard College. All rights reserved.
6  * Copyright (c) 1992, 1993
7  *	The Regents of the University of California.  All rights reserved.
8  *
9  * This software was developed by the Computer Systems Engineering group
10  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
11  * contributed to Berkeley.
12  *
13  * All advertising materials mentioning features or use of this software
14  * must display the following acknowledgement:
15  *	This product includes software developed by Harvard University.
16  *	This product includes software developed by the University of
17  *	California, Lawrence Berkeley Laboratory.
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions
21  * are met:
22  * 1. Redistributions of source code must retain the above copyright
23  *    notice, this list of conditions and the following disclaimer.
24  * 2. Redistributions in binary form must reproduce the above copyright
25  *    notice, this list of conditions and the following disclaimer in the
26  *    documentation and/or other materials provided with the distribution.
27  * 3. All advertising materials mentioning features or use of this software
28  *    must display the following acknowledgement:
29  *	This product includes software developed by the University of
30  *	California, Berkeley and its contributors.
31  * 4. Neither the name of the University nor the names of its contributors
32  *    may be used to endorse or promote products derived from this software
33  *    without specific prior written permission.
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
36  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
39  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45  * SUCH DAMAGE.
46  *
47  *	@(#)autoconf.c	8.4 (Berkeley) 10/1/93
48  */
49 
50 #include "opt_ddb.h"
51 #include "opt_kgdb.h"
52 
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/buf.h>
56 #include <sys/disklabel.h>
57 #include <sys/device.h>
58 #include <sys/disk.h>
59 #include <sys/dkstat.h>
60 #include <sys/conf.h>
61 #include <sys/reboot.h>
62 #include <sys/socket.h>
63 #include <sys/malloc.h>
64 #include <sys/queue.h>
65 #include <sys/msgbuf.h>
66 #include <sys/boot_flag.h>
67 
68 #include <net/if.h>
69 
70 #include <dev/cons.h>
71 
72 #include <uvm/uvm_extern.h>
73 
74 #include <machine/bus.h>
75 #include <machine/autoconf.h>
76 #include <machine/openfirm.h>
77 #include <machine/sparc64.h>
78 #include <machine/cpu.h>
79 #include <machine/pmap.h>
80 #include <sparc64/sparc64/timerreg.h>
81 
82 #include <dev/ata/atavar.h>
83 #include <dev/ata/wdvar.h>
84 #include <dev/pci/pcivar.h>
85 #include <dev/sbus/sbusvar.h>
86 
87 #ifdef DDB
88 #include <machine/db_machdep.h>
89 #include <ddb/db_sym.h>
90 #include <ddb/db_extern.h>
91 #endif
92 
93 
94 int printspl = 0;
95 
96 /*
97  * The following several variables are related to
98  * the configuration process, and are used in initializing
99  * the machine.
100  */
101 int	stdinnode;	/* node ID of ROM's console input device */
102 int	fbnode;		/* node ID of ROM's console output device */
103 int	optionsnode;	/* node ID of ROM's options */
104 
105 #ifdef KGDB
106 extern	int kgdb_debug_panic;
107 #endif
108 
109 static	int rootnode;
110 char platform_type[32];
111 
112 static	char *str2hex __P((char *, int *));
113 static	int mbprint __P((void *, const char *));
114 static	void crazymap __P((char *, int *));
115 int	st_crazymap __P((int));
116 void	sync_crash __P((void));
117 int	mainbus_match __P((struct device *, struct cfdata *, void *));
118 static	void mainbus_attach __P((struct device *, struct device *, void *));
119 
120 struct	bootpath bootpath[8];
121 int	nbootpath;
122 static	void bootpath_build __P((void));
123 static	void bootpath_print __P((struct bootpath *));
124 
125 /* Global interrupt mappings for all device types.  Match against the OBP
126  * 'device_type' property.
127  */
128 struct intrmap intrmap[] = {
129 	{ "block",	PIL_FD },	/* Floppy disk */
130 	{ "serial",	PIL_SER },	/* zs */
131 	{ "scsi",	PIL_SCSI },
132 	{ "network",	PIL_NET },
133 	{ "display",	PIL_VIDEO },
134 	{ "audio",	PIL_AUD },
135 	{ "ide",	PIL_SCSI },
136 /* The following devices don't have device types: */
137 	{ "SUNW,CS4231",	PIL_AUD },
138 	{ NULL,		0 }
139 };
140 
141 #ifdef DEBUG
142 #define ACDB_BOOTDEV	0x1
143 #define	ACDB_PROBE	0x2
144 int autoconf_debug = 0x0;
145 #define DPRINTF(l, s)   do { if (autoconf_debug & l) printf s; } while (0)
146 #else
147 #define DPRINTF(l, s)
148 #endif
149 
150 /*
151  * Most configuration on the SPARC is done by matching OPENPROM Forth
152  * device names with our internal names.
153  */
154 int
155 matchbyname(parent, cf, aux)
156 	struct device *parent;
157 	struct cfdata *cf;
158 	void *aux;
159 {
160 	printf("%s: WARNING: matchbyname\n", cf->cf_name);
161 	return (0);
162 }
163 
164 /*
165  * Convert hex ASCII string to a value.  Returns updated pointer.
166  * Depends on ASCII order (this *is* machine-dependent code, you know).
167  */
168 static char *
169 str2hex(str, vp)
170 	register char *str;
171 	register int *vp;
172 {
173 	register int v, c;
174 
175 	for (v = 0;; v = v * 16 + c, str++) {
176 		c = *(u_char *)str;
177 		if (c <= '9') {
178 			if ((c -= '0') < 0)
179 				break;
180 		} else if (c <= 'F') {
181 			if ((c -= 'A' - 10) < 10)
182 				break;
183 		} else if (c <= 'f') {
184 			if ((c -= 'a' - 10) < 10)
185 				break;
186 		} else
187 			break;
188 	}
189 	*vp = v;
190 	return (str);
191 }
192 
193 /*
194  * locore.s code calls bootstrap() just before calling main().
195  *
196  * What we try to do is as follows:
197  *
198  * 1) We will try to re-allocate the old message buffer.
199  *
200  * 2) We will then get the list of the total and available
201  *	physical memory and available virtual memory from the
202  *	prom.
203  *
204  * 3) We will pass the list to pmap_bootstrap to manage them.
205  *
206  * We will try to run out of the prom until we get to cpu_init().
207  */
208 void
209 bootstrap(nctx)
210 	int nctx;
211 {
212 	extern int end;	/* End of kernel */
213 #if defined(DDB) && defined(DB_ELF_SYMBOLS)
214 	extern void *ssym, *esym;
215 #endif
216 #ifndef	__arch64__
217 	/* Assembly glue for the PROM */
218 	extern void OF_sym2val32 __P((void *));
219 	extern void OF_val2sym32 __P((void *));
220 #endif
221 
222 	/*
223 	 * Initialize ddb first and register OBP callbacks.
224 	 * We can do this because ddb_init() does not allocate anything,
225 	 * just initialze some pointers to important things
226 	 * like the symtab.
227 	 *
228 	 * By doing this first and installing the OBP callbacks
229 	 * we get to do symbolic debugging of pmap_bootstrap().
230 	 */
231 #ifdef KGDB
232 /* Moved zs_kgdb_init() to dev/zs.c:consinit(). */
233 	zs_kgdb_init();		/* XXX */
234 #endif
235 	/* Initialize the PROM console so printf will not panic */
236 	(*cn_tab->cn_init)(cn_tab);
237 #ifdef DDB
238 #ifdef DB_ELF_SYMBOLS
239 	ddb_init((int)((caddr_t)esym - (caddr_t)ssym), ssym, esym);
240 #else
241 	ddb_init();
242 #endif
243 #ifdef __arch64__
244 	/* This can only be installed on an 64-bit system cause otherwise our stack is screwed */
245 	OF_set_symbol_lookup(OF_sym2val, OF_val2sym);
246 #else
247 #if 1
248 	OF_set_symbol_lookup(OF_sym2val32, OF_val2sym32);
249 #endif
250 #endif
251 #endif
252 
253 	pmap_bootstrap(KERNBASE, (u_long)&end, nctx);
254 }
255 
256 /*
257  * bootpath_build: build a bootpath. Used when booting a generic
258  * kernel to find our root device.  Newer proms give us a bootpath,
259  * for older proms we have to create one.  An element in a bootpath
260  * has 4 fields: name (device name), val[0], val[1], and val[2]. Note that:
261  * Interpretation of val[] is device-dependent. Some examples:
262  *
263  * if (val[0] == -1) {
264  *	val[1] is a unit number    (happens most often with old proms)
265  * } else {
266  *	[sbus device] val[0] is a sbus slot, and val[1] is an sbus offset
267  *	[scsi disk] val[0] is target, val[1] is lun, val[2] is partition
268  *	[scsi tape] val[0] is target, val[1] is lun, val[2] is file #
269  *	[pci device] val[0] is device, val[1] is function, val[2] might be partition
270  * }
271  *
272  */
273 
274 static void
275 bootpath_build()
276 {
277 	register char *cp, *pp;
278 	register struct bootpath *bp;
279 	register long chosen;
280 	char buf[128];
281 
282 	bzero((void*)bootpath, sizeof(bootpath));
283 	bp = bootpath;
284 
285 	/*
286 	 * Grab boot path from PROM
287 	 */
288 	chosen = OF_finddevice("/chosen");
289 	OF_getprop(chosen, "bootpath", buf, sizeof(buf));
290 	cp = buf;
291 	while (cp != NULL && *cp == '/') {
292 		/* Step over '/' */
293 		++cp;
294 		/* Extract name */
295 		pp = bp->name;
296 		while (*cp != '@' && *cp != '/' && *cp != '\0')
297 			*pp++ = *cp++;
298 		*pp = '\0';
299 		if (*cp == '@') {
300 			cp = str2hex(++cp, &bp->val[0]);
301 			if (*cp == ',')
302 				cp = str2hex(++cp, &bp->val[1]);
303 			if (*cp == ':')
304 				/* XXX - we handle just one char */
305 				bp->val[2] = *++cp - 'a', ++cp;
306 		} else {
307 			bp->val[0] = -1; /* no #'s: assume unit 0, no
308 					    sbus offset/adddress */
309 		}
310 		++bp;
311 		++nbootpath;
312 	}
313 	bp->name[0] = 0;
314 
315 	bootpath_print(bootpath);
316 
317 	/* Setup pointer to boot flags */
318 	OF_getprop(chosen, "bootargs", buf, sizeof(buf));
319 	cp = buf;
320 
321 	/* Find start of boot flags */
322 	while (*cp) {
323 		while(*cp == ' ' || *cp == '\t') cp++;
324 		if (*cp == '-' || *cp == '\0')
325 			break;
326 		while(*cp != ' ' && *cp != '\t' && *cp != '\0') cp++;
327 
328 	}
329 	if (*cp != '-')
330 		return;
331 
332 	for (;*++cp;) {
333 		int fl;
334 
335 		fl = 0;
336 		BOOT_FLAG(*cp, fl);
337 		if (!fl) {
338 			printf("unknown option `%c'\n", *cp);
339 			continue;
340 		}
341 		boothowto |= fl;
342 
343 		/* specialties */
344 		if (*cp == 'd') {
345 #if defined(KGDB)
346 			kgdb_debug_panic = 1;
347 			kgdb_connect(1);
348 #elif defined(DDB)
349 			Debugger();
350 #else
351 			printf("kernel has no debugger\n");
352 #endif
353 		} else if (*cp == 't') {
354 			/* turn on traptrace w/o breaking into kdb */
355 			extern int trap_trace_dis;
356 
357 			trap_trace_dis = 0;
358 		}
359 	}
360 }
361 
362 /*
363  * print out the bootpath
364  * the %x isn't 0x%x because the Sun EPROMs do it this way, and
365  * consistency with the EPROMs is probably better here.
366  */
367 
368 static void
369 bootpath_print(bp)
370 	struct bootpath *bp;
371 {
372 	printf("bootpath: ");
373 	while (bp->name[0]) {
374 		if (bp->val[0] == -1)
375 			printf("/%s%x", bp->name, bp->val[1]);
376 		else
377 			printf("/%s@%x,%x", bp->name, bp->val[0], bp->val[1]);
378 		if (bp->val[2] != 0)
379 			printf(":%c", bp->val[2] + 'a');
380 		bp++;
381 	}
382 	printf("\n");
383 }
384 
385 
386 /*
387  * save or read a bootpath pointer from the boothpath store.
388  *
389  * XXX. required because of SCSI... we don't have control over the "sd"
390  * device, so we can't set boot device there.   we patch in with
391  * dk_establish(), and use this to recover the bootpath.
392  */
393 struct bootpath *
394 bootpath_store(storep, bp)
395 	int storep;
396 	struct bootpath *bp;
397 {
398 	static struct bootpath *save;
399 	struct bootpath *retval;
400 
401 	retval = save;
402 	if (storep)
403 		save = bp;
404 
405 	return (retval);
406 }
407 
408 /*
409  * Set up the sd target mappings for non SUN4 PROMs.
410  * Find out about the real SCSI target, given the PROM's idea of the
411  * target of the (boot) device (i.e., the value in bp->v0val[0]).
412  */
413 static void
414 crazymap(prop, map)
415 	char *prop;
416 	int *map;
417 {
418 	int i;
419 
420 	/*
421 	 * Set up the identity mapping for old sun4 monitors
422 	 * and v[2-] OpenPROMs. Note: dkestablish() does the
423 	 * SCSI-target juggling for sun4 monitors.
424 	 */
425 	for (i = 0; i < 8; ++i)
426 		map[i] = i;
427 }
428 
429 int
430 sd_crazymap(n)
431 	int	n;
432 {
433 	static int prom_sd_crazymap[8]; /* static: compute only once! */
434 	static int init = 0;
435 
436 	if (init == 0) {
437 		crazymap("sd-targets", prom_sd_crazymap);
438 		init = 1;
439 	}
440 	return prom_sd_crazymap[n];
441 }
442 
443 int
444 st_crazymap(n)
445 	int	n;
446 {
447 	static int prom_st_crazymap[8]; /* static: compute only once! */
448 	static int init = 0;
449 
450 	if (init == 0) {
451 		crazymap("st-targets", prom_st_crazymap);
452 		init = 1;
453 	}
454 	return prom_st_crazymap[n];
455 }
456 
457 
458 /*
459  * Determine mass storage and memory configuration for a machine.
460  * We get the PROM's root device and make sure we understand it, then
461  * attach it as `mainbus0'.  We also set up to handle the PROM `sync'
462  * command.
463  */
464 void
465 cpu_configure()
466 {
467 
468 	/* build the bootpath */
469 	bootpath_build();
470 
471 #if notyet
472         /* FIXME FIXME FIXME  This is probably *WRONG!!!**/
473         OF_set_callback(sync_crash);
474 #endif
475 
476 	/* block clock interrupts and anything below */
477 	splclock();
478 	/* Enable device interrupts */
479         setpstate(getpstate()|PSTATE_IE);
480 
481 	if (config_rootfound("mainbus", NULL) == NULL)
482 		panic("mainbus not configured");
483 
484 	/* Enable device interrupts */
485         setpstate(getpstate()|PSTATE_IE);
486 
487 	(void)spl0();
488 }
489 
490 
491 void
492 cpu_rootconf()
493 {
494 	struct bootpath *bp;
495 	struct device *bootdv;
496 	int bootpartition;
497 
498 	bp = nbootpath == 0 ? NULL : &bootpath[nbootpath-1];
499 	bootdv = bp == NULL ? NULL : bp->dev;
500 	bootpartition = bootdv == NULL ? 0 : bp->val[2];
501 
502 	setroot(bootdv, bootpartition);
503 }
504 
505 /*
506  * Console `sync' command.  SunOS just does a `panic: zero' so I guess
507  * no one really wants anything fancy...
508  */
509 void
510 sync_crash()
511 {
512 
513 	panic("PROM sync command");
514 }
515 
516 char *
517 clockfreq(freq)
518 	long freq;
519 {
520 	char *p;
521 	static char buf[10];
522 
523 	freq /= 1000;
524 	sprintf(buf, "%ld", freq / 1000);
525 	freq %= 1000;
526 	if (freq) {
527 		freq += 1000;	/* now in 1000..1999 */
528 		p = buf + strlen(buf);
529 		sprintf(p, "%ld", freq);
530 		*p = '.';	/* now buf = %d.%3d */
531 	}
532 	return (buf);
533 }
534 
535 /* ARGSUSED */
536 static int
537 mbprint(aux, name)
538 	void *aux;
539 	const char *name;
540 {
541 	struct mainbus_attach_args *ma = aux;
542 
543 	if (name)
544 		printf("%s at %s", ma->ma_name, name);
545 	if (ma->ma_address)
546 		printf(" addr 0x%08lx", (u_long)ma->ma_address[0]);
547 	if (ma->ma_pri)
548 		printf(" ipl %d", ma->ma_pri);
549 	return (UNCONF);
550 }
551 
552 int
553 findroot()
554 {
555 	register int node;
556 
557 	if ((node = rootnode) == 0 && (node = OF_peer(0)) == 0)
558 		panic("no PROM root device");
559 	rootnode = node;
560 	return (node);
561 }
562 
563 /*
564  * Given a `first child' node number, locate the node with the given name.
565  * Return the node number, or 0 if not found.
566  */
567 int
568 findnode(first, name)
569 	int first;
570 	register const char *name;
571 {
572 	int node;
573 	char buf[32];
574 
575 	for (node = first; node; node = OF_peer(node)) {
576 		if ((OF_getprop(node, "name", buf, sizeof(buf)) > 0) &&
577 			(strcmp(buf, name) == 0))
578 			return (node);
579 	}
580 	return (0);
581 }
582 
583 int
584 mainbus_match(parent, cf, aux)
585 	struct device *parent;
586 	struct cfdata *cf;
587 	void *aux;
588 {
589 
590 	return (1);
591 }
592 
593 int autoconf_nzs = 0;	/* must be global so obio.c can see it */
594 
595 /*
596  * Attach the mainbus.
597  *
598  * Our main job is to attach the CPU (the root node we got in configure())
599  * and iterate down the list of `mainbus devices' (children of that node).
600  * We also record the `node id' of the default frame buffer, if any.
601  */
602 static void
603 mainbus_attach(parent, dev, aux)
604 	struct device *parent, *dev;
605 	void *aux;
606 {
607 extern struct sparc_bus_dma_tag mainbus_dma_tag;
608 extern struct sparc_bus_space_tag mainbus_space_tag;
609 
610 	struct mainbus_attach_args ma;
611 	char buf[32];
612 	const char *const *ssp, *sp = NULL;
613 	int node0, node, rv;
614 
615 	static const char *const openboot_special[] = {
616 		/* ignore these (end with NULL) */
617 		/*
618 		 * These are _root_ devices to ignore. Others must be handled
619 		 * elsewhere.
620 		 */
621 		"virtual-memory",
622 		"aliases",
623 		"memory",
624 		"openprom",
625 		"options",
626 		"packages",
627 		"chosen",
628 		NULL
629 	};
630 
631 	OF_getprop(findroot(), "name", platform_type, sizeof(platform_type));
632 	printf(": %s\n", platform_type);
633 
634 	/*
635 	 * Locate and configure the ``early'' devices.  These must be
636 	 * configured before we can do the rest.  For instance, the
637 	 * EEPROM contains the Ethernet address for the LANCE chip.
638 	 * If the device cannot be located or configured, panic.
639 	 */
640 
641 	node = findroot();
642 
643 	/* Establish the first component of the boot path */
644 	bootpath_store(1, bootpath);
645 
646 	/* first early device to be configured is the cpu */
647 	for (node = OF_child(node); node; node = OF_peer(node)) {
648 		if (OF_getprop(node, "device_type", buf, sizeof(buf)) <= 0)
649 			continue;
650 		if (strcmp(buf, "cpu") != 0)
651 			continue;
652 		bzero(&ma, sizeof(ma));
653 		ma.ma_bustag = &mainbus_space_tag;
654 		ma.ma_dmatag = &mainbus_dma_tag;
655 		ma.ma_node = node;
656 		ma.ma_name = "cpu";
657 		config_found(dev, &ma, mbprint);
658 		break;
659 	}
660 	if (node == 0)
661 		panic("None of the CPUs found");
662 
663 	node = findroot();	/* re-init root node */
664 
665 	/* Find the "options" node */
666 	node0 = OF_child(node);
667 	optionsnode = findnode(node0, "options");
668 	if (optionsnode == 0)
669 		panic("no options in OPENPROM");
670 
671 	/*
672 	 * Configure the devices, in PROM order.  Skip
673 	 * PROM entries that are not for devices, or which must be
674 	 * done before we get here.
675 	 */
676 	for (node = node0; node; node = OF_peer(node)) {
677 		int portid;
678 
679 		DPRINTF(ACDB_PROBE, ("Node: %x", node));
680 		if ((OF_getprop(node, "device_type", buf, sizeof(buf)) > 0) &&
681 		    strcmp(buf, "cpu") == 0)
682 			continue;
683 		OF_getprop(node, "name", buf, sizeof(buf));
684 		DPRINTF(ACDB_PROBE, (" name %s\n", buf));
685 		for (ssp = openboot_special; (sp = *ssp) != NULL; ssp++)
686 			if (strcmp(buf, sp) == 0)
687 				break;
688 		if (sp != NULL)
689 			continue; /* an "early" device already configured */
690 
691 		bzero(&ma, sizeof ma);
692 		ma.ma_bustag = &mainbus_space_tag;
693 		ma.ma_dmatag = &mainbus_dma_tag;
694 		ma.ma_name = buf;
695 		ma.ma_node = node;
696 		if (OF_getprop(node, "upa-portid", &portid, sizeof(portid)) !=
697 		    sizeof(portid))
698 			portid = -1;
699 		ma.ma_upaid = portid;
700 
701 		if (PROM_getprop(node, "reg", sizeof(*ma.ma_reg),
702 				 &ma.ma_nreg, (void**)&ma.ma_reg) != 0)
703 			continue;
704 #ifdef DEBUG
705 		if (autoconf_debug & ACDB_PROBE) {
706 			if (ma.ma_nreg)
707 				printf(" reg %08lx.%08lx\n",
708 					(long)ma.ma_reg->ur_paddr,
709 					(long)ma.ma_reg->ur_len);
710 			else
711 				printf(" no reg\n");
712 		}
713 #endif
714 		rv = PROM_getprop(node, "interrupts", sizeof(*ma.ma_interrupts),
715 			&ma.ma_ninterrupts, (void**)&ma.ma_interrupts);
716 		if (rv != 0 && rv != ENOENT) {
717 			free(ma.ma_reg, M_DEVBUF);
718 			continue;
719 		}
720 #ifdef DEBUG
721 		if (autoconf_debug & ACDB_PROBE) {
722 			if (ma.ma_interrupts)
723 				printf(" interrupts %08x\n", *ma.ma_interrupts);
724 			else
725 				printf(" no interrupts\n");
726 		}
727 #endif
728 		rv = PROM_getprop(node, "address", sizeof(*ma.ma_address),
729 			&ma.ma_naddress, (void**)&ma.ma_address);
730 		if (rv != 0 && rv != ENOENT) {
731 			free(ma.ma_reg, M_DEVBUF);
732 			if (ma.ma_ninterrupts)
733 				free(ma.ma_interrupts, M_DEVBUF);
734 			continue;
735 		}
736 #ifdef DEBUG
737 		if (autoconf_debug & ACDB_PROBE) {
738 			if (ma.ma_naddress)
739 				printf(" address %08x\n", *ma.ma_address);
740 			else
741 				printf(" no address\n");
742 		}
743 #endif
744 		(void) config_found(dev, (void *)&ma, mbprint);
745 		free(ma.ma_reg, M_DEVBUF);
746 		if (ma.ma_ninterrupts)
747 			free(ma.ma_interrupts, M_DEVBUF);
748 		if (ma.ma_naddress)
749 			free(ma.ma_address, M_DEVBUF);
750 	}
751 	/* Try to attach PROM console */
752 	bzero(&ma, sizeof ma);
753 	ma.ma_name = "pcons";
754 	(void) config_found(dev, (void *)&ma, mbprint);
755 }
756 
757 CFATTACH_DECL(mainbus, sizeof(struct device),
758     mainbus_match, mainbus_attach, NULL, NULL);
759 
760 int
761 PROM_getprop(node, name, size, nitem, bufp)
762 	int	node;
763 	char	*name;
764 	size_t	size;
765 	int	*nitem;
766 	void	**bufp;
767 {
768 	void	*buf;
769 	long	len;
770 
771 	*nitem = 0;
772 	len = PROM_getproplen(node, name);
773 	if (len <= 0)
774 		return (ENOENT);
775 
776 	if ((len % size) != 0)
777 		return (EINVAL);
778 
779 	buf = *bufp;
780 	if (buf == NULL) {
781 		/* No storage provided, so we allocate some */
782 		buf = malloc(len, M_DEVBUF, M_NOWAIT);
783 		if (buf == NULL)
784 			return (ENOMEM);
785 	}
786 
787 	OF_getprop(node, name, buf, len);
788 	*bufp = buf;
789 	*nitem = len / size;
790 	return (0);
791 }
792 
793 
794 /*
795  * Internal form of proplen().  Returns the property length.
796  */
797 long
798 PROM_getproplen(node, name)
799 	int node;
800 	char *name;
801 {
802 	return (OF_getproplen(node, name));
803 }
804 
805 /*
806  * Return a string property.  There is a (small) limit on the length;
807  * the string is fetched into a static buffer which is overwritten on
808  * subsequent calls.
809  */
810 char *
811 PROM_getpropstring(node, name)
812 	int node;
813 	char *name;
814 {
815 	static char stringbuf[32];
816 
817 	return (PROM_getpropstringA(node, name, stringbuf));
818 }
819 
820 /* Alternative PROM_getpropstring(), where caller provides the buffer */
821 char *
822 PROM_getpropstringA(node, name, buffer)
823 	int node;
824 	char *name;
825 	char *buffer;
826 {
827 	int blen;
828 
829 	if (PROM_getprop(node, name, 1, &blen, (void **)&buffer) != 0)
830 		blen = 0;
831 
832 	buffer[blen] = '\0';	/* usually unnecessary */
833 	return (buffer);
834 }
835 
836 /*
837  * Fetch an integer (or pointer) property.
838  * The return value is the property, or the default if there was none.
839  */
840 int
841 PROM_getpropint(node, name, deflt)
842 	int node;
843 	char *name;
844 	int deflt;
845 {
846 	int intbuf;
847 
848 
849 
850 	if (OF_getprop(node, name, &intbuf, sizeof(intbuf)) != sizeof(intbuf))
851 		return (deflt);
852 
853 	return (intbuf);
854 }
855 
856 /*
857  * OPENPROM functions.  These are here mainly to hide the OPENPROM interface
858  * from the rest of the kernel.
859  */
860 int
861 firstchild(node)
862 	int node;
863 {
864 
865 	return OF_child(node);
866 }
867 
868 int
869 nextsibling(node)
870 	int node;
871 {
872 
873 	return OF_peer(node);
874 }
875 
876 /* The following are used primarily in consinit() */
877 
878 int
879 node_has_property(node, prop)	/* returns 1 if node has given property */
880 	register int node;
881 	register const char *prop;
882 {
883 	return (OF_getproplen(node, (caddr_t)prop) != -1);
884 }
885 
886 #ifdef RASTERCONSOLE
887 /*
888  * Try to figure out where the PROM stores the cursor row & column
889  * variables.  Returns nonzero on error.
890  */
891 int
892 romgetcursoraddr(rowp, colp)
893 	register int **rowp, **colp;
894 {
895 	cell_t row = NULL, col = NULL;
896 
897 	OF_interpret("stdout @ is my-self addr line# addr column# ", 0, 2,
898 		&col, &row);
899 	/*
900 	 * We are running on a 64-bit machine, so these things point to
901 	 * 64-bit values.  To convert them to pointers to integers, add
902 	 * 4 to the address.
903 	 */
904 	*rowp = (int *)(row+4);
905 	*colp = (int *)(col+4);
906 	return (row == NULL || col == NULL);
907 }
908 #endif /* RASTERCONSOLE */
909 
910 void
911 callrom()
912 {
913 
914 	__asm __volatile("wrpr	%%g0, 0, %%tl" : );
915 	OF_enter();
916 }
917 
918 /*
919  * find a device matching "name" and unit number
920  */
921 struct device *
922 getdevunit(name, unit)
923 	char *name;
924 	int unit;
925 {
926 	struct device *dev = alldevs.tqh_first;
927 	char num[10], fullname[16];
928 	int lunit;
929 
930 	/* compute length of name and decimal expansion of unit number */
931 	sprintf(num, "%d", unit);
932 	lunit = strlen(num);
933 	if (strlen(name) + lunit >= sizeof(fullname) - 1)
934 		panic("config_attach: device name too long");
935 
936 	strcpy(fullname, name);
937 	strcat(fullname, num);
938 
939 	while (strcmp(dev->dv_xname, fullname) != 0) {
940 		if ((dev = dev->dv_list.tqe_next) == NULL)
941 			return NULL;
942 	}
943 	return dev;
944 }
945 
946 
947 /*
948  * Device registration used to determine the boot device.
949  *
950  * Copied from the sparc port.
951  */
952 #include <dev/scsipi/scsi_all.h>
953 #include <dev/scsipi/scsipi_all.h>
954 #include <dev/scsipi/scsiconf.h>
955 
956 #define BUSCLASS_NONE		0
957 #define BUSCLASS_MAINBUS	1
958 #define BUSCLASS_IOMMU		2
959 #define BUSCLASS_OBIO		3
960 #define BUSCLASS_SBUS		4
961 #define BUSCLASS_VME		5
962 #define BUSCLASS_PCI		6
963 #define BUSCLASS_XDC		7
964 #define BUSCLASS_XYC		8
965 #define BUSCLASS_FDC		9
966 
967 static int bus_class __P((struct device *));
968 static int dev_compatible __P((struct device *, void *, char *));
969 static int instance_match __P((struct device *, void *, struct bootpath *));
970 static void nail_bootdev __P((struct device *, struct bootpath *));
971 
972 static struct {
973 	char	*name;
974 	int	class;
975 } bus_class_tab[] = {
976 	{ "mainbus",	BUSCLASS_MAINBUS },
977 	{ "upa",	BUSCLASS_MAINBUS },
978 	{ "psycho",	BUSCLASS_MAINBUS },
979 	{ "obio",	BUSCLASS_OBIO },
980 	{ "iommu",	BUSCLASS_IOMMU },
981 	{ "sbus",	BUSCLASS_SBUS },
982 	{ "xbox",	BUSCLASS_SBUS },
983 	{ "esp",	BUSCLASS_SBUS },
984 	{ "dma",	BUSCLASS_SBUS },
985 	{ "espdma",	BUSCLASS_SBUS },
986 	{ "ledma",	BUSCLASS_SBUS },
987 	{ "simba",	BUSCLASS_PCI },
988 	{ "ppb",	BUSCLASS_PCI },
989 	{ "pciide",	BUSCLASS_PCI },
990 	{ "siop",	BUSCLASS_PCI },
991 	{ "pci",	BUSCLASS_PCI },
992 	{ "fdc",	BUSCLASS_FDC },
993 };
994 
995 /*
996  * A list of driver names may have differently named PROM nodes.
997  */
998 static struct {
999 	char	*name;
1000 	char	*compat[6];
1001 } dev_compat_tab[] = {
1002 	{ "dma",	{ "espdma", NULL }},
1003 	{ "isp",	{ "QLGC,isp", "PTI,isp", "ptiisp", "scsi", NULL }},
1004 	{ "fdc",	{ "SUNW,fdtwo",	NULL }},
1005 	{ "psycho",	{ "pci", NULL }},
1006 	{ "wd",		{ "disk", "ide-disk", NULL }},
1007 	{ "sd",		{ "disk", NULL }},
1008 	{ "hme",	{ "SUNW,hme", "network", NULL }},
1009 	{ "esp",	{ "SUNW,fas", "fas", NULL }},
1010 	{ "siop",	{ "glm",  "SUNW,glm", NULL }},
1011 	{ NULL,		{ NULL }},
1012 };
1013 
1014 int
1015 dev_compatible(dev, aux, bpname)
1016 	struct device *dev;
1017 	void *aux;
1018 	char *bpname;
1019 {
1020 	int i, j;
1021 
1022 	/*
1023 	 * Step 1:
1024 	 *
1025 	 * If this is a PCI device, find it's device class and try that.
1026 	 */
1027 	if ((bus_class(dev->dv_parent)) == BUSCLASS_PCI) {
1028 		struct pci_attach_args *pa = aux;
1029 
1030 		DPRINTF(ACDB_BOOTDEV,
1031 			("\n%s: dev_compatible: checking PCI class %x\n",
1032 				dev->dv_xname, pa->pa_class));
1033 
1034 		switch (PCI_CLASS(pa->pa_class)) {
1035 			/*
1036 			 * We can only really have pci-pci bridges,
1037 			 * disk controllers, or NICs on the bootpath.
1038 			 */
1039 		case PCI_CLASS_BRIDGE:
1040 			if (PCI_SUBCLASS(pa->pa_class) !=
1041 				PCI_SUBCLASS_BRIDGE_PCI)
1042 				break;
1043 			DPRINTF(ACDB_BOOTDEV,
1044 				("\n%s: dev_compatible: comparing %s with %s\n",
1045 					dev->dv_xname, bpname, "pci"));
1046 			if (strcmp(bpname, "pci") == 0)
1047 				return (0);
1048 			break;
1049 		case PCI_CLASS_MASS_STORAGE:
1050 			if (PCI_SUBCLASS(pa->pa_class) ==
1051 				PCI_SUBCLASS_MASS_STORAGE_IDE) {
1052 				DPRINTF(ACDB_BOOTDEV,
1053 					("\n%s: dev_compatible: "
1054 						"comparing %s with %s\n",
1055 						dev->dv_xname, bpname, "ide"));
1056 				if (strcmp(bpname, "ide") == 0)
1057 					return (0);
1058 			}
1059 			if (PCI_SUBCLASS(pa->pa_class) ==
1060 				PCI_SUBCLASS_MASS_STORAGE_SCSI) {
1061 				DPRINTF(ACDB_BOOTDEV,
1062 					("\n%s: dev_compatible: "
1063 						"comparing %s with %s\n",
1064 						dev->dv_xname, bpname, "scsi"));
1065 				if (strcmp(bpname, "scsi") == 0)
1066 					return (0);
1067 			}
1068 			break;
1069 		case PCI_CLASS_NETWORK:
1070 			DPRINTF(ACDB_BOOTDEV,
1071 				("\n%s: dev_compatible: comparing %s with %s\n",
1072 					dev->dv_xname, bpname, "network"));
1073 			if (strcmp(bpname, "network") == 0)
1074 				return (0);
1075 			break;
1076 		default:
1077 			break;
1078 		}
1079 	}
1080 
1081 	/*
1082 	 * Step 2:
1083 	 *
1084 	 * Look through the list of equivalent names and see if any of them
1085 	 * match.  This is a nasty O(n^2) operation.
1086 	 */
1087 	for (i = 0; dev_compat_tab[i].name != NULL; i++) {
1088 		if (strcmp(dev->dv_cfdata->cf_name,
1089 			dev_compat_tab[i].name) == 0) {
1090 			DPRINTF(ACDB_BOOTDEV,
1091 				("\n%s: dev_compatible: translating %s\n",
1092 					dev->dv_xname, dev_compat_tab[i].name));
1093 			for (j = 0; dev_compat_tab[i].compat[j] != NULL; j++) {
1094 				DPRINTF(ACDB_BOOTDEV,
1095 					("\n%s: dev_compatible: "
1096 						"comparing %s to %s\n",
1097 						dev->dv_xname, bpname,
1098 						dev_compat_tab[i].compat[j]));
1099 				if (strcmp(bpname,
1100 					dev_compat_tab[i].compat[j]) == 0)
1101 					return (0);
1102 			}
1103 		}
1104 	}
1105 	DPRINTF(ACDB_BOOTDEV,
1106 		("\n%s: dev_compatible: no match\n",
1107 			dev->dv_xname));
1108 	return (1);
1109 }
1110 
1111 static int
1112 bus_class(dev)
1113 	struct device *dev;
1114 {
1115 	const char *name;
1116 	int i, class;
1117 
1118 	class = BUSCLASS_NONE;
1119 	if (dev == NULL)
1120 		return (class);
1121 
1122 	name = dev->dv_cfdata->cf_name;
1123 	for (i = sizeof(bus_class_tab)/sizeof(bus_class_tab[0]); i-- > 0;) {
1124 		if (strcmp(name, bus_class_tab[i].name) == 0) {
1125 			class = bus_class_tab[i].class;
1126 			break;
1127 		}
1128 	}
1129 
1130 	return (class);
1131 }
1132 
1133 int
1134 instance_match(dev, aux, bp)
1135 	struct device *dev;
1136 	void *aux;
1137 	struct bootpath *bp;
1138 {
1139 	struct mainbus_attach_args *ma;
1140 	struct sbus_attach_args *sa;
1141 	struct pci_attach_args *pa;
1142 
1143 	/*
1144 	 * Several devices are represented on bootpaths in one of
1145 	 * two formats, e.g.:
1146 	 *	(1) ../sbus@.../esp@<offset>,<slot>/sd@..  (PROM v3 style)
1147 	 *	(2) /sbus0/esp0/sd@..                      (PROM v2 style)
1148 	 *
1149 	 * hence we fall back on a `unit number' check if the bus-specific
1150 	 * instance parameter check does not produce a match.
1151 	 *
1152 	 * For PCI devices, we get:
1153 	 *	../pci@../xxx@<dev>,<fn>/...
1154 	 */
1155 
1156 	/*
1157 	 * Rank parent bus so we know which locators to check.
1158 	 */
1159 	switch (bus_class(dev->dv_parent)) {
1160 	case BUSCLASS_MAINBUS:
1161 		ma = aux;
1162 		DPRINTF(ACDB_BOOTDEV,
1163 		    ("instance_match: mainbus device, want %#x have %#x\n",
1164 		    ma->ma_upaid, bp->val[0]));
1165 		if (bp->val[0] == ma->ma_upaid)
1166 			return (1);
1167 		break;
1168 	case BUSCLASS_SBUS:
1169 		sa = aux;
1170 		DPRINTF(ACDB_BOOTDEV, ("instance_match: sbus device, "
1171 		    "want slot %#x offset %#x have slot %#x offset %#x\n",
1172 		     bp->val[0], bp->val[1], sa->sa_slot, sa->sa_offset));
1173 		if (bp->val[0] == sa->sa_slot && bp->val[1] == sa->sa_offset)
1174 			return (1);
1175 		break;
1176 	case BUSCLASS_PCI:
1177 		pa = aux;
1178 		DPRINTF(ACDB_BOOTDEV, ("instance_match: pci device, "
1179 		    "want dev %#x fn %#x have dev %#x fn %#x\n",
1180 		     bp->val[0], bp->val[1], pa->pa_device, pa->pa_function));
1181 		if (bp->val[0] == pa->pa_device &&
1182 		    bp->val[1] == pa->pa_function)
1183 			return (1);
1184 		break;
1185 	default:
1186 		break;
1187 	}
1188 
1189 	if (bp->val[0] == -1 && bp->val[1] == dev->dv_unit)
1190 		return (1);
1191 
1192 	return (0);
1193 }
1194 
1195 struct device *booted_device;
1196 
1197 void
1198 nail_bootdev(dev, bp)
1199 	struct device *dev;
1200 	struct bootpath *bp;
1201 {
1202 
1203 	if (bp->dev != NULL)
1204 		panic("device_register: already got a boot device: %s",
1205 			bp->dev->dv_xname);
1206 
1207 	/*
1208 	 * Mark this bootpath component by linking it to the matched
1209 	 * device. We pick up the device pointer in cpu_rootconf().
1210 	 */
1211 	booted_device = bp->dev = dev;
1212 
1213 	/*
1214 	 * Then clear the current bootpath component, so we don't spuriously
1215 	 * match similar instances on other busses, e.g. a disk on
1216 	 * another SCSI bus with the same target.
1217 	 */
1218 	bootpath_store(1, NULL);
1219 }
1220 
1221 void
1222 device_register(dev, aux)
1223 	struct device *dev;
1224 	void *aux;
1225 {
1226 	struct bootpath *bp = bootpath_store(0, NULL);
1227 	const char *dvname;
1228 	char *bpname;
1229 
1230 	/*
1231 	 * If device name does not match current bootpath component
1232 	 * then there's nothing interesting to consider.
1233 	 */
1234 	if (bp == NULL)
1235 		return;
1236 
1237 	/*
1238 	 * Translate device name to device class name in case the prom uses
1239 	 * that.
1240 	 */
1241 	bpname = bp->name;
1242 	dvname = dev->dv_cfdata->cf_name;
1243 	DPRINTF(ACDB_BOOTDEV,
1244 	    ("\n%s: device_register: dvname %s(%s) bpname %s\n",
1245 	    dev->dv_xname, dvname, dev->dv_xname, bpname));
1246 
1247 	/* First, match by name */
1248 	if (strcmp(dvname, bpname) != 0) {
1249 		if (dev_compatible(dev, aux, bpname) != 0)
1250 			return;
1251 	}
1252 
1253 	if (bus_class(dev) != BUSCLASS_NONE) {
1254 		/*
1255 		 * A bus or controller device of sorts. Check instance
1256 		 * parameters and advance boot path on match.
1257 		 */
1258 		if (instance_match(dev, aux, bp) != 0) {
1259 			bp->dev = dev;
1260 			bootpath_store(1, bp + 1);
1261 			DPRINTF(ACDB_BOOTDEV, ("\t-- found bus controller %s\n",
1262 			    dev->dv_xname));
1263 			return;
1264 		}
1265 	} else if (strcmp(dvname, "le") == 0 ||
1266 		   strcmp(dvname, "hme") == 0) {
1267 		/*
1268 		 * ethernet devices.
1269 		 */
1270 		if (instance_match(dev, aux, bp) != 0) {
1271 			nail_bootdev(dev, bp);
1272 			DPRINTF(ACDB_BOOTDEV, ("\t-- found ethernet controller %s\n",
1273 			    dev->dv_xname));
1274 			return;
1275 		}
1276 	} else if (strcmp(dvname, "sd") == 0 || strcmp(dvname, "cd") == 0) {
1277 		/*
1278 		 * A SCSI disk or cd; retrieve target/lun information
1279 		 * from parent and match with current bootpath component.
1280 		 * Note that we also have look back past the `scsibus'
1281 		 * device to determine whether this target is on the
1282 		 * correct controller in our boot path.
1283 		 */
1284 		struct scsipibus_attach_args *sa = aux;
1285 		struct scsipi_periph *periph = sa->sa_periph;
1286 		struct scsibus_softc *sbsc =
1287 			(struct scsibus_softc *)dev->dv_parent;
1288 		u_int target = bp->val[0];
1289 		u_int lun = bp->val[1];
1290 
1291 		/* Check the controller that this scsibus is on */
1292 		if ((bp-1)->dev != sbsc->sc_dev.dv_parent)
1293 			return;
1294 
1295 		/*
1296 		 * Bounds check: we know the target and lun widths.
1297 		 */
1298 		if (target >= periph->periph_channel->chan_ntargets ||
1299 		    lun >= periph->periph_channel->chan_nluns) {
1300 			printf("SCSI disk bootpath component not accepted: "
1301 			       "target %u; lun %u\n", target, lun);
1302 			return;
1303 		}
1304 
1305 		if (periph->periph_target == target &&
1306 		    periph->periph_lun == lun) {
1307 			nail_bootdev(dev, bp);
1308 			DPRINTF(ACDB_BOOTDEV, ("\t-- found [cs]d disk %s\n",
1309 			    dev->dv_xname));
1310 			return;
1311 		}
1312 	} else if (strcmp("wd", dvname) == 0) {
1313 		/* IDE disks. */
1314 		struct ata_device *adev = aux;
1315 
1316 		/*
1317 		 * The PROM gives you names like "disk@1,0", where the first value
1318 		 * appears to be both the drive & channel combined (channel * 2 +
1319 		 * drive), and the second value we don't use (what is it anyway?)
1320 		 */
1321 		if ((adev->adev_channel * 2) + adev->adev_drv_data->drive ==
1322 		    bp->val[0]) {
1323 			nail_bootdev(dev, bp);
1324 			DPRINTF(ACDB_BOOTDEV, ("\t-- found wd disk %s\n",
1325 			    dev->dv_xname));
1326 			return;
1327 		}
1328 	} else {
1329 		/*
1330 		 * Generic match procedure.
1331 		 */
1332 		if (instance_match(dev, aux, bp) != 0) {
1333 			nail_bootdev(dev, bp);
1334 			DPRINTF(ACDB_BOOTDEV, ("\t-- found generic device %s\n",
1335 			    dev->dv_xname));
1336 			return;
1337 		}
1338 	}
1339 }
1340