code:
/*	$OpenBSD: mem.c,v 1.36 2015/02/10 22:44:35 miod Exp $	*/

/*
 * Copyright (c) 1998-2004 Michael Shalayeff
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * Copyright (c) 1991,1992,1994, The University of Utah and
 * the Computer Systems Laboratory (CSL).  All rights reserved.
 *
 * Subject to your agreements with CMU,
 * permission to use, copy, modify and distribute this software and its
 * documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 *
 * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
 * IS" CONDITION.  THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
 * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * CSL requests users of this software to return to csl-dist@cs.utah.edu any
 * improvements that they make and grant CSL redistribution rights.
 *
 *	Utah $Hdr: mem.c 1.9 94/12/16$
 */
/*
 * Mach Operating System
 * Copyright (c) 1992 Carnegie Mellon University
 * All Rights Reserved.
 *
 * Permission to use, copy, modify and distribute this software and its
 * documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 *
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * Carnegie Mellon requests users of this software to return to
 *
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 * any improvements or extensions that they make and grant Carnegie Mellon
 * the rights to redistribute these changes.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/uio.h>
#include <sys/types.h>
#include <sys/device.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/file.h>

#include <uvm/uvm_extern.h>

#include <machine/conf.h>
#include <machine/bus.h>
#include <machine/iomod.h>
#include <machine/autoconf.h>
#include <machine/pmap.h>

#include <hppa/dev/cpudevs.h>
#include <hppa/dev/viper.h>

#define	VIPER_HPA	0xfffbf000

/* registers on the PCXL2 MIOC */
struct l2_mioc {
	u_int32_t	pad[0x20];	/* 0x000 */
	u_int32_t	mioc_control;	/* 0x080 MIOC control bits */
	u_int32_t	mioc_status;	/* 0x084 MIOC status bits */
	u_int32_t	pad1[6];	/* 0x088 */
	u_int32_t	sltcv;		/* 0x0a0 L2 cache control */
#define	SLTCV_AVWL	0x00002000	/* extra cycle for addr valid write low */
#define	SLTCV_UP4COUT	0x00001000	/* update cache on CPU castouts */
#define	SLTCV_EDCEN	0x08000000	/* enable error correction */
#define	SLTCV_EDTAG	0x10000000	/* enable diagtag */
#define	SLTCV_CHKTP	0x20000000	/* enable parity checking */
#define	SLTCV_LOWPWR	0x40000000	/* low power mode */
#define	SLTCV_ENABLE	0x80000000	/* enable L2 cache */
#define	SLTCV_BITS	"\020\15avwl\16up4cout\24edcen\25edtag\26chktp\27lowpwr\30l2ena"
	u_int32_t	tagmask;	/* 0x0a4 L2 cache tag mask */
	u_int32_t	diagtag;	/* 0x0a8 L2 invalidates tag */
	u_int32_t	sltestat;	/* 0x0ac L2 last logged tag read */
	u_int32_t	slteadd;	/* 0x0b0 L2 pa of -- " -- */
	u_int32_t	pad2[3];	/* 0x0b4 */
	u_int32_t	mtcv;		/* 0x0c0 MIOC timings */
	u_int32_t	ref;		/* 0x0cc MIOC refresh timings */
	u_int32_t	pad3[4];	/* 0x0d0 */
	u_int32_t	mderradd;	/* 0x0e0 addr of most evil mem error */
	u_int32_t	pad4;		/* 0x0e4 */
	u_int32_t	dmaerr;		/* 0x0e8 addr of most evil dma error */
	u_int32_t	dioerr;		/* 0x0ec addr of most evil dio error */
	u_int32_t	gsc_timeout;	/* 0x0f0 1-compl of GSC timeout delay */
	u_int32_t	hidmamem;	/* 0x0f4 amount of phys mem installed */
	u_int32_t	pad5[2];	/* 0x0f8 */
	u_int32_t	memcomp[16];	/* 0x100 memory address comparators */
	u_int32_t	memmask[16];	/* 0x140 masks for -- " -- */
	u_int32_t	memtest;	/* 0x180 test address decoding */
	u_int32_t	pad6[0xf];	/* 0x184 */
	u_int32_t	outchk;		/* 0x1c0 address decoding output */
	u_int32_t	pad7[0x168];	/* 0x200 */
	u_int32_t	gsc15x_config;	/* 0x7a0 writev enable */
};

struct mem_softc {
	struct device sc_dev;

	volatile struct vi_trs *sc_vp;
	volatile struct l2_mioc *sc_l2;
};

int	memmatch(struct device *, void *, void *);
void	memattach(struct device *, struct device *, void *);

struct cfattach mem_ca = {
	sizeof(struct mem_softc), memmatch, memattach
};

struct cfdriver mem_cd = {
	NULL, "mem", DV_DULL
};

caddr_t zeropage;

int
memmatch(parent, cfdata, aux)
	struct device *parent;
	void *cfdata;
	void *aux;
{
	register struct confargs *ca = aux;

	if (ca->ca_type.iodc_type != HPPA_TYPE_MEMORY ||
	    ca->ca_type.iodc_sv_model != HPPA_MEMORY_PDEP)
		return 0;

	return 1;
}

void
memattach(parent, self, aux)
	struct device *parent;
	struct device *self;
	void *aux;
{
	struct pdc_iodc_minit pdc_minit PDC_ALIGNMENT;
	struct mem_softc *sc = (struct mem_softc *)self;
	struct confargs *ca = aux;
	int err;

	printf (":");

	/* XXX check if we are dealing w/ Viper */
	if (ca->ca_hpa == (hppa_hpa_t)VIPER_HPA) {

		sc->sc_vp = (struct vi_trs *)
		    &((struct iomod *)ca->ca_hpa)->priv_trs;

		printf(" viper rev %x,", sc->sc_vp->vi_status.hw_rev);

		/* XXX other values seem to blow it up */
		if (sc->sc_vp->vi_status.hw_rev == 0) {
			u_int32_t vic;
			int s, settimeout;

			switch (cpu_hvers) {
			case HPPA_BOARD_HP705:
			case HPPA_BOARD_HP710:
			case HPPA_BOARD_HP715_33:
			case HPPA_BOARD_HP715S_33:
			case HPPA_BOARD_HP715T_33:
			case HPPA_BOARD_HP715_50:
			case HPPA_BOARD_HP715S_50:
			case HPPA_BOARD_HP715T_50:
			case HPPA_BOARD_HP715_75:
			case HPPA_BOARD_HP720:
			case HPPA_BOARD_HP725_50:
			case HPPA_BOARD_HP725_75:
			case HPPA_BOARD_HP730_66:
			case HPPA_BOARD_HP750_66:
				settimeout = 1;
				break;
			default:
				settimeout = 0;
				break;
			}
			if (sc->sc_dev.dv_cfdata->cf_flags & 1)
				settimeout = !settimeout;

#ifdef DEBUG
			printf(" ctrl %b", VI_CTRL, VI_CTRL_BITS);
#endif
			s = splhigh();
			vic = VI_CTRL;
			vic &= ~VI_CTRL_CORE_DEN;
			vic &= ~VI_CTRL_SGC0_DEN;
			vic &= ~VI_CTRL_SGC1_DEN;
			vic |=  VI_CTRL_EISA_DEN;
			vic |=  VI_CTRL_CORE_PRF;

			if (settimeout && (vic & VI_CTRL_VSC_TOUT) == 0)
				vic |= (850 << 19);	/* clks */

			sc->sc_vp->vi_control = vic;

			__asm volatile("stwas %1, 0(%0)"
			    :: "r" (&VI_CTRL), "r" (vic) : "memory");
			splx(s);
#ifdef DEBUG
			printf (" >> %b,", vic, VI_CTRL_BITS);
#endif
		} else {
			/* set at least VI_CTRL_EISA_DEN ? */
		}
	} else
		sc->sc_vp = NULL;

	if ((err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_NINIT,
	    &pdc_minit, ca->ca_hpa, PAGE0->imm_spa_size)) < 0)
		pdc_minit.max_spa = PAGE0->imm_max_mem;

	printf(" size %d", pdc_minit.max_spa / (1024*1024));
	if (pdc_minit.max_spa % (1024*1024))
		printf(".%d", pdc_minit.max_spa % (1024*1024));
	printf("MB");

	/* L2 cache controller is a part of the memory controller on PCXL2 */
	if (cpu_type == hpcxl2) {
		sc->sc_l2 = (struct l2_mioc *)ca->ca_hpa;
#ifdef DEBUG
		printf(", sltcv %b", sc->sc_l2->sltcv, SLTCV_BITS);
#endif
		/* sc->sc_l2->sltcv |= SLTCV_UP4COUT; */
		if (sc->sc_l2->sltcv & SLTCV_ENABLE) {
			u_int32_t tagmask = sc->sc_l2->tagmask >> 20;

			printf(", %dMB L2 cache", tagmask + 1);
		}
	}

	printf("\n");
}

void
viper_setintrwnd(mask)
	u_int32_t mask;
{
	register struct mem_softc *sc;

	sc = mem_cd.cd_devs[0];

	if (sc->sc_vp)
		sc->sc_vp->vi_intrwd = mask;
}

void
viper_eisa_en()
{
	struct mem_softc *sc;

	sc = mem_cd.cd_devs[0];
	if (sc->sc_vp) {
		u_int32_t vic;
		int s;

		s = splhigh();
		vic = VI_CTRL;
		vic &= ~VI_CTRL_EISA_DEN;
		sc->sc_vp->vi_control = vic;
		__asm volatile("stwas %1, 0(%0)"
		    :: "r" (&VI_CTRL), "r" (vic) : "memory");
		splx(s);
	}
}

int
mmopen(dev, flag, ioflag, p)
	dev_t dev;
	int flag;
	int ioflag;
	struct proc *p;
{
	return (0);
}

/*ARGSUSED*/
int
mmclose(dev, flag, mode, p)
	dev_t dev;
	int flag, mode;
	struct proc *p;
{
	return (0);
}

int
mmrw(dev, uio, flags)
	dev_t dev;
	struct uio *uio;
	int flags;
{
	struct iovec *iov;
	vaddr_t	v, o;
	int error = 0;
	size_t c;

	while (uio->uio_resid > 0 && error == 0) {
		iov = uio->uio_iov;
		if (iov->iov_len == 0) {
			uio->uio_iov++;
			uio->uio_iovcnt--;
			if (uio->uio_iovcnt < 0)
				panic("mmrw");
			continue;
		}
		switch (minor(dev)) {

		case 0:				/*  /dev/mem  */

			/* If the address isn't in RAM, bail. */
			v = uio->uio_offset;
			if (atop(v) > physmem) {
				error = EFAULT;
				/* this will break us out of the loop */
				continue;
			}
			c = ptoa(physmem) - v;
			c = ulmin(c, uio->uio_resid);
			error = uiomove((caddr_t)v, c, uio);
			break;

		case 1:				/*  /dev/kmem  */
			v = uio->uio_offset;
			o = v & PGOFSET;
			c = ulmin(uio->uio_resid, PAGE_SIZE - o);
			if (atop(v) > physmem && !uvm_kernacc((caddr_t)v,
			    c, (uio->uio_rw == UIO_READ) ? B_READ : B_WRITE)) {
				error = EFAULT;
				/* this will break us out of the loop */
				continue;
			}
			error = uiomove((caddr_t)v, c, uio);
			break;

		case 2:				/*  /dev/null  */
			if (uio->uio_rw == UIO_WRITE)
				uio->uio_resid = 0;
			return (0);

		case 12:			/*  /dev/zero  */
			/* Write to /dev/zero is ignored. */
			if (uio->uio_rw == UIO_WRITE) {
				uio->uio_resid = 0;
				return (0);
			}
			/*
			 * On the first call, allocate and zero a page
			 * of memory for use with /dev/zero.
			 */
			if (zeropage == NULL)
				zeropage = malloc(PAGE_SIZE, M_TEMP,
				    M_WAITOK | M_ZERO);
			c = ulmin(iov->iov_len, PAGE_SIZE);
			error = uiomove(zeropage, c, uio);
			break;

		default:
			return (ENXIO);
		}
	}

	return (error);
}

paddr_t
mmmmap(dev, off, prot)
	dev_t dev;
	off_t off;
	int prot;
{
	if (minor(dev) != 0)
		return (-1);

	/*
	 * Allow access only in RAM.
	 */
#if 0
	if (off < ptoa(firstusablepage) ||
	    off >= ptoa(lastusablepage + 1))
		return (-1);
#endif
	return (off);
}

int
mmioctl(dev, cmd, data, flags, p)
	dev_t dev;
	u_long cmd;
	caddr_t data;
	int flags;
	struct proc *p;
{
	return (EOPNOTSUPP);
}


code:
/*	$OpenBSD: mongoose.c,v 1.21 2010/05/24 15:04:53 deraadt Exp $	*/

