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