xref: /openbsd/sys/arch/sparc64/sparc64/autoconf.c (revision 6dfc32ac)
1 /*	$OpenBSD: autoconf.c,v 1.151 2024/05/17 20:05:08 miod Exp $	*/
2 /*	$NetBSD: autoconf.c,v 1.51 2001/07/24 19:32:11 eeh Exp $ */
3 
4 /*
5  * Copyright (c) 1996
6  *    The President and Fellows of Harvard College. All rights reserved.
7  * Copyright (c) 1992, 1993
8  *	The Regents of the University of California.  All rights reserved.
9  *
10  * This software was developed by the Computer Systems Engineering group
11  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
12  * contributed to Berkeley.
13  *
14  * All advertising materials mentioning features or use of this software
15  * must display the following acknowledgement:
16  *	This product includes software developed by Harvard University.
17  *	This product includes software developed by the University of
18  *	California, Lawrence Berkeley Laboratory.
19  *
20  * Redistribution and use in source and binary forms, with or without
21  * modification, are permitted provided that the following conditions
22  * are met:
23  * 1. Redistributions of source code must retain the above copyright
24  *    notice, this list of conditions and the following disclaimer.
25  * 2. Redistributions in binary form must reproduce the above copyright
26  *    notice, this list of conditions and the following disclaimer in the
27  *    documentation and/or other materials provided with the distribution.
28  * 3. Neither the name of the University nor the names of its contributors
29  *    may be used to endorse or promote products derived from this software
30  *    without specific prior written permission.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
36  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42  * SUCH DAMAGE.
43  *
44  *	@(#)autoconf.c	8.4 (Berkeley) 10/1/93
45  */
46 
47 #include "mpath.h"
48 
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/buf.h>
52 #include <sys/disklabel.h>
53 #include <sys/device.h>
54 #include <sys/disk.h>
55 #include <sys/conf.h>
56 #include <sys/reboot.h>
57 #include <sys/socket.h>
58 #include <sys/malloc.h>
59 #include <sys/queue.h>
60 #include <sys/msgbuf.h>
61 
62 #include <net/if.h>
63 
64 #include <dev/cons.h>
65 #include <dev/clock_subr.h>
66 
67 #include <uvm/uvm_extern.h>
68 
69 #include <machine/bus.h>
70 #include <machine/boot_flag.h>
71 #include <machine/autoconf.h>
72 #include <machine/hypervisor.h>
73 #include <machine/mdesc.h>
74 #include <machine/openfirm.h>
75 #include <machine/sparc64.h>
76 #include <machine/cpu.h>
77 #include <machine/pmap.h>
78 #include <machine/trap.h>
79 #include <sparc64/sparc64/cache.h>
80 #include <sparc64/dev/vbusvar.h>
81 #include <sparc64/dev/cbusvar.h>
82 
83 #include <stand/boot/bootarg.h>
84 
85 #include <dev/ata/atavar.h>
86 #include <dev/pci/pcivar.h>
87 #include <dev/sbus/sbusvar.h>
88 
89 #include <scsi/scsi_all.h>
90 #include <scsi/scsiconf.h>
91 #if NMPATH > 0
92 #include <scsi/mpathvar.h>
93 #endif
94 
95 #ifdef DDB
96 #include <machine/db_machdep.h>
97 #include <ddb/db_sym.h>
98 #include <ddb/db_extern.h>
99 #endif
100 
101 #include "softraid.h"
102 #if NSOFTRAID > 0
103 #include <sys/sensors.h>
104 #include <dev/softraidvar.h>
105 
106 /* XXX */
107 #undef DPRINTF
108 #undef DNPRINTF
109 #endif
110 
111 int printspl = 0;
112 
113 /*
114  * The following several variables are related to
115  * the configuration process, and are used in initializing
116  * the machine.
117  */
118 int	stdinnode;	/* node ID of ROM's console input device */
119 int	fbnode;		/* node ID of ROM's console output device */
120 int	optionsnode;	/* node ID of ROM's options */
121 
122 static	int rootnode;
123 
124 static	char *str2hex(char *, long *);
125 static	int mbprint(void *, const char *);
126 int	mainbus_match(struct device *, void *, void *);
127 static	void mainbus_attach(struct device *, struct device *, void *);
128 int	get_ncpus(void);
129 
130 struct device *booted_device;
131 struct	bootpath bootpath[16];
132 int	nbootpath;
133 int	bootnode;
134 static	void bootpath_build(void);
135 static	void bootpath_print(struct bootpath *);
136 void bootpath_nodes(struct bootpath *, int);
137 
138 struct openbsd_bootdata obd __attribute__((section(".openbsd.bootdata")));
139 
140 void nail_bootdev(struct device *, struct bootpath *);
141 
142 /* Global interrupt mappings for all device types.  Match against the OBP
143  * 'device_type' property.
144  */
145 struct intrmap intrmap[] = {
146 	{ "block",	PIL_FD },	/* Floppy disk */
147 	{ "serial",	PIL_SER },	/* zs */
148 	{ "scsi",	PIL_SCSI },
149 	{ "scsi-2",	PIL_SCSI },
150 	{ "network",	PIL_NET },
151 	{ "display",	PIL_VIDEO },
152 	{ "audio",	PIL_AUD },
153 	{ "ide",	PIL_SCSI },
154 /* The following devices don't have device types: */
155 	{ "SUNW,CS4231",	PIL_AUD },
156 	{ NULL,		0 }
157 };
158 
159 #ifdef SUN4V
160 void	sun4v_soft_state_init(void);
161 void	sun4v_set_soft_state(int, const char *);
162 
163 #define __align32 __attribute__((__aligned__(32)))
164 char sun4v_soft_state_booting[] __align32 = "OpenBSD booting";
165 char sun4v_soft_state_running[] __align32 = "OpenBSD running";
166 
167 void	sun4v_interrupt_init(void);
168 void	sun4v_sdio_init(void);
169 #endif
170 
171 extern void us_tlb_flush_pte(vaddr_t, uint64_t);
172 extern void us3_tlb_flush_pte(vaddr_t, uint64_t);
173 extern void sun4v_tlb_flush_pte(vaddr_t, uint64_t);
174 extern void us_tlb_flush_ctx(uint64_t);
175 extern void us3_tlb_flush_ctx(uint64_t);
176 extern void sun4v_tlb_flush_ctx(uint64_t);
177 
178 void (*sp_tlb_flush_pte)(vaddr_t, uint64_t) = us_tlb_flush_pte;
179 void (*sp_tlb_flush_ctx)(uint64_t) = us_tlb_flush_ctx;
180 
181 #ifdef DEBUG
182 #define ACDB_BOOTDEV	0x1
183 #define	ACDB_PROBE	0x2
184 int autoconf_debug = 0x0;
185 #define DPRINTF(l, s)   do { if (autoconf_debug & l) printf s; } while (0)
186 #else
187 #define DPRINTF(l, s)
188 #endif
189 
190 /*
191  * Convert hex ASCII string to a value.  Returns updated pointer.
192  * Depends on ASCII order (this *is* machine-dependent code, you know).
193  */
194 static char *
str2hex(char * str,long * vp)195 str2hex(char *str, long *vp)
196 {
197 	long v;
198 	int c;
199 
200 	if (*str == 'w') {
201 		for (v = 1;; v++) {
202 			if (str[v] >= '0' && str[v] <= '9')
203 				continue;
204 			if (str[v] >= 'a' && str[v] <= 'f')
205 				continue;
206 			if (str[v] >= 'A' && str[v] <= 'F')
207 				continue;
208 			if (str[v] == '\0' || str[v] == ',')
209 				break;
210 			*vp = 0;
211 			return (str + v);
212 		}
213 		str++;
214 	}
215 
216 	for (v = 0;; v = v * 16 + c, str++) {
217 		c = *(u_char *)str;
218 		if (c <= '9') {
219 			if ((c -= '0') < 0)
220 				break;
221 		} else if (c <= 'F') {
222 			if ((c -= 'A' - 10) < 10)
223 				break;
224 		} else if (c <= 'f') {
225 			if ((c -= 'a' - 10) < 10)
226 				break;
227 		} else
228 			break;
229 	}
230 	*vp = v;
231 	return (str);
232 }
233 
234 /*
235  * Hunt through the device tree for CPUs.  There should be no need to
236  * go more than four levels deep; an UltraSPARC-IV on Seregeti shows
237  * up as /ssm@0,0/cmp@0,0/cpu@0 and a SPARC64-VI will show up as
238  * /cmp@0,0/core@0/cpu@0.
239  */
240 int
get_ncpus(void)241 get_ncpus(void)
242 {
243 	int node, child, stack[4], depth, ncpus;
244 	char buf[32];
245 
246 	stack[0] = findroot();
247 	depth = 0;
248 
249 	ncpus = 0;
250 	for (;;) {
251 		node = stack[depth];
252 
253 		if (node == 0 || node == -1) {
254 			if (--depth < 0)
255 				goto done;
256 
257 			stack[depth] = OF_peer(stack[depth]);
258 			continue;
259 		}
260 
261 		if (OF_getprop(node, "device_type", buf, sizeof(buf)) > 0 &&
262 		    strcmp(buf, "cpu") == 0)
263 			ncpus++;
264 
265 		child = OF_child(node);
266 		if (child != 0 && child != -1 && depth < 3)
267 			stack[++depth] = child;
268 		else
269 			stack[depth] = OF_peer(stack[depth]);
270 	}
271 
272 done:
273 	ncpusfound = ncpus;
274 #ifdef MULTIPROCESSOR
275 	return (ncpus);
276 #else
277 	return (1);
278 #endif
279 }
280 
281 /*
282  * locore.s code calls bootstrap() just before calling main().
283  *
284  * What we try to do is as follows:
285  *
286  * 1) We will try to re-allocate the old message buffer.
287  *
288  * 2) We will then get the list of the total and available
289  *	physical memory and available virtual memory from the
290  *	prom.
291  *
292  * 3) We will pass the list to pmap_bootstrap to manage them.
293  *
294  * We will try to run out of the prom until we get to cpu_init().
295  */
296 void
bootstrap(int nctx)297 bootstrap(int nctx)
298 {
299 	extern int end;	/* End of kernel */
300 	struct trapvec *romtba;
301 #if defined(SUN4US) || defined(SUN4V)
302 	char buf[32];
303 #endif
304 	int impl = 0;
305 	int ncpus;
306 
307 	/* Initialize the PROM console so printf will not panic. */
308 	(*cn_tab->cn_init)(cn_tab);
309 
310 	/*
311 	 * Initialize ddb first and register OBP callbacks.
312 	 * We can do this because ddb_init() does not allocate anything,
313 	 * just initializes some pointers to important things
314 	 * like the symtab.
315 	 *
316 	 * By doing this first and installing the OBP callbacks
317 	 * we get to do symbolic debugging of pmap_bootstrap().
318 	 */
319 #ifdef DDB
320 	db_machine_init();
321 	ddb_init();
322 	/* This can only be installed on an 64-bit system cause otherwise our stack is screwed */
323 	OF_set_symbol_lookup(OF_sym2val, OF_val2sym);
324 #endif
325 
326 #if defined (SUN4US) || defined(SUN4V)
327 	if (OF_getprop(findroot(), "compatible", buf, sizeof(buf)) > 0) {
328 		if (strcmp(buf, "sun4us") == 0)
329 			cputyp = CPU_SUN4US;
330 		if (strcmp(buf, "sun4v") == 0)
331 			cputyp = CPU_SUN4V;
332 	}
333 #endif
334 
335 	/* We cannot read %ver on sun4v systems. */
336 	if (CPU_ISSUN4U || CPU_ISSUN4US)
337 		impl = (getver() & VER_IMPL) >> VER_IMPL_SHIFT;
338 
339 	if (impl >= IMPL_CHEETAH) {
340 		extern vaddr_t dlflush_start;
341 		vaddr_t *pva;
342 		u_int32_t insn;
343 
344 		for (pva = &dlflush_start; *pva; pva++) {
345 			insn = *(u_int32_t *)(*pva);
346 			insn &= ~(ASI_DCACHE_TAG << 5);
347 			insn |= (ASI_DCACHE_INVALIDATE << 5);
348 			*(u_int32_t *)(*pva) = insn;
349 			flush((void *)(*pva));
350 		}
351 
352 		cacheinfo.c_dcache_flush_page = us3_dcache_flush_page;
353 		sp_tlb_flush_pte = us3_tlb_flush_pte;
354 		sp_tlb_flush_ctx = us3_tlb_flush_ctx;
355 	}
356 
357 	if ((impl >= IMPL_ZEUS && impl <= IMPL_JUPITER) || CPU_ISSUN4V) {
358 		extern vaddr_t dlflush_start;
359 		vaddr_t *pva;
360 
361 		for (pva = &dlflush_start; *pva; pva++) {
362 			*(u_int32_t *)(*pva) = 0x01000000; /* nop */
363 			flush((void *)(*pva));
364 		}
365 
366 		cacheinfo.c_dcache_flush_page = no_dcache_flush_page;
367 	}
368 
369 #ifdef MULTIPROCESSOR
370 	if (impl >= IMPL_OLYMPUS_C && impl <= IMPL_JUPITER) {
371 		struct sun4u_patch {
372 			u_int32_t addr;
373 			u_int32_t insn;
374 		} *p;
375 
376 		extern struct sun4u_patch sun4u_mtp_patch;
377 		extern struct sun4u_patch sun4u_mtp_patch_end;
378 
379 		for (p = &sun4u_mtp_patch; p < &sun4u_mtp_patch_end; p++) {
380 			*(u_int32_t *)(vaddr_t)p->addr = p->insn;
381 			flush((void *)(vaddr_t)p->addr);
382 		}
383 	}
384 #endif
385 
386 #ifdef SUN4V
387 	if (CPU_ISSUN4V) {
388 		struct sun4v_patch {
389 			u_int32_t addr;
390 			u_int32_t insn;
391 		} *p;
392 
393 		extern struct sun4v_patch sun4v_patch;
394 		extern struct sun4v_patch sun4v_patch_end;
395 
396 		for (p = &sun4v_patch; p < &sun4v_patch_end; p++) {
397 			*(u_int32_t *)(vaddr_t)p->addr = p->insn;
398 			flush((void *)(vaddr_t)p->addr);
399 		}
400 
401 #ifdef MULTIPROCESSOR
402 		extern struct sun4v_patch sun4v_mp_patch;
403 		extern struct sun4v_patch sun4v_mp_patch_end;
404 
405 		for (p = &sun4v_mp_patch; p < &sun4v_mp_patch_end; p++) {
406 			*(u_int32_t *)(vaddr_t)p->addr = p->insn;
407 			flush((void *)(vaddr_t)p->addr);
408 		}
409 #endif
410 
411 		sp_tlb_flush_pte = sun4v_tlb_flush_pte;
412 		sp_tlb_flush_ctx = sun4v_tlb_flush_ctx;
413 	}
414 #endif
415 
416 	/*
417 	 * Copy over the OBP breakpoint trap vector; OpenFirmware 5.x
418 	 * needs it to be able to return to the ok prompt.
419 	 */
420 	romtba = (struct trapvec *)sparc_rdpr(tba);
421 	bcopy(&romtba[T_MON_BREAKPOINT], &trapbase[T_MON_BREAKPOINT],
422 	    sizeof(struct trapvec));
423 	flush((void *)trapbase);
424 
425 	ncpus = get_ncpus();
426 	pmap_bootstrap(KERNBASE, (u_long)&end, nctx, ncpus);
427 
428 	if (obd.version == BOOTDATA_VERSION &&
429 	    obd.len >= BOOTDATA_LEN_BOOTHOWTO)
430 		boothowto = obd.boothowto;
431 
432 #ifdef SUN4V
433 	if (CPU_ISSUN4V) {
434 		sun4v_soft_state_init();
435 		sun4v_set_soft_state(SIS_TRANSITION, sun4v_soft_state_booting);
436 		sun4v_interrupt_init();
437 		sun4v_sdio_init();
438 	}
439 #endif
440 }
441 
442 void
bootpath_nodes(struct bootpath * bp,int nbp)443 bootpath_nodes(struct bootpath *bp, int nbp)
444 {
445 	int chosen;
446 	int i;
447 	char buf[128], *cp, c;
448 
449 	chosen = OF_finddevice("/chosen");
450 	OF_getprop(chosen, "bootpath", buf, sizeof(buf));
451 	cp = buf;
452 
453 	for (i = 0; i < nbp; i++, bp++) {
454 		if (*cp == '\0')
455 			return;
456 		while (*cp != '\0' && *cp == '/')
457 			cp++;
458 		while (*cp && *cp != '/')
459 			cp++;
460 		c = *cp;
461 		*cp = '\0';
462 		bootnode = bp->node = OF_finddevice(buf);
463 		*cp = c;
464 	}
465 }
466 
467 /*
468  * bootpath_build: build a bootpath. Used when booting a generic
469  * kernel to find our root device.  Newer proms give us a bootpath,
470  * for older proms we have to create one.  An element in a bootpath
471  * has 4 fields: name (device name), val[0], val[1], and val[2]. Note that:
472  * Interpretation of val[] is device-dependent. Some examples:
473  *
474  * if (val[0] == -1) {
475  *	val[1] is a unit number    (happens most often with old proms)
476  * } else {
477  *	[sbus device] val[0] is a sbus slot, and val[1] is an sbus offset
478  *	[scsi disk] val[0] is target, val[1] is lun, val[2] is partition
479  *	[scsi tape] val[0] is target, val[1] is lun, val[2] is file #
480  *	[pci device] val[0] is device, val[1] is function, val[2] might be partition
481  * }
482  *
483  */
484 
485 static void
bootpath_build(void)486 bootpath_build(void)
487 {
488 	register char *cp, *pp;
489 	register struct bootpath *bp;
490 	register long chosen;
491 	char buf[128];
492 
493 	bzero((void *)bootpath, sizeof(bootpath));
494 	bp = bootpath;
495 
496 	/*
497 	 * Grab boot path from PROM
498 	 */
499 	chosen = OF_finddevice("/chosen");
500 	OF_getprop(chosen, "bootpath", buf, sizeof(buf));
501 	cp = buf;
502 	while (cp != NULL && *cp == '/') {
503 		/* Step over '/' */
504 		++cp;
505 		/* Extract name */
506 		pp = bp->name;
507 		while (*cp != '@' && *cp != '/' && *cp != '\0')
508 			*pp++ = *cp++;
509 		*pp = '\0';
510 		if (*cp == '@') {
511 			cp = str2hex(++cp, &bp->val[0]);
512 			if (*cp == ',')
513 				cp = str2hex(++cp, &bp->val[1]);
514 			if (*cp == ':') {
515 				/*
516 				 * We only store one character here, as we will
517 				 * only use this field to compute a partition
518 				 * index for block devices.  However, it might
519 				 * be an ethernet media specification, so be
520 				 * sure to skip all letters.
521 				 */
522 				bp->val[2] = *++cp - 'a';
523 				while (*cp != '\0' && *cp != '/')
524 					cp++;
525 			}
526 		} else {
527 			bp->val[0] = -1; /* no #'s: assume unit 0, no
528 					    sbus offset/address */
529 		}
530 		++bp;
531 		++nbootpath;
532 	}
533 	bp->name[0] = 0;
534 
535 	bootpath_nodes(bootpath, nbootpath);
536 
537 	/* Setup pointer to boot flags */
538 	OF_getprop(chosen, "bootargs", buf, sizeof(buf));
539 	cp = buf;
540 
541 	/* Find start of boot flags */
542 	while (*cp) {
543 		while(*cp == ' ' || *cp == '\t') cp++;
544 		if (*cp == '-' || *cp == '\0')
545 			break;
546 		while(*cp != ' ' && *cp != '\t' && *cp != '\0') cp++;
547 
548 	}
549 	if (*cp != '-')
550 		return;
551 
552 	for (;*++cp;) {
553 		int fl;
554 
555 		fl = 0;
556 		switch(*cp) {
557 		case 'a':
558 			fl |= RB_ASKNAME;
559 			break;
560 		case 'b':
561 			fl |= RB_HALT;
562 			break;
563 		case 'c':
564 			fl |= RB_CONFIG;
565 			break;
566 		case 'd':
567 			fl |= RB_KDB;
568 			break;
569 		case 's':
570 			fl |= RB_SINGLE;
571 			break;
572 		default:
573 			break;
574 		}
575 		if (!fl) {
576 			printf("unknown option `%c'\n", *cp);
577 			continue;
578 		}
579 		boothowto |= fl;
580 
581 		/* specialties */
582 		if (*cp == 'd') {
583 #if defined(DDB)
584 			db_enter();
585 #else
586 			printf("kernel has no debugger\n");
587 #endif
588 		}
589 	}
590 }
591 
592 /*
593  * print out the bootpath
594  * the %x isn't 0x%x because the Sun EPROMs do it this way, and
595  * consistency with the EPROMs is probably better here.
596  */
597 
598 static void
bootpath_print(struct bootpath * bp)599 bootpath_print(struct bootpath *bp)
600 {
601 	printf("bootpath: ");
602 	while (bp->name[0]) {
603 		if (bp->val[0] == -1)
604 			printf("/%s%lx", bp->name, bp->val[1]);
605 		else
606 			printf("/%s@%lx,%lx", bp->name, bp->val[0], bp->val[1]);
607 		if (bp->val[2] != 0)
608 			printf(":%c", (int)bp->val[2] + 'a');
609 		bp++;
610 	}
611 	printf("\n");
612 }
613 
614 
615 /*
616  * save or read a bootpath pointer from the boothpath store.
617  *
618  * XXX. required because of SCSI... we don't have control over the "sd"
619  * device, so we can't set boot device there.   we patch in with
620  * device_register(), and use this to recover the bootpath.
621  */
622 struct bootpath *
bootpath_store(int storep,struct bootpath * bp)623 bootpath_store(int storep, struct bootpath *bp)
624 {
625 	static struct bootpath *save;
626 	struct bootpath *retval;
627 
628 	retval = save;
629 	if (storep)
630 		save = bp;
631 
632 	return (retval);
633 }
634 
635 /*
636  * Determine mass storage and memory configuration for a machine.
637  * We get the PROM's root device and make sure we understand it, then
638  * attach it as `mainbus0'.
639  */
640 void
cpu_configure(void)641 cpu_configure(void)
642 {
643 #ifdef SUN4V
644 	int pause = 0;
645 
646 	if (CPU_ISSUN4V) {
647 		const char *prop;
648 		size_t len;
649 		int idx;
650 
651 		mdesc_init();
652 		idx = mdesc_find_node("cpu");
653 		prop = mdesc_get_prop_data(idx, "hwcap-list", &len);
654 		if (prop) {
655 			while (len > 0) {
656 				if (strcmp(prop, "pause") == 0)
657 					pause = 1;
658 				len -= strlen(prop) + 1;
659 				prop += strlen(prop) + 1;
660 			}
661 		}
662 	}
663 
664 	if (pause) {
665 		struct sun4v_patch {
666 			u_int32_t addr;
667 			u_int32_t insn;
668 		} *p;
669 		paddr_t pa;
670 
671 		extern struct sun4v_patch sun4v_pause_patch;
672 		extern struct sun4v_patch sun4v_pause_patch_end;
673 
674 		/*
675 		 * Use physical addresses to patch since kernel .text
676 		 * is already mapped read-only at this point.
677 		 */
678 		for (p = &sun4v_pause_patch; p < &sun4v_pause_patch_end; p++) {
679 			pmap_extract(pmap_kernel(), (vaddr_t)p->addr, &pa);
680 			stwa(pa, ASI_PHYS_NON_CACHED, p->insn);
681 			flush((void *)(vaddr_t)p->addr);
682 		}
683 	}
684 #endif
685 
686 	if (obd.version == BOOTDATA_VERSION &&
687 	    obd.len >= BOOTDATA_LEN_BOOTHOWTO) {
688 #if NSOFTRAID > 0
689 		memcpy(sr_bootuuid.sui_id, obd.sr_uuid,
690 		    sizeof(sr_bootuuid.sui_id));
691 		memcpy(sr_bootkey, obd.sr_maskkey, sizeof(sr_bootkey));
692 #endif
693 		explicit_bzero(obd.sr_maskkey, sizeof(obd.sr_maskkey));
694 	}
695 
696 	/* build the bootpath */
697 	bootpath_build();
698 
699 	if (boothowto & RB_CONFIG) {
700 #ifdef BOOT_CONFIG
701 		user_config();
702 #else
703 		printf("kernel does not support -c; continuing..\n");
704 #endif
705 	}
706 
707 	/* block clock interrupts and anything below */
708 	splclock();
709 	/* Enable device interrupts */
710         setpstate(getpstate()|PSTATE_IE);
711 
712 	if (config_rootfound("mainbus", NULL) == NULL)
713 		panic("mainbus not configured");
714 
715 	/* Enable device interrupts */
716         setpstate(getpstate()|PSTATE_IE);
717 
718 	(void)spl0();
719 	cold = 0;
720 
721 #ifdef SUN4V
722 	if (CPU_ISSUN4V)
723 		sun4v_set_soft_state(SIS_NORMAL, sun4v_soft_state_running);
724 #endif
725 }
726 
727 #ifdef SUN4V
728 
729 #define HSVC_GROUP_INTERRUPT	0x002
730 #define HSVC_GROUP_SOFT_STATE	0x003
731 #define HSVC_GROUP_SDIO		0x108
732 
733 int sun4v_soft_state_initialized = 0;
734 
735 void
sun4v_soft_state_init(void)736 sun4v_soft_state_init(void)
737 {
738 	uint64_t minor;
739 
740 	if (prom_set_sun4v_api_version(HSVC_GROUP_SOFT_STATE, 1, 0, &minor))
741 		return;
742 
743 	prom_sun4v_soft_state_supported();
744 	sun4v_soft_state_initialized = 1;
745 }
746 
747 void
sun4v_set_soft_state(int state,const char * desc)748 sun4v_set_soft_state(int state, const char *desc)
749 {
750 	paddr_t pa;
751 	int err;
752 
753 	if (!sun4v_soft_state_initialized)
754 		return;
755 
756 	if (!pmap_extract(pmap_kernel(), (vaddr_t)desc, &pa))
757 		panic("sun4v_set_soft_state: pmap_extract failed");
758 
759 	err = hv_soft_state_set(state, pa);
760 	if (err != H_EOK)
761 		printf("soft_state_set: %d\n", err);
762 }
763 
764 void
sun4v_interrupt_init(void)765 sun4v_interrupt_init(void)
766 {
767 	uint64_t minor;
768 
769 	if (prom_set_sun4v_api_version(HSVC_GROUP_INTERRUPT, 3, 0, &minor))
770 		return;
771 
772 	sun4v_group_interrupt_major = 3;
773 }
774 
775 void
sun4v_sdio_init(void)776 sun4v_sdio_init(void)
777 {
778 	uint64_t minor;
779 
780 	if (prom_set_sun4v_api_version(HSVC_GROUP_SDIO, 1, 0, &minor))
781 		return;
782 
783 	sun4v_group_sdio_major = 1;
784 }
785 
786 #endif
787 
788 void
diskconf(void)789 diskconf(void)
790 {
791 	struct bootpath *bp;
792 	struct device *bootdv;
793 
794 	bootpath_print(bootpath);
795 
796 	bp = nbootpath == 0 ? NULL : &bootpath[nbootpath-1];
797 	bootdv = (bp == NULL) ? NULL : bp->dev;
798 
799 #if NMPATH > 0
800 	if (bootdv != NULL)
801 		bootdv = mpath_bootdv(bootdv);
802 #endif
803 
804 	setroot(bootdv, bp->val[2], RB_USERREQ | RB_HALT);
805 	dumpconf();
806 }
807 
808 char *
clockfreq(long freq)809 clockfreq(long freq)
810 {
811 	char *p;
812 	static char buf[10];
813 
814 	freq /= 1000;
815 	snprintf(buf, sizeof buf, "%ld", freq / 1000);
816 	freq %= 1000;
817 	if (freq) {
818 		freq += 1000;	/* now in 1000..1999 */
819 		p = buf + strlen(buf);
820 		snprintf(p, buf + sizeof buf - p, "%ld", freq);
821 		*p = '.';	/* now buf = %d.%3d */
822 	}
823 	return (buf);
824 }
825 
826 static int
mbprint(void * aux,const char * name)827 mbprint(void *aux, const char *name)
828 {
829 	struct mainbus_attach_args *ma = aux;
830 
831 	if (name)
832 		printf("\"%s\" at %s", ma->ma_name, name);
833 	if (ma->ma_address)
834 		printf(" addr 0x%08lx", (u_long)ma->ma_address[0]);
835 	if (ma->ma_pri)
836 		printf(" ipl %d", ma->ma_pri);
837 	return (UNCONF);
838 }
839 
840 int
findroot(void)841 findroot(void)
842 {
843 	int node;
844 
845 	if ((node = rootnode) == 0 && (node = OF_peer(0)) == 0)
846 		panic("no PROM root device");
847 	rootnode = node;
848 	return (node);
849 }
850 
851 /*
852  * Given a `first child' node number, locate the node with the given name.
853  * Return the node number, or 0 if not found.
854  */
855 int
findnode(int first,const char * name)856 findnode(int first, const char *name)
857 {
858 	int node;
859 	char buf[32];
860 
861 	for (node = first; node; node = OF_peer(node)) {
862 		if ((OF_getprop(node, "name", buf, sizeof(buf)) > 0) &&
863 			(strcmp(buf, name) == 0))
864 			return (node);
865 	}
866 	return (0);
867 }
868 
869 int
mainbus_match(struct device * parent,void * cf,void * aux)870 mainbus_match(struct device *parent, void *cf, void *aux)
871 {
872 	return (1);
873 }
874 
875 /*
876  * Attach the mainbus.
877  *
878  * Our main job is to attach the CPU (the root node we got in cpu_configure())
879  * and iterate down the list of `mainbus devices' (children of that node).
880  * We also record the `node id' of the default frame buffer, if any.
881  */
882 static void
mainbus_attach(struct device * parent,struct device * dev,void * aux)883 mainbus_attach(struct device *parent, struct device *dev, void *aux)
884 {
885 extern struct sparc_bus_dma_tag mainbus_dma_tag;
886 extern bus_space_tag_t mainbus_space_tag;
887 
888 	struct mainbus_attach_args ma;
889 	char buf[64];
890 	const char *const *ssp, *sp = NULL;
891 	int node0, node, rv, len;
892 
893 	static const char *const openboot_special[] = {
894 		/* ignore these (end with NULL) */
895 		/*
896 		 * These are _root_ devices to ignore. Others must be handled
897 		 * elsewhere.
898 		 */
899 		"virtual-memory",
900 		"aliases",
901 		"memory",
902 		"openprom",
903 		"options",
904 		"packages",
905 		"chosen",
906 		"counter-timer",
907 		NULL
908 	};
909 
910 	/*
911 	 * Print the "banner-name" property in dmesg.  It provides a
912 	 * description of the machine that is generally more
913 	 * informative than the "name" property.  However, if the
914 	 * "banner-name" property is missing, fall back on the "name"
915 	 * property.
916 	 */
917 	if (OF_getprop(findroot(), "banner-name", buf, sizeof(buf)) > 0 ||
918 	    OF_getprop(findroot(), "name", buf, sizeof(buf)) > 0)
919 		printf(": %s\n", buf);
920 	else
921 		printf("\n");
922 
923 	/*
924 	 * Base the hw.product and hw.vendor strings on the "name"
925 	 * property.  They describe the hardware in a much more
926 	 * consistent way than the "banner-property".
927 	 */
928 	if ((len = OF_getprop(findroot(), "name", buf, sizeof(buf))) > 0) {
929 		hw_prod = malloc(len, M_DEVBUF, M_NOWAIT);
930 		if (hw_prod)
931 			strlcpy(hw_prod, buf, len);
932 
933 		if (strncmp(buf, "SUNW,", 5) == 0)
934 			hw_vendor = "Sun";
935 		if (strncmp(buf, "FJSV,", 5) == 0)
936 			hw_vendor = "Fujitsu";
937 		if (strncmp(buf, "TAD,", 4) == 0)
938 			hw_vendor = "Tadpole";
939 		if (strncmp(buf, "NATE,", 5) == 0)
940 			hw_vendor = "Naturetech";
941 		if (strncmp(buf, "ORCL,", 5) == 0)
942 			hw_vendor = "Oracle";
943 
944 		/*
945 		 * The Momentum Leopard-V advertises itself as
946 		 * SUNW,UltraSPARC-IIi-Engine, but can be
947 		 * distinguished by looking at the "model" property.
948 		 */
949 		if (OF_getprop(findroot(), "model", buf, sizeof(buf)) > 0 &&
950 		    strncmp(buf, "MOMENTUM,", 9) == 0)
951 			hw_vendor = "Momentum";
952 	}
953 
954 	/* Establish the first component of the boot path */
955 	bootpath_store(1, bootpath);
956 
957 	/* We configure the CPUs first. */
958 
959 	node = findroot();
960 	for (node0 = OF_child(node); node0; node0 = OF_peer(node0)) {
961 		if (OF_getprop(node0, "name", buf, sizeof(buf)) <= 0)
962 			continue;
963 	}
964 
965 	for (node = OF_child(node); node; node = OF_peer(node)) {
966 		if (!checkstatus(node))
967 			continue;
968 
969 		/*
970 		 * UltraSPARC-IV cpus appear as two "cpu" nodes below
971 		 * a "cmp" node.
972 		 */
973 		if (OF_getprop(node, "name", buf, sizeof(buf)) <= 0)
974 			continue;
975 		if (strcmp(buf, "cmp") == 0) {
976 			bzero(&ma, sizeof(ma));
977 			ma.ma_node = node;
978 			ma.ma_name = buf;
979 			getprop(node, "reg", sizeof(*ma.ma_reg),
980 			    &ma.ma_nreg, (void **)&ma.ma_reg);
981 			config_found(dev, &ma, mbprint);
982 			continue;
983 		}
984 
985 		if (OF_getprop(node, "device_type", buf, sizeof(buf)) <= 0)
986 			continue;
987 		if (strcmp(buf, "cpu") == 0) {
988 			bzero(&ma, sizeof(ma));
989 			ma.ma_node = node;
990 			OF_getprop(node, "name", buf, sizeof(buf));
991 			if (strcmp(buf, "cpu") == 0)
992 				OF_getprop(node, "compatible", buf, sizeof(buf));
993 			ma.ma_name = buf;
994 			getprop(node, "reg", sizeof(*ma.ma_reg),
995 			    &ma.ma_nreg, (void **)&ma.ma_reg);
996 			config_found(dev, &ma, mbprint);
997 			continue;
998 		}
999 	}
1000 
1001 	node = findroot();	/* re-init root node */
1002 
1003 	/* Find the "options" node */
1004 	node0 = OF_child(node);
1005 	optionsnode = findnode(node0, "options");
1006 	if (optionsnode == 0)
1007 		panic("no options in OPENPROM");
1008 
1009 	for (node0 = OF_child(node); node0; node0 = OF_peer(node0)) {
1010 		if (OF_getprop(node0, "name", buf, sizeof(buf)) <= 0)
1011 			continue;
1012 	}
1013 
1014 	/*
1015 	 * Configure the devices, in PROM order.  Skip
1016 	 * PROM entries that are not for devices, or which must be
1017 	 * done before we get here.
1018 	 */
1019 	for (node = OF_child(node); node; node = OF_peer(node)) {
1020 		int portid;
1021 
1022 		DPRINTF(ACDB_PROBE, ("Node: %x", node));
1023 		if (OF_getprop(node, "device_type", buf, sizeof(buf)) > 0 &&
1024 		    strcmp(buf, "cpu") == 0)
1025 			continue;
1026 		if (OF_getprop(node, "name", buf, sizeof(buf)) > 0 &&
1027 		    strcmp(buf, "cmp") == 0)
1028 			continue;
1029 		DPRINTF(ACDB_PROBE, (" name %s\n", buf));
1030 		for (ssp = openboot_special; (sp = *ssp) != NULL; ssp++)
1031 			if (strcmp(buf, sp) == 0)
1032 				break;
1033 		if (sp != NULL)
1034 			continue; /* an "early" device already configured */
1035 
1036 		if (!checkstatus(node))
1037 			continue;
1038 
1039 		bzero(&ma, sizeof ma);
1040 		ma.ma_bustag = mainbus_space_tag;
1041 		ma.ma_dmatag = &mainbus_dma_tag;
1042 		ma.ma_name = buf;
1043 		ma.ma_node = node;
1044 		if (OF_getprop(node, "upa-portid", &portid, sizeof(portid)) !=
1045 		    sizeof(portid)) {
1046 			if (OF_getprop(node, "portid", &portid,
1047 			    sizeof(portid)) != sizeof(portid))
1048 				portid = -1;
1049 		}
1050 		ma.ma_upaid = portid;
1051 
1052 		if (getprop(node, "reg", sizeof(*ma.ma_reg),
1053 			     &ma.ma_nreg, (void **)&ma.ma_reg) != 0)
1054 			continue;
1055 #ifdef DEBUG
1056 		if (autoconf_debug & ACDB_PROBE) {
1057 			if (ma.ma_nreg)
1058 				printf(" reg %08lx.%08lx\n",
1059 					(long)ma.ma_reg->ur_paddr,
1060 					(long)ma.ma_reg->ur_len);
1061 			else
1062 				printf(" no reg\n");
1063 		}
1064 #endif
1065 		rv = getprop(node, "interrupts", sizeof(*ma.ma_interrupts),
1066 			&ma.ma_ninterrupts, (void **)&ma.ma_interrupts);
1067 		if (rv != 0 && rv != ENOENT) {
1068 			free(ma.ma_reg, M_DEVBUF, 0);
1069 			continue;
1070 		}
1071 #ifdef DEBUG
1072 		if (autoconf_debug & ACDB_PROBE) {
1073 			if (ma.ma_interrupts)
1074 				printf(" interrupts %08x\n",
1075 					*ma.ma_interrupts);
1076 			else
1077 				printf(" no interrupts\n");
1078 		}
1079 #endif
1080 		rv = getprop(node, "address", sizeof(*ma.ma_address),
1081 			&ma.ma_naddress, (void **)&ma.ma_address);
1082 		if (rv != 0 && rv != ENOENT) {
1083 			free(ma.ma_reg, M_DEVBUF, 0);
1084 			free(ma.ma_interrupts, M_DEVBUF, 0);
1085 			continue;
1086 		}
1087 #ifdef DEBUG
1088 		if (autoconf_debug & ACDB_PROBE) {
1089 			if (ma.ma_naddress)
1090 				printf(" address %08x\n",
1091 					*ma.ma_address);
1092 			else
1093 				printf(" no address\n");
1094 		}
1095 #endif
1096 		config_found(dev, &ma, mbprint);
1097 		free(ma.ma_reg, M_DEVBUF, 0);
1098 		free(ma.ma_interrupts, M_DEVBUF, 0);
1099 		free(ma.ma_address, M_DEVBUF, 0);
1100 	}
1101 
1102 	extern int prom_cngetc(dev_t);
1103 
1104 	/* Attach PROM console if no other console attached. */
1105 	if (cn_tab->cn_getc == prom_cngetc) {
1106 		bzero(&ma, sizeof ma);
1107 		ma.ma_name = "pcons";
1108 		config_found(dev, &ma, mbprint);
1109 	}
1110 
1111 	extern todr_chip_handle_t todr_handle;
1112 
1113 	if (todr_handle == NULL) {
1114 		bzero(&ma, sizeof ma);
1115 		ma.ma_name = "prtc";
1116 		config_found(dev, &ma, mbprint);
1117 	}
1118 }
1119 
1120 const struct cfattach mainbus_ca = {
1121 	sizeof(struct device), mainbus_match, mainbus_attach
1122 };
1123 
1124 int
getprop(int node,char * name,size_t size,int * nitem,void ** bufp)1125 getprop(int node, char *name, size_t size, int *nitem, void **bufp)
1126 {
1127 	void	*buf;
1128 	long	len;
1129 
1130 	*nitem = 0;
1131 	len = getproplen(node, name);
1132 	if (len <= 0)
1133 		return (ENOENT);
1134 
1135 	if ((len % size) != 0)
1136 		return (EINVAL);
1137 
1138 	buf = *bufp;
1139 	if (buf == NULL) {
1140 		/* No storage provided, so we allocate some */
1141 		buf = malloc(len + 1, M_DEVBUF, M_NOWAIT);
1142 		if (buf == NULL)
1143 			return (ENOMEM);
1144 	}
1145 
1146 	OF_getprop(node, name, buf, len);
1147 	*bufp = buf;
1148 	*nitem = len / size;
1149 	return (0);
1150 }
1151 
1152 
1153 /*
1154  * Internal form of proplen().  Returns the property length.
1155  */
1156 long
getproplen(int node,char * name)1157 getproplen(int node, char *name)
1158 {
1159 	return (OF_getproplen(node, name));
1160 }
1161 
1162 /*
1163  * Return a string property.  There is a (small) limit on the length;
1164  * the string is fetched into a static buffer which is overwritten on
1165  * subsequent calls.
1166  */
1167 char *
getpropstring(int node,char * name)1168 getpropstring(int node, char *name)
1169 {
1170 	static char stringbuf[32];
1171 
1172 	return (getpropstringA(node, name, stringbuf));
1173 }
1174 
1175 /* Alternative getpropstring(), where caller provides the buffer */
1176 char *
getpropstringA(int node,char * name,char * buffer)1177 getpropstringA(int node, char *name, char *buffer)
1178 {
1179 	int blen;
1180 
1181 	if (getprop(node, name, 1, &blen, (void **)&buffer) != 0)
1182 		blen = 0;
1183 
1184 	buffer[blen] = '\0';	/* usually unnecessary */
1185 	return (buffer);
1186 }
1187 
1188 /*
1189  * Fetch an integer (or pointer) property.
1190  * The return value is the property, or the default if there was none.
1191  */
1192 int
getpropint(int node,char * name,int deflt)1193 getpropint(int node, char *name, int deflt)
1194 {
1195 	int intbuf;
1196 
1197 	if (OF_getprop(node, name, &intbuf, sizeof(intbuf)) != sizeof(intbuf))
1198 		return (deflt);
1199 
1200 	return (intbuf);
1201 }
1202 
1203 int
getpropspeed(int node,char * name)1204 getpropspeed(int node, char *name)
1205 {
1206 	char buf[128];
1207 	int i, speed = 0;
1208 
1209 	if (OF_getprop(node, name, buf, sizeof(buf)) != -1) {
1210 		for (i = 0; i < sizeof(buf); i++) {
1211 			if (buf[i] < '0' || buf[i] > '9')
1212 				break;
1213 			speed *= 10;
1214 			speed += buf[i] - '0';
1215 		}
1216 	}
1217 
1218 	if (speed == 0)
1219 		speed = 9600;
1220 
1221 	return (speed);
1222 }
1223 
1224 /*
1225  * OPENPROM functions.  These are here mainly to hide the OPENPROM interface
1226  * from the rest of the kernel.
1227  */
1228 int
firstchild(int node)1229 firstchild(int node)
1230 {
1231 
1232 	return OF_child(node);
1233 }
1234 
1235 int
nextsibling(int node)1236 nextsibling(int node)
1237 {
1238 
1239 	return OF_peer(node);
1240 }
1241 
1242 int
checkstatus(int node)1243 checkstatus(int node)
1244 {
1245 	char buf[32];
1246 
1247 	/* If there is no "status" property, assume everything is fine. */
1248 	if (OF_getprop(node, "status", buf, sizeof(buf)) <= 0)
1249 		return 1;
1250 
1251 	/*
1252 	 * If OpenBoot Diagnostics discovers a problem with a device
1253 	 * it will mark it with "fail" or "fail-xxx", where "xxx" is
1254 	 * additional human-readable information about the particular
1255 	 * fault-condition.
1256 	 */
1257 	if (strcmp(buf, "disabled") == 0 || strncmp(buf, "fail", 4) == 0)
1258 		return 0;
1259 
1260 	return 1;
1261 }
1262 
1263 /* returns 1 if node has given property */
1264 int
node_has_property(int node,const char * prop)1265 node_has_property(int node, const char *prop)
1266 {
1267 	return (OF_getproplen(node, (caddr_t)prop) != -1);
1268 }
1269 
1270 /*
1271  * Try to figure out where the PROM stores the cursor row & column
1272  * variables.  Returns nonzero on error.
1273  */
1274 int
romgetcursoraddr(int ** rowp,int ** colp)1275 romgetcursoraddr(int **rowp, int **colp)
1276 {
1277 	cell_t row = 0, col = 0;
1278 
1279 	OF_interpret("stdout @ is my-self addr line# addr column# ",
1280 	    2, &col, &row);
1281 
1282 	/*
1283 	 * We are running on a 64-bit big-endian machine, so these things
1284 	 * point to 64-bit big-endian values.  To convert them to pointers
1285 	 * to int, add 4 to the address.
1286 	 */
1287 	if (row == 0 || col == 0)
1288 		return (-1);
1289 	*rowp = (int *)(row + 4);
1290 	*colp = (int *)(col + 4);
1291 	return (0);
1292 }
1293 
1294 void
callrom(void)1295 callrom(void)
1296 {
1297 
1298 	__asm volatile("wrpr	%%g0, 0, %%tl" : );
1299 	OF_enter();
1300 }
1301 
1302 /*
1303  * find a device matching "name" and unit number
1304  */
1305 struct device *
getdevunit(const char * name,int unit)1306 getdevunit(const char *name, int unit)
1307 {
1308 	struct device *dev = TAILQ_FIRST(&alldevs);
1309 	char num[10], fullname[16];
1310 	int lunit;
1311 
1312 	/* compute length of name and decimal expansion of unit number */
1313 	snprintf(num, sizeof num, "%d", unit);
1314 	lunit = strlen(num);
1315 	if (strlen(name) + lunit >= sizeof(fullname) - 1)
1316 		panic("config_attach: device name too long");
1317 
1318 	strlcpy(fullname, name, sizeof fullname);
1319 	strlcat(fullname, num, sizeof fullname);
1320 
1321 	while (strcmp(dev->dv_xname, fullname) != 0) {
1322 		if ((dev = TAILQ_NEXT(dev, dv_list)) == NULL)
1323 			return NULL;
1324 	}
1325 	return dev;
1326 }
1327 
1328 void
device_register(struct device * dev,void * aux)1329 device_register(struct device *dev, void *aux)
1330 {
1331 	struct mainbus_attach_args *ma = aux;
1332 	struct pci_attach_args *pa = aux;
1333 	struct sbus_attach_args *sa = aux;
1334 	struct vbus_attach_args *va = aux;
1335 	struct cbus_attach_args *ca = aux;
1336 	struct bootpath *bp = bootpath_store(0, NULL);
1337 	struct device *busdev = dev->dv_parent;
1338 	const char *devname = dev->dv_cfdata->cf_driver->cd_name;
1339 	const char *busname;
1340 	int node = -1;
1341 
1342 	/*
1343 	 * There is no point in continuing if we've exhausted all
1344 	 * bootpath components.
1345 	 */
1346 	if (bp == NULL)
1347 		return;
1348 
1349 	DPRINTF(ACDB_BOOTDEV,
1350 	    ("\n%s: device_register: devname %s(%s) component %s\n",
1351 	    dev->dv_xname, devname, dev->dv_xname, bp->name));
1352 
1353 	/*
1354 	 * Ignore mainbus0 itself, it certainly is not a boot device.
1355 	 */
1356 	if (busdev == NULL)
1357 		return;
1358 
1359 	/*
1360 	 * We don't know the type of 'aux'; it depends on the bus this
1361 	 * device attaches to.  We are only interested in certain bus
1362 	 * types; this is only used to find the boot device.
1363 	 */
1364 	busname = busdev->dv_cfdata->cf_driver->cd_name;
1365 	if (strcmp(busname, "mainbus") == 0 ||
1366 	    strcmp(busname, "ssm") == 0 || strcmp(busname, "upa") == 0)
1367 		node = ma->ma_node;
1368 	else if (strcmp(busname, "sbus") == 0 ||
1369 	    strcmp(busname, "dma") == 0 || strcmp(busname, "ledma") == 0)
1370 		node = sa->sa_node;
1371 	else if (strcmp(busname, "vbus") == 0)
1372 		node = va->va_node;
1373 	else if (strcmp(busname, "cbus") == 0)
1374 		node = ca->ca_node;
1375 	else if (strcmp(busname, "pci") == 0)
1376 		node = PCITAG_NODE(pa->pa_tag);
1377 
1378 	if (node == bootnode) {
1379 		if (strcmp(devname, "vdsk") == 0) {
1380 			/*
1381 			 * For virtual disks, don't nail the boot
1382 			 * device just yet.  Instead, we add fake a
1383 			 * SCSI target/lun, such that we match it the
1384 			 * next time around.
1385 			 */
1386 			bp->dev = dev;
1387 			(bp + 1)->val[0] = 0;
1388 			(bp + 1)->val[1] = 0;
1389 			nbootpath++;
1390 			bootpath_store(1, bp + 1);
1391 			return;
1392 		}
1393 
1394 		nail_bootdev(dev, bp);
1395 		return;
1396 	}
1397 
1398 	if (node == bp->node) {
1399 		bp->dev = dev;
1400 		DPRINTF(ACDB_BOOTDEV, ("\t-- matched component %s to %s\n",
1401 		    bp->name, dev->dv_xname));
1402 		bootpath_store(1, bp + 1);
1403 		return;
1404 	}
1405 
1406 	if (strcmp(devname, "scsibus") == 0) {
1407 		/*
1408 		 * Booting from anything but the first (physical) port
1409 		 * isn't supported by OBP.
1410 		 */
1411 		if (strcmp(bp->name, "fp") == 0 && bp->val[0] == 0) {
1412 			DPRINTF(ACDB_BOOTDEV, ("\t-- matched component %s to %s\n",
1413 			    bp->name, dev->dv_xname));
1414 			bootpath_store(1, bp + 1);
1415 			return;
1416 		}
1417 	}
1418 
1419 	if (strcmp(busname, "scsibus") == 0) {
1420 		/*
1421 		 * A SCSI disk or cd; retrieve target/lun information
1422 		 * from parent and match with current bootpath component.
1423 		 * Note that we also have look back past the `scsibus'
1424 		 * device to determine whether this target is on the
1425 		 * correct controller in our boot path.
1426 		 */
1427 		struct scsi_attach_args *sa = aux;
1428 		struct scsi_link *sl = sa->sa_sc_link;
1429 		u_int target = bp->val[0];
1430 		u_int lun = bp->val[1];
1431 
1432 		if (bp->val[0] & 0xffffffff00000000 && bp->val[0] != -1) {
1433 			/* Hardware RAID or Fibre channel? */
1434 			if (bp->val[0] == sl->port_wwn && lun == sl->lun) {
1435 				nail_bootdev(dev, bp);
1436 			}
1437 
1438 			/*
1439 			 * sata devices on some controllers don't get
1440 			 * port_wwn filled in, so look at devid too.
1441 			 */
1442 			if (sl->id && sl->id->d_len == 8 &&
1443 			    sl->id->d_type == DEVID_NAA &&
1444 			    memcmp(sl->id + 1, &bp->val[0], 8) == 0)
1445 				nail_bootdev(dev, bp);
1446 			return;
1447 		}
1448 
1449 		/* Check the controller that this scsibus is on. */
1450 		if ((bp-1)->dev != sl->bus->sc_dev.dv_parent)
1451 			return;
1452 
1453 		/*
1454 		 * Bounds check: we know the target and lun widths.
1455 		 */
1456 		if (target >= sl->bus->sb_adapter_buswidth ||
1457 		    lun >= sl->bus->sb_luns) {
1458 			printf("SCSI disk bootpath component not accepted: "
1459 			       "target %u; lun %u\n", target, lun);
1460 			return;
1461 		}
1462 
1463 		if (target == sl->target && lun == sl->lun) {
1464 			nail_bootdev(dev, bp);
1465 			return;
1466 		}
1467 	}
1468 
1469 	if (strcmp("wd", devname) == 0) {
1470 		/* IDE disks. */
1471 		struct ata_atapi_attach *aa = aux;
1472 		u_int channel, drive;
1473 
1474 		if (strcmp(bp->name, "ata") == 0 &&
1475 		    bp->val[0] == aa->aa_channel) {
1476 			channel = bp->val[0]; bp++;
1477 			drive = bp->val[0];
1478 		} else {
1479 			channel = bp->val[0] / 2;
1480 			drive = bp->val[0] % 2;
1481 		}
1482 
1483 		if (channel == aa->aa_channel &&
1484 		    drive == aa->aa_drv_data->drive) {
1485 			nail_bootdev(dev, bp);
1486 			return;
1487 		}
1488 	}
1489 }
1490 
1491 void
nail_bootdev(struct device * dev,struct bootpath * bp)1492 nail_bootdev(struct device *dev, struct bootpath *bp)
1493 {
1494 
1495 	if (bp->dev != NULL)
1496 		panic("device_register: already got a boot device: %s",
1497 			bp->dev->dv_xname);
1498 
1499 	/*
1500 	 * Mark this bootpath component by linking it to the matched
1501 	 * device. We pick up the device pointer in cpu_rootconf().
1502 	 */
1503 	booted_device = bp->dev = dev;
1504 	DPRINTF(ACDB_BOOTDEV, ("\t-- found bootdevice: %s\n",dev->dv_xname));
1505 
1506 	/*
1507 	 * Then clear the current bootpath component, so we don't spuriously
1508 	 * match similar instances on other busses, e.g. a disk on
1509 	 * another SCSI bus with the same target.
1510 	 */
1511 	bootpath_store(1, NULL);
1512 }
1513 
1514 const struct nam2blk nam2blk[] = {
1515 	{ "rd",		 5 },
1516 	{ "sd",		 7 },
1517 	{ "vnd",	 8 },
1518 	{ "wd",		12 },
1519 	{ "fd",		16 },
1520 	{ "cd",		18 },
1521 	{ NULL,		-1 }
1522 };
1523