/*
 * Copyright (c) 1998-2003 Michael Shalayeff
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/reboot.h>

#include <machine/bus.h>
#include <machine/iomod.h>
#include <machine/autoconf.h>

#include <hppa/dev/cpudevs.h>
#include <hppa/dev/viper.h>

#include <dev/eisa/eisareg.h>
#include <dev/eisa/eisavar.h>

#include <dev/isa/isareg.h>
#include <dev/isa/isavar.h>

#include <hppa/dev/mongoosereg.h>
#include <hppa/dev/mongoosevar.h>

void	mgattach_gedoens(struct device *, struct device *, void *);
int	mgmatch_gedoens(struct device *, void *, void *);

struct cfattach mg_gedoens_ca = {
	sizeof(struct mongoose_softc), mgmatch_gedoens, mgattach_gedoens
};

struct cfdriver mongoose_cd = {
	NULL, "mongoose", DV_DULL
};

void		 mg_eisa_attach_hook(struct device *parent,
		    struct device *self,
		    struct eisabus_attach_args *mg);
int		 mg_intr_map(void *v, u_int irq, eisa_intr_handle_t *ehp);
const char	*mg_intr_string(void *v, int irq);
void		 mg_isa_attach_hook(struct device *parent,
		    struct device *self,
		    struct isabus_attach_args *iba);
void		*mg_intr_establish(void *v, int irq, int type, int pri,
		    int (*handler)(void *), void *arg, const char *name);
void		 mg_intr_disestablish(void *v, void *cookie);
int		 mg_intr_check(void *v, int irq, int type);
int		 mg_eisa_iomap(void *v, bus_addr_t addr, bus_size_t size,
		    int flags, bus_space_handle_t *bshp);
int		 mg_eisa_memmap(void *v, bus_addr_t addr, bus_size_t size,
		    int flags, bus_space_handle_t *bshp);
void		 mg_eisa_memunmap(void *v, bus_space_handle_t bsh,
		    bus_size_t size);
void		 mg_isa_barrier(void *v, bus_space_handle_t h, bus_size_t o,
		    bus_size_t l, int op);
u_int16_t	 mg_isa_r2(void *v, bus_space_handle_t h, bus_size_t o);
u_int32_t	 mg_isa_r4(void *v, bus_space_handle_t h, bus_size_t o);
void		 mg_isa_w2(void *v, bus_space_handle_t h, bus_size_t o,
		    u_int16_t vv);
void		 mg_isa_w4(void *v, bus_space_handle_t h, bus_size_t o,
		    u_int32_t vv);
void		 mg_isa_rm_2(void *v, bus_space_handle_t h, bus_size_t o,
		    u_int16_t *a, bus_size_t c);
void		 mg_isa_rm_4(void *v, bus_space_handle_t h, bus_size_t o,
		    u_int32_t *a, bus_size_t c);
void		 mg_isa_wm_2(void *v, bus_space_handle_t h, bus_size_t o,
		    const u_int16_t *a, bus_size_t c);
void		 mg_isa_wm_4(void *v, bus_space_handle_t h, bus_size_t o,
		    const u_int32_t *a, bus_size_t c);
void		 mg_isa_sm_2(void *v, bus_space_handle_t h, bus_size_t o,
		    u_int16_t vv, bus_size_t c);
void		 mg_isa_sm_4(void *v, bus_space_handle_t h, bus_size_t o,
		    u_int32_t vv, bus_size_t c);
void		 mg_isa_rr_2(void *v, bus_space_handle_t h, bus_size_t o,
		    u_int16_t *a, bus_size_t c);
void		 mg_isa_rr_4(void *v, bus_space_handle_t h, bus_size_t o,
		    u_int32_t *a, bus_size_t c);
void		 mg_isa_wr_2(void *v, bus_space_handle_t h, bus_size_t o,
		    const u_int16_t *a, bus_size_t c);
void		 mg_isa_wr_4(void *v, bus_space_handle_t h, bus_size_t o,
		    const u_int32_t *a, bus_size_t c);
void		 mg_isa_sr_2(void *v, bus_space_handle_t h, bus_size_t o,
		    u_int16_t vv, bus_size_t c);
void		 mg_isa_sr_4(void *v, bus_space_handle_t h, bus_size_t o,
		    u_int32_t vv, bus_size_t c);

/* TODO: DMA guts */

void
mg_eisa_attach_hook(struct device *parent, struct device *self,
	struct eisabus_attach_args *mg)
{
}

int
mg_intr_map(void *v, u_int irq, eisa_intr_handle_t *ehp)
{
	*ehp = irq;
	return 0;
}

const char *
mg_intr_string(void *v, int irq)
{
	static char buf[16];

	snprintf(buf, sizeof buf, "isa irq %d", irq);
	return buf;
}

void
mg_isa_attach_hook(struct device *parent, struct device *self,
	struct isabus_attach_args *iba)
{

}

void *
mg_intr_establish(void *v, int irq, int type, int pri,
	int (*handler)(void *), void *arg, const char *name)
{
	struct hppa_isa_iv *iv;
	struct mongoose_softc *sc = v;
	volatile u_int8_t *imr, *pic;

	if (!sc || irq < 0 || irq >= MONGOOSE_NINTS ||
	    (0 <= irq && irq < MONGOOSE_NINTS && sc->sc_iv[irq].iv_handler))
		return NULL;

	if (type != IST_LEVEL && type != IST_EDGE) {
#ifdef DEBUG
		printf("%s: bad interrupt level (%d)\n", sc->sc_dev.dv_xname,
		    type);
#endif
		return NULL;
	}

	iv = &sc->sc_iv[irq];
	if (iv->iv_handler) {
#ifdef DEBUG
		printf("%s: irq %d already established\n", sc->sc_dev.dv_xname,
		    irq);
#endif
		return NULL;
	}

	iv->iv_name = name;
	iv->iv_pri = pri;
	iv->iv_handler = handler;
	iv->iv_arg = arg;

	if (irq < 8) {
		imr = &sc->sc_ctrl->imr0;
		pic = &sc->sc_ctrl->pic0;
	} else {
		imr = &sc->sc_ctrl->imr1;
		pic = &sc->sc_ctrl->pic1;
		irq -= 8;
	}

	*imr |= 1 << irq;
	*pic |= (type == IST_LEVEL) << irq;

	/* TODO: ack it? */

	return iv;
}

void
mg_intr_disestablish(void *v, void *cookie)
{
	struct hppa_isa_iv *iv = cookie;
	struct mongoose_softc *sc = v;
 	int irq = iv - sc->sc_iv;
 	volatile u_int8_t *imr;

	if (!sc || !cookie)
		return;

	if (irq < 8)
		imr = &sc->sc_ctrl->imr0;
	else
		imr = &sc->sc_ctrl->imr1;
	*imr &= ~(1 << irq);
	/* TODO: ack it? */

	iv->iv_handler = NULL;
}

int
mg_intr_check(void *v, int irq, int type)
{
	return 0;
}

int
mg_intr(void *v)
{
	struct mongoose_softc *sc = v;
	struct hppa_isa_iv *iv;
	int s, irq = 0;

	iv = &sc->sc_iv[irq];
	s = splraise(iv->iv_pri);
	(iv->iv_handler)(iv->iv_arg);
	splx(s);

	return 0;
}

int
mg_eisa_iomap(void *v, bus_addr_t addr, bus_size_t size, int flags,
	bus_space_handle_t *bshp)
{
	struct mongoose_softc *sc = v;

	/* see if it's ISA space we are mapping */
	if (0x100 <= addr && addr < 0x400) {
#define	TOISA(a) ((((a) & 0x3f8) << 9) + ((a) & 7))
		size = TOISA(addr + size) - TOISA(addr);
		addr = TOISA(addr);
	}

	return (sc->sc_bt->hbt_map)(NULL, sc->sc_iomap + addr, size,
				    flags, bshp);
}

int
mg_eisa_memmap(void *v, bus_addr_t addr, bus_size_t size, int flags,
	bus_space_handle_t *bshp)
{
	/* TODO: eisa memory map */
	return -1;
}

void
mg_eisa_memunmap(void *v, bus_space_handle_t bsh, bus_size_t size)
{
	/* TODO: eisa memory unmap */
}

void
mg_isa_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op)
{
	sync_caches();
}

u_int16_t
mg_isa_r2(void *v, bus_space_handle_t h, bus_size_t o)
{
	register u_int16_t r = *((volatile u_int16_t *)(h + o));
	return letoh16(r);
}

u_int32_t
mg_isa_r4(void *v, bus_space_handle_t h, bus_size_t o)
{
	register u_int32_t r = *((volatile u_int32_t *)(h + o));
	return letoh32(r);
}

void
mg_isa_w2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv)
{
	*((volatile u_int16_t *)(h + o)) = htole16(vv);
}

void
mg_isa_w4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv)
{
	*((volatile u_int32_t *)(h + o)) = htole32(vv);
}

void
mg_isa_rm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
{
	h += o;
	while (c--)
		*(a++) = letoh16(*(volatile u_int16_t *)h);
}

void
mg_isa_rm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
{
	h += o;
	while (c--)
		*(a++) = letoh32(*(volatile u_int32_t *)h);
}

void
mg_isa_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
{
	register u_int16_t r;
	h += o;
	while (c--) {
		r = *(a++);
		*(volatile u_int16_t *)h = htole16(r);
	}
}

void
mg_isa_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
{
	register u_int32_t r;
	h += o;
	while (c--) {
		r = *(a++);
		*(volatile u_int32_t *)h = htole32(r);
	}
}

void
mg_isa_sm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
{
	vv = htole16(vv);
	h += o;
	while (c--)
		*(volatile u_int16_t *)h = vv;
}

void
mg_isa_sm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
{
	vv = htole32(vv);
	h += o;
	while (c--)
		*(volatile u_int32_t *)h = vv;
}

void
mg_isa_rr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
{
	volatile u_int16_t *p = (u_int16_t *)(h + o);
	u_int32_t r;

	while (c--) {
		r = *p++;
		*a++ = letoh16(r);
	}
}

void
mg_isa_rr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
{
	volatile u_int32_t *p = (u_int32_t *)(h + o);
	u_int32_t r;

	while (c--) {
		r = *p++;
		*a++ = letoh32(r);
	}
}

void
mg_isa_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
{
	volatile u_int16_t *p = (u_int16_t *)(h + o);
	u_int32_t r;

	while (c--) {
		r = *a++;
		*p++ = htole16(r);
	}
}

void
mg_isa_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
{
	volatile u_int32_t *p = (u_int32_t *)(h + o);
	u_int32_t r;

	while (c--) {
		r = *a++;
		*p++ = htole32(r);
	}
}

void
mg_isa_sr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
{
	volatile u_int16_t *p = (u_int16_t *)(h + o);

	vv = htole16(vv);
	while (c--)
		*p++ = vv;
}

void
mg_isa_sr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
{
	volatile u_int32_t *p = (u_int32_t *)(h + o);

	vv = htole32(vv);
	while (c--)
		*p++ = vv;
}

int
mgattach_common(sc)
	struct mongoose_softc *sc;
{
	struct hppa_bus_space_tag *bt;
	union mongoose_attach_args ea;
	char brid[EISA_IDSTRINGLEN];

	viper_eisa_en();

	/* BUS RESET */
	sc->sc_ctrl->nmi_ext = MONGOOSE_NMI_BUSRESET;
	DELAY(1);
	sc->sc_ctrl->nmi_ext = 0;
	DELAY(100);

	/* determine eisa board id */
	{
		u_int8_t id[4], *p;
		p = (u_int8_t *)(sc->sc_iomap + EISA_SLOTOFF_VID);
		id[0] = *p++;
		id[1] = *p++;
		id[2] = *p++;
		id[3] = *p++;

		brid[0] = EISA_VENDID_0(id);
		brid[1] = EISA_VENDID_1(id);
		brid[2] = EISA_VENDID_2(id);
		brid[3] = EISA_PRODID_0(id + 2);
		brid[4] = EISA_PRODID_1(id + 2);
		brid[5] = EISA_PRODID_2(id + 2);
		brid[6] = EISA_PRODID_3(id + 2);
		brid[7] = '\0';
	}

	printf (": %s rev %d, %d MHz\n", brid, sc->sc_regs->version,
		(sc->sc_regs->clock? 33 : 25));
	sc->sc_regs->liowait = 1;	/* disable isa wait states */
	sc->sc_regs->lock    = 1;	/* bus unlock */

	/* attach EISA */
	sc->sc_ec.ec_v = sc;
	sc->sc_ec.ec_attach_hook = mg_eisa_attach_hook;
	sc->sc_ec.ec_intr_establish = mg_intr_establish;
	sc->sc_ec.ec_intr_disestablish = mg_intr_disestablish;
	sc->sc_ec.ec_intr_string = mg_intr_string;
	sc->sc_ec.ec_intr_map = mg_intr_map;
	/* inherit the bus tags for eisa from the mainbus */
	bt = &sc->sc_eiot;
	bcopy(sc->sc_bt, bt, sizeof(*bt));
	bt->hbt_cookie = sc;
	bt->hbt_map = mg_eisa_iomap;
#define	R(n)	bt->__CONCAT(hbt_,n) = &__CONCAT(mg_isa_,n)
	/* R(barrier); */
	R(r2); R(r4); R(w2); R(w4);
	R(rm_2);R(rm_4);R(wm_2);R(wm_4);R(sm_2);R(sm_4);
	R(rr_2);R(rr_4);R(wr_2);R(wr_4);R(sr_2);R(sr_4);

