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