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