	bt = &sc->sc_ememt;
	bcopy(sc->sc_bt, bt, sizeof(*bt));
	bt->hbt_cookie = sc;
	bt->hbt_map = mg_eisa_memmap;
	bt->hbt_unmap = mg_eisa_memunmap;
	/* attachment guts */
	ea.mongoose_eisa.eba_busname = "eisa";
	ea.mongoose_eisa.eba_iot = &sc->sc_eiot;
	ea.mongoose_eisa.eba_memt = &sc->sc_ememt;
	ea.mongoose_eisa.eba_dmat = NULL /* &sc->sc_edmat */;
	ea.mongoose_eisa.eba_ec = &sc->sc_ec;
	config_found((struct device *)sc, &ea.mongoose_eisa, mgprint);

	sc->sc_ic.ic_v = sc;
	sc->sc_ic.ic_attach_hook = mg_isa_attach_hook;
	sc->sc_ic.ic_intr_establish = mg_intr_establish;
	sc->sc_ic.ic_intr_disestablish = mg_intr_disestablish;
	sc->sc_ic.ic_intr_check = mg_intr_check;
	/* inherit the bus tags for isa from the eisa */
	bt = &sc->sc_imemt;
	bcopy(&sc->sc_ememt, bt, sizeof(*bt));
	bt = &sc->sc_iiot;
	bcopy(&sc->sc_eiot, bt, sizeof(*bt));
	/* TODO: DMA tags */
	/* attachment guts */
	ea.mongoose_isa.iba_busname = "isa";
	ea.mongoose_isa.iba_iot = &sc->sc_iiot;
	ea.mongoose_isa.iba_memt = &sc->sc_imemt;
#if NISADMA > 0
	ea.mongoose_isa.iba_dmat = &sc->sc_idmat;
#endif
	ea.mongoose_isa.iba_ic = &sc->sc_ic;
	config_found((struct device *)sc, &ea.mongoose_isa, mgprint);
#undef	R

	return (0);
}

int
mgprint(aux, pnp)
	void *aux;
	const char *pnp;
{
	union mongoose_attach_args *ea = aux;

	if (pnp)
		printf ("%s at %s", ea->mongoose_name, pnp);

	return (UNCONF);
}

int
mgmatch_gedoens(parent, cfdata, aux)
	struct device *parent;
	void *cfdata;
	void *aux;
{
	register struct confargs *ca = aux;
	/* struct cfdata *cf = cfdata; */
	bus_space_handle_t ioh;

	if (ca->ca_type.iodc_type != HPPA_TYPE_BHA ||
	    (ca->ca_type.iodc_sv_model != HPPA_BHA_EISA &&
	     ca->ca_type.iodc_sv_model != HPPA_BHA_WEISA))
		return 0;

	if (bus_space_map(ca->ca_iot, ca->ca_hpa + MONGOOSE_MONGOOSE,
	    IOMOD_HPASIZE, 0, &ioh))
		return 0;

	/* XXX check EISA signature */

	bus_space_unmap(ca->ca_iot, ioh, IOMOD_HPASIZE);

	return 1;
}

void
mgattach_gedoens(parent, self, aux)
	struct device *parent;
	struct device *self;
	void *aux;
{
	register struct confargs *ca = aux;
	register struct mongoose_softc *sc = (struct mongoose_softc *)self;
	bus_space_handle_t ioh;

	sc->sc_bt = ca->ca_iot;
	sc->sc_iomap = ca->ca_hpa;

	if (bus_space_map(ca->ca_iot, ca->ca_hpa + MONGOOSE_MONGOOSE,
	    sizeof(struct mongoose_regs), 0, &ioh) != 0) {
		printf(": can't map IO space\n");
		return;
	}
	sc->sc_regs = (struct mongoose_regs *)ioh;

	if (bus_space_map(ca->ca_iot, ca->ca_hpa + MONGOOSE_CTRL,
	    sizeof(struct mongoose_ctrl), 0, &ioh) != 0) {
		printf(": can't map control registers\n");
		bus_space_unmap(ca->ca_iot, (bus_space_handle_t)sc->sc_regs,
		    sizeof(struct mongoose_regs));
		return;
	}
	sc->sc_ctrl = (struct mongoose_ctrl *)ioh;

	if (mgattach_common(sc) != 0)
		return;

	/* attach interrupt */
	sc->sc_ih = cpu_intr_establish(IPL_HIGH, ca->ca_irq,
				       mg_intr, sc, sc->sc_dev.dv_xname);
}

license: unknown


code:
/*	$OpenBSD: mongoosereg.h,v 1.2 2008/08/24 18:53:36 miod Exp $	*/

/*
 * Copyright (c) 1998-2003 Michael Shalayeff
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

/* EISA Bus Adapter registers definitions */
#define	MONGOOSE_MONGOOSE	0x10000
struct mongoose_regs {
	u_int8_t	version;
	u_int8_t	lock;
	u_int8_t	liowait;
	u_int8_t	clock;
	u_int8_t	reserved[0xf000 - 4];
	u_int8_t	intack;
};

#define	MONGOOSE_CTRL		0x00000
#define	MONGOOSE_NINTS		16
struct mongoose_ctrl {
	struct dma0 {
		struct {
			u_int16_t	addr : 8;
			u_int16_t	count: 8;
		} ch[4];
		u_int8_t	command;
		u_int8_t	request;
		u_int8_t	mask_channel;
		u_int8_t	mode;
		u_int8_t	clr_byte_ptr;
		u_int8_t	master_clear;
		u_int8_t	mask_clear;
		u_int8_t	master_write;
		u_int8_t	pad[15];
	}	dma0;

	u_int8_t	irr0;		/* 0x20 */
	u_int8_t	imr0;
	u_int8_t	iack;		/* 0x22 -- 2 b2b reads generate
					(e)isa Iack cycle & returns int level */
	u_int8_t	pad0[29];

	struct timers {
		u_int8_t	sysclk;
		u_int8_t	refresh;
		u_int8_t	spkr;
		u_int8_t	ctrl;
		u_int32_t	pad;
	}	tmr[2];			/* 0x40 -- timers control */
	u_int8_t	pad1[16];

	u_int16_t	inmi;		/* 0x60 NMI control */
	u_int8_t	pad2[30];
	struct {
		u_int8_t	pad0;
		u_int8_t	ch2;
		u_int8_t	ch3;
		u_int8_t	ch1;
		u_int8_t	pad1;
		u_int8_t	pad2[3];
		u_int8_t	ch0;
		u_int8_t	pad4;
		u_int8_t	ch6;
		u_int8_t	ch7;
		u_int8_t	ch5;
		u_int8_t	pad5[3];
		u_int8_t	pad6[16];
	} pr;				/* 0x80 */

	u_int8_t	irr1;		/* 0xa0 */
	u_int8_t	imr1;
	u_int8_t	pad3[30];

	struct dma1 {
		struct {
			u_int32_t	addr : 16;
			u_int32_t	count: 16;
		} ch[4];
		u_int16_t	command;
		u_int16_t	request;
		u_int16_t	mask_channel;
		u_int16_t	mode;
		u_int16_t	clr_byte_ptr;
		u_int16_t	master_clear;
		u_int16_t	mask_clear;
		u_int16_t	master_write;
	}	dma1;			/* 0xc0 */

	u_int8_t	master_req;	/* 0xe0 master request register */
	u_int8_t	pad4[31];

	u_int8_t	pad5[0x3d0];	/* 0x4d0 */
	u_int8_t	pic0;		/* 0 - edge, 1 - level */
	u_int8_t	pic1;
	u_int8_t	pad6[0x460];
	u_int8_t	nmi;
	u_int8_t	nmi_ext;
#define	MONGOOSE_NMI_BUSRESET	0x01
#define	MONGOOSE_NMI_IOPORT_EN	0x02
#define	MONGOOSE_NMI_EN		0x04
#define	MONGOOSE_NMI_MTMO_EN	0x08
#define	MONGOOSE_NMI_RES4	0x10
#define	MONGOOSE_NMI_IOPORT_INT	0x20
#define	MONGOOSE_NMI_MASTER_INT	0x40
#define	MONGOOSE_NMI_INT	0x80
};

#define	MONGOOSE_IOMAP	0x100000


code:
/*	$OpenBSD: mongoosevar.h,v 1.2 2007/05/10 17:59:24 deraadt Exp $	*/

/*
 * Copyright (c) 1998-2003 Michael Shalayeff
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

struct hppa_isa_iv {
	const char *iv_name;
	int (*iv_handler)(void *arg);
	void *iv_arg;
	int iv_pri;

	/* don't do sharing, we won't have many slots anyway
	struct hppa_isa_iv *iv_next;
	*/
};

struct mongoose_softc {
	struct  device sc_dev;
	void *sc_ih;

	bus_space_tag_t sc_bt;
	volatile struct mongoose_regs *sc_regs;
	volatile struct mongoose_ctrl *sc_ctrl;
	bus_addr_t sc_iomap;

	/* interrupts section */
	struct hppa_eisa_chipset sc_ec;
	struct hppa_isa_chipset sc_ic;
	struct hppa_isa_iv sc_iv[MONGOOSE_NINTS];

	/* isa/eisa bus guts */
	struct hppa_bus_space_tag sc_eiot;
	struct hppa_bus_space_tag sc_ememt;
	struct hppa_bus_dma_tag sc_edmat;
	struct hppa_bus_space_tag sc_iiot;
	struct hppa_bus_space_tag sc_imemt;
	struct hppa_bus_dma_tag sc_idmat;
};

union mongoose_attach_args {
	char *mongoose_name;
	struct eisabus_attach_args mongoose_eisa;
	struct isabus_attach_args mongoose_isa;
};

int	mgattach_common(struct mongoose_softc *);
int	mgprint(void *, const char *);
int	mg_intr(void *);


code:
/*	$OpenBSD: pdc.c,v 1.39 2011/08/16 17:26:04 kettenis Exp $	*/

/*
 * Copyright (c) 1998-2003 Michael Shalayeff
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "com.h"

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/tty.h>
#include <sys/timeout.h>

#include <dev/cons.h>

#include <machine/conf.h>
#include <machine/pdc.h>
#include <machine/iomod.h>
#include <machine/autoconf.h>

typedef
struct pdc_softc {
	struct device sc_dv;
	struct tty *sc_tty;
	struct timeout sc_to;
} pdcsoftc_t;

pdcio_t pdc;
int pdcret[32] PDC_ALIGNMENT;
char pdc_consbuf[IODC_MINIOSIZ] PDC_ALIGNMENT;
iodcio_t pdc_cniodc, pdc_kbdiodc;
pz_device_t *pz_kbd, *pz_cons;

int pdcngetc(dev_t);
void pdcnputc(dev_t, char *);

struct consdev pdccons = { NULL, NULL, pdccngetc, pdccnputc,
     nullcnpollc, NULL, makedev(22, 0), CN_LOWPRI };

int pdcmatch(struct device *, void *, void *);
void pdcattach(struct device *, struct device *, void *);

struct cfattach pdc_ca = {
	sizeof(pdcsoftc_t), pdcmatch, pdcattach
};

struct cfdriver pdc_cd = {
	NULL, "pdc", DV_DULL
};

void pdcstart(struct tty *tp);
void pdctimeout(void *v);
int pdcparam(struct tty *tp, struct termios *);
int pdccnlookc(dev_t dev, int *cp);

#if NCOM > 0
/* serial console speed table */
static int pdc_speeds[] = {
	B50,
	B75,
	B110,
	B150,
	B300,
	B600,
	B1200,
	B2400,
	B4800,
	B7200,
	B9600,
	B19200,
	B38400,
	B57600,
	B115200,
	B230400,
};
#endif

void
pdc_init()
{
	static int kbd_iodc[IODC_MAXSIZE/sizeof(int)];
	static int cn_iodc[IODC_MAXSIZE/sizeof(int)];
	int err;

	/* XXX locore've done it XXX pdc = (pdcio_t)PAGE0->mem_pdc; */
	pz_kbd = &PAGE0->mem_kbd;
	pz_cons = &PAGE0->mem_cons;

	/* XXX should we reset the console/kbd here?
	   well, /boot did that for us anyway */
	if ((err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_READ,
	      pdcret, pz_cons->pz_hpa, IODC_IO, cn_iodc, IODC_MAXSIZE)) < 0 ||
	    (err = pdc_call((iodcio_t)pdc, 0, PDC_IODC, PDC_IODC_READ,
	      pdcret, pz_kbd->pz_hpa, IODC_IO, kbd_iodc, IODC_MAXSIZE)) < 0) {
#ifdef DEBUG
		printf("pdc_init: failed reading IODC (%d)\n", err);
#endif
	}

	pdc_cniodc = (iodcio_t)cn_iodc;
	pdc_kbdiodc = (iodcio_t)kbd_iodc;

	/* Start out with pdc as the console. */
	cn_tab = &pdccons;

	/* Figure out console settings. */
