1 /* $OpenBSD: cmd_hppa.c,v 1.12 2010/12/06 22:51:45 jasper Exp $ */ 2 3 /* 4 * Copyright (c) 2002, 2009 Miodrag Vallat 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26 * THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/param.h> 30 /* would come from <sys/param.h> if -D_KERNEL */ 31 #define offsetof(s, e) ((size_t)&((s *)0)->e) 32 33 #include <machine/iomod.h> 34 #include <machine/pdc.h> 35 36 #include <arch/hppa/dev/cpudevs.h> 37 #include <arch/hppa/dev/elroyreg.h> 38 39 #include <dev/pci/pcireg.h> 40 #include <dev/pci/pcidevs.h> 41 42 #include <libsa.h> 43 #include "cmd.h" 44 #include "dev_hppa.h" /* pdc */ 45 46 extern struct stable_storage sstor; 47 extern int sstorsiz; 48 49 /* storage sizes we're interested in */ 50 #define CONSOLEOFFSET \ 51 offsetof(struct stable_storage, ss_console) 52 #define CONSOLESIZE \ 53 (offsetof(struct stable_storage, ss_console) + \ 54 sizeof(struct device_path)) 55 56 #define KEYBOARDOFFSET \ 57 offsetof(struct stable_storage, ss_keyboard) 58 #define KEYBOARDSIZE \ 59 (offsetof(struct stable_storage, ss_keyboard) + \ 60 sizeof(struct device_path)) 61 62 /* 63 * Table for the possible console devices found during the device walk. 64 */ 65 struct consoledev { 66 struct device_path dp; 67 int type; 68 int iodc_type; 69 int iodc_model; 70 }; 71 72 #define PS2 1 73 #define HIL 2 74 #define USB 3 75 #define SERIAL 4 76 #define GRAPHICS 5 77 78 #define MAX_SERIALS 4 79 #define MAX_KEYBOARDS 4 80 #define MAX_GRAPHICS 4 81 82 struct consoledev serials[MAX_SERIALS]; 83 struct consoledev keyboards[MAX_KEYBOARDS]; 84 struct consoledev graphics[MAX_GRAPHICS]; 85 86 int walked; 87 88 void bus_walk(struct device_path *, int); 89 uint32_t dino_conf_read(u_int, int, int, u_int); 90 uint32_t elroy_conf_read(u_int, int, int, u_int); 91 int path_match(struct device_path *, struct device_path *); 92 void path_shift(struct device_path *, int); 93 void pci_bus_walk(struct device_path *, struct iodc_data *, 94 struct pdc_memmap *); 95 void register_device(struct consoledev *, int, struct device_path *, 96 struct iodc_data *, int, int); 97 98 int Xconsole(void); 99 void print_console(void); 100 int set_graphics(struct device_path *, int, char *); 101 int set_serial(struct device_path *, int, char *); 102 int set_console(struct device_path *); 103 104 int Xkeyboard(void); 105 void print_keyboard(void); 106 int set_keyboard(struct device_path *); 107 108 struct cmd_table cmd_machine[] = { 109 { "console", CMDT_CMD, Xconsole }, 110 { "keyboard", CMDT_CMD, Xkeyboard }, 111 { NULL, }, 112 }; 113 114 /* value to console speed table */ 115 const int i_speeds[] = { 116 50, 117 75, 118 110, 119 150, 120 300, 121 600, 122 1200, 123 2400, 124 4800, 125 7200, 126 9600, 127 19200, 128 38400, 129 57600, 130 115200, 131 230400, 132 }; 133 134 const char *c_speeds[] = { 135 "50", 136 "75", 137 "110", 138 "150", 139 "300", 140 "600", 141 "1200", 142 "2400", 143 "4800", 144 "7200", 145 "9600", 146 "19200", 147 "38400", 148 "57600", 149 "115200", 150 "230400", 151 }; 152 153 /* values to console parity table */ 154 const char *parities[] = { 155 "none", 156 "odd", 157 "<unknown parity>", 158 "even", 159 }; 160 161 /* 162 * C O N S O L E S E T T I N G S 163 */ 164 165 void 166 print_console() 167 { 168 int port, mode, speed, parity, bits; 169 int i; 170 171 #ifdef DEBUG 172 printf("console flags %x mod %x bc %d/%d/%d/%d/%d/%d\n", 173 sstor.ss_console.dp_flags, 174 sstor.ss_console.dp_mod, 175 sstor.ss_console.dp_bc[0], 176 sstor.ss_console.dp_bc[1], 177 sstor.ss_console.dp_bc[2], 178 sstor.ss_console.dp_bc[3], 179 sstor.ss_console.dp_bc[4], 180 sstor.ss_console.dp_bc[5]); 181 182 printf("console path %x/%x/%x/%x/%x/%x\n", 183 sstor.ss_console.dp_layers[0], 184 sstor.ss_console.dp_layers[1], 185 sstor.ss_console.dp_layers[2], 186 sstor.ss_console.dp_layers[3], 187 sstor.ss_console.dp_layers[4], 188 sstor.ss_console.dp_layers[5]); 189 #endif 190 191 printf("Console path: "); 192 193 /* look for a serial console */ 194 for (port = i = 0; i < MAX_SERIALS; i++) 195 if (path_match(&serials[i].dp, &sstor.ss_console)) { 196 port = i + 1; 197 break; 198 } 199 200 if (port == 0) { 201 /* 202 * Graphics console 203 */ 204 205 for (port = i = 0; i < MAX_GRAPHICS; i++) 206 if (path_match(&graphics[i].dp, &sstor.ss_console)) { 207 port = i; 208 break; 209 } 210 211 /* 212 * If the console could still not be identified, consider 213 * it is a simplified encoding for the default graphics 214 * console. Hence port == 0, no need to check. 215 */ 216 if (port == 0) 217 printf("graphics"); 218 else 219 printf("graphics_%d", port); 220 221 mode = sstor.ss_console.dp_layers[0]; 222 if (mode != 0) 223 printf(".%d", mode); 224 } else { 225 /* 226 * Serial console 227 */ 228 229 if (port == 1) 230 printf("rs232"); 231 else 232 printf("rs232_%d", port); 233 234 speed = PZL_SPEED(sstor.ss_console.dp_layers[0]); 235 printf(".%d", i_speeds[speed]); 236 237 bits = PZL_BITS(sstor.ss_console.dp_layers[0]); 238 printf(".%d", bits); 239 240 parity = PZL_PARITY(sstor.ss_console.dp_layers[0]); 241 printf(".%s", parities[parity]); 242 } 243 244 printf("\n"); 245 } 246 247 int 248 set_graphics(console, port, arg) 249 struct device_path *console; 250 int port; 251 char *arg; 252 { 253 int maxmode, mode = 0; 254 char *digit; 255 256 /* head */ 257 if (graphics[port].type == 0) { 258 printf("no such device found\n"); 259 return 0; 260 } 261 262 /* mode */ 263 if (arg != NULL) { 264 for (digit = arg; *digit != '\0'; digit++) { 265 if (*digit >= '0' && *digit <= '9') 266 mode = 10 * mode + (*digit - '0'); 267 else { 268 printf("invalid mode specification, %s\n", arg); 269 return 0; 270 } 271 } 272 273 if (mode <= 0) { 274 printf("invalid mode specification, %s\n", arg); 275 return 0; 276 } 277 } 278 279 /* 280 * If we are just changing the mode of the same graphics 281 * console, check that our mode is in the valid range. 282 */ 283 if (path_match(&graphics[port].dp, &sstor.ss_console)) { 284 maxmode = sstor.ss_console.dp_layers[1]; 285 286 /* pick back same mode if unspecified */ 287 if (mode == 0) 288 mode = sstor.ss_console.dp_layers[0]; 289 290 if (mode > maxmode) { 291 printf("invalid mode value, available range is 1-%d\n", 292 maxmode); 293 return 0; 294 } 295 } else { 296 if (mode == 0) 297 mode = 1; 298 maxmode = mode; 299 } 300 301 *console = graphics[port].dp; 302 console->dp_layers[0] = mode; 303 console->dp_layers[1] = maxmode; 304 console->dp_layers[2] = console->dp_layers[3] = 305 console->dp_layers[4] = console->dp_layers[5] = 0; 306 307 return 1; 308 } 309 310 int 311 set_serial(console, port, arg) 312 struct device_path *console; 313 int port; 314 char *arg; 315 { 316 char *dot; 317 int i; 318 int speed, parity, bits; 319 320 /* port */ 321 port--; 322 if (serials[port].type == 0) { 323 printf("no such device found\n"); 324 return 0; 325 } 326 327 /* speed */ 328 dot = strchr(arg, '.'); 329 if (dot != NULL) 330 *dot++ = '\0'; 331 332 speed = 0; 333 if (arg == NULL || *arg == '\0') { 334 for (i = 0; i < nitems(i_speeds); i++) 335 if (i_speeds[i] == 9600) { 336 speed = i; 337 break; 338 } 339 } else { 340 for (i = 0; i < nitems(c_speeds); i++) 341 if (strcmp(arg, c_speeds[i]) == 0) { 342 speed = i; 343 break; 344 } 345 if (speed == 0) { 346 printf("invalid speed specification, %s\n", arg); 347 return 0; 348 } 349 } 350 351 /* data bits */ 352 arg = dot; 353 dot = strchr(arg, '.'); 354 355 if (arg == NULL || *arg == '\0') 356 bits = 8; 357 else { 358 if (dot == arg + 1) 359 bits = *arg - '0'; 360 else 361 bits = 0; 362 363 if (bits < 5 || bits > 8) { 364 printf("invalid bits specification, %s\n", arg); 365 return 0; 366 } 367 } 368 if (dot != NULL) 369 *dot++ = '\0'; 370 371 /* parity */ 372 arg = dot; 373 if (arg == NULL || *arg == '\0') 374 parity = 0; /* none */ 375 else { 376 parity = -1; 377 for (i = 0; i <= 3; i++) 378 if (strcmp(arg, parities[i]) == 0) { 379 parity = i; 380 break; 381 } 382 if (parity == 2) 383 parity = -1; /* unknown parity */ 384 } 385 if (parity < 0) { 386 printf("invalid parity specification, %s\n", arg); 387 return 0; 388 } 389 390 *console = serials[port].dp; 391 console->dp_layers[0] = PZL_ENCODE(bits, parity, speed); 392 393 return 1; 394 } 395 396 int 397 set_console(console) 398 struct device_path *console; 399 { 400 char *arg = cmd.argv[1], *dot; 401 int port; 402 403 /* extract first word */ 404 dot = strchr(arg, '.'); 405 if (dot != NULL) 406 *dot++ = '\0'; 407 408 /* 409 * Graphics console 410 */ 411 if (strcmp(arg, "graphics") == 0) 412 return set_graphics(console, 0, dot); 413 if (strncmp(arg, "graphics_", 9) == 0) { 414 port = arg[9] - '0'; 415 if (port > 0 && port < MAX_GRAPHICS) 416 return set_graphics(console, port, dot); 417 } 418 419 /* 420 * Serial console 421 */ 422 if (strcmp(arg, "rs232") == 0) 423 return set_serial(console, 1, dot); 424 if (strncmp(arg, "rs232_", 6) == 0) { 425 port = arg[6] - '0'; 426 if (port > 0 && port <= MAX_SERIALS) 427 return set_serial(console, port, dot); 428 } 429 430 printf("invalid device specification, %s\n", arg); 431 return 0; 432 } 433 434 int 435 Xconsole() 436 { 437 struct device_path console; 438 int rc; 439 440 /* walk the device list if not already done */ 441 if (walked == 0) { 442 bus_walk(NULL, MAXMODBUS); 443 walked++; 444 } 445 446 if (sstorsiz < CONSOLESIZE) { 447 printf("no console information in stable storage\n"); 448 return 0; 449 } 450 451 if (cmd.argc == 1) { 452 print_console(); 453 } else { 454 console = sstor.ss_console; 455 if (set_console(&console)) { 456 if (memcmp(&sstor.ss_console, &console, 457 sizeof console) != 0) { 458 sstor.ss_console = console; 459 460 /* alea jacta est */ 461 rc = (*pdc)(PDC_STABLE, PDC_STABLE_WRITE, 462 CONSOLEOFFSET, &sstor.ss_console, 463 sizeof(sstor.ss_console)); 464 if (rc != 0) { 465 printf("failed to save console" 466 " settings, error %d\n", rc); 467 /* read sstor again for safety */ 468 (*pdc)(PDC_STABLE, PDC_STABLE_READ, 469 CONSOLEOFFSET, &sstor.ss_console, 470 sizeof(sstor.ss_console)); 471 } else 472 printf("you will need to power-cycle " 473 "your machine for the changes " 474 "to take effect.\n"); 475 } 476 print_console(); 477 } 478 } 479 480 return 0; 481 } 482 483 /* 484 * K E Y B O A R D S E T T I N G S 485 */ 486 487 void 488 print_keyboard() 489 { 490 int type; 491 int i; 492 493 #ifdef DEBUG 494 printf("keyboard flags %x mod %x bc %d/%d/%d/%d/%d/%d\n", 495 sstor.ss_keyboard.dp_flags, 496 sstor.ss_keyboard.dp_mod, 497 sstor.ss_keyboard.dp_bc[0], 498 sstor.ss_keyboard.dp_bc[1], 499 sstor.ss_keyboard.dp_bc[2], 500 sstor.ss_keyboard.dp_bc[3], 501 sstor.ss_keyboard.dp_bc[4], 502 sstor.ss_keyboard.dp_bc[5]); 503 504 printf("keyboard path %x/%x/%x/%x/%x/%x\n", 505 sstor.ss_keyboard.dp_layers[0], 506 sstor.ss_keyboard.dp_layers[1], 507 sstor.ss_keyboard.dp_layers[2], 508 sstor.ss_keyboard.dp_layers[3], 509 sstor.ss_keyboard.dp_layers[4], 510 sstor.ss_keyboard.dp_layers[5]); 511 #endif 512 513 printf("Keyboard path: "); 514 515 for (type = i = 0; i < MAX_KEYBOARDS; i++) 516 if (path_match(&keyboards[i].dp, &sstor.ss_keyboard)) { 517 type = keyboards[i].type; 518 break; 519 } 520 521 switch (type) { 522 case USB: 523 printf("usb"); 524 break; 525 case HIL: 526 printf("hil"); 527 break; 528 case PS2: 529 printf("ps2"); 530 break; 531 default: 532 printf("unknown"); 533 break; 534 } 535 536 printf("\n"); 537 } 538 539 int 540 set_keyboard(keyboard) 541 struct device_path *keyboard; 542 { 543 int i; 544 char *arg = cmd.argv[1]; 545 int type; 546 547 if (strcmp(arg, "hil") == 0) 548 type = HIL; 549 else if (strcmp(arg, "ps2") == 0) 550 type = PS2; 551 else if (strcmp(arg, "usb") == 0) 552 type = USB; 553 else { 554 /* XXX should probably handle multiple USB controllers */ 555 printf("invalid device specification, %s\n", arg); 556 return 0; 557 } 558 559 for (i = 0; i < MAX_KEYBOARDS; i++) 560 if (keyboards[i].type == type) { 561 *keyboard = keyboards[i].dp; 562 return 1; 563 } 564 565 printf("no such device found\n"); 566 return 0; 567 } 568 569 int 570 Xkeyboard() 571 { 572 struct device_path keyboard; 573 int rc; 574 575 /* walk the device list if not already done */ 576 if (walked == 0) { 577 bus_walk(NULL, MAXMODBUS); 578 walked++; 579 } 580 581 if (sstorsiz < KEYBOARDSIZE) { 582 printf("no keyboard information in stable storage\n"); 583 return 0; 584 } 585 586 if (cmd.argc == 1) { 587 print_keyboard(); 588 } else { 589 keyboard = sstor.ss_keyboard; 590 if (set_keyboard(&keyboard)) { 591 if (memcmp(&sstor.ss_keyboard, &keyboard, 592 sizeof keyboard) != 0) { 593 sstor.ss_keyboard = keyboard; 594 595 /* alea jacta est */ 596 rc = (*pdc)(PDC_STABLE, PDC_STABLE_WRITE, 597 KEYBOARDOFFSET, &sstor.ss_keyboard, 598 sizeof(sstor.ss_keyboard)); 599 if (rc != 0) { 600 printf("failed to save keyboard" 601 " settings, error %d\n", rc); 602 /* read sstor again for safety */ 603 (*pdc)(PDC_STABLE, PDC_STABLE_READ, 604 KEYBOARDOFFSET, &sstor.ss_keyboard, 605 sizeof(sstor.ss_keyboard)); 606 } else 607 printf("you will need to power-cycle " 608 "your machine for the changes " 609 "to take effect.\n"); 610 } 611 print_keyboard(); 612 } 613 } 614 615 return 0; 616 } 617 618 /* 619 * U T I L I T I E S 620 */ 621 622 /* 623 * Bus walker. 624 * This routine will walk all the modules on a given bus, registering 625 * serial ports, keyboard and graphics devices as they are found. 626 */ 627 void 628 bus_walk(struct device_path *idp, int maxmod) 629 { 630 struct device_path dp; 631 struct pdc_memmap memmap; 632 struct iodc_data mptr; 633 int err, i, kluge_ps2 = 0; /* kluge, see below */ 634 635 for (i = 0; i < maxmod; i++) { 636 if (idp) { 637 dp = *idp; 638 path_shift(&dp, i); 639 } else { 640 dp.dp_flags = 0; 641 dp.dp_bc[0] = dp.dp_bc[1] = dp.dp_bc[2] = 642 dp.dp_bc[3] = dp.dp_bc[4] = dp.dp_bc[5] = -1; 643 dp.dp_mod = i; 644 bzero(&dp.dp_layers, sizeof dp.dp_layers); 645 } 646 647 if ((pdc)(PDC_MEMMAP, PDC_MEMMAP_HPA, &memmap, &dp) < 0 && 648 (pdc)(PDC_SYSMAP, PDC_SYSMAP_HPA, &memmap, &dp) < 0) 649 continue; 650 651 if ((err = (pdc)(PDC_IODC, PDC_IODC_READ, &pdcbuf, memmap.hpa, 652 IODC_DATA, &mptr, sizeof(mptr))) < 0) 653 continue; 654 655 #ifdef DEBUG 656 printf("device %d/%d/%d/%d/%d/%d " 657 "flags %d mod %x type %x model %x\n", 658 dp.dp_bc[0], dp.dp_bc[1], dp.dp_bc[2], dp.dp_bc[3], 659 dp.dp_bc[4], dp.dp_bc[5], dp.dp_flags, dp.dp_mod, 660 mptr.iodc_type, mptr.iodc_sv_model); 661 #endif 662 663 /* 664 * If the device can be considered as a valid rs232, 665 * graphics console or keyboard, register it. 666 * 667 * Unfortunately, devices which should be considered as 668 * ``main'' aren't necessarily seen first. 669 * The rules we try to enforce here are as follows: 670 * - GIO PS/2 ports wins over any other PS/2 port. 671 * - the first GIO serial found wins over any other 672 * serial port. 673 * The second rule is a bit tricky to achieve, since on 674 * some machines (for example, 715/100XC), the two serial 675 * ports are not seen as attached to the same busses... 676 */ 677 switch (mptr.iodc_type) { 678 case HPPA_TYPE_BCPORT: 679 bus_walk(&dp, MAXMODBUS); 680 break; 681 case HPPA_TYPE_BRIDGE: 682 if (mptr.iodc_sv_model == HPPA_BRIDGE_DINO) { 683 pci_bus_walk(&dp, &mptr, &memmap); 684 break; 685 } 686 /* FALLTHROUGH */ 687 case HPPA_TYPE_BHA: 688 /* if there was no phantomas(4) here */ 689 if (dp.dp_bc[5] == -1) 690 path_shift(&dp, 0); 691 bus_walk(&dp, MAXMODBUS); 692 break; 693 case HPPA_TYPE_ADIRECT: 694 switch (mptr.iodc_sv_model) { 695 case HPPA_ADIRECT_RS232: 696 register_device(serials, MAX_SERIALS, 697 &dp, &mptr, SERIAL, 0); 698 break; 699 case HPPA_ADIRECT_HIL: 700 register_device(keyboards, MAX_KEYBOARDS, 701 &dp, &mptr, HIL, 0); 702 break; 703 case HPPA_ADIRECT_PEACOCK: 704 case HPPA_ADIRECT_LEONARDO: 705 register_device(graphics, MAX_GRAPHICS, 706 &dp, &mptr, GRAPHICS, 0); 707 break; 708 } 709 break; 710 case HPPA_TYPE_FIO: 711 switch (mptr.iodc_sv_model) { 712 case HPPA_FIO_HIL: 713 register_device(keyboards, MAX_KEYBOARDS, 714 &dp, &mptr, HIL, 0); 715 break; 716 case HPPA_FIO_RS232: /* com@gsc */ 717 register_device(serials, MAX_SERIALS, 718 &dp, &mptr, SERIAL, 0); 719 break; 720 case HPPA_FIO_DINOPCK: 721 register_device(keyboards, MAX_KEYBOARDS, 722 &dp, &mptr, PS2, 0); 723 break; 724 case HPPA_FIO_GPCIO: 725 /* 726 * KLUGE! At this point, there is no way to 727 * know if this port is the keyboard port or 728 * the mouse port. 729 * Let's assume the first port found is the 730 * keyboard, and ignore the others. 731 */ 732 if (kluge_ps2 != 0) 733 break; 734 register_device(keyboards, MAX_KEYBOARDS, 735 &dp, &mptr, PS2, 1); 736 kluge_ps2++; 737 break; 738 case HPPA_FIO_GRS232: /* com@dino, com@gsc */ 739 { 740 int j, first; 741 742 /* 743 * If a GIO serial port is already registered, 744 * register as extra port... 745 */ 746 first = 1; 747 for (j = 0; j < MAX_SERIALS; j++) 748 if (serials[j].type == SERIAL && 749 serials[j].iodc_type == 750 HPPA_TYPE_FIO && 751 serials[j].iodc_model == 752 HPPA_FIO_GRS232) { 753 first = 0; 754 break; 755 } 756 757 register_device(serials, MAX_SERIALS, 758 &dp, &mptr, SERIAL, first); 759 } 760 break; 761 case HPPA_FIO_SGC: 762 register_device(graphics, MAX_GRAPHICS, 763 &dp, &mptr, GRAPHICS, 0); 764 break; 765 case HPPA_FIO_GSGC: 766 register_device(graphics, MAX_GRAPHICS, 767 &dp, &mptr, GRAPHICS, 1); 768 break; 769 #if 0 /* can these really be used as console? */ 770 case HPPA_FIO_GRJ16: /* com@gsc */ 771 register_device(serials, MAX_SERIALS, 772 &dp, &mptr, SERIAL, 0); 773 break; 774 #endif 775 } 776 break; 777 case HPPA_TYPE_IOA: 778 switch (mptr.iodc_sv_model) { 779 case HPPA_IOA_UTURN: 780 bus_walk(&dp, MAXMODBUS - 1); 781 break; 782 } 783 break; 784 } 785 } 786 } 787 788 /* 789 * PCI bus walker. 790 * The PDC device enumeration stops at the PCI bridge level, however 791 * in order to properly handle console path on systems with PCI graphics 792 * and USB controllers, it is necessary to dig further. 793 * 794 * Note that there are apparently PDC routines to access bridge configuration 795 * space, but I have yet to find documentation about them. 796 * 797 * We ignore multi-function devices and subordinate PCI busses here, since 798 * PDC PCI device paths stop at the PCI device number, and subordinate 799 * busses are unlikely to be configured by the PDC. 800 */ 801 802 #define ELROY_MODEL 0x78 803 #define DINO_PAMR 0x804 804 #define DINO_CFG_ADDR 0x64 805 #define DINO_CFG_DATA 0x68 806 807 void 808 pci_bus_walk(struct device_path *idp, struct iodc_data *mptr, 809 struct pdc_memmap *memmap) 810 { 811 struct device_path dp; 812 int dev, fn, nfuncs; 813 uint32_t id, bhlcr, class; 814 uint32_t (*conf_read)(u_int, int, int, u_int); 815 816 if (mptr->iodc_model == ELROY_MODEL) 817 conf_read = elroy_conf_read; 818 else 819 conf_read = dino_conf_read; 820 821 for (dev = 0; dev < 32; dev++) { 822 id = (*conf_read)(memmap->hpa, dev, 0, PCI_ID_REG); 823 824 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID || PCI_VENDOR(id) == 0) 825 continue; 826 827 bhlcr = (*conf_read)(memmap->hpa, dev, 0, PCI_BHLC_REG); 828 nfuncs = PCI_HDRTYPE_MULTIFN(bhlcr) ? 8 : 1; 829 830 for (fn = 0; fn < nfuncs; fn++) { 831 dp = *idp; 832 path_shift(&dp, dev); 833 path_shift(&dp, fn); 834 835 if (fn != 0) 836 id = (*conf_read)(memmap->hpa, dev, fn, 837 PCI_ID_REG); 838 class = (*conf_read)(memmap->hpa, dev, fn, 839 PCI_CLASS_REG); 840 841 /* 842 * We are only interested in two kinds of devices 843 * here: sti graphics, and USB controllers. 844 */ 845 if (PCI_CLASS(class) == PCI_CLASS_SERIALBUS && 846 PCI_SUBCLASS(class) == PCI_SUBCLASS_SERIALBUS_USB) { 847 /* 848 * Note about the last parameter of the 849 * register_device() call below being zero: 850 * machines with USB keyboards have neither 851 * PS/2 nor HIL controllers, so it doesn't 852 * matter what order the USB controllers are 853 * in. 854 * However machines with PS/2 keyboards 855 * might have an USB PCI card plugged in, 856 * which better appear after the PS/2 857 * keyboard. 858 */ 859 register_device(keyboards, MAX_KEYBOARDS, 860 &dp, mptr, USB, 0); 861 continue; 862 } 863 864 switch (PCI_VENDOR(id)) { 865 case PCI_VENDOR_HP: 866 switch (PCI_PRODUCT(id)) { 867 case PCI_PRODUCT_HP_VISUALIZE_EG: 868 case PCI_PRODUCT_HP_VISUALIZE_FX2: 869 case PCI_PRODUCT_HP_VISUALIZE_FX4: 870 case PCI_PRODUCT_HP_VISUALIZE_FX6: 871 case PCI_PRODUCT_HP_VISUALIZE_FXE: 872 register_device(graphics, MAX_GRAPHICS, 873 &dp, mptr, GRAPHICS, 0); 874 break; 875 } 876 break; 877 case PCI_VENDOR_NS: 878 if (PCI_PRODUCT(id) == PCI_PRODUCT_NS_PC87560) { 879 /* serial_2 */ 880 path_shift(&dp, 2); 881 register_device(serials, MAX_SERIALS, 882 &dp, mptr, SERIAL, 1); 883 /* serial_1 */ 884 dp.dp_mod = 1; 885 register_device(serials, MAX_SERIALS, 886 &dp, mptr, SERIAL, 1); 887 } 888 break; 889 } 890 } 891 } 892 } 893 894 uint32_t 895 dino_conf_read(u_int hpa, int dev, int fn, u_int reg) 896 { 897 volatile uint32_t *dino = (volatile uint32_t *)hpa; 898 uint32_t pamr; 899 uint32_t addr, id; 900 901 addr = (dev << 11) | (fn << 8) | reg; 902 903 pamr = dino[DINO_PAMR / 4]; 904 dino[DINO_PAMR / 4] = 0; 905 dino[DINO_CFG_ADDR / 4] = addr; 906 id = dino[DINO_CFG_DATA / 4]; 907 dino[DINO_PAMR / 4] = pamr; 908 909 return letoh32(id); 910 } 911 912 uint32_t 913 elroy_conf_read(u_int hpa, int dev, int fn, u_int reg) 914 { 915 volatile struct elroy_regs *elroy = (volatile struct elroy_regs *)hpa; 916 uint32_t arb_mask, err_cfg, control; 917 uint32_t addr, id; 918 919 addr = (dev << 11) | (fn << 8) | reg; 920 921 arb_mask = *(volatile uint32_t *)&elroy->arb_mask; 922 err_cfg = *(volatile uint32_t *)&elroy->err_cfg; 923 control = *(volatile uint32_t *)&elroy->control; 924 925 if (arb_mask == 0) 926 *(volatile uint32_t *)&elroy->arb_mask = 927 htole32(ELROY_ARB_ENABLE); 928 *(volatile uint32_t *)&elroy->err_cfg = err_cfg | 929 htole32(ELROY_ERRCFG_SMART | ELROY_ERRCFG_CM); 930 *(volatile uint32_t *)&elroy->control = 931 (control | htole32(ELROY_CONTROL_CE)) & ~htole32(ELROY_CONTROL_HF); 932 933 *(volatile uint32_t *)&elroy->pci_conf_addr = htole32(addr); 934 addr = *(volatile uint32_t *)&elroy->pci_conf_addr; 935 id = *(volatile uint32_t *)&elroy->pci_conf_data; 936 937 *(volatile uint32_t *)&elroy->control = 938 control | htole32(ELROY_CONTROL_CE | ELROY_CONTROL_CL); 939 *(volatile uint32_t *)&elroy->control = control; 940 *(volatile uint32_t *)&elroy->err_cfg = err_cfg; 941 if (arb_mask == 0) 942 *(volatile uint32_t *)&elroy->arb_mask = arb_mask; 943 944 return letoh32(id); 945 } 946 947 /* 948 * Relaxed device comparison 949 */ 950 int 951 path_match(struct device_path *dev1, struct device_path *dev2) 952 { 953 return dev1->dp_mod == dev2->dp_mod && 954 dev1->dp_bc[0] == dev2->dp_bc[0] && 955 dev1->dp_bc[1] == dev2->dp_bc[1] && 956 dev1->dp_bc[2] == dev2->dp_bc[2] && 957 dev1->dp_bc[3] == dev2->dp_bc[3] && 958 dev1->dp_bc[4] == dev2->dp_bc[4] && 959 dev1->dp_bc[5] == dev2->dp_bc[5]; 960 } 961 962 /* 963 * Shift a device path, inserting a new value as dp_mod. 964 */ 965 void 966 path_shift(struct device_path *dp, int nmod) 967 { 968 dp->dp_bc[0] = dp->dp_bc[1]; 969 dp->dp_bc[1] = dp->dp_bc[2]; 970 dp->dp_bc[2] = dp->dp_bc[3]; 971 dp->dp_bc[3] = dp->dp_bc[4]; 972 dp->dp_bc[4] = dp->dp_bc[5]; 973 dp->dp_bc[5] = dp->dp_mod; 974 dp->dp_mod = nmod; 975 } 976 977 void 978 register_device(devlist, cnt, dp, mptr, type, first) 979 struct consoledev *devlist; 980 int cnt; 981 struct device_path *dp; 982 struct iodc_data *mptr; 983 int type; 984 int first; 985 { 986 int i; 987 struct consoledev *dev; 988 989 for (i = 0, dev = devlist; i < cnt; i++, dev++) 990 if (dev->type == 0) 991 break; 992 993 if (i == cnt) { 994 #ifdef DEBUG 995 printf("can't register device, need more room!\n"); 996 #endif 997 return; 998 } 999 1000 /* 1001 * If this is supposedly the main device, insert on top 1002 */ 1003 if (first != 0) { 1004 memcpy(devlist + 1, devlist, 1005 (cnt - 1) * sizeof(struct consoledev)); 1006 dev = devlist; 1007 } 1008 1009 dev->dp = *dp; 1010 dev->type = type; 1011 dev->iodc_type = mptr->iodc_type; 1012 dev->iodc_model = mptr->iodc_sv_model; 1013 1014 #ifdef DEBUG 1015 printf("(registered as type %d)\n", type); 1016 #endif 1017 } 1018