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