#if NCOM > 0
	if (PAGE0->mem_cons.pz_class == PCL_DUPLEX) {
		struct pz_device *pzd = &PAGE0->mem_cons;
		extern int comdefaultrate;
#ifdef DEBUG
		printf("console: class %d flags %b ",
		    pzd->pz_class, pzd->pz_flags, PZF_BITS);
		printf("bc %d/%d/%d/%d/%d/%d ",
		    pzd->pz_bc[0], pzd->pz_bc[1], pzd->pz_bc[2],
		    pzd->pz_bc[3], pzd->pz_bc[4], pzd->pz_bc[5]);
		printf("mod %x layers %x/%x/%x/%x/%x/%x hpa %x\n", pzd->pz_mod,
		    pzd->pz_layers[0], pzd->pz_layers[1], pzd->pz_layers[2],
		    pzd->pz_layers[3], pzd->pz_layers[4], pzd->pz_layers[5],
		    pzd->pz_hpa);

#endif

		/* compute correct baud rate */
		if (PZL_SPEED(pzd->pz_layers[0]) <
		    sizeof(pdc_speeds) / sizeof(int))
			comdefaultrate =
			    pdc_speeds[PZL_SPEED(pzd->pz_layers[0])];
		else
			comdefaultrate = B9600;	/* XXX */
	}
#endif
}

int
pdcmatch(parent, cfdata, aux)
	struct device *parent;
	void *cfdata;
	void *aux;
{
	struct cfdata *cf = cfdata;
	struct confargs *ca = aux;

	/* there could be only one */
	if (cf->cf_unit > 0 && !strcmp(ca->ca_name, "pdc"))
		return 0;

	return 1;
}

void
pdcattach(parent, self, aux)
	struct device *parent;
	struct device *self;
	void *aux;
{
	struct pdc_softc *sc = (struct pdc_softc *)self;

	if (!pdc)
		pdc_init();

	printf("\n");

	timeout_set(&sc->sc_to, pdctimeout, sc);
}

int
pdcopen(dev, flag, mode, p)
	dev_t dev;
	int flag, mode;
	struct proc *p;
{
	int unit = minor(dev);
	struct pdc_softc *sc;
	struct tty *tp;
	int s;
	int error = 0, setuptimeout = 0;

	if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
		return ENXIO;

	s = spltty();

	if (sc->sc_tty)
		tp = sc->sc_tty;
	else {
		tp = sc->sc_tty = ttymalloc(0);
	}

	tp->t_oproc = pdcstart;
	tp->t_param = pdcparam;
	tp->t_dev = dev;
	if ((tp->t_state & TS_ISOPEN) == 0) {
		ttychars(tp);
		tp->t_iflag = TTYDEF_IFLAG;
		tp->t_oflag = TTYDEF_OFLAG;
		tp->t_cflag = TTYDEF_CFLAG|CLOCAL;
		tp->t_lflag = TTYDEF_LFLAG;
		tp->t_ispeed = tp->t_ospeed = B9600;
		ttsetwater(tp);

		setuptimeout = 1;
	} else if (tp->t_state&TS_XCLUDE && suser(p, 0) != 0) {
		splx(s);
		return (EBUSY);
	}
	tp->t_state |= TS_CARR_ON;
	splx(s);

	error = (*linesw[tp->t_line].l_open)(dev, tp, p);
	if (error == 0 && setuptimeout)
		pdctimeout(sc);

	return error;
}

int
pdcclose(dev, flag, mode, p)
	dev_t dev;
	int flag, mode;
	struct proc *p;
{
	int unit = minor(dev);
	struct tty *tp;
	struct pdc_softc *sc;

	if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
		return ENXIO;

	tp = sc->sc_tty;
	timeout_del(&sc->sc_to);
	(*linesw[tp->t_line].l_close)(tp, flag, p);
	ttyclose(tp);
	return 0;
}

int
pdcread(dev, uio, flag)
	dev_t dev;
	struct uio *uio;
	int flag;
{
	int unit = minor(dev);
	struct tty *tp;
	struct pdc_softc *sc;

	if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
		return ENXIO;

	tp = sc->sc_tty;
	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
}

int
pdcwrite(dev, uio, flag)
	dev_t dev;
	struct uio *uio;
	int flag;
{
	int unit = minor(dev);
	struct tty *tp;
	struct pdc_softc *sc;

	if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
		return ENXIO;

	tp = sc->sc_tty;
	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
}

int
pdcioctl(dev, cmd, data, flag, p)
	dev_t dev;
	u_long cmd;
	caddr_t data;
	int flag;
	struct proc *p;
{
	int unit = minor(dev);
	int error;
	struct tty *tp;
	struct pdc_softc *sc;

	if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
		return ENXIO;

	tp = sc->sc_tty;
	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
	if (error >= 0)
		return error;
	error = ttioctl(tp, cmd, data, flag, p);
	if (error >= 0)
		return error;

	return ENOTTY;
}

int
pdcparam(tp, t)
	struct tty *tp;
	struct termios *t;
{

	return 0;
}

void
pdcstart(tp)
	struct tty *tp;
{
	int s;

	s = spltty();
	if (tp->t_state & (TS_TTSTOP | TS_BUSY)) {
		splx(s);
		return;
	}
	ttwakeupwr(tp);
	tp->t_state |= TS_BUSY;
	while (tp->t_outq.c_cc != 0)
		pdccnputc(tp->t_dev, getc(&tp->t_outq));
	tp->t_state &= ~TS_BUSY;
	splx(s);
}

int
pdcstop(tp, flag)
	struct tty *tp;
	int flag;
{
	int s;

	s = spltty();
	if (tp->t_state & TS_BUSY)
		if ((tp->t_state & TS_TTSTOP) == 0)
			tp->t_state |= TS_FLUSH;
	splx(s);
	return 0;
}

void
pdctimeout(v)
	void *v;
{
	struct pdc_softc *sc = v;
	struct tty *tp = sc->sc_tty;
	int c;

	while (pdccnlookc(tp->t_dev, &c)) {
		if (tp->t_state & TS_ISOPEN)
			(*linesw[tp->t_line].l_rint)(c, tp);
	}
	timeout_add(&sc->sc_to, 1);
}

struct tty *
pdctty(dev)
	dev_t dev;
{
	int unit = minor(dev);
	struct pdc_softc *sc;

	if (unit >= pdc_cd.cd_ndevs || (sc = pdc_cd.cd_devs[unit]) == NULL)
		return NULL;

	return sc->sc_tty;
}

int
pdccnlookc(dev, cp)
	dev_t dev;
	int *cp;
{
	int err, l;
	int s = splhigh();

	err = pdc_call(pdc_kbdiodc, 0, pz_kbd->pz_hpa, IODC_IO_CONSIN,
	    pz_kbd->pz_spa, pz_kbd->pz_layers, pdcret, 0, pdc_consbuf, 1, 0);

	l = pdcret[0];
	*cp = pdc_consbuf[0];
	splx(s);
#ifdef DEBUG
	if (err < 0)
		printf("pdccnlookc: input error: %d\n", err);
#endif

	return l;
}

int
pdccngetc(dev)
	dev_t dev;
{
	int c;

	if (!pdc)
		return 0;

	while(!pdccnlookc(dev, &c))
		;

	return (c);
}

void
pdccnputc(dev, c)
	dev_t dev;
	int c;
{
	register int err;
	int s = splhigh();

	*pdc_consbuf = c;
	err = pdc_call(pdc_cniodc, 0, pz_cons->pz_hpa, IODC_IO_CONSOUT,
	    pz_cons->pz_spa, pz_cons->pz_layers, pdcret, 0, pdc_consbuf, 1, 0);
	splx(s);

	if (err < 0) {
#ifdef DEBUG
		printf("pdccnputc: output error: %d\n", err);
#endif
	}
}


code:
/*	$OpenBSD: phantomas.c,v 1.5 2010/04/29 13:48:29 jsing Exp $	*/

/*
 * Copyright (c) 2002 Michael Shalayeff
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>

#include <machine/pdc.h>
#include <machine/iomod.h>
#include <machine/autoconf.h>

#include <hppa/dev/cpudevs.h>

struct cfdriver phantomas_cd = {
	NULL, "phantomas", DV_DULL
};

struct phantomas_softc {
	struct device sc_dev;

};

int	phantomasmatch(struct device *, void *, void *);
void	phantomasattach(struct device *, struct device *, void *);

struct cfattach phantomas_ca = {
	sizeof(struct phantomas_softc), phantomasmatch, phantomasattach
};

int
phantomasmatch(struct device *parent, void *cfdata, void *aux)
{
	struct confargs *ca = aux;

	if (ca->ca_type.iodc_type != HPPA_TYPE_BCPORT ||
	    ca->ca_type.iodc_sv_model != HPPA_BCPORT_PHANTOM)
		return (0);

	return (1);
}

void
phantomasattach(struct device *parent, struct device *self, void *aux)
{
	struct confargs *ca = aux, nca;

	printf("\n");

	nca = *ca;
	nca.ca_hpamask = HPPA_IOBEGIN;
	pdc_scanbus(self, &nca, MAXMODBUS, 0, 0);
}


code:
/*	$OpenBSD: power.c,v 1.9 2014/07/13 09:09:16 miod Exp $	*/

/*
 * Copyright (c) 2003 Michael Shalayeff
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/kthread.h>

#include <machine/reg.h>
#include <machine/pdc.h>
#include <machine/autoconf.h>

#include <hppa/dev/cpudevs.h>

struct power_softc {
	struct device sc_dev;
	void *sc_ih;

	struct proc *sc_thread;
	void (*sc_kicker)(void *);

	int sc_dr_cnt;
	paddr_t sc_pwr_reg;
	volatile int sc_interrupted;
};

int	powermatch(struct device *, void *, void *);
void	powerattach(struct device *, struct device *, void *);

struct cfattach power_ca = {
	sizeof(struct power_softc), powermatch, powerattach
};

struct cfdriver power_cd = {
	NULL, "power", DV_DULL
};

void power_thread_create(void *v);
void power_thread_dr(void *v);
void power_thread_reg(void *v);
void power_cold_hook_reg(int);
int power_intr(void *);

int
powermatch(struct device *parent, void *cfdata, void *aux)
{
	struct cfdata *cf = cfdata;
	struct confargs *ca = aux;

	if (cf->cf_unit > 0 && !strcmp(ca->ca_name, "power"))
		return (0);

	return (1);
}

void
powerattach(struct device *parent, struct device *self, void *aux)
{
	struct power_softc *sc = (struct power_softc *)self;
	struct confargs *ca = aux;

	switch (cpu_hvers) {
	case HPPA_BOARD_HP712_60:
	case HPPA_BOARD_HP712_80:
	case HPPA_BOARD_HP712_100:
	case HPPA_BOARD_HP712_120:
		sc->sc_kicker = power_thread_dr;
		printf(": DR25\n");
		break;

	default:
		if (ca->ca_hpa) {
			extern void (*cold_hook)(int);

			sc->sc_pwr_reg = ca->ca_hpa;
			cold_hook = power_cold_hook_reg;
			sc->sc_kicker = power_thread_reg;
			printf("\n");
		} else
			printf(": not available\n");
		break;
	}

	if (ca->ca_irq >= 0)
		sc->sc_ih = cpu_intr_establish(IPL_CLOCK, ca->ca_irq,
		    power_intr, sc, sc->sc_dev.dv_xname);

	if (sc->sc_kicker)
		kthread_create_deferred(power_thread_create, sc);
}

int
power_intr(void *v)
{
	struct power_softc *sc = v;

	sc->sc_interrupted = 1;

	return (1);
}

void
power_thread_create(void *v)
{
	struct power_softc *sc = v;

	if (kthread_create(sc->sc_kicker, sc, &sc->sc_thread,
	    sc->sc_dev.dv_xname))
		printf("WARNING: failed to create kernel power thread\n");
}

void
power_thread_dr(void *v)
{
	struct power_softc *sc = v;
	u_int32_t r;

	for (;;) {
		mfcpu(DR0_PCXL_SHINT_EN, r);	/* XXX don't ask */
		if (r & 0x80000000)
			sc->sc_dr_cnt = 0;
		else
			sc->sc_dr_cnt++;

		/*
		 * the bit is undampened straight wire from the power
		 * switch and thus we have do dampen it ourselves.
		 */
		if (sc->sc_dr_cnt == hz / 10)
			prsignal(initprocess, SIGUSR2);

		tsleep(v, PWAIT, "drpower", 10);
	}
}

void
power_thread_reg(void *v)
{
	struct power_softc *sc = v;
	u_int32_t r;

	for (;;) {
		__asm volatile("ldwas 0(%1), %0"
		    : "=&r" (r) : "r" (sc->sc_pwr_reg));

		if (!(r & 1))
			prsignal(initprocess, SIGUSR2);

		tsleep(v, PWAIT, "regpower", 10);
	}
}

void
power_cold_hook_reg(int on)
{
	extern struct pdc_power_info pdc_power_info;	/* machdep.c */
	int error;

	if ((error = pdc_call((iodcio_t)pdc, 0, PDC_SOFT_POWER,
	    PDC_SOFT_POWER_ENABLE, &pdc_power_info,
	    on == HPPA_COLD_HOT)))
		printf("power_cold_hook_reg: failed (%d)\n", error);
}


code:
/*	$OpenBSD: siop_sgc.c,v 1.1 2007/08/05 19:09:52 kettenis Exp $	*/

