1 /* $NetBSD: pdc.c,v 1.1 2014/02/24 07:23:42 skrll Exp $ */ 2 3 /* $OpenBSD: pdc.c,v 1.14 2001/04/29 21:05:43 mickey Exp $ */ 4 5 /* 6 * Copyright (c) 1998-2003 Michael Shalayeff 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: pdc.c,v 1.1 2014/02/24 07:23:42 skrll Exp $"); 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/device.h> 37 #include <sys/proc.h> 38 #include <sys/tty.h> 39 #include <sys/callout.h> 40 #include <sys/conf.h> 41 #include <sys/kauth.h> 42 43 #include <dev/cons.h> 44 #include <dev/clock_subr.h> 45 46 #include <machine/pdc.h> 47 #include <machine/iomod.h> 48 #include <machine/autoconf.h> 49 50 #include <hppa/hppa/machdep.h> 51 #include <hppa/dev/cpudevs.h> 52 53 typedef 54 struct pdc_softc { 55 device_t sc_dv; 56 struct tty *sc_tty; 57 struct callout sc_to; 58 } pdcsoftc_t; 59 60 pdcio_t pdc; 61 62 enum pdc_type pdc_type; 63 64 static struct pdc_result pdcret1 PDC_ALIGNMENT; 65 static struct pdc_result pdcret2 PDC_ALIGNMENT; 66 static char pdc_consbuf[IODC_MINIOSIZ] PDC_ALIGNMENT; 67 68 iodcio_t pdc_cniodc, pdc_kbdiodc; 69 pz_device_t *pz_kbd, *pz_cons; 70 71 int pdcmatch(device_t, cfdata_t, void *); 72 void pdcattach(device_t, device_t, void *); 73 74 CFATTACH_DECL_NEW(pdc, sizeof(pdcsoftc_t), 75 pdcmatch, pdcattach, NULL, NULL); 76 77 extern struct cfdriver pdc_cd; 78 79 static int pdc_attached; 80 81 dev_type_open(pdcopen); 82 dev_type_close(pdcclose); 83 dev_type_read(pdcread); 84 dev_type_write(pdcwrite); 85 dev_type_ioctl(pdcioctl); 86 dev_type_stop(pdcstop); 87 dev_type_tty(pdctty); 88 dev_type_poll(pdcpoll); 89 90 const struct cdevsw pdc_cdevsw = { 91 pdcopen, pdcclose, pdcread, pdcwrite, pdcioctl, 92 pdcstop, pdctty, pdcpoll, nommap, ttykqfilter, D_TTY 93 }; 94 95 void pdcstart(struct tty *); 96 void pdctimeout(void *); 97 int pdcparam(struct tty *, struct termios *); 98 int pdccnlookc(dev_t, int *); 99 100 static struct cnm_state pdc_cnm_state; 101 102 static int pdcgettod(todr_chip_handle_t, struct timeval *); 103 static int pdcsettod(todr_chip_handle_t, struct timeval *); 104 105 void 106 pdc_init(void) 107 { 108 static int kbd_iodc[IODC_MAXSIZE/sizeof(int)]; 109 static int cn_iodc[IODC_MAXSIZE/sizeof(int)]; 110 int err; 111 int pagezero_cookie; 112 113 pagezero_cookie = hppa_pagezero_map(); 114 115 pz_kbd = &PAGE0->mem_kbd; 116 pz_cons = &PAGE0->mem_cons; 117 118 pdc = (pdcio_t)PAGE0->mem_pdc; 119 120 /* XXX should we reset the console/kbd here? 121 well, /boot did that for us anyway */ 122 if ((err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_READ, 123 &pdcret1, pz_cons->pz_hpa, IODC_IO, cn_iodc, IODC_MAXSIZE)) < 0 || 124 (err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_READ, 125 &pdcret1, pz_kbd->pz_hpa, IODC_IO, kbd_iodc, IODC_MAXSIZE)) < 0) { 126 #ifdef DEBUG 127 printf("pdc_init: failed reading IODC (%d)\n", err); 128 #endif 129 } 130 131 hppa_pagezero_unmap(pagezero_cookie); 132 133 pdc_cniodc = (iodcio_t)cn_iodc; 134 pdc_kbdiodc = (iodcio_t)kbd_iodc; 135 136 /* XXX make pdc current console */ 137 cn_tab = &constab[0]; 138 } 139 140 void 141 pdc_settype(int modelno) 142 { 143 switch (modelno) { 144 /* 720, 750, 730, 735, 755 */ 145 case HPPA_BOARD_HP720: 146 case HPPA_BOARD_HP750_66: 147 case HPPA_BOARD_HP730_66: 148 case HPPA_BOARD_HP735_99: 149 case HPPA_BOARD_HP755_99: 150 case HPPA_BOARD_HP755_125: 151 case HPPA_BOARD_HP735_130: 152 153 /* 710, 705, 7[12]5 */ 154 case HPPA_BOARD_HP710: 155 case HPPA_BOARD_HP705: 156 case HPPA_BOARD_HP715_50: 157 case HPPA_BOARD_HP715_33: 158 case HPPA_BOARD_HP715S_50: 159 case HPPA_BOARD_HP715S_33: 160 case HPPA_BOARD_HP715T_50: 161 case HPPA_BOARD_HP715T_33: 162 case HPPA_BOARD_HP715_75: 163 case HPPA_BOARD_HP715_99: 164 case HPPA_BOARD_HP725_50: 165 case HPPA_BOARD_HP725_75: 166 case HPPA_BOARD_HP725_99: 167 168 /* 745, 742, 747 */ 169 case HPPA_BOARD_HP745I_50: 170 case HPPA_BOARD_HP742I_50: 171 case HPPA_BOARD_HP747I_100: 172 173 /* 712/{60,80,100,120}, 715/{64,80,100,...}, etc */ 174 case HPPA_BOARD_HP712_60: 175 case HPPA_BOARD_HP712_80: 176 case HPPA_BOARD_HP712_100: 177 case HPPA_BOARD_HP743I_64: 178 case HPPA_BOARD_HP743I_100: 179 case HPPA_BOARD_HP712_120: 180 case HPPA_BOARD_HP715_80: 181 case HPPA_BOARD_HP715_64: 182 case HPPA_BOARD_HP715_100: 183 case HPPA_BOARD_HP715_100XC: 184 case HPPA_BOARD_HP725_100: 185 case HPPA_BOARD_HP725_120: 186 case HPPA_BOARD_HP715_100L: 187 case HPPA_BOARD_HP715_120L: 188 case HPPA_BOARD_HP725_80L: 189 case HPPA_BOARD_HP725_100L: 190 case HPPA_BOARD_HP725_120L: 191 case HPPA_BOARD_HP743_50: 192 case HPPA_BOARD_HP743_100: 193 case HPPA_BOARD_HP715_80M: 194 case HPPA_BOARD_HP811: 195 case HPPA_BOARD_HP801: 196 case HPPA_BOARD_HP743T: 197 pdc_type = PDC_TYPE_SNAKE; 198 break; 199 200 default: 201 pdc_type = PDC_TYPE_UNKNOWN; 202 } 203 } 204 205 enum pdc_type 206 pdc_gettype(void) 207 { 208 209 return pdc_type; 210 } 211 212 int 213 pdcmatch(device_t parent, cfdata_t cf, void *aux) 214 { 215 struct confargs *ca = aux; 216 217 /* there could be only one */ 218 if (pdc_attached || strcmp(ca->ca_name, "pdc")) 219 return 0; 220 221 return 1; 222 } 223 224 void 225 pdcattach(device_t parent, device_t self, void *aux) 226 { 227 static struct todr_chip_handle todr = { 228 .todr_settime = pdcsettod, 229 .todr_gettime = pdcgettod, 230 }; 231 struct pdc_softc *sc = device_private(self); 232 233 sc->sc_dv = self; 234 pdc_attached = 1; 235 236 KASSERT(pdc != NULL); 237 238 cn_init_magic(&pdc_cnm_state); 239 cn_set_magic("+++++"); 240 241 /* attach the TOD clock */ 242 todr_attach(&todr); 243 244 aprint_normal("\n"); 245 246 callout_init(&sc->sc_to, 0); 247 } 248 249 int 250 pdcopen(dev_t dev, int flag, int mode, struct lwp *l) 251 { 252 struct pdc_softc *sc; 253 struct tty *tp; 254 int s; 255 int error = 0, setuptimeout; 256 257 sc = device_lookup_private(&pdc_cd, minor(dev)); 258 if (sc == NULL) 259 return ENXIO; 260 261 s = spltty(); 262 263 if (sc->sc_tty) { 264 tp = sc->sc_tty; 265 } else { 266 tp = tty_alloc(); 267 sc->sc_tty = tp; 268 tty_attach(tp); 269 } 270 271 tp->t_oproc = pdcstart; 272 tp->t_param = pdcparam; 273 tp->t_dev = dev; 274 275 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) { 276 splx(s); 277 return (EBUSY); 278 } 279 280 if ((tp->t_state & TS_ISOPEN) == 0) { 281 tp->t_state |= TS_CARR_ON; 282 ttychars(tp); 283 tp->t_iflag = TTYDEF_IFLAG; 284 tp->t_oflag = TTYDEF_OFLAG; 285 tp->t_cflag = TTYDEF_CFLAG|CLOCAL; 286 tp->t_lflag = TTYDEF_LFLAG; 287 tp->t_ispeed = tp->t_ospeed = 9600; 288 ttsetwater(tp); 289 290 setuptimeout = 1; 291 } else 292 setuptimeout = 0; 293 tp->t_state |= TS_CARR_ON; 294 295 splx(s); 296 297 error = (*tp->t_linesw->l_open)(dev, tp); 298 if (error == 0 && setuptimeout) 299 pdctimeout(sc); 300 301 return error; 302 } 303 304 int 305 pdcclose(dev_t dev, int flag, int mode, struct lwp *l) 306 { 307 struct tty *tp; 308 struct pdc_softc *sc; 309 310 sc = device_lookup_private(&pdc_cd, minor(dev)); 311 if (sc == NULL) 312 return ENXIO; 313 314 tp = sc->sc_tty; 315 callout_stop(&sc->sc_to); 316 (*tp->t_linesw->l_close)(tp, flag); 317 ttyclose(tp); 318 return 0; 319 } 320 321 int 322 pdcread(dev_t dev, struct uio *uio, int flag) 323 { 324 struct tty *tp; 325 struct pdc_softc *sc; 326 327 sc = device_lookup_private(&pdc_cd, minor(dev)); 328 if (sc == NULL) 329 return ENXIO; 330 331 tp = sc->sc_tty; 332 return ((*tp->t_linesw->l_read)(tp, uio, flag)); 333 } 334 335 int 336 pdcwrite(dev_t dev, struct uio *uio, int flag) 337 { 338 struct tty *tp; 339 struct pdc_softc *sc; 340 341 sc = device_lookup_private(&pdc_cd, minor(dev)); 342 if (sc == NULL) 343 return ENXIO; 344 345 tp = sc->sc_tty; 346 return ((*tp->t_linesw->l_write)(tp, uio, flag)); 347 } 348 349 int 350 pdcpoll(dev_t dev, int events, struct lwp *l) 351 { 352 struct pdc_softc *sc = device_lookup_private(&pdc_cd,minor(dev)); 353 struct tty *tp = sc->sc_tty; 354 355 return ((*tp->t_linesw->l_poll)(tp, events, l)); 356 } 357 358 int 359 pdcioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 360 { 361 int error; 362 struct tty *tp; 363 struct pdc_softc *sc; 364 365 sc = device_lookup_private(&pdc_cd, minor(dev)); 366 if (sc == NULL) 367 return ENXIO; 368 369 tp = sc->sc_tty; 370 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); 371 if (error >= 0) 372 return error; 373 error = ttioctl(tp, cmd, data, flag, l); 374 if (error >= 0) 375 return error; 376 377 return ENOTTY; 378 } 379 380 int 381 pdcparam(struct tty *tp, struct termios *t) 382 { 383 384 return 0; 385 } 386 387 void 388 pdcstart(struct tty *tp) 389 { 390 int s; 391 392 s = spltty(); 393 if (tp->t_state & (TS_TTSTOP | TS_BUSY)) { 394 splx(s); 395 return; 396 } 397 ttypull(tp); 398 tp->t_state |= TS_BUSY; 399 while (tp->t_outq.c_cc != 0) 400 pdccnputc(tp->t_dev, getc(&tp->t_outq)); 401 tp->t_state &= ~TS_BUSY; 402 splx(s); 403 } 404 405 void 406 pdcstop(struct tty *tp, int flag) 407 { 408 int s; 409 410 s = spltty(); 411 if (tp->t_state & TS_BUSY) 412 if ((tp->t_state & TS_TTSTOP) == 0) 413 tp->t_state |= TS_FLUSH; 414 splx(s); 415 } 416 417 void 418 pdctimeout(void *v) 419 { 420 struct pdc_softc *sc = v; 421 struct tty *tp = sc->sc_tty; 422 int c; 423 424 while (pdccnlookc(tp->t_dev, &c)) { 425 cn_check_magic(tp->t_dev, c, pdc_cnm_state); 426 if (tp->t_state & TS_ISOPEN) 427 (*tp->t_linesw->l_rint)(c, tp); 428 } 429 callout_reset(&sc->sc_to, 1, pdctimeout, sc); 430 } 431 432 struct tty * 433 pdctty(dev_t dev) 434 { 435 struct pdc_softc *sc; 436 437 sc = device_lookup_private(&pdc_cd, minor(dev)); 438 if (sc == NULL) 439 return NULL; 440 441 return sc->sc_tty; 442 } 443 444 void 445 pdccnprobe(struct consdev *cn) 446 { 447 448 cn->cn_dev = makedev(22,0); 449 cn->cn_pri = CN_NORMAL; 450 } 451 452 void 453 pdccninit(struct consdev *cn) 454 { 455 #ifdef DEBUG 456 printf("pdc0: console init\n"); 457 #endif 458 } 459 460 int 461 pdccnlookc(dev_t dev, int *cp) 462 { 463 int s, err __debugused, l, pagezero_cookie; 464 465 s = splhigh(); 466 pagezero_cookie = hppa_pagezero_map(); 467 err = pdc_call(pdc_kbdiodc, 0, pz_kbd->pz_hpa, IODC_IO_CONSIN, 468 pz_kbd->pz_spa, pz_kbd->pz_layers, &pdcret1, 0, pdc_consbuf, 1, 0); 469 l = pdcret1.result[0]; 470 *cp = pdc_consbuf[0]; 471 hppa_pagezero_unmap(pagezero_cookie); 472 splx(s); 473 474 #ifdef DEBUG 475 if (err < 0) 476 printf("pdccnlookc: input error: %d\n", err); 477 #endif 478 return l; 479 } 480 481 int 482 pdccngetc(dev_t dev) 483 { 484 int c; 485 486 if (!pdc) 487 return 0; 488 while (!pdccnlookc(dev, &c)) 489 ; 490 return (c); 491 } 492 493 void 494 pdccnputc(dev_t dev, int c) 495 { 496 int s, err, pagezero_cookie; 497 498 s = splhigh(); 499 pagezero_cookie = hppa_pagezero_map(); 500 *pdc_consbuf = c; 501 err = pdc_call(pdc_cniodc, 0, pz_cons->pz_hpa, IODC_IO_CONSOUT, 502 pz_cons->pz_spa, pz_cons->pz_layers, &pdcret1, 0, pdc_consbuf, 1, 0); 503 hppa_pagezero_unmap(pagezero_cookie); 504 splx(s); 505 506 if (err < 0) { 507 #if defined(DDB) || defined(KGDB) 508 Debugger(); 509 #endif /* DDB || KGDB */ 510 delay(250000); 511 #if 0 512 /* 513 * It's not a good idea to use the output to print 514 * an output error. 515 */ 516 printf("pdccnputc: output error: %d\n", err); 517 #endif 518 } 519 } 520 521 void 522 pdccnpollc(dev_t dev, int on) 523 { 524 } 525 526 static int 527 pdcgettod(todr_chip_handle_t tch, struct timeval *tvp) 528 { 529 struct pdc_tod *tod = (struct pdc_tod *)&pdcret1; 530 int error; 531 532 error = pdc_call((iodcio_t)pdc, 1, PDC_TOD, PDC_TOD_READ, 533 &pdcret1); 534 535 if (error == 0) { 536 tvp->tv_sec = tod->sec; 537 tvp->tv_usec = tod->usec; 538 } 539 return error; 540 } 541 542 static int 543 pdcsettod(todr_chip_handle_t tch, struct timeval *tvp) 544 { 545 int error; 546 547 error = pdc_call((iodcio_t)pdc, 1, PDC_TOD, PDC_TOD_WRITE, 548 tvp->tv_sec, tvp->tv_usec); 549 550 return error; 551 } 552 553 554 int 555 pdcproc_chassis_display(unsigned long disp) 556 { 557 int err; 558 559 err = pdc_call((iodcio_t)pdc, 0, PDC_CHASSIS, PDC_CHASSIS_DISP, disp); 560 561 return err; 562 } 563 564 int 565 pdcproc_chassis_info(struct pdc_chassis_info *pci, struct pdc_chassis_lcd *pcl) 566 { 567 int err; 568 569 err = pdc_call((iodcio_t)pdc, 0, PDC_CHASSIS, PDC_CHASSIS_INFO, 570 &pdcret1, &pdcret2 , sizeof(*pcl)); 571 if (err < 0) 572 return err; 573 574 memcpy(pci, &pdcret1, sizeof(*pci)); 575 memcpy(pcl, &pdcret2, sizeof(*pcl)); 576 577 return err; 578 } 579 580 int 581 pdcproc_pim(int type, struct pdc_pim *pp, void **buf, size_t *sz) 582 { 583 static char data[896] __attribute__((__aligned__(8))); 584 int err; 585 586 err = pdc_call((iodcio_t)pdc, 0, PDC_PIM, type, &pdcret1, data, 587 sizeof(data)); 588 if (err < 0) 589 return err; 590 591 memcpy(pp, &pdcret1, sizeof(*pp)); 592 *buf = data; 593 *sz = sizeof(data); 594 595 return err; 596 } 597 598 int 599 pdcproc_model_info(struct pdc_model *pm) 600 { 601 int err; 602 603 err = pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_INFO, &pdcret1); 604 if (err < 0) 605 return err; 606 607 memcpy(pm, &pdcret1, sizeof(*pm)); 608 609 return err; 610 } 611 612 int 613 pdcproc_model_cpuid(struct pdc_cpuid *pc) 614 { 615 int err; 616 617 err = pdc_call((iodcio_t)pdc, 0, PDC_MODEL, PDC_MODEL_CPUID, &pdcret1); 618 if (err < 0) 619 return err; 620 621 memcpy(pc, &pdcret1, sizeof(*pc)); 622 623 return err; 624 } 625 626 int 627 pdcproc_cache(struct pdc_cache *pc) 628 { 629 int err; 630 631 err = pdc_call((iodcio_t)pdc, 0, PDC_CACHE, PDC_CACHE_DFLT, &pdcret1); 632 633 if (err < 0) 634 return err; 635 636 memcpy(pc, &pdcret1, sizeof(*pc)); 637 638 return err; 639 } 640 641 642 int 643 pdcproc_cache_spidbits(struct pdc_spidb *pcs) 644 { 645 int err; 646 647 err = pdc_call((iodcio_t)pdc, 0, PDC_CACHE, PDC_CACHE_GETSPIDB, 648 &pdcret1); 649 650 if (err < 0) 651 return err; 652 653 memcpy(pcs, &pdcret1, sizeof(*pcs)); 654 655 return err; 656 } 657 658 int 659 pdcproc_hpa_processor(hppa_hpa_t *hpa) 660 { 661 int err; 662 663 err = pdc_call((iodcio_t)pdc, 0, PDC_HPA, PDC_HPA_DFLT, &pdcret1); 664 if (err < 0) 665 return err; 666 667 *hpa = pdcret1.result[0]; 668 669 return err; 670 } 671 672 int 673 pdcproc_coproc(struct pdc_coproc *pc) 674 { 675 int err; 676 677 err = pdc_call((iodcio_t)pdc, 0, PDC_COPROC, PDC_COPROC_DFLT, &pdcret1); 678 if (err < 0) 679 return err; 680 681 memcpy(pc, &pdcret1, sizeof(*pc)); 682 683 return err; 684 } 685 686 int 687 pdcproc_iodc_read(hppa_hpa_t hpa, int command, int *actcnt, 688 struct pdc_iodc_read *buf1, size_t sz1, struct iodc_data *buf2, 689 size_t sz2) 690 { 691 int err; 692 693 err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_READ, 694 &pdcret1, hpa, command, &pdcret2, sizeof(pdcret2)); 695 696 if (err < 0) 697 return err; 698 699 if (actcnt != NULL) { 700 struct pdc_iodc_read *pir = (struct pdc_iodc_read *)&pdcret1; 701 702 *actcnt = pir->size; 703 } 704 705 memcpy(buf1, &pdcret1, sz1); 706 memcpy(buf2, &pdcret2, sz2); 707 708 return err; 709 } 710 711 int 712 pdcproc_iodc_ninit(struct pdc_iodc_minit *pimi, hppa_hpa_t hpa, int sz) 713 { 714 int err; 715 716 err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_NINIT, &pdcret1, 717 hpa, sz); 718 719 if (err < 0) 720 return err; 721 722 memcpy(pimi, &pdcret1, sizeof(*pimi)); 723 724 return err; 725 } 726 727 int 728 pdcproc_instr(unsigned int *mem) 729 { 730 int err; 731 732 err = pdc_call((iodcio_t)pdc, 0, PDC_INSTR, PDC_INSTR_DFLT, &pdcret1); 733 if (err < 0) 734 return err; 735 736 memcpy(mem, &pdcret1, sizeof(*mem)); 737 738 return err; 739 } 740 741 int 742 pdcproc_block_tlb(struct pdc_btlb *pb) 743 { 744 int err; 745 746 err = pdc_call((iodcio_t)pdc, 0, PDC_BLOCK_TLB, PDC_BTLB_DEFAULT, 747 &pdcret1); 748 if (err < 0) 749 return err; 750 751 memcpy(pb, &pdcret1, sizeof(*pb)); 752 753 return err; 754 } 755 756 int 757 pdcproc_btlb_insert(pa_space_t sp, vaddr_t va, paddr_t pa, vsize_t sz, 758 u_int prot, int index) 759 { 760 int err; 761 762 err = pdc_call((iodcio_t)pdc, 0, PDC_BLOCK_TLB, PDC_BTLB_INSERT, sp, 763 va, pa, sz, prot, index); 764 765 return err; 766 } 767 768 int 769 pdcproc_btlb_purge(pa_space_t sp, vaddr_t va, paddr_t pa, vsize_t sz) 770 { 771 int err; 772 773 err = pdc_call((iodcio_t)pdc, 0, PDC_BLOCK_TLB, PDC_BTLB_PURGE, sp, va, 774 pa, sz); 775 776 return err; 777 } 778 779 int 780 pdcproc_btlb_purgeall(void) 781 { 782 int err; 783 784 err = pdc_call((iodcio_t)pdc, 0, PDC_BLOCK_TLB, PDC_BTLB_PURGE_ALL); 785 786 return err; 787 } 788 789 int pdcproc_tlb_info(struct pdc_hwtlb *ph) 790 { 791 int err; 792 793 err = pdc_call((iodcio_t)pdc, 0, PDC_TLB, PDC_TLB_INFO, &pdcret1); 794 if (err < 0) 795 return err; 796 797 memcpy(ph, &pdcret1, sizeof(*ph)); 798 799 return err; 800 } 801 802 int 803 pdcproc_tlb_config(struct pdc_hwtlb *ph, unsigned long hpt, 804 unsigned long hptsize, unsigned long type) 805 { 806 int err; 807 808 err = pdc_call((iodcio_t)pdc, 0, PDC_TLB, PDC_TLB_CONFIG, ph, hpt, 809 hptsize, type); 810 811 return err; 812 } 813 814 int 815 pdcproc_system_map_find_mod(struct pdc_system_map_find_mod *psm, 816 struct device_path *dev, int mod) 817 { 818 int err; 819 820 err = pdc_call((iodcio_t)pdc, 0, PDC_SYSTEM_MAP, 821 PDC_SYSTEM_MAP_FIND_MOD, &pdcret1, &pdcret2, mod); 822 if (err < 0) 823 return err; 824 825 memcpy(psm, &pdcret1, sizeof(*psm)); 826 memcpy(dev, &pdcret2, sizeof(*dev)); 827 828 return err; 829 } 830 831 int 832 pdcproc_system_map_find_addr(struct pdc_system_map_find_addr *psm, int mod, 833 int addr) 834 { 835 int err; 836 837 err = pdc_call((iodcio_t)pdc, 0, PDC_SYSTEM_MAP, 838 PDC_SYSTEM_MAP_FIND_ADDR, &pdcret1, mod, addr); 839 if (err < 0) 840 return err; 841 842 memcpy(psm, &pdcret1, sizeof(*psm)); 843 844 return err; 845 846 } 847 848 int 849 pdcproc_system_map_trans_path(struct pdc_memmap *pmm, struct device_path *dev) 850 { 851 int err; 852 853 memcpy(&pdcret2, dev, sizeof(*dev)); 854 855 err = pdc_call((iodcio_t)pdc, 0, PDC_SYSTEM_MAP, 856 PDC_SYSTEM_MAP_TRANS_PATH, &pdcret1, &pdcret2); 857 if (err < 0) 858 return err; 859 860 memcpy(pmm, &pdcret1, sizeof(*pmm)); 861 862 return err; 863 } 864 865 int 866 pdcproc_soft_power_info(struct pdc_power_info *pspi) 867 { 868 int err; 869 870 err = pdc_call((iodcio_t)pdc, 0, PDC_SOFT_POWER, PDC_SOFT_POWER_INFO, 871 &pdcret1, 0); 872 if (err < 0) 873 return err; 874 875 memcpy(pspi, &pdcret1, sizeof(*pspi)); 876 877 return err; 878 } 879 880 int 881 pdcproc_soft_power_enable(int action) 882 { 883 int err; 884 885 err = pdc_call((iodcio_t)pdc, 0, PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, 886 &pdcret1, action); 887 888 return err; 889 } 890 891 int 892 pdcproc_memmap(struct pdc_memmap *pmm, struct device_path *dev) 893 { 894 int err; 895 896 memcpy(&pdcret2, dev, sizeof(*dev)); 897 898 err = pdc_call((iodcio_t)pdc, 0, PDC_MEMMAP, PDC_MEMMAP_HPA, &pdcret1, 899 &pdcret2); 900 if (err < 0) 901 return err; 902 903 memcpy(pmm, &pdcret1, sizeof(*pmm)); 904 905 return err; 906 } 907 908 int 909 pdcproc_ioclrerrors(void) 910 { 911 int err; 912 913 err = pdc_call((iodcio_t)pdc, 0, PDC_IO, PDC_IO_READ_AND_CLEAR_ERRORS); 914 915 return err; 916 } 917 918 int 919 pdcproc_ioreset(void) 920 { 921 int err; 922 923 err = pdc_call((iodcio_t)pdc, 0, PDC_IO, PDC_IO_RESET_DEVICES); 924 925 return err; 926 } 927 928 int 929 pdcproc_doreset(void) 930 { 931 int err; 932 933 err = pdc_call((iodcio_t)pdc, 0, PDC_BROADCAST_RESET, PDC_DO_RESET); 934 935 return err; 936 } 937 938 int 939 pdcproc_lan_station_id(char *addr, size_t sz, hppa_hpa_t hpa) 940 { 941 struct pdc_lan_station_id *mac = (struct pdc_lan_station_id *)&pdcret1; 942 int err; 943 944 err = pdc_call((iodcio_t)pdc, 0, PDC_LAN_STATION_ID, 945 PDC_LAN_STATION_ID_READ, &pdcret1, hpa); 946 if (err < 0) 947 return err; 948 949 memcpy(addr, mac->addr, sz); 950 951 return 0; 952 } 953 954 int 955 pdcproc_pci_inttblsz(int *nentries) 956 { 957 struct pdc_pat_io_num *ppio = (struct pdc_pat_io_num *)&pdcret1; 958 int err; 959 960 err = pdc_call((iodcio_t)pdc, 0, PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL_SZ, 961 &pdcret1); 962 963 *nentries = ppio->num; 964 965 return err; 966 } 967 968 /* Maximum number of supported interrupt routing entries. */ 969 #define MAX_INT_TBL_SZ 16 970 971 int 972 pdcproc_pci_gettable(int nentries, size_t size, void *table) 973 { 974 int err; 975 static struct pdc_pat_pci_rt int_tbl[MAX_INT_TBL_SZ] PDC_ALIGNMENT; 976 977 if (nentries > MAX_INT_TBL_SZ) 978 panic("interrupt routing table too big (%d entries)", nentries); 979 980 pdcret1.result[0] = nentries; 981 982 err = pdc_call((iodcio_t)pdc, 0, PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL, 983 &pdcret1, 0, &int_tbl); 984 if (err < 0) 985 return err; 986 987 memcpy(table, int_tbl, size); 988 989 return err; 990 } 991