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