/*
 * Copyright (c) 2007 Mark Kettenis
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>

#include <machine/autoconf.h>
#include <machine/bus.h>
#include <machine/iomod.h>

#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>

#include <dev/ic/siopreg.h>
#include <dev/ic/siopvar_common.h>
#include <dev/ic/siopvar.h>

#include <hppa/dev/cpudevs.h>

#define IO_II_INTEN		0x20000000
#define IO_II_PACKEN		0x10000000
#define IO_II_PREFETCHEN	0x08000000

int siop_sgc_match(struct device *, void *, void *);
void siop_sgc_attach(struct device *, struct device *, void *);
int siop_sgc_intr(void *);
void siop_sgc_reset(struct siop_common_softc *);

u_int8_t siop_sgc_r1(void *, bus_space_handle_t, bus_size_t);
u_int16_t siop_sgc_r2(void *, bus_space_handle_t, bus_size_t);
void siop_sgc_w1(void *, bus_space_handle_t, bus_size_t, u_int8_t);
void siop_sgc_w2(void *, bus_space_handle_t, bus_size_t, u_int16_t);

struct siop_sgc_softc {
	struct siop_softc sc_siop;
	bus_space_tag_t sc_iot;
	bus_space_handle_t sc_ioh;
	struct hppa_bus_space_tag sc_bustag;
};

struct cfattach siop_gedoens_ca = {
	sizeof(struct siop_sgc_softc), siop_sgc_match, siop_sgc_attach
};

int
siop_sgc_match(struct device *parent, void *match, void *aux)
{
	struct confargs *ca = aux;

	if (ca->ca_type.iodc_type != HPPA_TYPE_ADMA ||
	    ca->ca_type.iodc_sv_model != HPPA_ADMA_FWSCSI)
		return 0;

	return 1;
}

void
siop_sgc_attach(struct device *parent, struct device *self, void *aux)
{
	struct siop_sgc_softc *sc = (struct siop_sgc_softc *)self;
	struct confargs *ca = aux;
	volatile struct iomod *regs;

	sc->sc_iot = ca->ca_iot;
	if (bus_space_map(sc->sc_iot, ca->ca_hpa,
	    IOMOD_HPASIZE, 0, &sc->sc_ioh)) {
		printf(": cannot map io space\n");
		return;
	}

	sc->sc_bustag = *sc->sc_iot;
	sc->sc_bustag.hbt_r1 = siop_sgc_r1;
	sc->sc_bustag.hbt_r2 = siop_sgc_r2;
	sc->sc_bustag.hbt_w1 = siop_sgc_w1;
	sc->sc_bustag.hbt_w2 = siop_sgc_w2;

	sc->sc_siop.sc_c.features = SF_CHIP_PF | SF_CHIP_BE | SF_BUS_WIDE;
	sc->sc_siop.sc_c.maxburst = 4;
	sc->sc_siop.sc_c.maxoff = 8;
	sc->sc_siop.sc_c.clock_div = 3;
	sc->sc_siop.sc_c.clock_period = 250;
	sc->sc_siop.sc_c.ram_size = 0;

	sc->sc_siop.sc_c.sc_reset = siop_sgc_reset;
	sc->sc_siop.sc_c.sc_dmat = ca->ca_dmatag;

	sc->sc_siop.sc_c.sc_rt = &sc->sc_bustag;
	bus_space_subregion(sc->sc_iot, sc->sc_ioh, IOMOD_DEVOFFSET,
	    IOMOD_HPASIZE - IOMOD_DEVOFFSET, &sc->sc_siop.sc_c.sc_rh);

	regs = bus_space_vaddr(sc->sc_iot, sc->sc_ioh);
	regs->io_command = CMD_RESET;
	while ((regs->io_status & IO_ERR_MEM_RY) == 0)
		delay(100);
	regs->io_ii_rw = IO_II_PACKEN | IO_II_PREFETCHEN;

	siop_sgc_reset(&sc->sc_siop.sc_c);

	regs->io_eim = cpu_gethpa(0) | (31 - ca->ca_irq);
	regs->io_ii_rw |= IO_II_INTEN;
	cpu_intr_establish(IPL_BIO, ca->ca_irq, siop_intr, sc,
	    sc->sc_siop.sc_c.sc_dev.dv_xname);

	printf(": NCR53C720 rev %d\n", bus_space_read_1(sc->sc_siop.sc_c.sc_rt,
	    sc->sc_siop.sc_c.sc_rh, SIOP_CTEST3) >> 4);

	siop_attach(&sc->sc_siop);
}

void
siop_sgc_reset(struct siop_common_softc *sc)
{
	bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_DCNTL, DCNTL_EA);
	bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST0, CTEST0_EHP);
	bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4, CTEST4_MUX);

	bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_STIME0,
	    (0xc << STIME0_SEL_SHIFT));
}

u_int8_t
siop_sgc_r1(void *v, bus_space_handle_t h, bus_size_t o)
{
	return *(volatile u_int8_t *)(h + (o ^ 3));
}

u_int16_t
siop_sgc_r2(void *v, bus_space_handle_t h, bus_size_t o)
{
	if (o == SIOP_SIST0) {
		u_int16_t reg;

		reg = siop_sgc_r1(v, h, SIOP_SIST0);
		reg |= siop_sgc_r1(v, h, SIOP_SIST1) << 8;
		return reg;
	}
	return *(volatile u_int16_t *)(h + (o ^ 2));
}

void
siop_sgc_w1(void *v, bus_space_handle_t h, bus_size_t o, u_int8_t vv)
{
	*(volatile u_int8_t *)(h + (o ^ 3)) = vv;
}

void
siop_sgc_w2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv)
{
	*(volatile u_int16_t *)(h + (o ^ 2)) = vv;
}


code:
/*	$OpenBSD: ssio.c,v 1.7 2009/03/08 22:19:04 miod Exp $	*/

/*
 * Copyright (c) 2007 Mark Kettenis
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * Driver for the National Semiconductor PC87560 Legacy I/O chip.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>

#include <machine/bus.h>
#include <machine/iomod.h>

#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#include <dev/pci/pciidereg.h>

#include <hppa/dev/ssiovar.h>

#include "ukbd.h"
#if NUKBD > 0
#include <dev/usb/ohcireg.h>
#include <dev/usb/ukbdvar.h>
#endif

/* PCI config space. */
#define SSIO_PCI_DMA_RC2	0x64
#define SSIO_PCI_INT_TC1	0x67
#define SSIO_PCI_INT_TC2	0x68
#define SSIO_PCI_INT_RC1	0x69
#define SSIO_PCI_INT_RC2	0x6a
#define SSIO_PCI_INT_RC3	0x6b
#define SSIO_PCI_INT_RC4	0x6c
#define SSIO_PCI_INT_RC5	0x6d
#define SSIO_PCI_INT_RC6	0x6e
#define SSIO_PCI_INT_RC7	0x6f
#define SSIO_PCI_INT_RC8	0x70
#define SSIO_PCI_INT_RC9	0x71
#define SSIO_PCI_SP1BAR		0x94
#define SSIO_PCI_SP2BAR		0x98
#define SSIO_PCI_PPBAR		0x9c

#define SSIO_PCI_INT_TC1_MASK	0xff
#define SSIO_PCI_INT_TC1_SHIFT	24

#define SSIO_PCI_INT_TC2_MASK	0xff
#define SSIO_PCI_INT_TC2_SHIFT	0

#define SSIO_PCI_INT_RC1_MASK	0xff
#define SSIO_PCI_INT_RC1_SHIFT	8

#define SSIO_PCI_INT_RC2_MASK	0xff
#define SSIO_PCI_INT_RC2_SHIFT	16

#define SSIO_PCI_INT_RC3_MASK	0xff
#define SSIO_PCI_INT_RC3_SHIFT	24

#define SSIO_PCI_INT_RC4_MASK	0xff
#define SSIO_PCI_INT_RC4_SHIFT	0

#define SSIO_PCI_INT_RC5_MASK	0xff
#define SSIO_PCI_INT_RC5_SHIFT	8

#define SSIO_PCI_INT_RC6_MASK	0xff
#define SSIO_PCI_INT_RC6_SHIFT	16

#define SSIO_PCI_INT_RC7_MASK	0xff
#define SSIO_PCI_INT_RC7_SHIFT	24

#define SSIO_PCI_INT_RC8_MASK	0xff
#define SSIO_PCI_INT_RC8_SHIFT	0

#define SSIO_PCI_INT_RC9_MASK	0xff
#define SSIO_PCI_INT_RC9_SHIFT	8

/* Cascaded i8259-compatible PICs. */
#define SSIO_PIC1	0x20
#define SSIO_PIC2	0xa0
#define SSIO_NINTS	16

int	ssio_match(struct device *, void *, void *);
void	ssio_attach(struct device *, struct device *, void *);

struct ssio_iv {
	int (*handler)(void *);
	void *arg;
};

struct ssio_iv ssio_intr_table[SSIO_NINTS];

struct ssio_softc {
	struct device sc_dev;

	bus_space_tag_t sc_iot;
	bus_space_handle_t sc_ic1h;
	bus_space_handle_t sc_ic2h;
	void *sc_ih;
};

struct cfattach ssio_ca = {
	sizeof(struct ssio_softc), ssio_match, ssio_attach
};

struct cfdriver ssio_cd = {
	NULL, "ssio", DV_DULL
};

const struct pci_matchid ssio_devices[] = {
	{ PCI_VENDOR_NS, PCI_PRODUCT_NS_PC87560 }
};

int	ssio_intr(void *);
int	ssio_print(void *, const char *);

int
ssio_match(struct device *parent, void *match, void *aux)
{
	struct pci_attach_args *pa = aux;
	pcireg_t bhlc, id;
	pcitag_t tag;

	/*
	 * The firmware doesn't always switch the IDE function into native
	 * mode.  So we do that ourselves since it makes life much simpler.
	 * Note that we have to do this in the match function since the
	 * Legacy I/O function attaches after the IDE function.
	 */
	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NS &&
	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NS_PC87415) {
		bhlc = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
		if (!PCI_HDRTYPE_MULTIFN(bhlc))
			return (0);

		tag = pci_make_tag(pa->pa_pc, pa->pa_bus, pa->pa_device, 1);
		id = pci_conf_read(pa->pa_pc, tag, PCI_ID_REG);
		if (PCI_VENDOR(id) != PCI_VENDOR_NS ||
		    PCI_PRODUCT(id) != PCI_PRODUCT_NS_PC87560)
			return (0);

		pa->pa_class |= PCIIDE_INTERFACE_PCI(0) << PCI_INTERFACE_SHIFT;
		pa->pa_class |= PCIIDE_INTERFACE_PCI(1) << PCI_INTERFACE_SHIFT;
		pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG,
		    pa->pa_class);
		return (0);
	}

	return (pci_matchbyid((struct pci_attach_args *)aux, ssio_devices,
	    sizeof(ssio_devices) / sizeof (ssio_devices[0])));
}

