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