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