void
ssio_attach(struct device *parent, struct device *self, void *aux)
{
	struct ssio_softc *sc = (void *)self;
	struct pci_attach_args *pa = aux;
	struct ssio_attach_args saa;
	pci_intr_handle_t ih;
	const char *intrstr;
	pcireg_t reg;
#if NUKBD > 0
	pcitag_t tag;
#endif

	sc->sc_iot = pa->pa_iot;
	if (bus_space_map(sc->sc_iot, SSIO_PIC1, 2, 0, &sc->sc_ic1h)) {
		printf(": unable to map PIC1 registers\n");
		return;
	}
	if (bus_space_map(sc->sc_iot, SSIO_PIC2, 2, 0, &sc->sc_ic2h)) {
		printf(": unable to map PIC2 registers\n");
		goto unmap_ic1;
	}

	if (pci_intr_map(pa, &ih)) {
		printf(": unable to map interrupt\n");
		goto unmap_ic2;
	}
	intrstr = pci_intr_string(pa->pa_pc, ih);
	/* XXX Probably should be IPL_NESTED. */
	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_TTY, ssio_intr,
	    sc, sc->sc_dev.dv_xname);
	if (sc->sc_ih == NULL) {
		printf(": couldn't establish interrupt\n");
		goto unmap_ic2;
	}

	printf(": %s\n", intrstr);

	/*
	 * We use the following interrupt mapping:
	 *
	 * USB (INTD#)		IRQ 1
	 * IDE Channel 1	IRQ 5
	 * Serial Port 1	IRQ 4
	 * Serial Port 2	IRQ 3
	 * Parallel Port	IRQ 7
	 *
	 * USB and IDE are set to level triggered, all others to edge
	 * triggered.
	 *
	 * We disable all other interrupts since we don't need them.
	 */
	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, SSIO_PCI_DMA_RC2);
	reg &= ~(SSIO_PCI_INT_TC1_MASK << SSIO_PCI_INT_TC1_SHIFT);
	reg |= 0x22 << SSIO_PCI_INT_TC1_SHIFT;
	pci_conf_write(pa->pa_pc, pa->pa_tag, SSIO_PCI_DMA_RC2, reg);

	reg = 0;
	reg |= 0x34 << SSIO_PCI_INT_RC1_SHIFT;	/* SP1, SP2 */
	reg |= 0x07 << SSIO_PCI_INT_RC2_SHIFT;	/* PP */
	reg |= 0x05 << SSIO_PCI_INT_RC3_SHIFT;	/* IDE1 */
	pci_conf_write(pa->pa_pc, pa->pa_tag, SSIO_PCI_INT_TC2, reg);

	reg = 0;
	reg |= 0x10 << SSIO_PCI_INT_RC5_SHIFT;	/* INTD# (USB) */
	pci_conf_write(pa->pa_pc, pa->pa_tag, SSIO_PCI_INT_RC4, reg);

	/* Program PIC1. */
	bus_space_write_1(sc->sc_iot, sc->sc_ic1h, 0, 0x11);
	bus_space_write_1(sc->sc_iot, sc->sc_ic1h, 1, 0x00);
	bus_space_write_1(sc->sc_iot, sc->sc_ic1h, 1, 0x04);
	bus_space_write_1(sc->sc_iot, sc->sc_ic1h, 1, 0x01);

	/* Priority (3-7,0-2). */
	bus_space_write_1(sc->sc_iot, sc->sc_ic1h, 0, 0xc2);

	/* Program PIC2. */
	bus_space_write_1(sc->sc_iot, sc->sc_ic2h, 0, 0x11);
	bus_space_write_1(sc->sc_iot, sc->sc_ic2h, 1, 0x00);
	bus_space_write_1(sc->sc_iot, sc->sc_ic2h, 1, 0x02);
	bus_space_write_1(sc->sc_iot, sc->sc_ic2h, 1, 0x01);

	/* Unmask all interrupts. */
	bus_space_write_1(sc->sc_iot, sc->sc_ic1h, 1, 0x00);
	bus_space_write_1(sc->sc_iot, sc->sc_ic2h, 1, 0x00);

	/* Serial Port 1. */
	saa.saa_name = "com";
	saa.saa_iot = sc->sc_iot;
	saa.saa_iobase = pci_conf_read(pa->pa_pc, pa->pa_tag, SSIO_PCI_SP1BAR);
	saa.saa_iobase &= 0xfffffffe;
	saa.saa_irq = 4;
	config_found(self, &saa, ssio_print);

	/* Serial Port 2. */
	saa.saa_name = "com";
	saa.saa_iot = sc->sc_iot;
	saa.saa_iobase = pci_conf_read(pa->pa_pc, pa->pa_tag, SSIO_PCI_SP2BAR);
	saa.saa_iobase &= 0xfffffffe;
	saa.saa_irq = 3;
	config_found(self, &saa, ssio_print);

	/* Parallel Port. */
	saa.saa_name = "lpt";
	saa.saa_iot = sc->sc_iot;
	saa.saa_iobase = pci_conf_read(pa->pa_pc, pa->pa_tag, SSIO_PCI_PPBAR);
	saa.saa_iobase &= 0xfffffffe;
	saa.saa_irq = 7;
	config_found(self, &saa, ssio_print);

#if NUKBD > 0
	/*
	 * If a USB keybard is used for console input, the firmware passes
	 * the mmio address of the USB controller the keyboard is attached
	 * to.  Since we know the USB controller is function 2 on the same
	 * device and comes right after us (we're function 1 remember),
	 * this is a convenient spot to mark the USB keyboard as console
	 * if the address matches.
	 */
	tag = pci_make_tag(pa->pa_pc, pa->pa_bus, pa->pa_device, 2);
	reg = pci_conf_read(pa->pa_pc, tag, PCI_CBMEM);

	if (PAGE0->mem_kbd.pz_class == PCL_KEYBD &&
	    PAGE0->mem_kbd.pz_hpa == reg)
		ukbd_cnattach();
#endif

	return;

unmap_ic2:
	bus_space_unmap(sc->sc_iot, sc->sc_ic2h, 2);
unmap_ic1:
	bus_space_unmap(sc->sc_iot, sc->sc_ic1h, 2);
}

int
ssio_intr(void *v)
{
	struct ssio_softc *sc = v;
	struct ssio_iv *iv;
	int claimed = 0;
	int irq, isr;

	/* Poll for interrupt. */
	bus_space_write_1(sc->sc_iot, sc->sc_ic1h, 0, 0x0c);
	irq = bus_space_read_1(sc->sc_iot, sc->sc_ic1h, 0);
	irq &= 0x07;

	if (irq  == 7) {
		bus_space_write_1(sc->sc_iot, sc->sc_ic1h, 0, 0x0b);
		isr = bus_space_read_1(sc->sc_iot, sc->sc_ic1h, 0);
		if ((isr & 0x80) == 0)
			/* Spurious interrupt. */
			return (0);
	}

	iv = &ssio_intr_table[irq];
	if (iv->handler)
		claimed = iv->handler(iv->arg);

	/* Signal EOI. */
	bus_space_write_1(sc->sc_iot, sc->sc_ic1h, 0, 0x60 | (irq & 0x0f));

	return (claimed);
}

void *
ssio_intr_establish(int pri, int irq, int (*handler)(void *), void *arg,
    const char *name)
{
	struct ssio_iv *iv;

	if (irq < 0 || irq >= SSIO_NINTS || ssio_intr_table[irq].handler)
		return (NULL);

	iv = &ssio_intr_table[irq];
	iv->handler = handler;
	iv->arg = arg;

	return (iv);
}

int
ssio_print(void *aux, const char *pnp)
{
	struct ssio_attach_args *saa = aux;

	if (pnp)
		printf("%s at %s", saa->saa_name, pnp);
	if (saa->saa_iobase) {
		printf(" offset %lx", saa->saa_iobase);
		if (!pnp && saa->saa_irq >= 0)
			printf(" irq %d", saa->saa_irq);
	}

	return (UNCONF);
}


code:
/*	$OpenBSD: ssiovar.h,v 1.1 2007/06/19 22:51:26 kettenis Exp $	*/

/*
 * Copyright (c) 2007 Mark Kettenis
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

struct ssio_attach_args {
	const char *saa_name;
	bus_space_tag_t saa_iot;
	bus_addr_t saa_iobase;
	int saa_irq;
};

#define ssiocf_irq	cf_loc[0]
#define SSIO_UNK_IRQ	-1

void *ssio_intr_establish(int, int, int (*)(void *), void *, const char *);


code:
/*	$OpenBSD: sti_pci_machdep.c,v 1.2 2009/04/10 17:11:27 miod Exp $	*/

/*
 * Copyright (c) 2007, 2009 Miodrag Vallat.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice, this permission notice, and the disclaimer below
 * appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>

#include <machine/iomod.h>
#include <machine/autoconf.h>

#include <dev/pci/pcivar.h>

int	sti_pci_is_console(struct pci_attach_args *, bus_addr_t *);

int
sti_pci_is_console(struct pci_attach_args *paa, bus_addr_t *bases)
{
	u_int32_t cf;
	bus_addr_t addr;
	int bar;
	int rc;

	/*
	 * PAGE0 console information will point to one of our BARs,
	 * but depending on the particular sti model, this might not
	 * be the BAR mapping the rom (region #0).
	 *
	 * For example, on Visualize FXe, regions #0, #2 and #3 are
	 * mapped by BAR 0x18, while region #1 is mapped by BAR 0x10,
	 * which matches PAGE0 console address.
	 *
	 * Rather than trying to be smart, reread the region->BAR array
	 * again, and compare the BAR mapping region #1 against PAGE0
	 * values, we simply try all the valid BARs; if any of them
	 * matches what PAGE0 says, then we are the console, and it
	 * doesn't matter which BAR matched.
	 */
	for (bar = PCI_MAPREG_START; bar <= PCI_MAPREG_PPB_END; ) {
		cf = pci_conf_read(paa->pa_pc, paa->pa_tag, bar);

		if (PCI_MAPREG_TYPE(cf) == PCI_MAPREG_TYPE_IO) {
			rc = pci_io_find(paa->pa_pc, paa->pa_tag, bar, &addr,
			    NULL);
			bar += 4;
		} else {
			rc = pci_mem_find(paa->pa_pc, paa->pa_tag, bar, &addr,
			    NULL, NULL);
			if (PCI_MAPREG_MEM_TYPE(cf) ==
			    PCI_MAPREG_MEM_TYPE_64BIT)
				bar += 8;
			else
				bar += 4;
		}

		if (rc == 0 &&
		    (hppa_hpa_t)addr == (hppa_hpa_t)PAGE0->mem_cons.pz_hpa)
			return 1;
	}

	return 0;
}


code:
/*	$OpenBSD: sti_sgc.c,v 1.40 2014/08/30 14:42:05 miod Exp $	*/

/*
 * Copyright (c) 2000-2003 Michael Shalayeff
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
/*
 * These cards has to be known to work so far:
 *	- HPA1991AGrayscale rev 0.02	(705/35) (byte-wide)
 *	- HPA1991AC19       rev 0.02	(715/33) (byte-wide)
 *	- HPA208LC1280      rev 8.04	(712/80) just works
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>

#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/iomod.h>
#include <machine/autoconf.h>

#include <dev/wscons/wsdisplayvar.h>
#include <dev/wscons/wsconsio.h>

#include <dev/ic/stireg.h>
#include <dev/ic/stivar.h>

#include <hppa/dev/cpudevs.h>

#define	STI_ROMSIZE	(sizeof(struct sti_dd) * 4)
#define	STI_ID_FDDI	0x280b31af	/* Medusa FDDI ROM id */

/* gecko optional graphics (these share the onboard's prom) */
const char sti_sgc_opt[] = { 0x17, 0x20, 0x30, 0x40, 0x70, 0xc0, 0xd0 };

extern struct cfdriver sti_cd;

int	sti_sgc_probe(struct device *, void *, void *);
void	sti_sgc_attach(struct device *, struct device *, void *);
paddr_t	sti_sgc_getrom(int, struct confargs *);

struct cfattach sti_gedoens_ca = {
	sizeof(struct sti_softc), sti_sgc_probe, sti_sgc_attach
};

/*
 * Locate STI ROM.
 * On some machines it may not be part of the HPA space.
 */
paddr_t
sti_sgc_getrom(int unit, struct confargs *ca)
{
	paddr_t rom = PAGE0->pd_resv2[1];
	int i;

	if (unit) {
		i = -1;
		if (ca->ca_type.iodc_sv_model == HPPA_FIO_GSGC)
			for (i = sizeof(sti_sgc_opt); i-- &&
			    sti_sgc_opt[i] != ca->ca_type.iodc_revision; )
				;
		if (i < 0)
			rom = 0;
	}

	if (rom < HPPA_IOBEGIN) {
		if (ca->ca_naddrs > 0)
			rom = ca->ca_addrs[0].addr;
		else
			rom = ca->ca_hpa;
	}

	return (rom);
}

int
sti_sgc_probe(struct device *parent, void *match, void *aux)
{
	struct cfdata *cf = match;
	struct confargs *ca = aux;
	bus_space_handle_t romh;
	paddr_t rom;
	u_int32_t id;
	u_char devtype;
	int rv = 0, romunmapped = 0;

	/* due to the graphic nature of this program do probe only one */
	if (cf->cf_unit > sti_cd.cd_ndevs)
		return (0);

	if (ca->ca_type.iodc_type != HPPA_TYPE_FIO)
		return (0);

	/* these need further checking for the graphics id */
	if (ca->ca_type.iodc_sv_model != HPPA_FIO_GSGC &&
	    ca->ca_type.iodc_sv_model != HPPA_FIO_SGC)
		return 0;

	rom = sti_sgc_getrom(cf->cf_unit, ca);
#ifdef STIDEBUG
	printf ("sti: hpa=%lx, rom=%lx\n", ca->ca_hpa, rom);
#endif

	/* if it does not map, probably part of the lasi space */
	if ((rv = bus_space_map(ca->ca_iot, rom, STI_ROMSIZE, 0, &romh))) {
#ifdef STIDEBUG
		printf ("sti: cannot map rom space (%d)\n", rv);
#endif
		if ((rom & HPPA_IOBEGIN) == HPPA_IOBEGIN) {
			romh = rom;
			romunmapped++;
		} else {
			/* in this case nobody has no freaking idea */
			return 0;
		}
	}

	devtype = bus_space_read_1(ca->ca_iot, romh, 3);

#ifdef STIDEBUG
	printf("sti: devtype=%d\n", devtype);
#endif
	rv = 1;
	switch (devtype) {
	case STI_DEVTYPE4:
		id = bus_space_read_4(ca->ca_iot, romh, 0x8);
		break;
	case STI_DEVTYPE1:
		id = (bus_space_read_1(ca->ca_iot, romh, 0x10 +  3) << 24) |
		     (bus_space_read_1(ca->ca_iot, romh, 0x10 +  7) << 16) |
		     (bus_space_read_1(ca->ca_iot, romh, 0x10 + 11) <<  8) |
		     (bus_space_read_1(ca->ca_iot, romh, 0x10 + 15));
		break;
	default:
#ifdef STIDEBUG
		printf("sti: unknown type (%x)\n", devtype);
#endif
		rv = 0;
	}

	if (rv &&
	    ca->ca_type.iodc_sv_model == HPPA_FIO_SGC && id == STI_ID_FDDI) {
#ifdef STIDEBUG
		printf("sti: not a graphics device\n");
#endif
		rv = 0;
	}

	if (ca->ca_naddrs >= sizeof(ca->ca_addrs)/sizeof(ca->ca_addrs[0])) {
		printf("sti: address list overflow\n");
		return (0);
	}

	ca->ca_addrs[ca->ca_naddrs].addr = rom;
	ca->ca_addrs[ca->ca_naddrs].size = sti_rom_size(ca->ca_iot, romh);
	ca->ca_naddrs++;

	if (!romunmapped)
		bus_space_unmap(ca->ca_iot, romh, STI_ROMSIZE);
	return (rv);
}

