Home | History | Annotate | Line # | Download | only in sparc64
      1 /*	$NetBSD: autoconf.c,v 1.245 2025/09/17 14:20:48 thorpej 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 <sys/cdefs.h>
     51 __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.245 2025/09/17 14:20:48 thorpej Exp $");
     52 
     53 #include "opt_ddb.h"
     54 #include "opt_kgdb.h"
     55 #include "opt_modular.h"
     56 #include "opt_multiprocessor.h"
     57 
     58 #include <sys/param.h>
     59 #include <sys/kernel.h>
     60 #include <sys/systm.h>
     61 #include <sys/buf.h>
     62 #include <sys/disklabel.h>
     63 #include <sys/device.h>
     64 #include <sys/disk.h>
     65 #include <sys/conf.h>
     66 #include <sys/reboot.h>
     67 #include <sys/socket.h>
     68 #include <sys/vnode.h>
     69 #include <sys/fcntl.h>
     70 #include <sys/queue.h>
     71 #include <sys/msgbuf.h>
     72 #include <sys/boot_flag.h>
     73 #include <sys/ksyms.h>
     74 #include <sys/kauth.h>
     75 #include <sys/userconf.h>
     76 #include <prop/proplib.h>
     77 
     78 #include <net/if.h>
     79 #include <net/if_ether.h>
     80 
     81 #include <dev/cons.h>
     82 #include <sparc64/dev/cons.h>
     83 
     84 #include <uvm/uvm_extern.h>
     85 
     86 #include <sys/bus.h>
     87 #include <machine/autoconf.h>
     88 #include <machine/openfirm.h>
     89 #include <machine/sparc64.h>
     90 #include <machine/cpu.h>
     91 #include <machine/pmap.h>
     92 #include <machine/bootinfo.h>
     93 #include <sparc64/sparc64/cache.h>
     94 #include <sparc64/sparc64/ofw_patch.h>
     95 #include <sparc64/sparc64/timerreg.h>
     96 #include <sparc64/dev/cbusvar.h>
     97 
     98 #include <dev/ata/atavar.h>
     99 #include <dev/pci/pcivar.h>
    100 #include <dev/ebus/ebusvar.h>
    101 #include <dev/sbus/sbusvar.h>
    102 #include <dev/i2c/i2cvar.h>
    103 
    104 #ifdef DDB
    105 #include <machine/db_machdep.h>
    106 #include <ddb/db_sym.h>
    107 #include <ddb/db_extern.h>
    108 #endif
    109 
    110 #ifdef RASTERCONSOLE
    111 #error options RASTERCONSOLE is obsolete for sparc64 - remove it from your config file
    112 #endif
    113 
    114 #include <dev/wsfb/genfbvar.h>
    115 
    116 #include "ksyms.h"
    117 
    118 int autoconf_debug = 0x0;
    119 
    120 struct evcnt intr_evcnts[] = {
    121 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "spur"),
    122 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev1"),
    123 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev2"),
    124 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev3"),
    125 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev4"),
    126 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev5"),
    127 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev6"),
    128 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev7"),
    129 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev8"),
    130 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev9"),
    131 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "clock"),
    132 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev11"),
    133 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev12"),
    134 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "lev13"),
    135 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr", "prof"),
    136 	EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "intr",  "lev15")
    137 };
    138 
    139 void *bootinfo = 0;
    140 
    141 #ifdef KGDB
    142 int kgdb_break_at_attach;
    143 #endif
    144 
    145 #define	OFPATHLEN	128
    146 
    147 char	machine_banner[100];
    148 char	machine_model[100];
    149 char	ofbootpath[OFPATHLEN], *ofboottarget, *ofbootpartition;
    150 char	ofbootargs[OFPATHLEN], *ofbootfile, *ofbootflags;
    151 int	ofbootpackage;
    152 
    153 static	int mbprint(void *, const char *);
    154 int	mainbus_match(device_t, cfdata_t, void *);
    155 static	void mainbus_attach(device_t, device_t, void *);
    156 static  void get_ncpus(void);
    157 static	void get_bootpath_from_prom(void);
    158 
    159 /*
    160  * Kernel 4MB mappings.
    161  */
    162 struct tlb_entry *kernel_tlbs;
    163 int kernel_dtlb_slots;
    164 int kernel_itlb_slots;
    165 
    166 /* Global interrupt mappings for all device types.  Match against the OBP
    167  * 'device_type' property.  Note, that the resulting PIL must be higher than
    168  * the highest soft interrupt level (IPL_SOFTSERIAL).
    169  */
    170 struct intrmap intrmap[] = {
    171 	{ "block",	PIL_FD },	/* Floppy disk */
    172 	{ "serial",	PIL_SER },	/* zs */
    173 	{ "scsi",	PIL_BIO },
    174 	{ "scsi-2",	PIL_BIO },
    175 	{ "network",	PIL_NET },
    176 	{ "display",	PIL_VIDEO },
    177 	{ "audio",	PIL_AUD },
    178 	{ "ide",	PIL_BIO },
    179 	{ "socal",	PIL_BIO },
    180 /* The following devices don't have device types: */
    181 	{ "SUNW,CS4231",	PIL_AUD },
    182 	{ "SUNW,bpp",	PIL_BIO },
    183 	{ NULL,		0 }
    184 };
    185 
    186 #ifdef SUN4V
    187 void	sun4v_soft_state_init(void);
    188 void	sun4v_set_soft_state(int, const char *);
    189 
    190 #define __align32 __attribute__((__aligned__(32)))
    191 char sun4v_soft_state_booting[] __align32 = "NetBSD booting";
    192 char sun4v_soft_state_running[] __align32 = "NetBSD running";
    193 
    194 void	sun4v_interrupt_init(void);
    195 #if 0
    196 XXX notyet
    197 void	sun4v_sdio_init(void);
    198 #endif
    199 #endif
    200 
    201 int console_node, console_instance;
    202 struct genfb_colormap_callback gfb_cb;
    203 static void of_set_palette(void *, int, int, int, int);
    204 static void copyprops(device_t, int, prop_dictionary_t, int);
    205 
    206 static void
    207 get_ncpus(void)
    208 {
    209 #ifdef MULTIPROCESSOR
    210 	int node, l;
    211 	char sbuf[32];
    212 
    213 	node = findroot();
    214 
    215 	sparc_ncpus = 0;
    216 	for (node = OF_child(node); node; node = OF_peer(node)) {
    217 		if (OF_getprop(node, "device_type", sbuf, sizeof(sbuf)) <= 0)
    218 			continue;
    219 		if (strcmp(sbuf, "cpu") != 0)
    220 			continue;
    221 		sparc_ncpus++;
    222 		l = prom_getpropint(node, "dcache-line-size", 0);
    223 		if (l > dcache_line_size)
    224 			dcache_line_size = l;
    225 		l = prom_getpropint(node, "icache-line-size", 0);
    226 		if (l > icache_line_size)
    227 			icache_line_size = l;
    228 	}
    229 #else
    230 	/* #define sparc_ncpus 1 */
    231 	icache_line_size = dcache_line_size = 8; /* will be fixed later */
    232 #endif
    233 }
    234 
    235 /*
    236  * lookup_bootinfo:
    237  * Look up information in bootinfo of boot loader.
    238  */
    239 void *
    240 lookup_bootinfo(int type)
    241 {
    242 	struct btinfo_common *bt;
    243 	char *help = bootinfo;
    244 
    245 	/* Check for a bootinfo record first. */
    246 	if (help == NULL)
    247 		return (NULL);
    248 
    249 	do {
    250 		bt = (struct btinfo_common *)help;
    251 		if (bt->type == type)
    252 			return ((void *)help);
    253 		help += bt->next;
    254 	} while (bt->next != 0 &&
    255 		(size_t)help < (size_t)bootinfo + BOOTINFO_SIZE);
    256 
    257 	return (NULL);
    258 }
    259 
    260 /*
    261  * locore.s code calls bootstrap() just before calling main().
    262  *
    263  * What we try to do is as follows:
    264  * - Initialize PROM and the console
    265  * - Read in part of information provided by a bootloader and find out
    266  *   kernel load and end addresses
    267  * - Initialize ksyms
    268  * - Find out number of active CPUs
    269  * - Finalize the bootstrap by calling pmap_bootstrap()
    270  *
    271  * We will try to run out of the prom until we get out of pmap_bootstrap().
    272  */
    273 void
    274 bootstrap(void *o0, void *bootargs, void *bootsize, void *o3, void *ofw)
    275 {
    276 	void *bi;
    277 	long bmagic;
    278 	char buf[32];
    279 
    280 #if NKSYMS || defined(DDB) || defined(MODULAR)
    281 	struct btinfo_symtab *bi_sym;
    282 #endif
    283 	struct btinfo_count *bi_count;
    284 	struct btinfo_kernend *bi_kend;
    285 	struct btinfo_tlb *bi_tlb;
    286 	struct btinfo_boothowto *bi_howto;
    287 
    288 	extern void *romtba;
    289 	extern void* get_romtba(void);
    290 	extern void  OF_val2sym32(void *);
    291 	extern void OF_sym2val32(void *);
    292 	extern struct consdev consdev_prom;
    293 
    294 	/* Save OpenFirmware entry point */
    295 	romp   = ofw;
    296 	romtba = get_romtba();
    297 
    298 	prom_init();
    299 	console_instance = promops.po_stdout;
    300 	console_node = OF_instance_to_package(promops.po_stdout);
    301 
    302 	/* Initialize the PROM console so printf will not panic */
    303 	cn_tab = &consdev_prom;
    304 	(*cn_tab->cn_init)(cn_tab);
    305 
    306 	DPRINTF(ACDB_BOOTARGS,
    307 		("sparc64_init(%p, %p, %p, %p, %p)\n", o0, bootargs, bootsize,
    308 			o3, ofw));
    309 
    310 	/* Extract bootinfo pointer */
    311 	if ((long)bootsize >= (4 * sizeof(uint64_t))) {
    312 		/* Loaded by 64-bit bootloader */
    313 		bi = (void*)(u_long)(((uint64_t*)bootargs)[3]);
    314 		bmagic = (long)(((uint64_t*)bootargs)[0]);
    315 	} else if ((long)bootsize >= (4 * sizeof(uint32_t))) {
    316 		/* Loaded by 32-bit bootloader */
    317 		bi = (void*)(u_long)(((uint32_t*)bootargs)[3]);
    318 		bmagic = (long)(((uint32_t*)bootargs)[0]);
    319 	} else {
    320 		printf("Bad bootinfo size.\n");
    321 die_old_boot_loader:
    322 		printf("This kernel requires NetBSD boot loader version 1.9 "
    323 		       "or newer\n");
    324 		panic("sparc64_init.");
    325 	}
    326 
    327 	DPRINTF(ACDB_BOOTARGS,
    328 		("sparc64_init: bmagic=%lx, bi=%p\n", bmagic, bi));
    329 
    330 	/* Read in the information provided by NetBSD boot loader */
    331 	if (SPARC_MACHINE_OPENFIRMWARE != bmagic) {
    332 		printf("No bootinfo information.\n");
    333 		goto die_old_boot_loader;
    334 	}
    335 
    336 	bootinfo = (void*)(u_long)((uint64_t*)bi)[1];
    337 	LOOKUP_BOOTINFO(bi_kend, BTINFO_KERNEND);
    338 
    339 	if (bi_kend->addr == (vaddr_t)0) {
    340 		panic("Kernel end address is not found in bootinfo.\n");
    341 	}
    342 
    343 #if NKSYMS || defined(DDB) || defined(MODULAR)
    344 	LOOKUP_BOOTINFO(bi_sym, BTINFO_SYMTAB);
    345 	ksyms_addsyms_elf(bi_sym->nsym, (int *)(u_long)bi_sym->ssym,
    346 			(int *)(u_long)bi_sym->esym);
    347 #ifdef DDB
    348 #ifdef __arch64__
    349 	/* This can only be installed on an 64-bit system cause otherwise our stack is screwed */
    350 	OF_set_symbol_lookup(OF_sym2val, OF_val2sym);
    351 #else
    352 	OF_set_symbol_lookup(OF_sym2val32, OF_val2sym32);
    353 #endif
    354 #endif
    355 #endif
    356 	if (OF_getprop(findroot(), "compatible", buf, sizeof(buf)) > 0) {
    357 		if (strcmp(buf, "sun4us") == 0)
    358 			setcputyp(CPU_SUN4US);
    359 		else if (strcmp(buf, "sun4v") == 0)
    360 			setcputyp(CPU_SUN4V);
    361 	}
    362 
    363 	bi_howto = lookup_bootinfo(BTINFO_BOOTHOWTO);
    364 	if (bi_howto)
    365 		boothowto = bi_howto->boothowto;
    366 
    367 	LOOKUP_BOOTINFO(bi_count, BTINFO_DTLB_SLOTS);
    368 	kernel_dtlb_slots = bi_count->count;
    369 	kernel_itlb_slots = kernel_dtlb_slots-1;
    370 	bi_count = lookup_bootinfo(BTINFO_ITLB_SLOTS);
    371 	if (bi_count)
    372 		kernel_itlb_slots = bi_count->count;
    373 	LOOKUP_BOOTINFO(bi_tlb, BTINFO_DTLB);
    374 	kernel_tlbs = &bi_tlb->tlb[0];
    375 
    376 	get_ncpus();
    377 	pmap_bootstrap(KERNBASE, bi_kend->addr);
    378 
    379 #ifdef SUN4V
    380 	if (CPU_ISSUN4V) {
    381 		sun4v_soft_state_init();
    382 		sun4v_set_soft_state(SIS_TRANSITION, sun4v_soft_state_booting);
    383 		sun4v_interrupt_init();
    384 #if 0
    385 XXX notyet
    386 		sun4v_sdio_init();
    387 #endif
    388 	}
    389 #endif
    390 }
    391 
    392 /*
    393  * get_bootpath_from_prom()
    394  * fetch the OF settings to identify our boot device during autoconfiguration
    395  */
    396 
    397 static void
    398 get_bootpath_from_prom(void)
    399 {
    400 	struct btinfo_bootdev *bdev = NULL;
    401 	char sbuf[OFPATHLEN], *cp;
    402 	int chosen;
    403 
    404 	/*
    405 	 * Grab boot path from PROM
    406 	 */
    407 	if ((chosen = OF_finddevice("/chosen")) == -1)
    408 		return;
    409 
    410 	bdev = lookup_bootinfo(BTINFO_BOOTDEV);
    411 	if (bdev != NULL) {
    412 		strcpy(ofbootpath, bdev->name);
    413 	} else {
    414 		if (OF_getprop(chosen, "bootpath", sbuf, sizeof(sbuf)) < 0)
    415 			return;
    416 		strcpy(ofbootpath, sbuf);
    417 	}
    418 	DPRINTF(ACDB_BOOTDEV, ("bootpath: %s\n", ofbootpath));
    419 	ofbootpackage = prom_finddevice(ofbootpath);
    420 
    421 	/*
    422 	 * Strip partition or boot protocol
    423 	 */
    424 	cp = strrchr(ofbootpath, ':');
    425 	if (cp) {
    426 		*cp = '\0';
    427 		ofbootpartition = cp+1;
    428 	}
    429 	cp = strrchr(ofbootpath, '@');
    430 	if (cp) {
    431 		for (; cp != ofbootpath; cp--) {
    432 			if (*cp == '/') {
    433 				ofboottarget = cp+1;
    434 				break;
    435 			}
    436 		}
    437 	}
    438 
    439 	DPRINTF(ACDB_BOOTDEV, ("bootpath phandle: 0x%x\n", ofbootpackage));
    440 	DPRINTF(ACDB_BOOTDEV, ("boot target: %s\n",
    441 	    ofboottarget ? ofboottarget : "<none>"));
    442 	DPRINTF(ACDB_BOOTDEV, ("boot partition: %s\n",
    443 	    ofbootpartition ? ofbootpartition : "<none>"));
    444 
    445 	/* Setup pointer to boot flags */
    446 	if (OF_getprop(chosen, "bootargs", sbuf, sizeof(sbuf)) == -1)
    447 		return;
    448 	strcpy(ofbootargs, sbuf);
    449 
    450 	cp = ofbootargs;
    451 
    452 	/* Find start of boot flags */
    453 	while (*cp) {
    454 		while(*cp == ' ' || *cp == '\t') cp++;
    455 		if (*cp == '-' || *cp == '\0')
    456 			break;
    457 		while(*cp != ' ' && *cp != '\t' && *cp != '\0') cp++;
    458 		if (*cp != '\0')
    459 			*cp++ = '\0';
    460 	}
    461 	if (cp != ofbootargs)
    462 		ofbootfile = ofbootargs;
    463 	ofbootflags = cp;
    464 	if (*cp != '-')
    465 		return;
    466 
    467 	for (;*++cp;) {
    468 		int fl;
    469 
    470 		fl = 0;
    471 		BOOT_FLAG(*cp, fl);
    472 		if (!fl) {
    473 			printf("unknown option `%c'\n", *cp);
    474 			continue;
    475 		}
    476 		boothowto |= fl;
    477 
    478 		/* specialties */
    479 		if (*cp == 'd') {
    480 #if defined(KGDB)
    481 			kgdb_break_at_attach = 1;
    482 #elif defined(DDB)
    483 			Debugger();
    484 #else
    485 			printf("kernel has no debugger\n");
    486 #endif
    487 		} else if (*cp == 't') {
    488 			/* turn on traptrace w/o breaking into kdb */
    489 			extern int trap_trace_dis;
    490 
    491 			trap_trace_dis = 0;
    492 		}
    493 	}
    494 }
    495 
    496 /*
    497  * Determine mass storage and memory configuration for a machine.
    498  * We get the PROM's root device and make sure we understand it, then
    499  * attach it as `mainbus0'.  We also set up to handle the PROM `sync'
    500  * command.
    501  */
    502 void
    503 cpu_configure(void)
    504 {
    505 
    506 	bool userconf = (boothowto & RB_USERCONF) != 0;
    507 
    508 	/* fetch boot device settings */
    509 	get_bootpath_from_prom();
    510 	if (((boothowto & RB_USERCONF) != 0) && !userconf)
    511 		/*
    512 		 * Old bootloaders do not pass boothowto, and MI code
    513 		 * has already handled userconfig before we get here
    514 		 * and finally fetch the right options. So if we missed
    515 		 * it, just do it here.
    516  		 */
    517 		userconf_prompt();
    518 
    519 	/* block clock interrupts and anything below */
    520 	splclock();
    521 	/* Enable device interrupts */
    522         setpstate(getpstate()|PSTATE_IE);
    523 
    524 	if (config_rootfound("mainbus", NULL) == NULL)
    525 		panic("mainbus not configured");
    526 
    527 	/* Enable device interrupts */
    528         setpstate(getpstate()|PSTATE_IE);
    529 
    530 	(void)spl0();
    531 
    532 #ifdef SUN4V
    533 	if (CPU_ISSUN4V)
    534 		sun4v_set_soft_state(SIS_NORMAL, sun4v_soft_state_running);
    535 #endif
    536 }
    537 
    538 #ifdef SUN4V
    539 
    540 #define HSVC_GROUP_INTERRUPT	0x002
    541 #define HSVC_GROUP_SOFT_STATE	0x003
    542 #define HSVC_GROUP_SDIO		0x108
    543 
    544 int sun4v_soft_state_initialized = 0;
    545 
    546 void
    547 sun4v_soft_state_init(void)
    548 {
    549 	uint64_t minor;
    550 
    551 	if (prom_set_sun4v_api_version(HSVC_GROUP_SOFT_STATE, 1, 0, &minor))
    552 		return;
    553 
    554 	prom_sun4v_soft_state_supported();
    555 	sun4v_soft_state_initialized = 1;
    556 }
    557 
    558 void
    559 sun4v_set_soft_state(int state, const char *desc)
    560 {
    561 	paddr_t pa;
    562 	int err;
    563 
    564 	if (!sun4v_soft_state_initialized)
    565 		return;
    566 
    567 	if (!pmap_extract(pmap_kernel(), (vaddr_t)desc, &pa))
    568 		panic("sun4v_set_soft_state: pmap_extract failed");
    569 
    570 	err = hv_soft_state_set(state, pa);
    571 	if (err != H_EOK)
    572 		printf("soft_state_set: %d\n", err);
    573 }
    574 
    575 void
    576 sun4v_interrupt_init(void)
    577 {
    578 	uint64_t minor;
    579 
    580 	if (prom_set_sun4v_api_version(HSVC_GROUP_INTERRUPT, 3, 0, &minor))
    581 		return;
    582 
    583 	sun4v_group_interrupt_major = 3;
    584 }
    585 
    586 #if 0
    587 XXX notyet
    588 void
    589 sun4v_sdio_init(void)
    590 {
    591 	uint64_t minor;
    592 
    593 	if (prom_set_sun4v_api_version(HSVC_GROUP_SDIO, 1, 0, &minor))
    594 		return;
    595 
    596 	sun4v_group_sdio_major = 1;
    597 }
    598 #endif
    599 
    600 #endif
    601 
    602 void
    603 cpu_rootconf(void)
    604 {
    605 	if (booted_device == NULL) {
    606 		printf("FATAL: boot device not found, check your firmware "
    607 		    "settings!\n");
    608 	}
    609 
    610 	rootconf();
    611 }
    612 
    613 char *
    614 clockfreq(uint64_t freq)
    615 {
    616 	static char buf[10];
    617 	size_t len;
    618 
    619 	freq /= 1000;
    620 	len = snprintf(buf, sizeof(buf), "%" PRIu64, freq / 1000);
    621 	freq %= 1000;
    622 	if (freq)
    623 		snprintf(buf + len, sizeof(buf) - len, ".%03" PRIu64, freq);
    624 	return buf;
    625 }
    626 
    627 /* ARGSUSED */
    628 static int
    629 mbprint(void *aux, const char *name)
    630 {
    631 	struct mainbus_attach_args *ma = aux;
    632 
    633 	if (name)
    634 		aprint_normal("%s at %s", ma->ma_name, name);
    635 	if (ma->ma_address)
    636 		aprint_normal(" addr 0x%08lx", (u_long)ma->ma_address[0]);
    637 	if (ma->ma_pri)
    638 		aprint_normal(" ipl %d", ma->ma_pri);
    639 	return (UNCONF);
    640 }
    641 
    642 int
    643 mainbus_match(device_t parent, cfdata_t cf, void *aux)
    644 {
    645 
    646 	return (1);
    647 }
    648 
    649 /*
    650  * Attach the mainbus.
    651  *
    652  * Our main job is to attach the CPU (the root node we got in configure())
    653  * and iterate down the list of `mainbus devices' (children of that node).
    654  * We also record the `node id' of the default frame buffer, if any.
    655  */
    656 static void
    657 mainbus_attach(device_t parent, device_t dev, void *aux)
    658 {
    659 extern struct sparc_bus_dma_tag mainbus_dma_tag;
    660 extern struct sparc_bus_space_tag mainbus_space_tag;
    661 
    662 	struct mainbus_attach_args ma;
    663 	char sbuf[32];
    664 	const char *const *ssp, *sp = NULL;
    665 	char *c;
    666 	int node0, node, rv, i;
    667 
    668 	static const char *const openboot_special[] = {
    669 		/* ignore these (end with NULL) */
    670 		/*
    671 		 * These are _root_ devices to ignore. Others must be handled
    672 		 * elsewhere.
    673 		 */
    674 		"virtual-memory",
    675 		"aliases",
    676 		"memory",
    677 		"openprom",
    678 		"options",
    679 		"packages",
    680 		"chosen",
    681 		NULL
    682 	};
    683 
    684 	if (OF_getprop(findroot(), "banner-name", machine_banner,
    685 	    sizeof machine_banner) < 0)
    686 		i = 0;
    687 	else {
    688 		i = 1;
    689 		if (((c = strchr(machine_banner, '(')) != NULL) &&
    690 		    c != &machine_banner[0]) {
    691 				while (*c == '(' || *c == ' ') {
    692 					*c = '\0';
    693 					c--;
    694 				}
    695 			}
    696 	}
    697 	OF_getprop(findroot(), "name", machine_model, sizeof machine_model);
    698 	prom_getidprom();
    699 	if (i)
    700 		aprint_normal(": %s (%s): hostid %lx\n", machine_model,
    701 		    machine_banner, hostid);
    702 	else
    703 		aprint_normal(": %s: hostid %lx\n", machine_model, hostid);
    704 	aprint_naive("\n");
    705 
    706 	devhandle_t selfh = device_handle(dev);
    707 
    708 	/*
    709 	 * Locate and configure the ``early'' devices.  These must be
    710 	 * configured before we can do the rest.  For instance, the
    711 	 * EEPROM contains the Ethernet address for the LANCE chip.
    712 	 * If the device cannot be located or configured, panic.
    713 	 */
    714 	if (sparc_ncpus == 0)
    715 		panic("None of the CPUs found");
    716 
    717 	/*
    718 	 * Init static interrupt eventcounters
    719 	 */
    720 	for (i = 0; i < __arraycount(intr_evcnts); i++)
    721 		evcnt_attach_static(&intr_evcnts[i]);
    722 
    723 	node = findroot();
    724 
    725 	/* first early device to be configured is the CPU */
    726 	for (node = OF_child(node); node; node = OF_peer(node)) {
    727 		if (OF_getprop(node, "device_type", sbuf, sizeof(sbuf)) <= 0)
    728 			continue;
    729 		if (strcmp(sbuf, "cpu") != 0)
    730 			continue;
    731 		memset(&ma, 0, sizeof(ma));
    732 		ma.ma_bustag = &mainbus_space_tag;
    733 		ma.ma_dmatag = &mainbus_dma_tag;
    734 		ma.ma_node = node;
    735 		ma.ma_name = "cpu";
    736 		config_found(dev, &ma, mbprint,
    737 		    CFARGS(.devhandle = devhandle_from_of(selfh, ma.ma_node)));
    738 	}
    739 
    740 	node = findroot();	/* re-init root node */
    741 
    742 	/* Find the "options" node */
    743 	node0 = OF_child(node);
    744 
    745 	/*
    746 	 * Configure the devices, in PROM order.  Skip
    747 	 * PROM entries that are not for devices, or which must be
    748 	 * done before we get here.
    749 	 */
    750 	for (node = node0; node; node = OF_peer(node)) {
    751 		int portid;
    752 
    753 		DPRINTF(ACDB_PROBE, ("Node: %x", node));
    754 		if ((OF_getprop(node, "device_type", sbuf, sizeof(sbuf)) > 0) &&
    755 		    strcmp(sbuf, "cpu") == 0)
    756 			continue;
    757 		OF_getprop(node, "name", sbuf, sizeof(sbuf));
    758 		DPRINTF(ACDB_PROBE, (" name %s\n", sbuf));
    759 		for (ssp = openboot_special; (sp = *ssp) != NULL; ssp++)
    760 			if (strcmp(sbuf, sp) == 0)
    761 				break;
    762 		if (sp != NULL)
    763 			continue; /* an "early" device already configured */
    764 
    765 		memset(&ma, 0, sizeof ma);
    766 		ma.ma_bustag = &mainbus_space_tag;
    767 		ma.ma_dmatag = &mainbus_dma_tag;
    768 		ma.ma_name = sbuf;
    769 		ma.ma_node = node;
    770 		if (OF_getprop(node, "upa-portid", &portid, sizeof(portid)) !=
    771 		    sizeof(portid) &&
    772 		    OF_getprop(node, "portid", &portid, sizeof(portid)) !=
    773 		    sizeof(portid))
    774 			portid = -1;
    775 		ma.ma_upaid = portid;
    776 
    777 		if (prom_getprop(node, "reg", sizeof(*ma.ma_reg),
    778 				 &ma.ma_nreg, &ma.ma_reg) != 0)
    779 			continue;
    780 #ifdef DEBUG
    781 		if (autoconf_debug & ACDB_PROBE) {
    782 			if (ma.ma_nreg)
    783 				printf(" reg %08lx.%08lx\n",
    784 					(long)ma.ma_reg->ur_paddr,
    785 					(long)ma.ma_reg->ur_len);
    786 			else
    787 				printf(" no reg\n");
    788 		}
    789 #endif
    790 		rv = prom_getprop(node, "interrupts", sizeof(*ma.ma_interrupts),
    791 			&ma.ma_ninterrupts, &ma.ma_interrupts);
    792 		if (rv != 0 && rv != ENOENT) {
    793 			free(ma.ma_reg, M_DEVBUF);
    794 			continue;
    795 		}
    796 #ifdef DEBUG
    797 		if (autoconf_debug & ACDB_PROBE) {
    798 			if (ma.ma_interrupts)
    799 				printf(" interrupts %08x\n", *ma.ma_interrupts);
    800 			else
    801 				printf(" no interrupts\n");
    802 		}
    803 #endif
    804 		rv = prom_getprop(node, "address", sizeof(*ma.ma_address),
    805 			&ma.ma_naddress, &ma.ma_address);
    806 		if (rv != 0 && rv != ENOENT) {
    807 			free(ma.ma_reg, M_DEVBUF);
    808 			if (ma.ma_ninterrupts)
    809 				free(ma.ma_interrupts, M_DEVBUF);
    810 			continue;
    811 		}
    812 #ifdef DEBUG
    813 		if (autoconf_debug & ACDB_PROBE) {
    814 			if (ma.ma_naddress)
    815 				printf(" address %08x\n", *ma.ma_address);
    816 			else
    817 				printf(" no address\n");
    818 		}
    819 #endif
    820 		(void) config_found(dev, (void *)&ma, mbprint,
    821 		    CFARGS(.devhandle = prom_node_to_devhandle(selfh,
    822 							       ma.ma_node)));
    823 		free(ma.ma_reg, M_DEVBUF);
    824 		if (ma.ma_ninterrupts)
    825 			free(ma.ma_interrupts, M_DEVBUF);
    826 		if (ma.ma_naddress)
    827 			free(ma.ma_address, M_DEVBUF);
    828 	}
    829 	/* Try to attach PROM console */
    830 	memset(&ma, 0, sizeof ma);
    831 	ma.ma_name = "pcons";
    832 	(void) config_found(dev, (void *)&ma, mbprint, CFARGS_NONE);
    833 }
    834 
    835 CFATTACH_DECL_NEW(mainbus, 0,
    836     mainbus_match, mainbus_attach, NULL, NULL);
    837 
    838 
    839 /*
    840  * Try to figure out where the PROM stores the cursor row & column
    841  * variables.  Returns nonzero on error.
    842  */
    843 int
    844 romgetcursoraddr(int **rowp, int **colp)
    845 {
    846 	cell_t row = 0UL, col = 0UL;
    847 
    848 	OF_interpret("stdout @ is my-self addr line# addr column# ", 0, 2,
    849 		&col, &row);
    850 	/*
    851 	 * We are running on a 64-bit machine, so these things point to
    852 	 * 64-bit values.  To convert them to pointers to integers, add
    853 	 * 4 to the address.
    854 	 */
    855 	*rowp = (int *)(intptr_t)(row+4);
    856 	*colp = (int *)(intptr_t)(col+4);
    857 	return (row == 0UL || col == 0UL);
    858 }
    859 
    860 /*
    861  * Match a device_t against the bootpath, by
    862  * comparing its firmware package handle. If they match
    863  * exactly, we found the boot device.
    864  */
    865 static void
    866 dev_path_exact_match(device_t dev, int ofnode)
    867 {
    868 
    869 	if (ofnode != ofbootpackage)
    870 		return;
    871 
    872 	booted_device = dev;
    873 	DPRINTF(ACDB_BOOTDEV, ("found bootdevice: %s\n", device_xname(dev)));
    874 }
    875 
    876 /*
    877  * Match a device_t against the bootpath, by
    878  * comparing its firmware package handle and calculating
    879  * the target/lun suffix and comparing that against
    880  * the bootpath remainder.
    881  */
    882 static void
    883 dev_path_drive_match(device_t dev, int ctrlnode, int target,
    884     uint64_t wwn, int lun)
    885 {
    886 	int child = 0, ide_node = 0;
    887 	char buf[OFPATHLEN];
    888 
    889 	DPRINTF(ACDB_BOOTDEV, ("dev_path_drive_match: %s, controller %x, "
    890 	    "target %d wwn %016" PRIx64 " lun %d\n", device_xname(dev),
    891 	    ctrlnode, target, wwn, lun));
    892 
    893 	/*
    894 	 * The ofbootpackage points to a disk on this controller, so
    895 	 * iterate over all child nodes and compare.
    896 	 */
    897 	for (child = prom_firstchild(ctrlnode); child != 0;
    898 	    child = prom_nextsibling(child))
    899 		if (child == ofbootpackage)
    900 			break;
    901 
    902 	if (child != ofbootpackage) {
    903 		/*
    904 		 * Try Mac firmware style (also used by QEMU/OpenBIOS):
    905 		 * below the controller there is an intermediate node
    906 		 * for each IDE channel, and individual targets always
    907 		 * are "@0"
    908 		 */
    909 		for (ide_node = prom_firstchild(ctrlnode); ide_node != 0;
    910 		    ide_node = prom_nextsibling(ide_node)) {
    911 			const char * name = prom_getpropstring(ide_node,
    912 			    "device_type");
    913 			if (strcmp(name, "ide") != 0) continue;
    914 			for (child = prom_firstchild(ide_node); child != 0;
    915 			    child = prom_nextsibling(child))
    916 				if (child == ofbootpackage)
    917 					break;
    918 			if (child == ofbootpackage)
    919 				break;
    920 		}
    921 	}
    922 
    923 	if (child == ofbootpackage) {
    924 		const char * name = prom_getpropstring(child, "name");
    925 
    926 		/* boot device is on this controller */
    927 		DPRINTF(ACDB_BOOTDEV, ("found controller of bootdevice\n"));
    928 
    929 		/*
    930 		 * Note: "child" here is == ofbootpackage (s.a.), which
    931 		 * may be completely wrong for the device we are checking,
    932 		 * what we really do here is to match "target" and "lun".
    933 		 */
    934 		if (wwn)
    935 			snprintf(buf, sizeof(buf), "%s@w%016" PRIx64 ",%d",
    936 			    name, wwn, lun);
    937 		else if (ide_node)
    938 			snprintf(buf, sizeof(buf), "%s@0",
    939 			    device_is_a(dev, "cd") ? "cdrom" : "disk");
    940 		else
    941 			snprintf(buf, sizeof(buf), "%s@%d,%d",
    942 			    name, target, lun);
    943 		if (ofboottarget && strcmp(buf, ofboottarget) == 0) {
    944 			booted_device = dev;
    945 			if (ofbootpartition)
    946 				booted_partition = *ofbootpartition - 'a';
    947 			DPRINTF(ACDB_BOOTDEV, ("found boot device: %s"
    948 			    ", partition %d\n", device_xname(dev),
    949 			    booted_partition));
    950 		}
    951 	}
    952 }
    953 
    954  /*
    955  * Recursively check for a child node.
    956  */
    957 static bool
    958 has_child_node(int parent, int search)
    959 {
    960 	int child;
    961 
    962 	for (child = prom_firstchild(parent); child != 0;
    963 	    child = prom_nextsibling(child)) {
    964 		if (child == search)
    965 			return true;
    966 		if (has_child_node(child, search))
    967 			return true;
    968 	}
    969 
    970 	return false;
    971 }
    972 
    973 /*
    974  * The interposed pseudo-parent node in OpenBIOS has a
    975  * device_type = "ide" and no "compatible" property.
    976  * It is the secondary bus if the name is "ide1" or "ide"
    977  * with newer OpenBIOS versions. In the latter case, read
    978  * the first reg value to discriminate the two channels.
    979  */
    980 static bool
    981 openbios_secondary_ata_heuristic(int parent)
    982 {
    983 	char tmp[OFPATHLEN];
    984 	int regs[4];
    985 
    986 	if (OF_getprop(parent, "device_type", tmp, sizeof(tmp)) <= 0)
    987 		return false;
    988 	if (strcmp(tmp, "ide") != 0)
    989 		return false;
    990 	DPRINTF(ACDB_BOOTDEV, ("parent device_type is ide\n"));
    991 
    992 	if (OF_getprop(parent, "compatible", tmp, sizeof(tmp)) > 0)
    993 		return false;
    994 	DPRINTF(ACDB_BOOTDEV, ("parent has no compatible property\n"));
    995 
    996 	if (OF_getprop(parent, "name", tmp, sizeof(tmp)) <= 0)
    997 		return false;
    998 	if (strcmp(tmp, "ide1") == 0) {
    999 		DPRINTF(ACDB_BOOTDEV, ("parent seems to be an (old) OpenBIOS"
   1000 		   " secondary ATA bus, applying workaround target+2\n"));
   1001 		return true;
   1002 	} else if (strcmp(tmp, "ide") == 0) {
   1003 		if (OF_getprop(parent, "reg", &regs, sizeof(regs))
   1004 		    >= sizeof(regs[0])) {
   1005 			DPRINTF(ACDB_BOOTDEV, ("parent seems to be an OpenBIOS"
   1006 			   " ATA bus #%u\n", regs[0]));
   1007 
   1008 			return regs[0] == 1;
   1009 		}
   1010 
   1011 	}
   1012 
   1013 	return false;
   1014 }
   1015 
   1016 /*
   1017  * Match a device_t against the controller/target/lun/wwn
   1018  * info passed in from the bootloader (if available),
   1019  * otherwise fall back to old style string matching
   1020  * heuristics.
   1021  */
   1022 static void
   1023 dev_bi_unit_drive_match(device_t dev, int ctrlnode, int target,
   1024     uint64_t wwn, int lun)
   1025 {
   1026 	static struct btinfo_bootdev_unit *bi_unit = NULL;
   1027 	uint32_t off = 0;
   1028 	static bool passed = false;
   1029 #ifdef DEBUG
   1030 	char ctrl_path[OFPATHLEN], parent_path[OFPATHLEN], dev_path[OFPATHLEN];
   1031 #endif
   1032 
   1033 	if (!passed) {
   1034 		bi_unit = lookup_bootinfo(BTINFO_BOOTDEV_UNIT);
   1035 		passed = true;
   1036 	}
   1037 
   1038 	if (bi_unit == NULL) {
   1039 		dev_path_drive_match(dev, ctrlnode, target, wwn, lun);
   1040 		return;
   1041 	}
   1042 
   1043 #ifdef DEBUG
   1044 	DPRINTF(ACDB_BOOTDEV, ("dev_bi_unit_drive_match: %s, controller %x, "
   1045 	    "target %d wwn %016" PRIx64 " lun %d\n", device_xname(dev),
   1046 	    ctrlnode, target, wwn, lun));
   1047 
   1048 	OF_package_to_path(ctrlnode, ctrl_path, sizeof(ctrl_path));
   1049 	OF_package_to_path(bi_unit->phandle, dev_path, sizeof(dev_path));
   1050 	OF_package_to_path(bi_unit->parent, parent_path, sizeof(parent_path));
   1051 	DPRINTF(ACDB_BOOTDEV, ("controller %x : %s\n", ctrlnode, ctrl_path));
   1052 	DPRINTF(ACDB_BOOTDEV, ("phandle %x : %s\n", bi_unit->phandle, dev_path));
   1053 	DPRINTF(ACDB_BOOTDEV, ("parent %x : %s\n", bi_unit->parent, parent_path));
   1054 #endif
   1055 	if (ctrlnode != bi_unit->parent
   1056 	    && !has_child_node(ctrlnode, bi_unit->phandle)) {
   1057 		DPRINTF(ACDB_BOOTDEV, ("controller %x : %s does not match "
   1058 		    "bootinfo: %x : %s\n",
   1059 		    ctrlnode, ctrl_path, bi_unit->parent, parent_path));
   1060 		return;
   1061 	}
   1062 	if (ctrlnode == bi_unit->parent) {
   1063 		DPRINTF(ACDB_BOOTDEV, ("controller %x : %s is bootinfo"
   1064 		    " parent\n", ctrlnode, ctrl_path));
   1065 	} else {
   1066 		DPRINTF(ACDB_BOOTDEV, ("controller %x : %s is parent of"
   1067 		    " %x : %s\n", ctrlnode, ctrl_path, bi_unit->parent,
   1068 		    parent_path));
   1069 
   1070 		/*
   1071 		 * Our kernel and "real" OpenFirmware use a 0 .. 3 numbering
   1072 		 * scheme for IDE devices, but OpenBIOS splits it into
   1073 		 * two "buses" and numbers each 0..1.
   1074 		 * Check if we are on the secondary "bus" and adjust
   1075 		 * if needed...
   1076 		 */
   1077 		if (openbios_secondary_ata_heuristic(bi_unit->parent))
   1078 			off = 2;
   1079 	}
   1080 
   1081 	if (bi_unit->wwn != wwn || (bi_unit->target+off) != target
   1082 	    || bi_unit->lun != lun) {
   1083 		DPRINTF(ACDB_BOOTDEV, ("mismatch: wwn %016" PRIx64 " - %016" PRIx64
   1084 		    ", target %d - %d, lun %d - %d\n",
   1085 		    bi_unit->wwn, wwn, bi_unit->target, target, bi_unit->lun, lun));
   1086 		return;
   1087 	}
   1088 
   1089 	booted_device = dev;
   1090 	if (ofbootpartition)
   1091 		booted_partition = *ofbootpartition - 'a';
   1092 	DPRINTF(ACDB_BOOTDEV, ("found boot device: %s"
   1093 	    ", partition %d\n", device_xname(dev),
   1094 	    booted_partition));
   1095 }
   1096 
   1097 /*
   1098  * Called back during autoconfiguration for each device found
   1099  */
   1100 void
   1101 device_register(device_t dev, void *aux)
   1102 {
   1103 	device_t busdev = device_parent(dev);
   1104 	devhandle_t devhandle;
   1105 	int ofnode = 0;
   1106 
   1107 	/*
   1108 	 * If the device has a valid OpenFirmware node association,
   1109 	 * grab it now.
   1110 	 */
   1111 	devhandle = device_handle(dev);
   1112 	if (devhandle_type(devhandle) == DEVHANDLE_TYPE_OF) {
   1113 		ofnode = devhandle_to_of(devhandle);
   1114 	}
   1115 
   1116 	/*
   1117 	 * We don't know the type of 'aux' - it depends on the
   1118 	 * bus this device attaches to. We are only interested in
   1119 	 * certain bus types, this only is used to find the boot
   1120 	 * device.
   1121 	 */
   1122 	if (busdev == NULL) {
   1123 		/*
   1124 		 * Ignore mainbus0 itself, it certainly is not a boot
   1125 		 * device.
   1126 		 */
   1127 	} else if (device_is_a(busdev, "iic")) {
   1128 		struct i2c_attach_args *ia = aux;
   1129 
   1130 		if (ia->ia_name == NULL)	/* indirect config */
   1131 			return;
   1132 
   1133 		if (device_is_a(dev, "pcagpio")) {
   1134 			if (!strcmp(machine_model, "SUNW,Sun-Fire-V240") ||
   1135 			    !strcmp(machine_model, "SUNW,Sun-Fire-V210")) {
   1136 				add_gpio_props_v210(dev, aux);
   1137 			}
   1138 		}
   1139 		if (device_is_a(dev, "pcf8574io")) {
   1140 			if (!strcmp(machine_model, "SUNW,Ultra-250")) {
   1141 				add_gpio_props_e250(dev, aux);
   1142 			}
   1143 		}
   1144 		return;
   1145 	} else if (device_is_a(dev, "sd") || device_is_a(dev, "cd")) {
   1146 		struct scsipibus_attach_args *sa = aux;
   1147 		struct scsipi_periph *periph = sa->sa_periph;
   1148 		int off = 0;
   1149 
   1150 		/*
   1151 		 * There are two "cd" attachments:
   1152 		 *   atapibus -> atabus -> controller
   1153 		 *   scsibus -> controller
   1154 		 * We want the node of the controller.
   1155 		 */
   1156 		if (device_is_a(busdev, "atapibus")) {
   1157 			busdev = device_parent(busdev);
   1158 			/*
   1159 			 * if the atapibus is connected to the secondary
   1160 			 * channel of the atabus, we need an offset of 2
   1161 			 * to match OF's idea of the target number.
   1162 			 * (i.e. on U5/U10 "cdrom" and "disk2" have the
   1163 			 * same target encoding, though different names)
   1164 			 */
   1165 			if (periph->periph_channel->chan_channel == 1)
   1166 				off = 2;
   1167 		}
   1168 
   1169 		/*
   1170 		 * busdev now points to the direct descendent of the
   1171 		 * controller ("atabus" or "scsibus").  Get the
   1172 		 * controller's devhandle.  Hoist it up one more so
   1173 		 * that busdev points at the controller.
   1174 		 */
   1175 		busdev = device_parent(busdev);
   1176 		devhandle = device_handle(busdev);
   1177 		KASSERT(devhandle_type(devhandle) == DEVHANDLE_TYPE_OF);
   1178 		ofnode = devhandle_to_of(devhandle);
   1179 
   1180 		/*
   1181 		 * Special sun4v handling in case the kernel is running in a
   1182 		 * secondary logical domain
   1183 		 *
   1184 		 * The bootpath looks something like this:
   1185 		 *   /virtual-devices@100/channel-devices@200/disk@1:a (disk)
   1186 		 *   /virtual-devices@100/channel-devices@200/disk@4:f (cdrom)
   1187 		 *
   1188 		 * The device hierarchy constructed during autoconfiguration
   1189 		 * is:
   1190 		 *   /mainbus/vbus/cbus/vdsk/scsibus/sd or
   1191 		 *   /mainbus/vbus/cbus/vdsk/scsibus/cd
   1192 		 */
   1193 		if (CPU_ISSUN4V && device_is_a(busdev, "vdsk")) {
   1194 			dev_path_exact_match(dev, ofnode);
   1195 		} else {
   1196 			dev_bi_unit_drive_match(dev, ofnode,
   1197 			    periph->periph_target + off, 0, periph->periph_lun);
   1198 		}
   1199 
   1200 		if (device_is_a(busdev, "scsibus")) {
   1201 			/* see if we're in a known SCA drivebay */
   1202 			add_drivebay_props(dev, ofnode, aux);
   1203 		}
   1204 		return;
   1205 	} else if (device_is_a(dev, "wd")) {
   1206 		struct ata_device *adev = aux;
   1207 
   1208 		/*
   1209 		 * busdev points to the direct descendent of the controller,
   1210 		 * e.g. "atabus".  Get the controller's devhandle.
   1211 		 */
   1212 		devhandle = device_handle(device_parent(busdev));
   1213 		KASSERT(devhandle_type(devhandle) == DEVHANDLE_TYPE_OF);
   1214 		ofnode = devhandle_to_of(devhandle);
   1215 
   1216 		dev_bi_unit_drive_match(dev, ofnode, adev->adev_channel*2+
   1217 		    adev->adev_drv_data->drive, 0, 0);
   1218 		return;
   1219 	} else if (device_is_a(dev, "ld")) {
   1220 		/*
   1221 		 * Get the devhandle of the RAID (or whatever) controller.
   1222 		 */
   1223 		devhandle = device_handle(busdev);
   1224 		ofnode = devhandle_to_of(devhandle);
   1225 	}
   1226 
   1227 	if (busdev == NULL)
   1228 		return;
   1229 
   1230 	if (ofnode != 0) {
   1231 		uint8_t eaddr[ETHER_ADDR_LEN];
   1232 		char tmpstr[32];
   1233 		char tmpstr2[32];
   1234 		int node;
   1235 		uint32_t id = 0;
   1236 		uint64_t nwwn = 0, pwwn = 0;
   1237 		prop_dictionary_t dict;
   1238 		prop_data_t blob;
   1239 		prop_number_t pwwnd = NULL, nwwnd = NULL;
   1240 		prop_number_t idd = NULL;
   1241 
   1242 		dev_path_exact_match(dev, ofnode);
   1243 
   1244 		if (OF_getprop(ofnode, "name", tmpstr, sizeof(tmpstr)) <= 0)
   1245 			tmpstr[0] = 0;
   1246 		if (OF_getprop(ofnode, "device_type", tmpstr2, sizeof(tmpstr2)) <= 0)
   1247 			tmpstr2[0] = 0;
   1248 
   1249 		/*
   1250 		 * If this is a network interface, note the
   1251 		 * mac address.
   1252 		 */
   1253 		if (strcmp(tmpstr, "network") == 0
   1254 		   || strcmp(tmpstr, "ethernet") == 0
   1255 		   || strcmp(tmpstr2, "network") == 0
   1256 		   || strcmp(tmpstr2, "ethernet") == 0
   1257 		   || OF_getprop(ofnode, "mac-address", &eaddr, sizeof(eaddr))
   1258 		      >= ETHER_ADDR_LEN
   1259 		   || OF_getprop(ofnode, "local-mac-address", &eaddr, sizeof(eaddr))
   1260 		      >= ETHER_ADDR_LEN) {
   1261 
   1262 			dict = device_properties(dev);
   1263 
   1264 			/*
   1265 			 * Is it a network interface with FCode?
   1266 			 */
   1267 			if (strcmp(tmpstr, "network") == 0 ||
   1268 			    strcmp(tmpstr2, "network") == 0) {
   1269 				prop_dictionary_set_bool(dict,
   1270 				    "without-seeprom", true);
   1271 				prom_getether(ofnode, eaddr);
   1272 			} else {
   1273 				if (!prom_get_node_ether(ofnode, eaddr))
   1274 					goto noether;
   1275 			}
   1276 			blob = prop_data_create_copy(eaddr, ETHER_ADDR_LEN);
   1277 			prop_dictionary_set(dict, "mac-address", blob);
   1278 			prop_object_release(blob);
   1279 			of_to_dataprop(dict, ofnode, "shared-pins",
   1280 			    "shared-pins");
   1281 		}
   1282 noether:
   1283 
   1284 		/* is this a FC node? */
   1285 		if (strcmp(tmpstr, "scsi-fcp") == 0) {
   1286 
   1287 			dict = device_properties(dev);
   1288 
   1289 			if (OF_getprop(ofnode, "port-wwn", &pwwn, sizeof(pwwn))
   1290 			    == sizeof(pwwn)) {
   1291 				pwwnd =
   1292 				    prop_number_create_unsigned(pwwn);
   1293 				prop_dictionary_set(dict, "port-wwn", pwwnd);
   1294 				prop_object_release(pwwnd);
   1295 			}
   1296 
   1297 			if (OF_getprop(ofnode, "node-wwn", &nwwn, sizeof(nwwn))
   1298 			    == sizeof(nwwn)) {
   1299 				nwwnd =
   1300 				    prop_number_create_unsigned(nwwn);
   1301 				prop_dictionary_set(dict, "node-wwn", nwwnd);
   1302 				prop_object_release(nwwnd);
   1303 			}
   1304 		}
   1305 
   1306 		/* is this an spi device?  look for scsi-initiator-id */
   1307 		if (strcmp(tmpstr2, "scsi") == 0 ||
   1308 		    strcmp(tmpstr2, "scsi-2") == 0) {
   1309 
   1310 			dict = device_properties(dev);
   1311 
   1312 			for (node = ofnode; node != 0; node = OF_parent(node)) {
   1313 				if (OF_getprop(node, "scsi-initiator-id", &id,
   1314 				    sizeof(id)) <= 0)
   1315 					continue;
   1316 
   1317 				idd = prop_number_create_unsigned(id);
   1318 				prop_dictionary_set(dict,
   1319 						    "scsi-initiator-id", idd);
   1320 				prop_object_release(idd);
   1321 				break;
   1322 			}
   1323 		}
   1324 	}
   1325 
   1326 	/*
   1327 	 * Check for I2C busses and add data for their direct configuration.
   1328 	 */
   1329 	if (device_is_a(dev, "iic")) {
   1330 		devhandle_t bushandle = device_handle(busdev);
   1331 		int busnode =
   1332 		    devhandle_type(bushandle) == DEVHANDLE_TYPE_OF ?
   1333 		    devhandle_to_of(bushandle) : 0;
   1334 
   1335 		if (busnode) {
   1336 			prop_dictionary_t props = device_properties(busdev);
   1337 			prop_object_t cfg = prop_dictionary_get(props,
   1338 				"i2c-child-devices");
   1339 			if (!cfg) {
   1340 				int node;
   1341 				const char *name;
   1342 
   1343 				/*
   1344 				 * pmu's i2c devices are under the "i2c" node,
   1345 				 * so find it out.
   1346 				 */
   1347 				name = prom_getpropstring(busnode, "name");
   1348 				if (strcmp(name, "pmu") == 0) {
   1349 					for (node = OF_child(busnode);
   1350 					     node != 0; node = OF_peer(node)) {
   1351 						name = prom_getpropstring(node,
   1352 						    "name");
   1353 						if (strcmp(name, "i2c") == 0) {
   1354 							busnode = node;
   1355 							break;
   1356 						}
   1357 					}
   1358 				}
   1359 
   1360 				cfg = of_copy_i2c_devs(busnode,
   1361 				    sizeof(cell_t), 1);
   1362 				if (cfg != NULL) {
   1363 					prop_dictionary_set(props,
   1364 					    "i2c-child-devices", cfg);
   1365 					prop_object_release(cfg);
   1366 				}
   1367 			}
   1368 		}
   1369 
   1370 		if (!strcmp(machine_model, "TAD,SPARCLE"))
   1371 			add_spdmem_props_sparcle(busdev);
   1372 
   1373 		if (device_is_a(busdev, "pcfiic") &&
   1374 		    (!strcmp(machine_model, "SUNW,Sun-Fire-V240") ||
   1375 		    !strcmp(machine_model, "SUNW,Sun-Fire-V210")))
   1376 			add_env_sensors_v210(busdev);
   1377 
   1378 		/* E450 SUNW,envctrl */
   1379 		if (device_is_a(busdev, "pcfiic") &&
   1380 		    (!strcmp(machine_model, "SUNW,Ultra-4")))
   1381 			add_i2c_props_e450(busdev, busnode);
   1382 
   1383 		/* E250 SUNW,envctrltwo */
   1384 		if (device_is_a(busdev, "pcfiic") &&
   1385 		    (!strcmp(machine_model, "SUNW,Ultra-250")))
   1386 			add_i2c_props_e250(busdev, busnode);
   1387 	}
   1388 
   1389 	/* set properties for PCI framebuffers */
   1390 	if (device_is_a(busdev, "pci")) {
   1391 		/* see if this is going to be console */
   1392 		struct pci_attach_args *pa = aux;
   1393 		prop_dictionary_t dict;
   1394 		int sub;
   1395 		int console = 0;
   1396 
   1397 		dict = device_properties(dev);
   1398 
   1399 		/* we only care about display devices from here on */
   1400 		if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY)
   1401 			return;
   1402 
   1403 		console = (ofnode == console_node);
   1404 
   1405 		if (!console) {
   1406 			/*
   1407 			 * see if any child matches since OF attaches
   1408 			 * nodes for each head and /chosen/stdout
   1409 			 * points to the head rather than the device
   1410 			 * itself in this case
   1411 			 */
   1412 			sub = OF_child(ofnode);
   1413 			while ((sub != 0) && (sub != console_node)) {
   1414 				sub = OF_peer(sub);
   1415 			}
   1416 			if (sub == console_node) {
   1417 				console = true;
   1418 			}
   1419 		}
   1420 
   1421 		copyprops(busdev, ofnode, dict, console);
   1422 
   1423 		if (console) {
   1424 			uint64_t cmap_cb;
   1425 			prop_dictionary_set_uint32(dict,
   1426 			    "instance_handle", console_instance);
   1427 
   1428 			gfb_cb.gcc_cookie =
   1429 			    (void *)(intptr_t)console_instance;
   1430 			gfb_cb.gcc_set_mapreg = of_set_palette;
   1431 			cmap_cb = (uint64_t)(uintptr_t)&gfb_cb;
   1432 			prop_dictionary_set_uint64(dict,
   1433 			    "cmap_callback", cmap_cb);
   1434 		}
   1435 #ifdef notyet
   1436 		else {
   1437 			int width;
   1438 
   1439 			/*
   1440 			 * the idea is to 'open' display devices with no useful
   1441 			 * properties, in the hope that the firmware will
   1442 			 * properly initialize them and we can run things like
   1443 			 * genfb on them
   1444 			 */
   1445 			if (OF_getprop(node, "width", &width, sizeof(width))
   1446 			    != 4) {
   1447 				instance = OF_open(name);
   1448 			}
   1449 		}
   1450 #endif
   1451 		set_static_edid(dict);
   1452 	}
   1453 
   1454 	set_hw_props(dev);
   1455 }
   1456 
   1457 /*
   1458  * Called back after autoconfiguration of a device is done
   1459  */
   1460 void
   1461 device_register_post_config(device_t dev, void *aux)
   1462 {
   1463 	if (booted_device == NULL && device_is_a(dev, "sd")) {
   1464 		struct scsipibus_attach_args *sa = aux;
   1465 		struct scsipi_periph *periph = sa->sa_periph;
   1466 		uint64_t wwn = 0;
   1467 
   1468 		/*
   1469 		 * If this is a FC-AL drive it will have
   1470 		 * acquired its WWN device property by now,
   1471 		 * so we can properly match it.
   1472 		 */
   1473 		if (prop_dictionary_get_uint64(device_properties(dev),
   1474 		    "port-wwn", &wwn)) {
   1475 			/*
   1476 			 * Different to what we do in device_register,
   1477 			 * we do not pass the "controller" ofnode,
   1478 			 * because FC-AL devices attach below a "fp" node,
   1479 			 * E.g.: /pci/SUNW,qlc@4/fp@0,0/disk
   1480 			 * and we need the parent of "disk" here.
   1481 			 */
   1482 			devhandle_t ctlr_devhandle = device_handle(
   1483 			    device_parent(device_parent(dev)));
   1484 			KASSERT(devhandle_type(ctlr_devhandle) ==
   1485 			    DEVHANDLE_TYPE_OF);
   1486 			int ofnode = devhandle_to_of(ctlr_devhandle);
   1487 
   1488 			for (ofnode = OF_child(ofnode);
   1489 			     ofnode != 0 && booted_device == NULL;
   1490 			     ofnode = OF_peer(ofnode)) {
   1491 				dev_bi_unit_drive_match(dev, ofnode,
   1492 				    periph->periph_target,
   1493 				    wwn, periph->periph_lun);
   1494 			}
   1495 		}
   1496 	}
   1497 }
   1498 
   1499 static void
   1500 copyprops(device_t busdev, int node, prop_dictionary_t dict, int is_console)
   1501 {
   1502 	device_t cntrlr;
   1503 	prop_dictionary_t psycho;
   1504 	paddr_t fbpa, mem_base = 0;
   1505 	uint32_t temp, fboffset;
   1506 	uint32_t fbaddr = 0;
   1507 	int options;
   1508 	char output_device[OFPATHLEN];
   1509 	char *pos;
   1510 
   1511 	cntrlr = device_parent(busdev);
   1512 	if (cntrlr != NULL) {
   1513 		psycho = device_properties(cntrlr);
   1514 		prop_dictionary_get_uint64(psycho, "mem_base", &mem_base);
   1515 	}
   1516 
   1517 	if (is_console)
   1518 		prop_dictionary_set_bool(dict, "is_console", 1);
   1519 
   1520 	of_to_uint32_prop(dict, node, "width", "width");
   1521 	of_to_uint32_prop(dict, node, "height", "height");
   1522 	of_to_uint32_prop(dict, node, "linebytes", "linebytes");
   1523 	if (!of_to_uint32_prop(dict, node, "depth", "depth") &&
   1524 	    /* Some cards have an extra space in the property name */
   1525 	    !of_to_uint32_prop(dict, node, "depth ", "depth")) {
   1526 		/*
   1527 		 * XXX we should check linebytes vs. width but those
   1528 		 * FBs that don't have a depth property ( /chaos/control... )
   1529 		 * won't have linebytes either
   1530 		 */
   1531 		prop_dictionary_set_uint32(dict, "depth", 8);
   1532 	}
   1533 
   1534 	OF_getprop(node, "address", &fbaddr, sizeof(fbaddr));
   1535 	if (fbaddr != 0) {
   1536 
   1537 		pmap_extract(pmap_kernel(), fbaddr, &fbpa);
   1538 #ifdef DEBUG
   1539 		printf("membase: %lx fbpa: %lx\n", (unsigned long)mem_base,
   1540 		    (unsigned long)fbpa);
   1541 #endif
   1542 		if (mem_base == 0) {
   1543 			/* XXX this is guesswork */
   1544 			fboffset = (uint32_t)(fbpa & 0xffffffff);
   1545 		}
   1546 			fboffset = (uint32_t)(fbpa - mem_base);
   1547 		prop_dictionary_set_uint32(dict, "address", fboffset);
   1548 	}
   1549 
   1550 	if (!of_to_dataprop(dict, node, "EDID", "EDID"))
   1551 		of_to_dataprop(dict, node, "edid", "EDID");
   1552 
   1553 	temp = 0;
   1554 	if (OF_getprop(node, "ATY,RefCLK", &temp, sizeof(temp)) != 4) {
   1555 
   1556 		OF_getprop(OF_parent(node), "ATY,RefCLK", &temp,
   1557 		    sizeof(temp));
   1558 	}
   1559 	if (temp != 0)
   1560 		prop_dictionary_set_uint32(dict, "refclk", temp / 10);
   1561 
   1562 	/*
   1563 	 * finally, let's see if there's a video mode specified in
   1564 	 * output-device and pass it on so drivers like radeonfb
   1565 	 * can do their thing
   1566 	 */
   1567 
   1568 	if (!is_console)
   1569 		return;
   1570 
   1571 	options = OF_finddevice("/options");
   1572 	if ((options == 0) || (options == -1))
   1573 		return;
   1574 	if (OF_getprop(options, "output-device", output_device, OFPATHLEN) == 0)
   1575 		return;
   1576 	/* find the mode string if there is one */
   1577 	pos = strstr(output_device, ":r");
   1578 	if (pos == NULL)
   1579 		return;
   1580 	prop_dictionary_set_string(dict, "videomode", pos + 2);
   1581 }
   1582 
   1583 static void
   1584 of_set_palette(void *cookie, int index, int r, int g, int b)
   1585 {
   1586 	int ih = (int)((intptr_t)cookie);
   1587 
   1588 	OF_call_method_1("color!", ih, 4, r, g, b, index);
   1589 }
   1590