1 /* $NetBSD: autoconf.c,v 1.68 2002/11/03 01:54:45 mrg 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 "opt_ddb.h" 51 #include "opt_kgdb.h" 52 53 #include <sys/param.h> 54 #include <sys/systm.h> 55 #include <sys/buf.h> 56 #include <sys/disklabel.h> 57 #include <sys/device.h> 58 #include <sys/disk.h> 59 #include <sys/dkstat.h> 60 #include <sys/conf.h> 61 #include <sys/reboot.h> 62 #include <sys/socket.h> 63 #include <sys/malloc.h> 64 #include <sys/queue.h> 65 #include <sys/msgbuf.h> 66 #include <sys/boot_flag.h> 67 68 #include <net/if.h> 69 70 #include <dev/cons.h> 71 72 #include <uvm/uvm_extern.h> 73 74 #include <machine/bus.h> 75 #include <machine/autoconf.h> 76 #include <machine/openfirm.h> 77 #include <machine/sparc64.h> 78 #include <machine/cpu.h> 79 #include <machine/pmap.h> 80 #include <sparc64/sparc64/timerreg.h> 81 82 #include <dev/ata/atavar.h> 83 #include <dev/ata/wdvar.h> 84 #include <dev/pci/pcivar.h> 85 #include <dev/sbus/sbusvar.h> 86 87 #ifdef DDB 88 #include <machine/db_machdep.h> 89 #include <ddb/db_sym.h> 90 #include <ddb/db_extern.h> 91 #endif 92 93 94 int printspl = 0; 95 96 /* 97 * The following several variables are related to 98 * the configuration process, and are used in initializing 99 * the machine. 100 */ 101 int stdinnode; /* node ID of ROM's console input device */ 102 int fbnode; /* node ID of ROM's console output device */ 103 int optionsnode; /* node ID of ROM's options */ 104 105 #ifdef KGDB 106 extern int kgdb_debug_panic; 107 #endif 108 109 static int rootnode; 110 char platform_type[32]; 111 112 static char *str2hex __P((char *, int *)); 113 static int mbprint __P((void *, const char *)); 114 static void crazymap __P((char *, int *)); 115 int st_crazymap __P((int)); 116 void sync_crash __P((void)); 117 int mainbus_match __P((struct device *, struct cfdata *, void *)); 118 static void mainbus_attach __P((struct device *, struct device *, void *)); 119 120 struct bootpath bootpath[8]; 121 int nbootpath; 122 static void bootpath_build __P((void)); 123 static void bootpath_print __P((struct bootpath *)); 124 125 /* Global interrupt mappings for all device types. Match against the OBP 126 * 'device_type' property. 127 */ 128 struct intrmap intrmap[] = { 129 { "block", PIL_FD }, /* Floppy disk */ 130 { "serial", PIL_SER }, /* zs */ 131 { "scsi", PIL_SCSI }, 132 { "network", PIL_NET }, 133 { "display", PIL_VIDEO }, 134 { "audio", PIL_AUD }, 135 { "ide", PIL_SCSI }, 136 /* The following devices don't have device types: */ 137 { "SUNW,CS4231", PIL_AUD }, 138 { NULL, 0 } 139 }; 140 141 #ifdef DEBUG 142 #define ACDB_BOOTDEV 0x1 143 #define ACDB_PROBE 0x2 144 int autoconf_debug = 0x0; 145 #define DPRINTF(l, s) do { if (autoconf_debug & l) printf s; } while (0) 146 #else 147 #define DPRINTF(l, s) 148 #endif 149 150 /* 151 * Most configuration on the SPARC is done by matching OPENPROM Forth 152 * device names with our internal names. 153 */ 154 int 155 matchbyname(parent, cf, aux) 156 struct device *parent; 157 struct cfdata *cf; 158 void *aux; 159 { 160 printf("%s: WARNING: matchbyname\n", cf->cf_name); 161 return (0); 162 } 163 164 /* 165 * Convert hex ASCII string to a value. Returns updated pointer. 166 * Depends on ASCII order (this *is* machine-dependent code, you know). 167 */ 168 static char * 169 str2hex(str, vp) 170 register char *str; 171 register int *vp; 172 { 173 register int v, c; 174 175 for (v = 0;; v = v * 16 + c, str++) { 176 c = *(u_char *)str; 177 if (c <= '9') { 178 if ((c -= '0') < 0) 179 break; 180 } else if (c <= 'F') { 181 if ((c -= 'A' - 10) < 10) 182 break; 183 } else if (c <= 'f') { 184 if ((c -= 'a' - 10) < 10) 185 break; 186 } else 187 break; 188 } 189 *vp = v; 190 return (str); 191 } 192 193 /* 194 * locore.s code calls bootstrap() just before calling main(). 195 * 196 * What we try to do is as follows: 197 * 198 * 1) We will try to re-allocate the old message buffer. 199 * 200 * 2) We will then get the list of the total and available 201 * physical memory and available virtual memory from the 202 * prom. 203 * 204 * 3) We will pass the list to pmap_bootstrap to manage them. 205 * 206 * We will try to run out of the prom until we get to cpu_init(). 207 */ 208 void 209 bootstrap(nctx) 210 int nctx; 211 { 212 extern int end; /* End of kernel */ 213 #if defined(DDB) && defined(DB_ELF_SYMBOLS) 214 extern void *ssym, *esym; 215 #endif 216 #ifndef __arch64__ 217 /* Assembly glue for the PROM */ 218 extern void OF_sym2val32 __P((void *)); 219 extern void OF_val2sym32 __P((void *)); 220 #endif 221 222 /* 223 * Initialize ddb first and register OBP callbacks. 224 * We can do this because ddb_init() does not allocate anything, 225 * just initialze some pointers to important things 226 * like the symtab. 227 * 228 * By doing this first and installing the OBP callbacks 229 * we get to do symbolic debugging of pmap_bootstrap(). 230 */ 231 #ifdef KGDB 232 /* Moved zs_kgdb_init() to dev/zs.c:consinit(). */ 233 zs_kgdb_init(); /* XXX */ 234 #endif 235 /* Initialize the PROM console so printf will not panic */ 236 (*cn_tab->cn_init)(cn_tab); 237 #ifdef DDB 238 #ifdef DB_ELF_SYMBOLS 239 ddb_init((int)((caddr_t)esym - (caddr_t)ssym), ssym, esym); 240 #else 241 ddb_init(); 242 #endif 243 #ifdef __arch64__ 244 /* This can only be installed on an 64-bit system cause otherwise our stack is screwed */ 245 OF_set_symbol_lookup(OF_sym2val, OF_val2sym); 246 #else 247 #if 1 248 OF_set_symbol_lookup(OF_sym2val32, OF_val2sym32); 249 #endif 250 #endif 251 #endif 252 253 pmap_bootstrap(KERNBASE, (u_long)&end, nctx); 254 } 255 256 /* 257 * bootpath_build: build a bootpath. Used when booting a generic 258 * kernel to find our root device. Newer proms give us a bootpath, 259 * for older proms we have to create one. An element in a bootpath 260 * has 4 fields: name (device name), val[0], val[1], and val[2]. Note that: 261 * Interpretation of val[] is device-dependent. Some examples: 262 * 263 * if (val[0] == -1) { 264 * val[1] is a unit number (happens most often with old proms) 265 * } else { 266 * [sbus device] val[0] is a sbus slot, and val[1] is an sbus offset 267 * [scsi disk] val[0] is target, val[1] is lun, val[2] is partition 268 * [scsi tape] val[0] is target, val[1] is lun, val[2] is file # 269 * [pci device] val[0] is device, val[1] is function, val[2] might be partition 270 * } 271 * 272 */ 273 274 static void 275 bootpath_build() 276 { 277 register char *cp, *pp; 278 register struct bootpath *bp; 279 register long chosen; 280 char buf[128]; 281 282 bzero((void*)bootpath, sizeof(bootpath)); 283 bp = bootpath; 284 285 /* 286 * Grab boot path from PROM 287 */ 288 chosen = OF_finddevice("/chosen"); 289 OF_getprop(chosen, "bootpath", buf, sizeof(buf)); 290 cp = buf; 291 while (cp != NULL && *cp == '/') { 292 /* Step over '/' */ 293 ++cp; 294 /* Extract name */ 295 pp = bp->name; 296 while (*cp != '@' && *cp != '/' && *cp != '\0') 297 *pp++ = *cp++; 298 *pp = '\0'; 299 if (*cp == '@') { 300 cp = str2hex(++cp, &bp->val[0]); 301 if (*cp == ',') 302 cp = str2hex(++cp, &bp->val[1]); 303 if (*cp == ':') 304 /* XXX - we handle just one char */ 305 bp->val[2] = *++cp - 'a', ++cp; 306 } else { 307 bp->val[0] = -1; /* no #'s: assume unit 0, no 308 sbus offset/adddress */ 309 } 310 ++bp; 311 ++nbootpath; 312 } 313 bp->name[0] = 0; 314 315 bootpath_print(bootpath); 316 317 /* Setup pointer to boot flags */ 318 OF_getprop(chosen, "bootargs", buf, sizeof(buf)); 319 cp = buf; 320 321 /* Find start of boot flags */ 322 while (*cp) { 323 while(*cp == ' ' || *cp == '\t') cp++; 324 if (*cp == '-' || *cp == '\0') 325 break; 326 while(*cp != ' ' && *cp != '\t' && *cp != '\0') cp++; 327 328 } 329 if (*cp != '-') 330 return; 331 332 for (;*++cp;) { 333 int fl; 334 335 fl = 0; 336 BOOT_FLAG(*cp, fl); 337 if (!fl) { 338 printf("unknown option `%c'\n", *cp); 339 continue; 340 } 341 boothowto |= fl; 342 343 /* specialties */ 344 if (*cp == 'd') { 345 #if defined(KGDB) 346 kgdb_debug_panic = 1; 347 kgdb_connect(1); 348 #elif defined(DDB) 349 Debugger(); 350 #else 351 printf("kernel has no debugger\n"); 352 #endif 353 } else if (*cp == 't') { 354 /* turn on traptrace w/o breaking into kdb */ 355 extern int trap_trace_dis; 356 357 trap_trace_dis = 0; 358 } 359 } 360 } 361 362 /* 363 * print out the bootpath 364 * the %x isn't 0x%x because the Sun EPROMs do it this way, and 365 * consistency with the EPROMs is probably better here. 366 */ 367 368 static void 369 bootpath_print(bp) 370 struct bootpath *bp; 371 { 372 printf("bootpath: "); 373 while (bp->name[0]) { 374 if (bp->val[0] == -1) 375 printf("/%s%x", bp->name, bp->val[1]); 376 else 377 printf("/%s@%x,%x", bp->name, bp->val[0], bp->val[1]); 378 if (bp->val[2] != 0) 379 printf(":%c", bp->val[2] + 'a'); 380 bp++; 381 } 382 printf("\n"); 383 } 384 385 386 /* 387 * save or read a bootpath pointer from the boothpath store. 388 * 389 * XXX. required because of SCSI... we don't have control over the "sd" 390 * device, so we can't set boot device there. we patch in with 391 * dk_establish(), and use this to recover the bootpath. 392 */ 393 struct bootpath * 394 bootpath_store(storep, bp) 395 int storep; 396 struct bootpath *bp; 397 { 398 static struct bootpath *save; 399 struct bootpath *retval; 400 401 retval = save; 402 if (storep) 403 save = bp; 404 405 return (retval); 406 } 407 408 /* 409 * Set up the sd target mappings for non SUN4 PROMs. 410 * Find out about the real SCSI target, given the PROM's idea of the 411 * target of the (boot) device (i.e., the value in bp->v0val[0]). 412 */ 413 static void 414 crazymap(prop, map) 415 char *prop; 416 int *map; 417 { 418 int i; 419 420 /* 421 * Set up the identity mapping for old sun4 monitors 422 * and v[2-] OpenPROMs. Note: dkestablish() does the 423 * SCSI-target juggling for sun4 monitors. 424 */ 425 for (i = 0; i < 8; ++i) 426 map[i] = i; 427 } 428 429 int 430 sd_crazymap(n) 431 int n; 432 { 433 static int prom_sd_crazymap[8]; /* static: compute only once! */ 434 static int init = 0; 435 436 if (init == 0) { 437 crazymap("sd-targets", prom_sd_crazymap); 438 init = 1; 439 } 440 return prom_sd_crazymap[n]; 441 } 442 443 int 444 st_crazymap(n) 445 int n; 446 { 447 static int prom_st_crazymap[8]; /* static: compute only once! */ 448 static int init = 0; 449 450 if (init == 0) { 451 crazymap("st-targets", prom_st_crazymap); 452 init = 1; 453 } 454 return prom_st_crazymap[n]; 455 } 456 457 458 /* 459 * Determine mass storage and memory configuration for a machine. 460 * We get the PROM's root device and make sure we understand it, then 461 * attach it as `mainbus0'. We also set up to handle the PROM `sync' 462 * command. 463 */ 464 void 465 cpu_configure() 466 { 467 468 /* build the bootpath */ 469 bootpath_build(); 470 471 #if notyet 472 /* FIXME FIXME FIXME This is probably *WRONG!!!**/ 473 OF_set_callback(sync_crash); 474 #endif 475 476 /* block clock interrupts and anything below */ 477 splclock(); 478 /* Enable device interrupts */ 479 setpstate(getpstate()|PSTATE_IE); 480 481 if (config_rootfound("mainbus", NULL) == NULL) 482 panic("mainbus not configured"); 483 484 /* Enable device interrupts */ 485 setpstate(getpstate()|PSTATE_IE); 486 487 (void)spl0(); 488 } 489 490 491 void 492 cpu_rootconf() 493 { 494 struct bootpath *bp; 495 struct device *bootdv; 496 int bootpartition; 497 498 bp = nbootpath == 0 ? NULL : &bootpath[nbootpath-1]; 499 bootdv = bp == NULL ? NULL : bp->dev; 500 bootpartition = bootdv == NULL ? 0 : bp->val[2]; 501 502 setroot(bootdv, bootpartition); 503 } 504 505 /* 506 * Console `sync' command. SunOS just does a `panic: zero' so I guess 507 * no one really wants anything fancy... 508 */ 509 void 510 sync_crash() 511 { 512 513 panic("PROM sync command"); 514 } 515 516 char * 517 clockfreq(freq) 518 long freq; 519 { 520 char *p; 521 static char buf[10]; 522 523 freq /= 1000; 524 sprintf(buf, "%ld", freq / 1000); 525 freq %= 1000; 526 if (freq) { 527 freq += 1000; /* now in 1000..1999 */ 528 p = buf + strlen(buf); 529 sprintf(p, "%ld", freq); 530 *p = '.'; /* now buf = %d.%3d */ 531 } 532 return (buf); 533 } 534 535 /* ARGSUSED */ 536 static int 537 mbprint(aux, name) 538 void *aux; 539 const char *name; 540 { 541 struct mainbus_attach_args *ma = aux; 542 543 if (name) 544 printf("%s at %s", ma->ma_name, name); 545 if (ma->ma_address) 546 printf(" addr 0x%08lx", (u_long)ma->ma_address[0]); 547 if (ma->ma_pri) 548 printf(" ipl %d", ma->ma_pri); 549 return (UNCONF); 550 } 551 552 int 553 findroot() 554 { 555 register int node; 556 557 if ((node = rootnode) == 0 && (node = OF_peer(0)) == 0) 558 panic("no PROM root device"); 559 rootnode = node; 560 return (node); 561 } 562 563 /* 564 * Given a `first child' node number, locate the node with the given name. 565 * Return the node number, or 0 if not found. 566 */ 567 int 568 findnode(first, name) 569 int first; 570 register const char *name; 571 { 572 int node; 573 char buf[32]; 574 575 for (node = first; node; node = OF_peer(node)) { 576 if ((OF_getprop(node, "name", buf, sizeof(buf)) > 0) && 577 (strcmp(buf, name) == 0)) 578 return (node); 579 } 580 return (0); 581 } 582 583 int 584 mainbus_match(parent, cf, aux) 585 struct device *parent; 586 struct cfdata *cf; 587 void *aux; 588 { 589 590 return (1); 591 } 592 593 int autoconf_nzs = 0; /* must be global so obio.c can see it */ 594 595 /* 596 * Attach the mainbus. 597 * 598 * Our main job is to attach the CPU (the root node we got in configure()) 599 * and iterate down the list of `mainbus devices' (children of that node). 600 * We also record the `node id' of the default frame buffer, if any. 601 */ 602 static void 603 mainbus_attach(parent, dev, aux) 604 struct device *parent, *dev; 605 void *aux; 606 { 607 extern struct sparc_bus_dma_tag mainbus_dma_tag; 608 extern struct sparc_bus_space_tag mainbus_space_tag; 609 610 struct mainbus_attach_args ma; 611 char buf[32]; 612 const char *const *ssp, *sp = NULL; 613 int node0, node, rv; 614 615 static const char *const openboot_special[] = { 616 /* ignore these (end with NULL) */ 617 /* 618 * These are _root_ devices to ignore. Others must be handled 619 * elsewhere. 620 */ 621 "virtual-memory", 622 "aliases", 623 "memory", 624 "openprom", 625 "options", 626 "packages", 627 "chosen", 628 NULL 629 }; 630 631 OF_getprop(findroot(), "name", platform_type, sizeof(platform_type)); 632 printf(": %s\n", platform_type); 633 634 /* 635 * Locate and configure the ``early'' devices. These must be 636 * configured before we can do the rest. For instance, the 637 * EEPROM contains the Ethernet address for the LANCE chip. 638 * If the device cannot be located or configured, panic. 639 */ 640 641 node = findroot(); 642 643 /* Establish the first component of the boot path */ 644 bootpath_store(1, bootpath); 645 646 /* first early device to be configured is the cpu */ 647 for (node = OF_child(node); node; node = OF_peer(node)) { 648 if (OF_getprop(node, "device_type", buf, sizeof(buf)) <= 0) 649 continue; 650 if (strcmp(buf, "cpu") != 0) 651 continue; 652 bzero(&ma, sizeof(ma)); 653 ma.ma_bustag = &mainbus_space_tag; 654 ma.ma_dmatag = &mainbus_dma_tag; 655 ma.ma_node = node; 656 ma.ma_name = "cpu"; 657 config_found(dev, &ma, mbprint); 658 break; 659 } 660 if (node == 0) 661 panic("None of the CPUs found"); 662 663 node = findroot(); /* re-init root node */ 664 665 /* Find the "options" node */ 666 node0 = OF_child(node); 667 optionsnode = findnode(node0, "options"); 668 if (optionsnode == 0) 669 panic("no options in OPENPROM"); 670 671 /* 672 * Configure the devices, in PROM order. Skip 673 * PROM entries that are not for devices, or which must be 674 * done before we get here. 675 */ 676 for (node = node0; node; node = OF_peer(node)) { 677 int portid; 678 679 DPRINTF(ACDB_PROBE, ("Node: %x", node)); 680 if ((OF_getprop(node, "device_type", buf, sizeof(buf)) > 0) && 681 strcmp(buf, "cpu") == 0) 682 continue; 683 OF_getprop(node, "name", buf, sizeof(buf)); 684 DPRINTF(ACDB_PROBE, (" name %s\n", buf)); 685 for (ssp = openboot_special; (sp = *ssp) != NULL; ssp++) 686 if (strcmp(buf, sp) == 0) 687 break; 688 if (sp != NULL) 689 continue; /* an "early" device already configured */ 690 691 bzero(&ma, sizeof ma); 692 ma.ma_bustag = &mainbus_space_tag; 693 ma.ma_dmatag = &mainbus_dma_tag; 694 ma.ma_name = buf; 695 ma.ma_node = node; 696 if (OF_getprop(node, "upa-portid", &portid, sizeof(portid)) != 697 sizeof(portid)) 698 portid = -1; 699 ma.ma_upaid = portid; 700 701 if (PROM_getprop(node, "reg", sizeof(*ma.ma_reg), 702 &ma.ma_nreg, (void**)&ma.ma_reg) != 0) 703 continue; 704 #ifdef DEBUG 705 if (autoconf_debug & ACDB_PROBE) { 706 if (ma.ma_nreg) 707 printf(" reg %08lx.%08lx\n", 708 (long)ma.ma_reg->ur_paddr, 709 (long)ma.ma_reg->ur_len); 710 else 711 printf(" no reg\n"); 712 } 713 #endif 714 rv = PROM_getprop(node, "interrupts", sizeof(*ma.ma_interrupts), 715 &ma.ma_ninterrupts, (void**)&ma.ma_interrupts); 716 if (rv != 0 && rv != ENOENT) { 717 free(ma.ma_reg, M_DEVBUF); 718 continue; 719 } 720 #ifdef DEBUG 721 if (autoconf_debug & ACDB_PROBE) { 722 if (ma.ma_interrupts) 723 printf(" interrupts %08x\n", *ma.ma_interrupts); 724 else 725 printf(" no interrupts\n"); 726 } 727 #endif 728 rv = PROM_getprop(node, "address", sizeof(*ma.ma_address), 729 &ma.ma_naddress, (void**)&ma.ma_address); 730 if (rv != 0 && rv != ENOENT) { 731 free(ma.ma_reg, M_DEVBUF); 732 if (ma.ma_ninterrupts) 733 free(ma.ma_interrupts, M_DEVBUF); 734 continue; 735 } 736 #ifdef DEBUG 737 if (autoconf_debug & ACDB_PROBE) { 738 if (ma.ma_naddress) 739 printf(" address %08x\n", *ma.ma_address); 740 else 741 printf(" no address\n"); 742 } 743 #endif 744 (void) config_found(dev, (void *)&ma, mbprint); 745 free(ma.ma_reg, M_DEVBUF); 746 if (ma.ma_ninterrupts) 747 free(ma.ma_interrupts, M_DEVBUF); 748 if (ma.ma_naddress) 749 free(ma.ma_address, M_DEVBUF); 750 } 751 /* Try to attach PROM console */ 752 bzero(&ma, sizeof ma); 753 ma.ma_name = "pcons"; 754 (void) config_found(dev, (void *)&ma, mbprint); 755 } 756 757 CFATTACH_DECL(mainbus, sizeof(struct device), 758 mainbus_match, mainbus_attach, NULL, NULL); 759 760 int 761 PROM_getprop(node, name, size, nitem, bufp) 762 int node; 763 char *name; 764 size_t size; 765 int *nitem; 766 void **bufp; 767 { 768 void *buf; 769 long len; 770 771 *nitem = 0; 772 len = PROM_getproplen(node, name); 773 if (len <= 0) 774 return (ENOENT); 775 776 if ((len % size) != 0) 777 return (EINVAL); 778 779 buf = *bufp; 780 if (buf == NULL) { 781 /* No storage provided, so we allocate some */ 782 buf = malloc(len, M_DEVBUF, M_NOWAIT); 783 if (buf == NULL) 784 return (ENOMEM); 785 } 786 787 OF_getprop(node, name, buf, len); 788 *bufp = buf; 789 *nitem = len / size; 790 return (0); 791 } 792 793 794 /* 795 * Internal form of proplen(). Returns the property length. 796 */ 797 long 798 PROM_getproplen(node, name) 799 int node; 800 char *name; 801 { 802 return (OF_getproplen(node, name)); 803 } 804 805 /* 806 * Return a string property. There is a (small) limit on the length; 807 * the string is fetched into a static buffer which is overwritten on 808 * subsequent calls. 809 */ 810 char * 811 PROM_getpropstring(node, name) 812 int node; 813 char *name; 814 { 815 static char stringbuf[32]; 816 817 return (PROM_getpropstringA(node, name, stringbuf)); 818 } 819 820 /* Alternative PROM_getpropstring(), where caller provides the buffer */ 821 char * 822 PROM_getpropstringA(node, name, buffer) 823 int node; 824 char *name; 825 char *buffer; 826 { 827 int blen; 828 829 if (PROM_getprop(node, name, 1, &blen, (void **)&buffer) != 0) 830 blen = 0; 831 832 buffer[blen] = '\0'; /* usually unnecessary */ 833 return (buffer); 834 } 835 836 /* 837 * Fetch an integer (or pointer) property. 838 * The return value is the property, or the default if there was none. 839 */ 840 int 841 PROM_getpropint(node, name, deflt) 842 int node; 843 char *name; 844 int deflt; 845 { 846 int intbuf; 847 848 849 850 if (OF_getprop(node, name, &intbuf, sizeof(intbuf)) != sizeof(intbuf)) 851 return (deflt); 852 853 return (intbuf); 854 } 855 856 /* 857 * OPENPROM functions. These are here mainly to hide the OPENPROM interface 858 * from the rest of the kernel. 859 */ 860 int 861 firstchild(node) 862 int node; 863 { 864 865 return OF_child(node); 866 } 867 868 int 869 nextsibling(node) 870 int node; 871 { 872 873 return OF_peer(node); 874 } 875 876 /* The following are used primarily in consinit() */ 877 878 int 879 node_has_property(node, prop) /* returns 1 if node has given property */ 880 register int node; 881 register const char *prop; 882 { 883 return (OF_getproplen(node, (caddr_t)prop) != -1); 884 } 885 886 #ifdef RASTERCONSOLE 887 /* 888 * Try to figure out where the PROM stores the cursor row & column 889 * variables. Returns nonzero on error. 890 */ 891 int 892 romgetcursoraddr(rowp, colp) 893 register int **rowp, **colp; 894 { 895 cell_t row = NULL, col = NULL; 896 897 OF_interpret("stdout @ is my-self addr line# addr column# ", 0, 2, 898 &col, &row); 899 /* 900 * We are running on a 64-bit machine, so these things point to 901 * 64-bit values. To convert them to pointers to integers, add 902 * 4 to the address. 903 */ 904 *rowp = (int *)(row+4); 905 *colp = (int *)(col+4); 906 return (row == NULL || col == NULL); 907 } 908 #endif /* RASTERCONSOLE */ 909 910 void 911 callrom() 912 { 913 914 __asm __volatile("wrpr %%g0, 0, %%tl" : ); 915 OF_enter(); 916 } 917 918 /* 919 * find a device matching "name" and unit number 920 */ 921 struct device * 922 getdevunit(name, unit) 923 char *name; 924 int unit; 925 { 926 struct device *dev = alldevs.tqh_first; 927 char num[10], fullname[16]; 928 int lunit; 929 930 /* compute length of name and decimal expansion of unit number */ 931 sprintf(num, "%d", unit); 932 lunit = strlen(num); 933 if (strlen(name) + lunit >= sizeof(fullname) - 1) 934 panic("config_attach: device name too long"); 935 936 strcpy(fullname, name); 937 strcat(fullname, num); 938 939 while (strcmp(dev->dv_xname, fullname) != 0) { 940 if ((dev = dev->dv_list.tqe_next) == NULL) 941 return NULL; 942 } 943 return dev; 944 } 945 946 947 /* 948 * Device registration used to determine the boot device. 949 * 950 * Copied from the sparc port. 951 */ 952 #include <dev/scsipi/scsi_all.h> 953 #include <dev/scsipi/scsipi_all.h> 954 #include <dev/scsipi/scsiconf.h> 955 956 #define BUSCLASS_NONE 0 957 #define BUSCLASS_MAINBUS 1 958 #define BUSCLASS_IOMMU 2 959 #define BUSCLASS_OBIO 3 960 #define BUSCLASS_SBUS 4 961 #define BUSCLASS_VME 5 962 #define BUSCLASS_PCI 6 963 #define BUSCLASS_XDC 7 964 #define BUSCLASS_XYC 8 965 #define BUSCLASS_FDC 9 966 967 static int bus_class __P((struct device *)); 968 static int dev_compatible __P((struct device *, void *, char *)); 969 static int instance_match __P((struct device *, void *, struct bootpath *)); 970 static void nail_bootdev __P((struct device *, struct bootpath *)); 971 972 static struct { 973 char *name; 974 int class; 975 } bus_class_tab[] = { 976 { "mainbus", BUSCLASS_MAINBUS }, 977 { "upa", BUSCLASS_MAINBUS }, 978 { "psycho", BUSCLASS_MAINBUS }, 979 { "obio", BUSCLASS_OBIO }, 980 { "iommu", BUSCLASS_IOMMU }, 981 { "sbus", BUSCLASS_SBUS }, 982 { "xbox", BUSCLASS_SBUS }, 983 { "esp", BUSCLASS_SBUS }, 984 { "dma", BUSCLASS_SBUS }, 985 { "espdma", BUSCLASS_SBUS }, 986 { "ledma", BUSCLASS_SBUS }, 987 { "simba", BUSCLASS_PCI }, 988 { "ppb", BUSCLASS_PCI }, 989 { "pciide", BUSCLASS_PCI }, 990 { "siop", BUSCLASS_PCI }, 991 { "pci", BUSCLASS_PCI }, 992 { "fdc", BUSCLASS_FDC }, 993 }; 994 995 /* 996 * A list of driver names may have differently named PROM nodes. 997 */ 998 static struct { 999 char *name; 1000 char *compat[6]; 1001 } dev_compat_tab[] = { 1002 { "dma", { "espdma", NULL }}, 1003 { "isp", { "QLGC,isp", "PTI,isp", "ptiisp", "scsi", NULL }}, 1004 { "fdc", { "SUNW,fdtwo", NULL }}, 1005 { "psycho", { "pci", NULL }}, 1006 { "wd", { "disk", "ide-disk", NULL }}, 1007 { "sd", { "disk", NULL }}, 1008 { "hme", { "SUNW,hme", "network", NULL }}, 1009 { "esp", { "SUNW,fas", "fas", NULL }}, 1010 { "siop", { "glm", "SUNW,glm", NULL }}, 1011 { NULL, { NULL }}, 1012 }; 1013 1014 int 1015 dev_compatible(dev, aux, bpname) 1016 struct device *dev; 1017 void *aux; 1018 char *bpname; 1019 { 1020 int i, j; 1021 1022 /* 1023 * Step 1: 1024 * 1025 * If this is a PCI device, find it's device class and try that. 1026 */ 1027 if ((bus_class(dev->dv_parent)) == BUSCLASS_PCI) { 1028 struct pci_attach_args *pa = aux; 1029 1030 DPRINTF(ACDB_BOOTDEV, 1031 ("\n%s: dev_compatible: checking PCI class %x\n", 1032 dev->dv_xname, pa->pa_class)); 1033 1034 switch (PCI_CLASS(pa->pa_class)) { 1035 /* 1036 * We can only really have pci-pci bridges, 1037 * disk controllers, or NICs on the bootpath. 1038 */ 1039 case PCI_CLASS_BRIDGE: 1040 if (PCI_SUBCLASS(pa->pa_class) != 1041 PCI_SUBCLASS_BRIDGE_PCI) 1042 break; 1043 DPRINTF(ACDB_BOOTDEV, 1044 ("\n%s: dev_compatible: comparing %s with %s\n", 1045 dev->dv_xname, bpname, "pci")); 1046 if (strcmp(bpname, "pci") == 0) 1047 return (0); 1048 break; 1049 case PCI_CLASS_MASS_STORAGE: 1050 if (PCI_SUBCLASS(pa->pa_class) == 1051 PCI_SUBCLASS_MASS_STORAGE_IDE) { 1052 DPRINTF(ACDB_BOOTDEV, 1053 ("\n%s: dev_compatible: " 1054 "comparing %s with %s\n", 1055 dev->dv_xname, bpname, "ide")); 1056 if (strcmp(bpname, "ide") == 0) 1057 return (0); 1058 } 1059 if (PCI_SUBCLASS(pa->pa_class) == 1060 PCI_SUBCLASS_MASS_STORAGE_SCSI) { 1061 DPRINTF(ACDB_BOOTDEV, 1062 ("\n%s: dev_compatible: " 1063 "comparing %s with %s\n", 1064 dev->dv_xname, bpname, "scsi")); 1065 if (strcmp(bpname, "scsi") == 0) 1066 return (0); 1067 } 1068 break; 1069 case PCI_CLASS_NETWORK: 1070 DPRINTF(ACDB_BOOTDEV, 1071 ("\n%s: dev_compatible: comparing %s with %s\n", 1072 dev->dv_xname, bpname, "network")); 1073 if (strcmp(bpname, "network") == 0) 1074 return (0); 1075 break; 1076 default: 1077 break; 1078 } 1079 } 1080 1081 /* 1082 * Step 2: 1083 * 1084 * Look through the list of equivalent names and see if any of them 1085 * match. This is a nasty O(n^2) operation. 1086 */ 1087 for (i = 0; dev_compat_tab[i].name != NULL; i++) { 1088 if (strcmp(dev->dv_cfdata->cf_name, 1089 dev_compat_tab[i].name) == 0) { 1090 DPRINTF(ACDB_BOOTDEV, 1091 ("\n%s: dev_compatible: translating %s\n", 1092 dev->dv_xname, dev_compat_tab[i].name)); 1093 for (j = 0; dev_compat_tab[i].compat[j] != NULL; j++) { 1094 DPRINTF(ACDB_BOOTDEV, 1095 ("\n%s: dev_compatible: " 1096 "comparing %s to %s\n", 1097 dev->dv_xname, bpname, 1098 dev_compat_tab[i].compat[j])); 1099 if (strcmp(bpname, 1100 dev_compat_tab[i].compat[j]) == 0) 1101 return (0); 1102 } 1103 } 1104 } 1105 DPRINTF(ACDB_BOOTDEV, 1106 ("\n%s: dev_compatible: no match\n", 1107 dev->dv_xname)); 1108 return (1); 1109 } 1110 1111 static int 1112 bus_class(dev) 1113 struct device *dev; 1114 { 1115 const char *name; 1116 int i, class; 1117 1118 class = BUSCLASS_NONE; 1119 if (dev == NULL) 1120 return (class); 1121 1122 name = dev->dv_cfdata->cf_name; 1123 for (i = sizeof(bus_class_tab)/sizeof(bus_class_tab[0]); i-- > 0;) { 1124 if (strcmp(name, bus_class_tab[i].name) == 0) { 1125 class = bus_class_tab[i].class; 1126 break; 1127 } 1128 } 1129 1130 return (class); 1131 } 1132 1133 int 1134 instance_match(dev, aux, bp) 1135 struct device *dev; 1136 void *aux; 1137 struct bootpath *bp; 1138 { 1139 struct mainbus_attach_args *ma; 1140 struct sbus_attach_args *sa; 1141 struct pci_attach_args *pa; 1142 1143 /* 1144 * Several devices are represented on bootpaths in one of 1145 * two formats, e.g.: 1146 * (1) ../sbus@.../esp@<offset>,<slot>/sd@.. (PROM v3 style) 1147 * (2) /sbus0/esp0/sd@.. (PROM v2 style) 1148 * 1149 * hence we fall back on a `unit number' check if the bus-specific 1150 * instance parameter check does not produce a match. 1151 * 1152 * For PCI devices, we get: 1153 * ../pci@../xxx@<dev>,<fn>/... 1154 */ 1155 1156 /* 1157 * Rank parent bus so we know which locators to check. 1158 */ 1159 switch (bus_class(dev->dv_parent)) { 1160 case BUSCLASS_MAINBUS: 1161 ma = aux; 1162 DPRINTF(ACDB_BOOTDEV, 1163 ("instance_match: mainbus device, want %#x have %#x\n", 1164 ma->ma_upaid, bp->val[0])); 1165 if (bp->val[0] == ma->ma_upaid) 1166 return (1); 1167 break; 1168 case BUSCLASS_SBUS: 1169 sa = aux; 1170 DPRINTF(ACDB_BOOTDEV, ("instance_match: sbus device, " 1171 "want slot %#x offset %#x have slot %#x offset %#x\n", 1172 bp->val[0], bp->val[1], sa->sa_slot, sa->sa_offset)); 1173 if (bp->val[0] == sa->sa_slot && bp->val[1] == sa->sa_offset) 1174 return (1); 1175 break; 1176 case BUSCLASS_PCI: 1177 pa = aux; 1178 DPRINTF(ACDB_BOOTDEV, ("instance_match: pci device, " 1179 "want dev %#x fn %#x have dev %#x fn %#x\n", 1180 bp->val[0], bp->val[1], pa->pa_device, pa->pa_function)); 1181 if (bp->val[0] == pa->pa_device && 1182 bp->val[1] == pa->pa_function) 1183 return (1); 1184 break; 1185 default: 1186 break; 1187 } 1188 1189 if (bp->val[0] == -1 && bp->val[1] == dev->dv_unit) 1190 return (1); 1191 1192 return (0); 1193 } 1194 1195 struct device *booted_device; 1196 1197 void 1198 nail_bootdev(dev, bp) 1199 struct device *dev; 1200 struct bootpath *bp; 1201 { 1202 1203 if (bp->dev != NULL) 1204 panic("device_register: already got a boot device: %s", 1205 bp->dev->dv_xname); 1206 1207 /* 1208 * Mark this bootpath component by linking it to the matched 1209 * device. We pick up the device pointer in cpu_rootconf(). 1210 */ 1211 booted_device = bp->dev = dev; 1212 1213 /* 1214 * Then clear the current bootpath component, so we don't spuriously 1215 * match similar instances on other busses, e.g. a disk on 1216 * another SCSI bus with the same target. 1217 */ 1218 bootpath_store(1, NULL); 1219 } 1220 1221 void 1222 device_register(dev, aux) 1223 struct device *dev; 1224 void *aux; 1225 { 1226 struct bootpath *bp = bootpath_store(0, NULL); 1227 const char *dvname; 1228 char *bpname; 1229 1230 /* 1231 * If device name does not match current bootpath component 1232 * then there's nothing interesting to consider. 1233 */ 1234 if (bp == NULL) 1235 return; 1236 1237 /* 1238 * Translate device name to device class name in case the prom uses 1239 * that. 1240 */ 1241 bpname = bp->name; 1242 dvname = dev->dv_cfdata->cf_name; 1243 DPRINTF(ACDB_BOOTDEV, 1244 ("\n%s: device_register: dvname %s(%s) bpname %s\n", 1245 dev->dv_xname, dvname, dev->dv_xname, bpname)); 1246 1247 /* First, match by name */ 1248 if (strcmp(dvname, bpname) != 0) { 1249 if (dev_compatible(dev, aux, bpname) != 0) 1250 return; 1251 } 1252 1253 if (bus_class(dev) != BUSCLASS_NONE) { 1254 /* 1255 * A bus or controller device of sorts. Check instance 1256 * parameters and advance boot path on match. 1257 */ 1258 if (instance_match(dev, aux, bp) != 0) { 1259 bp->dev = dev; 1260 bootpath_store(1, bp + 1); 1261 DPRINTF(ACDB_BOOTDEV, ("\t-- found bus controller %s\n", 1262 dev->dv_xname)); 1263 return; 1264 } 1265 } else if (strcmp(dvname, "le") == 0 || 1266 strcmp(dvname, "hme") == 0) { 1267 /* 1268 * ethernet devices. 1269 */ 1270 if (instance_match(dev, aux, bp) != 0) { 1271 nail_bootdev(dev, bp); 1272 DPRINTF(ACDB_BOOTDEV, ("\t-- found ethernet controller %s\n", 1273 dev->dv_xname)); 1274 return; 1275 } 1276 } else if (strcmp(dvname, "sd") == 0 || strcmp(dvname, "cd") == 0) { 1277 /* 1278 * A SCSI disk or cd; retrieve target/lun information 1279 * from parent and match with current bootpath component. 1280 * Note that we also have look back past the `scsibus' 1281 * device to determine whether this target is on the 1282 * correct controller in our boot path. 1283 */ 1284 struct scsipibus_attach_args *sa = aux; 1285 struct scsipi_periph *periph = sa->sa_periph; 1286 struct scsibus_softc *sbsc = 1287 (struct scsibus_softc *)dev->dv_parent; 1288 u_int target = bp->val[0]; 1289 u_int lun = bp->val[1]; 1290 1291 /* Check the controller that this scsibus is on */ 1292 if ((bp-1)->dev != sbsc->sc_dev.dv_parent) 1293 return; 1294 1295 /* 1296 * Bounds check: we know the target and lun widths. 1297 */ 1298 if (target >= periph->periph_channel->chan_ntargets || 1299 lun >= periph->periph_channel->chan_nluns) { 1300 printf("SCSI disk bootpath component not accepted: " 1301 "target %u; lun %u\n", target, lun); 1302 return; 1303 } 1304 1305 if (periph->periph_target == target && 1306 periph->periph_lun == lun) { 1307 nail_bootdev(dev, bp); 1308 DPRINTF(ACDB_BOOTDEV, ("\t-- found [cs]d disk %s\n", 1309 dev->dv_xname)); 1310 return; 1311 } 1312 } else if (strcmp("wd", dvname) == 0) { 1313 /* IDE disks. */ 1314 struct ata_device *adev = aux; 1315 1316 /* 1317 * The PROM gives you names like "disk@1,0", where the first value 1318 * appears to be both the drive & channel combined (channel * 2 + 1319 * drive), and the second value we don't use (what is it anyway?) 1320 */ 1321 if ((adev->adev_channel * 2) + adev->adev_drv_data->drive == 1322 bp->val[0]) { 1323 nail_bootdev(dev, bp); 1324 DPRINTF(ACDB_BOOTDEV, ("\t-- found wd disk %s\n", 1325 dev->dv_xname)); 1326 return; 1327 } 1328 } else { 1329 /* 1330 * Generic match procedure. 1331 */ 1332 if (instance_match(dev, aux, bp) != 0) { 1333 nail_bootdev(dev, bp); 1334 DPRINTF(ACDB_BOOTDEV, ("\t-- found generic device %s\n", 1335 dev->dv_xname)); 1336 return; 1337 } 1338 } 1339 } 1340