void
sti_sgc_attach(struct device *parent, struct device *self, void *aux)
{
	struct sti_softc *sc = (void *)self;
	struct confargs *ca = aux;
	bus_space_handle_t romh;
	paddr_t rom;
	u_int32_t romlen;
	int rv;
	int i;

	/* we stashed rom addr/len into the last slot during probe */
	rom = ca->ca_addrs[ca->ca_naddrs - 1].addr;
	romlen = ca->ca_addrs[ca->ca_naddrs - 1].size;
	if ((rv = bus_space_map(ca->ca_iot, rom, romlen, 0, &romh))) {
		if ((rom & HPPA_IOBEGIN) == HPPA_IOBEGIN)
			romh = rom;
		else {
			printf (": cannot map rom space (%d)\n", rv);
			return;
		}
	}

	sc->bases[0] = romh;
	for (i = 1; i < STI_REGION_MAX; i++)
		sc->bases[i] = ca->ca_hpa;

#ifdef	HP7300LC_CPU
	/* PCXL2: enable accel i/o for this space */
	if (cpu_type == hpcxl2)
		eaio_l2(0x8 >> (((ca->ca_hpa >> 25) & 3) - 2));
#endif

	if (ca->ca_hpa == (hppa_hpa_t)PAGE0->mem_cons.pz_hpa)
		sc->sc_flags |= STI_CONSOLE;
	if (sti_attach_common(sc, ca->ca_iot, ca->ca_iot, romh,
	    STI_CODEBASE_PA) == 0)
		startuphook_establish(sti_end_attach, sc);
}


code:
/*	$OpenBSD: uturn.c,v 1.7 2010/04/29 13:48:29 jsing Exp $	*/

/*
 * Copyright (c) 2004 Michael Shalayeff
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

/* TODO IOA programming */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/reboot.h>

#include <machine/iomod.h>
#include <machine/autoconf.h>

#include <hppa/dev/cpudevs.h>

struct uturn_regs {
	u_int64_t	resv0[2];
	u_int64_t	status;		/* 0x10: */
	u_int64_t	resv1[5];
	u_int64_t	debug;		/* 0x40: */
};

struct uturn_softc {
	struct device sc_dv;

	struct uturn_regs volatile *sc_regs;
};

int	uturnmatch(struct device *, void *, void *);
void	uturnattach(struct device *, struct device *, void *);

struct cfattach uturn_ca = {
	sizeof(struct uturn_softc), uturnmatch, uturnattach
};

struct cfdriver uturn_cd = {
	NULL, "uturn", DV_DULL
};

int
uturnmatch(parent, cfdata, aux)
	struct device *parent;
	void *cfdata;
	void *aux;
{
	struct confargs *ca = aux;
	/* struct cfdata *cf = cfdata; */

	/* there will be only one */
	if (ca->ca_type.iodc_type != HPPA_TYPE_IOA ||
	    ca->ca_type.iodc_sv_model != HPPA_IOA_UTURN)
		return 0;

	if (ca->ca_type.iodc_model == 0x58 &&
	    ca->ca_type.iodc_revision >= 0x20)
		return 0;

	return 1;
}

void
uturnattach(parent, self, aux)
	struct device *parent;
	struct device *self;
	void *aux;
{
	struct confargs *ca = aux, nca;
	struct uturn_softc *sc = (struct uturn_softc *)self;
	bus_space_handle_t ioh;
	hppa_hpa_t hpa;

	if (bus_space_map(ca->ca_iot, ca->ca_hpa, IOMOD_HPASIZE, 0, &ioh)) {
		printf(": can't map IO space\n");
		return;
	}
	sc->sc_regs = (struct uturn_regs *)ca->ca_hpa;

	printf(": %s rev %d\n",
	    ca->ca_type.iodc_revision < 0x10? "U2" : "UTurn",
	    ca->ca_type.iodc_revision & 0xf);

	/* keep it real */
	((struct iomod *)ioh)->io_control = 0x80;

	/*
	 * U2/UTurn is actually a combination of an Upper Bus
	 * Converter (UBC) and a Lower Bus Converter (LBC).  This
	 * driver attaches to the UBC; the LBC isn't very interesting,
	 * so we skip it.  This is easy, since it always is module 63,
	 * hence the MAXMODBUS - 1 below.
	 */
	nca = *ca;
	nca.ca_hpamask = HPPA_IOBEGIN;
	pdc_scanbus(self, &nca, MAXMODBUS - 1, 0, 0);

	/* XXX On some machines, PDC doesn't tell us about all devices. */
	switch (cpu_hvers) {
	case HPPA_BOARD_HP809:
	case HPPA_BOARD_HP819:
	case HPPA_BOARD_HP829:
	case HPPA_BOARD_HP839:
	case HPPA_BOARD_HP849:
	case HPPA_BOARD_HP859:
	case HPPA_BOARD_HP869:
		hpa = ((struct iomod *)ioh)->io_io_low << 16;
		pdc_scanbus(self, &nca, MAXMODBUS - 1, hpa, 0);
		break;
	default:
		break;
	}
}


code:
/*	$OpenBSD: viper.h,v 1.6 2007/04/10 17:47:54 miod Exp $	*/

/*
 * Copyright (c) 1991,1994 The University of Utah and
 * the Computer Systems Laboratory (CSL).  All rights reserved.
 *
 * Permission to use, copy, modify and distribute this software is hereby
 * granted provided that (1) source code retains these copyright, permission,
 * and disclaimer notices, and (2) redistributions including binaries
 * reproduce the notices in supporting documentation, and (3) all advertising
 * materials mentioning features or use of this software display the following
 * acknowledgement: ``This product includes software developed by the
 * Computer Systems Laboratory at the University of Utah.''
 *
 * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
 * IS" CONDITION.  THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
 * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * CSL requests users of this software to return to csl-dist@cs.utah.edu any
 * improvements that they make and grant CSL redistribution rights.
 *
 * 	Utah $Hdr: viper.h 1.8 94/12/14$
 */

/*
 * Viper control register.
 *
 * With respect to arbitration preference (*_prf), only one of these may be
 * set at any one time.  "preference" means that a particular device will
 * be granted the bus on every other arbitration cycle; these bits default
 * to unset (0).  Similarly, a device may be denied the bus (*_den); these
 * bits default to *set* (1).
 *
 * The macros V_CTRL_ANYPRF or V_CTRL_ANYDEN should be used to determine
 * if any preference or deny bits are set.
 */

#define VI_CTRL_EISA_DEN 0x00000001 /* EISA denied bus grants */
#define VI_CTRL_EISA_PRF 0x00000002 /* EISA bus has arbitration preference */
#define VI_CTRL_CORE_DEN 0x00000004 /* CORE denied bus grants */
#define VI_CTRL_CORE_PRF 0x00000008 /* CORE bus has arbitration preference */
#define VI_CTRL_SGC0_DEN 0x00000010 /* SGC0 denied bus grants */
#define VI_CTRL_SGC0_PRF 0x00000020 /* SGC0 has arbitration preference */
#define VI_CTRL_SGC1_DEN 0x00000040 /* SGC1 denied bus grants */
#define VI_CTRL_SGC1_PRF 0x00000080 /* SGC1 has arbitration preference */
#define VI_CTRL_CPU_PRF  0x00000200 /* CPU  has arbitration preference */
#define VI_CTRL_LPMC_EN  0x00010000 /* enable Low Priority Machine Checks */
#define VI_CTRL_IPREF_EN 0x00020000 /* enable instruction prefetching */
#define VI_CTRL_VSC_TOUT 0xfff80000 /* VSC clocks to wait before buserr tmo */

#define	VI_CTRL_ANYPRF	0x02AA
#define	VI_CTRL_ANYDEN	0x0055
#define	VI_CTRL		PAGE0->pz_Pdep.pd_Viper.v_Ctrlcpy
#define	VI_CTRL_BITS	"\020\001eisa_den\002eisa_prf\003core_den\004core_prf" \
			"\005sgc1_den\006sgc1_prf\007sgc0_den\010sgc0_prf" \
			"\012cpu_prf\021lpmc_en\022ipref_en"

#define	VI_STAT_BITS	"\020\001grf_buserr\002cpu_buserr\003ven_tmo" \
			"\004ven_buserr\005toc\006hardecc\007softecc\010cmdrst"
struct vi_stat {		/* (RO) */
	u_int	hw_rev	:24,	/* Viper hardware revision (24 bits!) */
		cmdreset: 1,	/* set if last chip reset caused by CMD_RESET */
		softecc	: 1,	/* correctable memory error (lpmc_en set) */
		hardecc	: 1,	/* uncorrectable memory error (HPMC) */
		toc	: 1,	/* Transfer Of Control signaled */
		vn_ader	: 1,	/* Venom address error (lpmc_en set) */
		vn_vscto: 1,	/* Venom VSC timeout (lpmc_en set) */
		cpu_ader: 1,	/* CPU address error or timeout (HPMC) */
		grf_ader: 1;	/* Graphics address error */
};

/*
 * Viper TRS.  The structures have been defined above; the remaining
 * fields are described here.
 *
 *	vi_intrwd (WO)
 *		If a high to low transition of the interrupt line occurs,
 *		Viper will send this to the CPU to be or'd into its EIR.
 *		In general, this is an ASP interrupt request.
 *
 *	vi_mem_ctrl (WO)
 *		Set various DRAM attributes (row, cols, refresh, etc).
 *
 *	vi_mem_wrchk (WO), vi_mem_rdchk (RO)
 *		read/write data to be for copyin/memtest.
 *
 *	vi_mem_limit (WO)
 *		Set an upper limit for non-IO memory accesses; this must
 *		be less than the actual memory size, low 22 bits ignored.
 *
 *	vi_merr_w0, vi_merr_w1, vi_merr_ckbyte, vi_merr_addr (RO)
 *		If memory error detection enabled and soft/hard ECC error,
 *		raw double word is stored here (w0: most significant word).
 *		The raw checkbyte data is stored in "vi_merr_ckbyte".
 *		The address of last logged error is in "vi_merr_addr".
 *
 */
struct vi_trs {
	u_int		vi_control;	/* PAGE0->pz_Pdep.pd_Viper.v_Ctrlcpy */
	struct vi_stat	vi_status;
	u_int		vi_intrwd;
	u_int		vi_resv1[13];
	u_int		vi_mem_ctrl;
	u_int		vi_mem_wrchk;
	u_int		vi_mem_limit;
	u_int		vi_resv2[1];
	u_int		vi_merr_w1;
	u_int		vi_merr_w2;
	u_int		vi_merr_ckbyte;
	u_int		vi_mem_rdchk;
	u_int		vi_merr_addr;
	u_int		vi_resv3[135];
};

/*
** Viper also creates HPA registers for the graphics accelerator (Venom).
** Venom has two sets of resisters; the User HPA contains registers that
** users are allowed to access, while the Supervisor HPA is only accessible
** by code running at the most priviliged level.  Both sets of registers
** are defined below.
*/

#define	VENOM_USER	((struct vn_user *)0xFFFBC000)
#define	VENOM_SUPR	((struct vn_supr *)0xFFFBD000)

/*
 * Define bits in the Venom "User Control" register.
 */
struct vnu_ctl {
	u_int	sdt_msk	:16,	/* screen door transparancy mask */
		: 6,
		d_z_intp: 1,	/* disable Z Interpolation when set */
		d_c_intp: 1,	/* disable Color Interpolation when set */
		d_ad_inc: 1,	/* disable I/O Addr Incrementing when set */
		: 1,
		z_fast	: 1,	/* enable Fast Z Interpolation when set */
		c_pseudo: 1,	/* enable Pseudo Color when set (disable RG) */
		z_prec24: 1,	/* enable 24-bit Z integer precision (o/w 16) */
		cmp_intp: 3;	/* enable cond: Z intp owrites old Z (<,>,=) */
};

/*
 * When vnu_ctl's "z_prec24" is set, 24-bit Z integer precision is enabled
 * (otherwise 16-bit integer precision is used).  When enabled, the format
 * of various User Control registers is changed; `vnu_prec' (defined below)
 * should make this format more clear.
 */
union vnu_prec {		/* 16 or 24 bit precision */
	struct {
		u_int	zero1;		/* must be zero */
		u_int	intg	:16,	/* integer part (16 bits) */
			frac	:12,	/* fractional part (12 bits) */
			zero2	: 4;	/* must be zero */
	} prec16;
	struct {
		u_int	frac_lo	: 4,	/* fractional part (lower 4 bits) */
			zero1	:28;	/* must be zero */
		u_int	intg	:24,	/* integer part (24 bits) */
			frac_hi	: 8;	/* fractional part (upper 8 bits) */
	} prec24;
};
#define	vnu_p16i	prec16.intg
#define	vnu_p16f	prec16.frac
#define	vnu_p24i	prec24.intg
#define	vnu_p24f	((prec24.frac_hi << 4) | prec24.frac_lo)
#define	vnu_p24fh	prec24.frac_hi
#define	vnu_p24fl	prec24.frac_lo

