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