/*
 * Venom User HPA registers.
 */
struct vn_user {
	u_int		vnu_resv1[32];
	struct vnu_ctl	vnu_uctl;	/* user control */
	u_int		vnu_spancnt;	/* span count (13 bits, signed) */
	u_int		vnu_graddr;	/* graphics address (24 bits: 6-29) */
	u_int		vnu_resv2;
	union vnu_prec	vnu_zslope;	/* Z Slope */
	union vnu_prec	vnu_z;		/* Z */
	u_int		vnu_resv3[8];
	u_int		vnu_bslope;	/* Blue Slope (12-19:int, 20-31:fra) */
	u_int		vnu_bcolor;	/* Blue Color (12-19:int, 20-31:fra) */
	u_int		vnu_resv4[2];
	u_int		vnu_rslope;	/* Red Slope (12-19:int, 20-31:fra) */
	u_int		vnu_rcolor;	/* Red Color (12-19:int, 20-31:fra) */
	u_int		vnu_resv5[2];
	u_int		vnu_gslope;	/* Green Slope (12-19:int, 20-31:fra) */
	u_int		vnu_gcolor;	/* Green Color (12-19:int, 20-31:fra) */
};

/*
 * Define bits in Venom "Supervisor Control" register.
 */
struct vns_ctl {
	u_int		: 4,
		ioaddr	: 2,	/* graphics addr (bits 4 & 5 of `vnu_graddr') */
		d_venom	: 1,	/* disable Venom operation processing */
			:25;
};

/*
 * Venom Supervisor HPA registers.
 */
struct vn_supr {
	u_int		vns_resv1[32];
	struct vns_ctl	vns_sctl;	/* supervisor control */
	u_int		vns_zaddr;	/* Z Buffer Address (RO) */
};

void viper_setintrwnd(u_int32_t mask);
void viper_eisa_en(void);


code:
/*	$OpenBSD: wax.c,v 1.10 2004/11/08 20:53:25 miod Exp $	*/

/*
 * Copyright (c) 1998-2003 Michael Shalayeff
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/reboot.h>

#include <machine/iomod.h>
#include <machine/autoconf.h>

#include <hppa/dev/cpudevs.h>

#include <hppa/gsc/gscbusvar.h>

#define	WAX_IOMASK	0xfff00000

struct wax_regs {
	u_int32_t wax_irr;	/* int request register */
	u_int32_t wax_imr;	/* int mask register */
	u_int32_t wax_ipr;	/* int pending register */
	u_int32_t wax_icr;	/* int command? register */
	u_int32_t wax_iar;	/* int acquire? register */
};

struct wax_softc {
	struct device sc_dv;
	struct gscbus_ic sc_ic;

	struct wax_regs volatile *sc_regs;
};

int	waxmatch(struct device *, void *, void *);
void	waxattach(struct device *, struct device *, void *);
void	wax_gsc_attach(struct device *);

struct cfattach wax_ca = {
	sizeof(struct wax_softc), waxmatch, waxattach
};

struct cfdriver wax_cd = {
	NULL, "wax", DV_DULL
};

int
waxmatch(parent, cfdata, aux)
	struct device *parent;
	void *cfdata;
	void *aux;
{
	struct confargs *ca = aux;
	struct cfdata *cf = cfdata;

	/* there will be only one */
	if (cf->cf_unit > 0 ||
	    ca->ca_type.iodc_type != HPPA_TYPE_BHA ||
	    ca->ca_type.iodc_sv_model != HPPA_BHA_WAX)
		return 0;

	return 1;
}

void
waxattach(parent, self, aux)
	struct device *parent;
	struct device *self;
	void *aux;
{
	struct wax_softc *sc = (struct wax_softc *)self;
	struct confargs *ca = aux;
	struct gsc_attach_args ga;
	bus_space_handle_t ioh;
	int s, in;

	if (bus_space_map(ca->ca_iot, ca->ca_hpa, IOMOD_HPASIZE, 0, &ioh)) {
		printf(": can't map IO space\n");
		return;
	}

	sc->sc_regs = (struct wax_regs *)ca->ca_hpa;

	printf("\n");

	/* interrupts guts */
	s = splhigh();
	sc->sc_regs->wax_iar = cpu_gethpa(0) | (31 - ca->ca_irq);
	sc->sc_regs->wax_icr = 0;
	sc->sc_regs->wax_imr = ~0U;
	in = sc->sc_regs->wax_irr;
	sc->sc_regs->wax_imr = 0;
	splx(s);

	sc->sc_ic.gsc_type = gsc_wax;
	sc->sc_ic.gsc_dv = sc;
	sc->sc_ic.gsc_base = sc->sc_regs;

	ga.ga_ca = *ca;	/* clone from us */
	if (!strcmp(parent->dv_xname, "mainbus0")) {
		ga.ga_dp.dp_bc[0] = ga.ga_dp.dp_bc[1];
		ga.ga_dp.dp_bc[1] = ga.ga_dp.dp_bc[2];
		ga.ga_dp.dp_bc[2] = ga.ga_dp.dp_bc[3];
		ga.ga_dp.dp_bc[3] = ga.ga_dp.dp_bc[4];
		ga.ga_dp.dp_bc[4] = ga.ga_dp.dp_bc[5];
		ga.ga_dp.dp_bc[5] = ga.ga_dp.dp_mod;
		ga.ga_dp.dp_mod = 0;
	}

	ga.ga_name = "gsc";
	ga.ga_hpamask = WAX_IOMASK;
	ga.ga_ic = &sc->sc_ic;
	config_found(self, &ga, gscprint);
}


code: src/sys/arch/hppa/gsc

path: sys/arch/hppa/gsc/CVS/Repository


code:
/*	$OpenBSD: arcofi_gsc.c,v 1.1 2011/12/21 23:12:03 miod Exp $	*/

/*
 * Copyright (c) 2011 Miodrag Vallat.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>

#include <machine/autoconf.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/intr.h>
#include <machine/iomod.h>

#include <sys/audioio.h>
#include <dev/audio_if.h>
#include <dev/ic/arcofivar.h>

#include <hppa/dev/cpudevs.h>
#include <hppa/gsc/gscbusvar.h>

int	arcofi_gsc_match(struct device *, void *, void *);
void	arcofi_gsc_attach(struct device *, struct device *, void *);

const struct cfattach arcofi_gsc_ca = {
	sizeof(struct arcofi_softc),
	arcofi_gsc_match,
	arcofi_gsc_attach
};

int
arcofi_gsc_match(struct device *parent, void *match, void *vaa)
{
	struct gsc_attach_args *ga = vaa;

	if (ga->ga_type.iodc_type == HPPA_TYPE_FIO &&
	    (ga->ga_type.iodc_sv_model == HPPA_FIO_A1 ||
	     ga->ga_type.iodc_sv_model == HPPA_FIO_A1NB))
		return 1;

	return 0;
}

void
arcofi_gsc_attach(struct device *parent, struct device *self, void *vaa)
{
	struct arcofi_softc *sc = (struct arcofi_softc *)self;
	struct gsc_attach_args *ga = vaa;
	unsigned int u;

	for (u = 0; u < ARCOFI_NREGS; u++)
		sc->sc_reg[u] = (u << 2) | 0x01;

	sc->sc_iot = ga->ga_iot;
	if (bus_space_map(sc->sc_iot, ga->ga_hpa, ARCOFI_NREGS << 2, 0,
	    &sc->sc_ioh) != 0) {
		printf(": can't map registers\n");
		return;
	}

	/* XXX no generic IPL_SOFT level available */
	sc->sc_sih = softintr_establish(IPL_SOFTTTY, &arcofi_swintr, sc);
	if (sc->sc_sih == NULL) {
		printf(": can't register soft interrupt\n");
		return;
	}
	gsc_intr_establish((struct gsc_softc *)parent, ga->ga_irq,
	    IPL_AUDIO, arcofi_hwintr, sc, sc->sc_dev.dv_xname);

	printf("\n");

	arcofi_attach(sc, "gsc");
}


code:
/*	$OpenBSD: com_gsc.c,v 1.21 2007/07/15 19:25:49 kettenis Exp $	*/

/*
 * Copyright (c) 1998-2003 Michael Shalayeff
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/tty.h>

#include <machine/bus.h>
#include <machine/intr.h>
#include <machine/iomod.h>
#include <machine/autoconf.h>

#include <dev/ic/comreg.h>
#include <dev/ic/comvar.h>

#include <hppa/dev/cpudevs.h>
#include <hppa/gsc/gscbusvar.h>

#define COM_GSC_FREQ	7372800

struct com_gsc_regs {
	u_int8_t reset;
};

int	com_gsc_probe(struct device *, void *, void *);
void	com_gsc_attach(struct device *, struct device *, void *);

struct cfattach com_gsc_ca = {
	sizeof(struct com_softc), com_gsc_probe, com_gsc_attach
};

int
com_gsc_probe(parent, match, aux)
	struct device *parent;
	void *match, *aux;
{
	struct gsc_attach_args *ga = aux;

	if (ga->ga_type.iodc_type != HPPA_TYPE_FIO ||
	    (ga->ga_type.iodc_sv_model != HPPA_FIO_GRS232 &&
	     ga->ga_type.iodc_sv_model != HPPA_FIO_RS232 &&
	     ga->ga_type.iodc_sv_model != HPPA_FIO_GRJ16))
		return (0);

	return (1);
	/* HOZER comprobe1(ga->ga_iot, ga->ga_hpa + IOMOD_DEVOFFSET); */
}

void
com_gsc_attach(parent, self, aux)
	struct device *parent, *self;
	void *aux;
{
	struct com_softc *sc = (void *)self;
	struct gsc_attach_args *ga = aux;

	sc->sc_iot = ga->ga_iot;
	sc->sc_iobase = (bus_addr_t)ga->ga_hpa;
	if (ga->ga_type.iodc_sv_model != HPPA_FIO_GRJ16)
		sc->sc_iobase += IOMOD_DEVOFFSET;

	if (bus_space_map(sc->sc_iot, sc->sc_iobase, COM_NPORTS,
	    0, &sc->sc_ioh)) {
		printf(": cannot map io space\n");
		return;
	}

	if (PAGE0->mem_cons.pz_class == PCL_DUPLEX &&
	    PAGE0->mem_cons.pz_hpa == ga->ga_hpa) {
		bus_space_unmap(sc->sc_iot, sc->sc_ioh, COM_NPORTS);
		comcnattach(sc->sc_iot, sc->sc_iobase, comdefaultrate,
		    COM_GSC_FREQ, comconscflag);
	}

	sc->sc_frequency = COM_GSC_FREQ;
	com_attach_subr(sc);

	sc->sc_ih = gsc_intr_establish((struct gsc_softc *)parent,
	    ga->ga_irq, IPL_TTY, comintr, sc, sc->sc_dev.dv_xname);
}


code:
/*	$OpenBSD: fdc_gsc.c,v 1.5 2004/04/07 18:24:19 mickey Exp $	*/

/*
 * Copyright (c) 1998 Michael Shalayeff
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>

#include <machine/iomod.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <machine/autoconf.h>

#include <dev/ic/fdreg.h>
#include <dev/ic/fdlink.h>

#include <hppa/dev/cpudevs.h>

/* controller driver configuration */
int fdc_gsc_probe(struct device *, void *, void *);
void fdc_gsc_attach(struct device *, struct device *, void *);

struct cfattach fdc_gsc_ca = {
	sizeof(struct fdc_softc), fdc_gsc_probe, fdc_gsc_attach
};

int
fdc_gsc_probe(parent, match, aux)
	struct device *parent;
	void *match, *aux;
{
	struct confargs *ca = aux;
	bus_space_handle_t ioh;
	int rv;

	if (ca->ca_type.iodc_type != HPPA_TYPE_FIO ||
	    ca->ca_type.iodc_sv_model != HPPA_FIO_GPCFD)
		return 0;

	/* Map the I/O space. */
	if (bus_space_map(ca->ca_iot, ca->ca_hpa, IOMOD_HPASIZE, 0, &ioh))
		return 0;

	rv = fdcprobe1(ca->ca_iot, ioh | IOMOD_DEVOFFSET);
	bus_space_unmap(ca->ca_iot, ioh, IOMOD_HPASIZE);
	return rv;
}

void
fdc_gsc_attach(parent, self, aux)
	struct device *parent, *self;
	void *aux;
{
	struct fdc_softc *sc = (void *)self;
	bus_space_handle_t ioh;
	struct confargs *ca = aux;

	/* Re-map the I/O space. */
	if (bus_space_map(ca->ca_iot, ca->ca_hpa, IOMOD_HPASIZE, 0, &ioh))
		panic("fdcattach: couldn't map I/O ports");

	ioh |= IOMOD_DEVOFFSET;
	sc->sc_iot = ca->ca_iot;
	sc->sc_ioh = ioh;
	sc->sc_ioh_ctl = ioh + FDCTL_OFFSET;

	fdc_attach_subr(sc);
}