code:
/*	$OpenBSD: z8530kbd.c,v 1.7 2014/12/07 13:10:45 miod Exp $	*/
/*	$NetBSD: zs_kbd.c,v 1.8 2008/03/29 19:15:35 tsutsui Exp $	*/

/*
 * Copyright (c) 2004 Steve Rumble
 * 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.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * 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 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 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.
 */

/*
 * IP20 serial keyboard driver attached to zs channel 0 at 600bps.
 * This layer is the parent of wskbd.
 */

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

#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wskbdvar.h>
#include <dev/wscons/wsksymdef.h>
#include <dev/wscons/wsksymvar.h>

#include <machine/autoconf.h>
#include <mips64/archtype.h>

#include <dev/ic/z8530reg.h>
#include <machine/z8530var.h>

#define ZSKBD_BAUD		600
#define ZSKBD_TXQ_LEN		16		/* power of 2 */
#define ZSKBD_RXQ_LEN		64		/* power of 2 */

#define ZSKBD_DIP_SYNC		0x6e		/* 110 */
#define ZSKBD_INTL_KEY		0x6f		/* 111 */
#define ZSKBD_KEY_UP		0x80
#define ZSKBD_KEY_ALL_UP	0xf0

#ifdef ZSKBD_DEBUG
int zskbd_debug = 0;

#define DPRINTF(_x) if (zskbd_debug) printf _x
#else
#define DPRINTF(_x)
#endif

struct zskbd_softc {
	struct device sc_dev;

	struct zskbd_devconfig *sc_dc;

#ifdef WSDISPLAY_COMPAT_RAWKBD
	int		sc_rawkbd;
#endif
};

struct zskbd_devconfig {
	/* transmit tail-chasing fifo */
	uint8_t		txq[ZSKBD_TXQ_LEN];
	u_int		txq_head;
	u_int		txq_tail;

	/* receive tail-chasing fifo */
	uint8_t		rxq[ZSKBD_RXQ_LEN];
	u_int		rxq_head;
	u_int		rxq_tail;

	/* number of non-keystroke bytes expected */
	int		expected;

	/* keyboard configuration */
#define ZSKBD_CTRL_A		0x0
#define ZSKBD_CTRL_A_SBEEP	0x2	/* 200 ms */
#define ZSKBD_CTRL_A_LBEEP	0x4	/* 1000 ms */
#define ZSKBD_CTRL_A_NOCLICK	0x8	/* turn off keyboard click */
#define ZSKBD_CTRL_A_RCB	0x10	/* request config byte */
#define ZSKBD_CTRL_A_NUMLK	0x20	/* num lock led */
#define ZSKBD_CTRL_A_CAPSLK	0x40	/* caps lock led */
#define ZSKBD_CTRL_A_AUTOREP	0x80	/* auto-repeat after 650 ms, 28x/sec */

#define ZSKBD_CTRL_B		0x1
#define ZSKBD_CTRL_B_CMPL_DS1_2	0x2	/* complement of ds1+ds2 (num+capslk) */
#define ZSKBD_CTRL_B_SCRLK	0x4	/* scroll lock light */
#define ZSKBD_CTRL_B_L1		0x8	/* user-configurable lights */
#define ZSKBD_CTRL_B_L2		0x10
#define ZSKBD_CTRL_B_L3		0x20
#define ZSKBD_CTRL_B_L4		0x40
	uint8_t		kbd_conf[2];

	/* dip switch settings */
	uint8_t		dip;

	/* wscons glue */
	struct device  *wskbddev;
	int		enabled;
};

struct zskbd_devconfig zskbd_consdc;

int	zskbd_match(struct device *, void *, void *);
void	zskbd_attach(struct device *, struct device *, void *);

struct cfdriver zskbd_cd = {
	NULL, "zskbd", DV_DULL
};

const struct cfattach zskbd_ca = {
	sizeof(struct zskbd_softc), zskbd_match, zskbd_attach
};

void	zskbd_rxint(struct zs_chanstate *);
void	zskbd_stint(struct zs_chanstate *, int);
void	zskbd_txint(struct zs_chanstate *);
void	zskbd_softint(struct zs_chanstate *);
int	zskbd_send(struct zs_chanstate *, uint8_t *, u_int);
int	zskbd_poll(struct zs_chanstate *, uint8_t *);
void	zskbd_ctrl(struct zs_chanstate *, uint8_t, uint8_t, uint8_t, uint8_t);
int	zskbd_process(struct zskbd_devconfig *, uint8_t);

void	zskbd_wskbd_input(struct zs_chanstate *, uint8_t);
int	zskbd_wskbd_enable(void *, int);
void	zskbd_wskbd_set_leds(void *, int);
int	zskbd_wskbd_get_leds(void *);
void	zskbd_wskbd_set_keyclick(void *, int);
int	zskbd_wskbd_get_keyclick(void *);
int	zskbd_wskbd_ioctl(void *, u_long, caddr_t, int, struct proc *);

void	zskbd_cnattach(int, int);
void	zskbd_wskbd_getc(void *, u_int *, int *);
void	zskbd_wskbd_pollc(void *, int);
void	zskbd_wskbd_bell(void *, u_int, u_int, u_int);

extern struct zschan   *zs_get_chan_addr(int, int);
extern int		zs_getc(void *);
extern void		zs_putc(void *, int);

static struct zsops zskbd_zsops = {
	zskbd_rxint,
	zskbd_stint,
	zskbd_txint,
	zskbd_softint
};

extern const struct wscons_keydesc wssgi_keydesctab[];
struct wskbd_mapdata sgikbd_wskbd_keymapdata = {
	wssgi_keydesctab,
	KB_US | KB_DEFAULT
};

const int zskbd_layouts[] = {
	KB_US,
	KB_DE,
	KB_FR,
	KB_IT,
	KB_DK,
	KB_ES,
	KB_NO,
	KB_SV,
	KB_SF,
	KB_UK,
	KB_BE,
	KB_SG,
	KB_NL,
	-1,	/* finnish */
	KB_PT,
	-1	/* greek */
};

const struct wskbd_accessops zskbd_wskbd_accessops = {
	zskbd_wskbd_enable,
	zskbd_wskbd_set_leds,
	zskbd_wskbd_ioctl
};

const struct wskbd_consops zskbd_wskbd_consops = {
	zskbd_wskbd_getc,
	zskbd_wskbd_pollc,
	zskbd_wskbd_bell
};

int			zskbd_is_console = 0;

int
zskbd_match(struct device *parent, void *vcf, void *aux)
{
	if (sys_config.system_type == SGI_IP20) {
		struct zsc_attach_args *args = aux;

		if (args->channel == 0)
			return 1;
	}

	return 0;
}

void
zskbd_attach(struct device *parent, struct device *self, void *aux)
{
	struct zskbd_softc *sc = (struct zskbd_softc *)self;
	struct zsc_softc *zsc = (struct zsc_softc *)parent;
	struct zsc_attach_args *args = aux;
	struct zs_chanstate *cs;
	struct zskbd_devconfig *dc;
	struct wskbddev_attach_args wskaa;
	int s, channel, rc;
	uint8_t key;

	printf(": ");

	/* Establish ourself with the MD z8530 driver */
	channel = args->channel;
	cs = zsc->zsc_cs[channel];
	cs->cs_ops = &zskbd_zsops;
	cs->cs_private = sc;

	if (zskbd_is_console)
		dc = &zskbd_consdc;
	else
		dc = malloc(sizeof(struct zskbd_devconfig), M_DEVBUF,
		    M_WAITOK | M_ZERO);
	sc->sc_dc = dc;

	s = splzs();
	zs_write_reg(cs, 9, (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET);
	cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_TIE;
	cs->cs_preg[4] = (cs->cs_preg[4] & ZSWR4_CLK_MASK) |
			 (ZSWR4_ONESB | ZSWR4_PARENB);	/* 1 stop, odd parity */
	cs->cs_preg[15] &= ~ZSWR15_ENABLE_ENHANCED;
	zs_set_speed(cs, ZSKBD_BAUD);
	zs_loadchannelregs(cs);

	/*
	 * Empty the keyboard input buffer (if the keyboard is the console
	 * input device and the user invoked UKC, the `enter key up' event
	 * will still be pending in the buffer).
	 */
	while ((zs_read_csr(cs) & ZSRR0_RX_READY) != 0)
		(void)zs_read_data(cs);

	if (!zskbd_is_console) {
		/*
		 * Ask the keyboard for its DIP switch settings. This will
		 * also let us know whether the keyboard is connected.
		 */
		dc->expected = 2;
		zskbd_ctrl(cs, ZSKBD_CTRL_A_RCB, 0, 0, 0);
		while (dc->expected != 0) {
			rc = zskbd_poll(cs, &key);
			if (rc != 0) {
				if (rc == ENXIO && dc->expected == 2) {
					printf("no keyboard");
					/*
					 * Attach wskbd nevertheless, in case
					 * the keyboard is plugged late.
					 */
					dc->expected = 0;
					goto dip;
				} else {
					printf("i/o error\n");
					return;
				}
			}

			zskbd_process(dc, key);
		}
	}

	printf("dipsw %02x", dc->dip);
	if (dc->dip < nitems(zskbd_layouts) && zskbd_layouts[dc->dip] != -1)
		sgikbd_wskbd_keymapdata.layout = zskbd_layouts[dc->dip];
dip:

	/*
	 * Disable key click by default. Note that if the keyboard is not
	 * currently connected, the bit will nevertheless stick and will
	 * disable the click as soon as a keyboard led needs to be lit.
	 */
	zskbd_ctrl(cs, ZSKBD_CTRL_A_NOCLICK, 0, 0, 0);

	splx(s);

	printf("\n");

	if (zskbd_is_console)
		dc->enabled = 1;

	/* attach wskbd */
	wskaa.console = zskbd_is_console;
	wskaa.keymap = &sgikbd_wskbd_keymapdata;
	wskaa.accessops = &zskbd_wskbd_accessops;
	wskaa.accesscookie = cs;
	dc->wskbddev = config_found(self, &wskaa, wskbddevprint);
}

void
zskbd_rxint(struct zs_chanstate *cs)
{
	struct zskbd_softc *sc = cs->cs_private;
	struct zskbd_devconfig *dc = sc->sc_dc;
	uint8_t c, r;

	/* clear errors */
	r = zs_read_reg(cs, 1);
	if (r & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE))
		zs_write_csr(cs, ZSWR0_RESET_ERRORS);

	/* read byte and append to our queue */
	c = zs_read_data(cs);

	dc->rxq[dc->rxq_tail] = c;
	dc->rxq_tail = (dc->rxq_tail + 1) & ~ZSKBD_RXQ_LEN;

	cs->cs_softreq = 1;
}

void
zskbd_stint(struct zs_chanstate *cs, int force)
{
	zs_write_csr(cs, ZSWR0_RESET_STATUS);
	cs->cs_softreq = 1;
}

void
zskbd_txint(struct zs_chanstate *cs)
{
	zs_write_reg(cs, 0, ZSWR0_RESET_TXINT);
	cs->cs_softreq = 1;
}

void
zskbd_softint(struct zs_chanstate *cs)
{
	struct zskbd_softc *sc = cs->cs_private;
	struct zskbd_devconfig *dc = sc->sc_dc;
	int rr0;
	uint8_t key;

	/* handle pending transmissions */
	if (dc->txq_head != dc->txq_tail) {
		int s;

		s = splzs();
		while (dc->txq_head != dc->txq_tail) {
			rr0 = zs_read_csr(cs);
			if ((rr0 & ZSRR0_TX_READY) == 0)
				break;
			zs_write_data(cs, dc->txq[dc->txq_head]);
			dc->txq_head = (dc->txq_head + 1) & ~ZSKBD_TXQ_LEN;
		}
		splx(s);
	}

	/* handle incoming keystrokes/config */
	while (dc->rxq_head != dc->rxq_tail) {
		key = dc->rxq[dc->rxq_head];
		dc->rxq_head = (dc->rxq_head + 1) & ~ZSKBD_RXQ_LEN;
		if (zskbd_process(dc, key) != 0) {
			/*
			 * The `international' key (only found in non-us
			 * layouts) is supposed to be keycode 111, but is
			 * apparently 110 (same as the status byte prefix)
			 * on some (all?) models.
			 */
			if (key == ZSKBD_DIP_SYNC)
				key = ZSKBD_INTL_KEY;

			/* toss wskbd a bone */
			if (dc->enabled)
				zskbd_wskbd_input(cs, key);
		}
	}
}

int
zskbd_process(struct zskbd_devconfig *dc, uint8_t key)
{
	switch (dc->expected) {
	case 2:
		if (key != ZSKBD_DIP_SYNC) {
			/* only during attach, thus no device name prefix */
			printf("unexpected configuration byte header"
			    " (%02x), ", key);
			/* transition state anyway */
		}
		dc->expected--;
		return 0;
	case 1:
		dc->dip = key;
		dc->expected--;
		return 0;
	default:
	case 0:
		return 1;
	}
}

/* expects to be in splzs() */
int
zskbd_send(struct zs_chanstate *cs, uint8_t *c, u_int len)
{
	struct zskbd_softc *sc = cs->cs_private;
	struct zskbd_devconfig *dc = sc->sc_dc;
	u_int i;
	int rr0;

	while (len != 0) {
		rr0 = zs_read_csr(cs);
		if ((rr0 & ZSRR0_TX_READY) == 0) {
			/*
			 * poll until whole transmission complete during
			 * autoconf
			 */
			if (cold) {
				for (i = 1000; i != 0; i--) {
					if ((rr0 & ZSRR0_TX_READY) != 0)
						break;
					delay(100);
				}
				if (i == 0)
					return EIO;
			} else
				break;
		}
		zs_write_data(cs, *c++);
		len--;
	}

	/*
	 * Enqueue any remaining bytes.
	 */
	while (len != 0) {
		dc->txq[dc->txq_tail] = *c++;
		dc->txq_tail = (dc->txq_tail + 1) & ~ZSKBD_TXQ_LEN;
		len--;
		cs->cs_softreq = 1;
	}

	return 0;
}

/* expects to be in splzs() */
int
zskbd_poll(struct zs_chanstate *cs, uint8_t *key)
{
	u_int i;
	int rr0, rr1, c;

	for (i = 1000; i != 0; i--) {
		rr0 = zs_read_csr(cs);
		if ((rr0 & ZSRR0_RX_READY) != 0)
			break;
		delay(100);
	}
	if (i == 0)
		return ENXIO;

	rr1 = zs_read_reg(cs, 1);
	c = zs_read_data(cs);

	if (rr1 & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE))
		return EIO;

	*key = (uint8_t)c;
	return 0;
}

/* expects to be in splzs() */
void
zskbd_ctrl(struct zs_chanstate *cs, uint8_t a_on, uint8_t a_off, uint8_t b_on,
    uint8_t b_off)
{
	struct zskbd_softc *sc = cs->cs_private;
	struct zskbd_devconfig *dc = sc->sc_dc;

	dc->kbd_conf[ZSKBD_CTRL_A] |=   a_on;
	dc->kbd_conf[ZSKBD_CTRL_A] &= ~(a_off | ZSKBD_CTRL_B);
	dc->kbd_conf[ZSKBD_CTRL_B] &=  ~b_off;
	dc->kbd_conf[ZSKBD_CTRL_B] |=  (b_on | ZSKBD_CTRL_B);

	zskbd_send(cs, dc->kbd_conf, 2);

	/* make sure we don't resend these each time */
	dc->kbd_conf[ZSKBD_CTRL_A] &= ~(ZSKBD_CTRL_A_RCB | ZSKBD_CTRL_A_SBEEP |
	    ZSKBD_CTRL_A_LBEEP);
}

/******************************************************************************
 * wskbd glue
 ******************************************************************************/

void
zskbd_wskbd_input(struct zs_chanstate *cs, uint8_t key)
{
	struct zskbd_softc *sc = cs->cs_private;
	u_int type;
#ifdef WSDISPLAY_COMPAT_RAWKBD
	int s;
#endif

	if (sc->sc_dc->wskbddev == NULL)
		return;	/* why bother */

	if (key & ZSKBD_KEY_UP) {
		if ((key & ZSKBD_KEY_ALL_UP) == ZSKBD_KEY_ALL_UP)
			type = WSCONS_EVENT_ALL_KEYS_UP;
		else
			type = WSCONS_EVENT_KEY_UP;
	} else
		type = WSCONS_EVENT_KEY_DOWN;

	wskbd_input(sc->sc_dc->wskbddev, type, (key & ~ZSKBD_KEY_UP));

	DPRINTF(("zskbd_wskbd_input: inputted key 0x%x\n", key));

#ifdef WSDISPLAY_COMPAT_RAWKBD
	if (sc->sc_rawkbd &&
	    type != WSCONS_EVENT_ALL_KEYS_UP) {
		s = spltty();
		wskbd_rawinput(sc->sc_dc->wskbddev, &key, 1);
		splx(s);
	}
#endif
}

int
zskbd_wskbd_enable(void *cookie, int on)
{
	struct zs_chanstate *cs = cookie;
	struct zskbd_softc *sc = cs->cs_private;

	if (on) {
		if (sc->sc_dc->enabled)
			return (EBUSY);
		else
			sc->sc_dc->enabled = 1;
	} else
		sc->sc_dc->enabled = 0;

	DPRINTF(("zskbd_wskbd_enable: %s\n", on ? "enabled" : "disabled"));

	return (0);
}

void
zskbd_wskbd_set_leds(void *cookie, int leds)
{
	struct zs_chanstate *cs = cookie;
	int 	s;
	uint8_t	a_on, a_off, b_on, b_off;

	a_on = a_off = b_on = b_off = 0;

	if (leds & WSKBD_LED_CAPS)
		a_on |=  ZSKBD_CTRL_A_CAPSLK;
	else
		a_off |= ZSKBD_CTRL_A_CAPSLK;

	if (leds & WSKBD_LED_NUM)
		a_on |=  ZSKBD_CTRL_A_NUMLK;
	else
		a_off |= ZSKBD_CTRL_A_NUMLK;

	if (leds & WSKBD_LED_SCROLL)
		b_on |=  ZSKBD_CTRL_B_SCRLK;
	else
		b_off |= ZSKBD_CTRL_B_SCRLK;

	s = splzs();
	zskbd_ctrl(cs, a_on, a_off, b_on, b_off);
	splx(s);
}

int
zskbd_wskbd_get_leds(void *cookie)
{
	struct zs_chanstate *cs = cookie;
	struct zskbd_softc *sc = cs->cs_private;
	int leds;

	leds = 0;

	if (sc->sc_dc->kbd_conf[ZSKBD_CTRL_A] & ZSKBD_CTRL_A_NUMLK)
		leds |= WSKBD_LED_NUM;

	if (sc->sc_dc->kbd_conf[ZSKBD_CTRL_A] & ZSKBD_CTRL_A_CAPSLK)
		leds |= WSKBD_LED_CAPS;

	if (sc->sc_dc->kbd_conf[ZSKBD_CTRL_B] & ZSKBD_CTRL_B_SCRLK)
		leds |= WSKBD_LED_SCROLL;

	return (leds);
}

#if 0
void
zskbd_wskbd_set_keyclick(void *cookie, int on)
{
	struct zs_chanstate *cs = cookie;
	int s;

	if (on) {
		if (!zskbd_wskbd_get_keyclick(cookie)) {
			s = splzs();
			zskbd_ctrl(cs, 0, ZSKBD_CTRL_A_NOCLICK, 0, 0);
			splx(s);
		}
	} else {
		if (zskbd_wskbd_get_keyclick(cookie)) {
			s = splzs();
			zskbd_ctrl(cs, ZSKBD_CTRL_A_NOCLICK, 0, 0, 0);
			splx(s);
		}
	}
}

int
zskbd_wskbd_get_keyclick(void *cookie)
{
	struct zs_chanstate *cs = cookie;
	struct zskbd_softc *sc = cs->cs_private;

	if (sc->sc_dc->kbd_conf[ZSKBD_CTRL_A] & ZSKBD_CTRL_A_NOCLICK)
		return (0);
	else
		return (1);
}
#endif

int
zskbd_wskbd_ioctl(void *cookie, u_long cmd, caddr_t data, int flag,
    struct proc *p)
{
	struct zs_chanstate *cs = cookie;
#ifdef WSDISPLAY_COMPAT_RAWKBD
	struct zskbd_softc *sc = cs->cs_private;
#endif

	switch (cmd) {
	case WSKBDIO_GTYPE:
		*(int *)data = WSKBD_TYPE_SGI;
		break;
	case WSKBDIO_SETLEDS:
		zskbd_wskbd_set_leds(cs, *(int *)data);
		break;
	case WSKBDIO_GETLEDS:
		*(int *)data = zskbd_wskbd_get_leds(cs);
		break;
#if 0
	case WSKBDIO_SETKEYCLICK:
		zskbd_wskbd_set_keyclick(cs, *(int *)data);
		break;
	case WSKBDIO_GETKEYCLICK:
		*(int *)data = zskbd_wskbd_get_keyclick(cs);
		break;
#endif
#ifdef WSDISPLAY_COMPAT_RAWKBD
	case WSKBDIO_SETMODE:
		sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
		break;
#endif
	default:
		return -1;
	}

	return 0;
}

/*
 * console routines
 */
void
zskbd_cnattach(int zsunit, int zschan)
{
	struct zschan *zs;
	struct zskbd_devconfig *dc;

	zs = zs_get_chan_addr(zsunit, zschan);
	dc = &zskbd_consdc;

	/*
	 * Try and figure out our dip switches early, in order to pick
	 * the right keyboard layout.
	 */
	dc->expected = 2;
	zs_putc(zs, ZSKBD_CTRL_A_RCB);
	zs_putc(zs, ZSKBD_CTRL_B);	/* unnecessary? */

	while (dc->expected != 0) {
		zskbd_process(dc, zs_getc(zs));
	}

	if (dc->dip < nitems(zskbd_layouts) && zskbd_layouts[dc->dip] != -1)
		sgikbd_wskbd_keymapdata.layout = zskbd_layouts[dc->dip];

	wskbd_cnattach(&zskbd_wskbd_consops, zs, &sgikbd_wskbd_keymapdata);
	zskbd_is_console = 1;
}

void
zskbd_wskbd_getc(void *cookie, u_int *type, int *data)
{
	int key;

	key = zs_getc(cookie);

	if (key & ZSKBD_KEY_UP)
		*type = WSCONS_EVENT_KEY_UP;
	else
		*type = WSCONS_EVENT_KEY_DOWN;

	*data = key & ~ZSKBD_KEY_UP;
}

void
zskbd_wskbd_pollc(void *cookie, int on)
{
}

void
zskbd_wskbd_bell(void *cookie, u_int pitch, u_int period, u_int volume)
{
	/*
	 * Since we don't have any state, this'll nuke our lights,
	 * key click, and other bits in ZSKBD_CTRL_A.
	 */
	if (period >= 1000)
		zs_putc(cookie, ZSKBD_CTRL_A_LBEEP);
	else
		zs_putc(cookie, ZSKBD_CTRL_A_SBEEP);
}


code:
/*	$OpenBSD: z8530ms.c,v 1.1 2012/04/17 22:06:33 miod Exp $	*/
/*	$NetBSD: zs_ms.c,v 1.7 2008/03/29 19:15:35 tsutsui Exp $	*/

/*
 * Copyright (c) 2004 Steve Rumble
 * 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.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * 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 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 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.
 */

/*
 * IP20 serial mouse driver attached to zs channel 1 at 4800bps.
 * This layer feeds wsmouse.
 *
 * 5 byte packets: sync, x1, y1, x2, y2
 * sync format: binary 10000LMR (left, middle, right) 0 is down
 */

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

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

#include <machine/autoconf.h>
#include <mips64/archtype.h>

#include <dev/ic/z8530reg.h>
#include <machine/z8530var.h>

#define ZSMS_BAUD	4800
#define ZSMS_RXQ_LEN	64	/* power of 2 */

/* protocol */
#define ZSMS_SYNC		0x80
#define ZSMS_SYNC_MASK		0xf8
#define ZSMS_SYNC_BTN_R		0x01
#define ZSMS_SYNC_BTN_M		0x02
#define ZSMS_SYNC_BTN_L		0x04
#define ZSMS_SYNC_BTN_MASK	0x07

struct zsms_softc {
	struct device	sc_dev;

	/* tail-chasing fifo */
	uint8_t		rxq[ZSMS_RXQ_LEN];
	uint8_t		rxq_head;
	uint8_t		rxq_tail;

	/* 5-byte packet as described above */
#define	ZSMS_PACKET_SYNC	0
#define	ZSMS_PACKET_X1		1
#define	ZSMS_PACKET_Y1		2
#define	ZSMS_PACKET_X2		3
#define	ZSMS_PACKET_Y2		4
	int8_t		packet[5];

#define ZSMS_STATE_SYNC	0x01
#define ZSMS_STATE_X1	0x02
#define ZSMS_STATE_Y1	0x04
#define ZSMS_STATE_X2	0x08
#define ZSMS_STATE_Y2	0x10
	uint8_t		state;

	/* wsmouse bits */
	int		enabled;
	struct device  *wsmousedev;
};

int	zsms_match(struct device *, void *, void *);
void	zsms_attach(struct device *, struct device *, void *);

struct cfdriver zsms_cd = {
	NULL, "zsms", DV_DULL
};

const struct cfattach zsms_ca = {
	sizeof(struct zsms_softc), zsms_match, zsms_attach
};

void	zsms_rxint(struct zs_chanstate *);
void	zsms_txint(struct zs_chanstate *);
void	zsms_stint(struct zs_chanstate *, int);
void	zsms_softint(struct zs_chanstate *);

void	zsms_wsmouse_input(struct zsms_softc *);
int	zsms_wsmouse_enable(void *);
void	zsms_wsmouse_disable(void *);
int	zsms_wsmouse_ioctl(void *, u_long, caddr_t, int, struct proc *);

static struct zsops zsms_zsops = {
	zsms_rxint,
	zsms_stint,
	zsms_txint,
	zsms_softint
};

static const struct wsmouse_accessops zsms_wsmouse_accessops = {
	zsms_wsmouse_enable,
	zsms_wsmouse_ioctl,
	zsms_wsmouse_disable
};

int
zsms_match(struct device *parent, void *vcf, void *aux)
{
	if (sys_config.system_type == SGI_IP20) {
		struct zsc_attach_args *args = aux;

		if (args->channel == 1)
			return (1);
	}

	return (0);
}

void
zsms_attach(struct device *parent, struct device *self, void *aux)
{
	struct zsc_softc	       *zsc = (struct zsc_softc *)parent;
	struct zsms_softc	       *sc = (struct zsms_softc *)self;
	struct zsc_attach_args	       *args = aux;
	struct zs_chanstate	       *cs;
	int				s, channel;
	struct wsmousedev_attach_args	wsmaa;

	/* Establish ourself with the MD z8530 driver */
	channel = args->channel;
	cs = zsc->zsc_cs[channel];
	cs->cs_ops = &zsms_zsops;
	cs->cs_private = sc;

	sc->enabled = 0;
	sc->rxq_head = 0;
	sc->rxq_tail = 0;
	sc->state = ZSMS_STATE_SYNC;

	printf("\n");

	s = splzs();
	zs_write_reg(cs, 9, (channel == 0) ? ZSWR9_A_RESET : ZSWR9_B_RESET);
	cs->cs_preg[1] = ZSWR1_RIE;
	zs_set_speed(cs, ZSMS_BAUD);
	zs_loadchannelregs(cs);
	splx(s);

	/* attach wsmouse */
	wsmaa.accessops =	&zsms_wsmouse_accessops;
	wsmaa.accesscookie =	sc;
	sc->wsmousedev =	config_found(self, &wsmaa, wsmousedevprint);
}

void
zsms_rxint(struct zs_chanstate *cs)
{
	struct zsms_softc *sc = cs->cs_private;
	uint8_t c, r;

	/* clear errors */
	r = zs_read_reg(cs, 1);
	if (r & (ZSRR1_FE | ZSRR1_DO | ZSRR1_PE))
		zs_write_csr(cs, ZSWR0_RESET_ERRORS);

	/* read byte and append to our queue */
	c = zs_read_data(cs);

	sc->rxq[sc->rxq_tail] = c;
	sc->rxq_tail = (sc->rxq_tail + 1) & ~ZSMS_RXQ_LEN;

	cs->cs_softreq = 1;
}

/* We should never get here. */
void
zsms_txint(struct zs_chanstate *cs)
{
	zs_write_reg(cs, 0, ZSWR0_RESET_TXINT);

	/* disable tx interrupts */
	CLR(cs->cs_preg[1], ZSWR1_TIE);
	zs_loadchannelregs(cs);
}

void
zsms_stint(struct zs_chanstate *cs, int force)
{
	zs_write_csr(cs, ZSWR0_RESET_STATUS);
	cs->cs_softreq = 1;
}

void
zsms_softint(struct zs_chanstate *cs)
{
	struct zsms_softc *sc = cs->cs_private;

	/* No need to keep score if nobody is listening */
	if (!sc->enabled) {
		sc->rxq_head = sc->rxq_tail;
		return;
	}

	/*
	 * Here's the real action. Read a full packet and
	 * then let wsmouse know what has happened.
	 */
	while (sc->rxq_head != sc->rxq_tail) {
		int8_t c = sc->rxq[sc->rxq_head];

		switch (sc->state) {
		case ZSMS_STATE_SYNC:
			if ((c & ZSMS_SYNC_MASK) == ZSMS_SYNC) {
				sc->packet[ZSMS_PACKET_SYNC] = c;
				sc->state = ZSMS_STATE_X1;
			}
			break;

		case ZSMS_STATE_X1:
			sc->packet[ZSMS_PACKET_X1] = c;
			sc->state = ZSMS_STATE_Y1;
			break;

		case ZSMS_STATE_Y1:
			sc->packet[ZSMS_PACKET_Y1] = c;
			sc->state = ZSMS_STATE_X2;
			break;

		case ZSMS_STATE_X2:
			sc->packet[ZSMS_PACKET_X2] = c;
			sc->state = ZSMS_STATE_Y2;
			break;

		case ZSMS_STATE_Y2:
			sc->packet[ZSMS_PACKET_Y2] = c;

			/* tweak wsmouse */
			zsms_wsmouse_input(sc);

			sc->state = ZSMS_STATE_SYNC;
		}

		sc->rxq_head = (sc->rxq_head + 1) & ~ZSMS_RXQ_LEN;
	}
}

/******************************************************************************
 * wsmouse glue
 ******************************************************************************/

void
zsms_wsmouse_input(struct zsms_softc *sc)
{
	u_int	btns;
	int bl, bm, br;
	int	x, y;

	if (sc->wsmousedev == NULL)
		return;

	btns = (uint8_t)sc->packet[ZSMS_PACKET_SYNC] & ZSMS_SYNC_BTN_MASK;

	bl = (btns & ZSMS_SYNC_BTN_L) == 0;
	bm = (btns & ZSMS_SYNC_BTN_M) == 0;
	br = (btns & ZSMS_SYNC_BTN_R) == 0;

	/* for wsmouse(4), 1 is down, 0 is up, the most left button is LSB */
	btns = 0;
	if (bl)
		btns |= 1 << 0;
	if (bm)
		btns |= 1 << 1;
	if (br)
		btns |= 1 << 2;

	x = (int)sc->packet[ZSMS_PACKET_X1] + (int)sc->packet[ZSMS_PACKET_X2];
	y = (int)sc->packet[ZSMS_PACKET_Y1] + (int)sc->packet[ZSMS_PACKET_Y2];

	wsmouse_input(sc->wsmousedev, btns, x, y, 0, 0, WSMOUSE_INPUT_DELTA);
}

int
zsms_wsmouse_enable(void *cookie)
{
	struct zsms_softc *sc = cookie;

	if (sc->enabled)
		return (EBUSY);

	sc->state = ZSMS_STATE_SYNC;
	sc->enabled = 1;

	return (0);
}

void
zsms_wsmouse_disable(void *cookie)
{
	struct zsms_softc *sc = cookie;

	sc->enabled = 0;
}

int
zsms_wsmouse_ioctl(void *cookie, u_long cmd, caddr_t data, int flag,
    struct proc *p)
{
	switch (cmd) {
	case WSMOUSEIO_GTYPE:
		*(u_int *)data = WSMOUSE_TYPE_SGI;
		break;
	default:
		return -1;
	}

	return 0;
}

license: unknown


code:
/*	$OpenBSD: zs.c,v 1.13 2014/12/07 13:12:05 miod Exp $	*/
/*	$NetBSD: zs.c,v 1.37 2011/02/20 07:59:50 matt Exp $	*/

/*-
 * Copyright (c) 1996, 2000 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Gordon W. Ross and Wayne Knowles
 *
 * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``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 FOUNDATION OR CONTRIBUTORS
 * 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 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.
 */

/*
 * Zilog Z8530 Dual UART driver (machine-dependent part)
 *
 * Runs two serial lines per chip using slave drivers.
 * Plain tty/async lines use the zstty slave.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/device.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/tty.h>
#include <sys/time.h>
#include <sys/syslog.h>

#include <mips64/archtype.h>
#include <mips64/arcbios.h>

#include <machine/autoconf.h>
#include <machine/cpu.h>
#include <machine/z8530var.h>

#include <dev/cons.h>

#include <dev/ic/z8530reg.h>

#include <sgi/hpc/hpcvar.h>
#include <sgi/hpc/hpcreg.h>

/*
 * Some warts needed by z8530tty.c -
 * The default parity REALLY needs to be the same as the PROM uses,
 * or you can not see messages done with printf during boot-up...
 */
int zs_def_cflag = (CREAD | CS8 | HUPCL);
int zs_major = 19;

#define PCLK		3672000	 /* PCLK pin input clock rate */

#ifndef ZS_DEFSPEED
#define ZS_DEFSPEED	9600
#endif

/*
 * Define interrupt levels.
 */
#define ZSHARD_PRI 64

/* SGI shouldn't need ZS_DELAY() as recovery time is done in hardware? */
#define ZS_DELAY()	delay(2)

/* The layout of this is hardware-dependent (padding, order). */
struct zschan {
	uint8_t pad1[3];
	volatile uint8_t zc_csr;	/* ctrl,status, and indirect access */
	uint8_t pad2[3];
	volatile uint8_t zc_data;	/* data */
};

struct zsdevice {
	struct	zschan zs_chan_b;
	struct	zschan zs_chan_a;
};

/* Return the byte offset of element within a structure */
#define OFFSET(struct_def, el)		((size_t)&((struct_def *)0)->el)

#define ZS_CHAN_A	OFFSET(struct zsdevice, zs_chan_a)
#define ZS_CHAN_B	OFFSET(struct zsdevice, zs_chan_b)
#define ZS_REG_CSR	3
#define ZS_REG_DATA	7
static int zs_chan_offset[] = {ZS_CHAN_A, ZS_CHAN_B};

cons_decl(zs);
struct consdev zs_cn = {
	zscnprobe,
	zscninit,
	zscngetc,
	zscnputc,
	zscnpollc,
	NULL
};

/* Flags from cninit() */
static int zs_consunit = -1;
static int zs_conschan = -1;

/* Default speed for all channels */
static int zs_defspeed = ZS_DEFSPEED;

static uint8_t zs_init_reg[17] = {
	0,				/* 0: CMD (reset, etc.) */
	0,				/* 1: No interrupts yet. */
	ZSHARD_PRI,			/* 2: IVECT */
	ZSWR3_RX_8 | ZSWR3_RX_ENABLE,
	ZSWR4_CLK_X16 | ZSWR4_ONESB,
	ZSWR5_TX_8 | ZSWR5_TX_ENABLE,
	0,				/* 6: TXSYNC/SYNCLO */
	0,				/* 7: RXSYNC/SYNCHI */
	0,				/* 8: alias for data port */
	ZSWR9_MASTER_IE,
	0,				/*10: Misc. TX/RX control bits */
	ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD | ZSWR11_TRXC_OUT_ENA,
	BPS_TO_TCONST(PCLK/16, ZS_DEFSPEED), /*12: BAUDLO (default=9600) */
	0,				/*13: BAUDHI (default=9600) */
	ZSWR14_BAUD_ENA,
	ZSWR15_BREAK_IE,
	ZSWR7P_TX_FIFO			/* 7': TX FIFO interrupt level */
};

/****************************************************************
 * Autoconfig
 ****************************************************************/

/* Definition of the driver for autoconfig. */
int	zs_hpc_match(struct device *, void *, void *);
void	zs_hpc_attach(struct device *, struct device *, void *);
int	zs_print(void *, const char *name);

struct cfdriver zs_cd = {
	NULL, "zs", DV_TTY
};

struct cfattach zs_hpc_ca = {
	sizeof(struct zsc_softc), zs_hpc_match, zs_hpc_attach
};

int		 zshard(void *);
void		 zssoft(void *);
struct zschan	*zs_get_chan_addr(int, int);
int		 zs_getc(void *);
void		 zs_putc(void *, int);

/*
 * Is the zs chip present?
 */
int
zs_hpc_match(struct device *parent, void *vcf, void *aux)
{
	struct cfdata *cf = vcf;
	struct hpc_attach_args *ha = aux;

	if (strcmp(ha->ha_name, cf->cf_driver->cd_name) == 0)
		return (1);

	return (0);
}

/*
 * Attach a found zs.
 *
 * Match slave number to zs unit number, so that misconfiguration will
 * not set up the keyboard as ttya, etc.
 */
void
zs_hpc_attach(struct device *parent, struct device *self, void *aux)
{
	struct zsc_softc *zsc = (void *)self;
	struct cfdata *cf = self->dv_cfdata;
	struct hpc_attach_args *haa = aux;
	struct zsc_attach_args zsc_args;
	struct zs_chanstate *cs;
	struct zs_channel *ch;
	int zs_unit, channel, err, s;
	int has_fifo;

	zsc->zsc_bustag = haa->ha_st;
	if ((err = bus_space_subregion(haa->ha_st, haa->ha_sh,
				       haa->ha_devoff, 0x10,
				       &zsc->zsc_base)) != 0) {
		printf(": unable to map 85c30 registers, error = %d\n",
		    err);
		return;
	}

	zs_unit = zsc->zsc_dev.dv_unit;

	/*
	 * Initialize software state for each channel.
	 *
	 * Done in reverse order of channels since the first serial port
	 * is actually attached to the *second* channel, and vice versa.
	 * Doing it this way should force a 'zstty*' to attach zstty0 to
	 * channel 1 and zstty1 to channel 0.  They couldn't have wired
	 * it up in a more sensible fashion, could they?
	 */
	for (channel = 1; channel >= 0; channel--) {
		zsc_args.channel = channel;
		ch = &zsc->zsc_cs_store[channel];
		cs = zsc->zsc_cs[channel] = (struct zs_chanstate *)ch;

		/*
		 * According to IRIX <sys/z8530.h>, on Indigo, the CTR, DCD,
		 * DTR and RTS bits are inverted.
		 *
		 * That is, inverted when compared to the Indy and Indigo 2
		 * designs. However, it turns out that the Indigo wiring is
		 * the `natural' one, with these pins being inverted from
		 * what one would naively expect, on the other designs.
		 *
		 * Choose wiring logic according to the hardware we run on,
		 * and the device flags.
		 */
		if (sys_config.system_type != SGI_IP20)
			ch->cs_flags |= ZSCFL_INVERT_WIRING;
		if (cf->cf_flags & ZSCFL_INVERT_WIRING)
			ch->cs_flags ^= ZSCFL_INVERT_WIRING;

		cs->cs_reg_csr = NULL;
		cs->cs_reg_data = NULL;
		cs->cs_channel = channel;
		cs->cs_private = NULL;
		cs->cs_ops = &zsops_null;
		cs->cs_brg_clk = PCLK / 16;

		if (bus_space_subregion(zsc->zsc_bustag, zsc->zsc_base,
					zs_chan_offset[channel],
					sizeof(struct zschan),
					&ch->cs_regs) != 0) {
			printf(": cannot map regs\n");
			return;
		}
		ch->cs_bustag = zsc->zsc_bustag;

		/*
		 * Figure out whether this chip is a 8530 or a 85230.
		 */
		if (channel == 1) {
			zs_write_reg(cs, 15, ZSWR15_ENABLE_ENHANCED);
			has_fifo = zs_read_reg(cs, 15) & ZSWR15_ENABLE_ENHANCED;

			if (has_fifo) {
				zs_write_reg(cs, 15, 0);
				printf(": 85230\n");
			} else
				printf(": 8530\n");
		}

		if (has_fifo)
			zs_init_reg[15] |= ZSWR15_ENABLE_ENHANCED;
		else
			zs_init_reg[15] &= ~ZSWR15_ENABLE_ENHANCED;
		memcpy(cs->cs_creg, zs_init_reg, 17);
		memcpy(cs->cs_preg, zs_init_reg, 17);

		/* If console, don't stomp speed, let zstty know */
		if (zs_unit == zs_consunit && channel == zs_conschan) {
			zsc_args.consdev = &zs_cn;
			zsc_args.hwflags = ZS_HWFLAG_CONSOLE;
			cs->cs_defspeed = bios_consrate;
		} else {
			zsc_args.consdev = NULL;
			zsc_args.hwflags = 0;
			cs->cs_defspeed = zs_defspeed;
		}

		cs->cs_defcflag = zs_def_cflag;

		/* Make these correspond to cs_defcflag (-crtscts) */
		cs->cs_rr0_dcd = ZSRR0_DCD;
		cs->cs_rr0_cts = 0;
		cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
		cs->cs_wr5_rts = 0;

		/*
		 * Clear the master interrupt enable.
		 * The INTENA is common to both channels,
		 * so just do it on the A channel.
		 */
		if (channel == 0) {
			zs_write_reg(cs, 9, 0);
		}
		/*
		 * Look for a child driver for this channel.
		 * The child attach will setup the hardware.
		 */
		if (!config_found(self, (void *)&zsc_args, zs_print)) {
			/* No sub-driver.  Just reset it. */
			uint8_t reset = (channel == 0) ?
				ZSWR9_A_RESET : ZSWR9_B_RESET;

			s = splhigh();
			zs_write_reg(cs, 9, reset);
			splx(s);
		}
	}

	zsc->sc_si = softintr_establish(IPL_SOFTTTY, zssoft, zsc);
	hpc_intr_establish(haa->ha_irq, IPL_TTY, zshard, zsc, self->dv_xname);

	/*
	 * Set the master interrupt enable and interrupt vector.
	 * (common to both channels, do it on A)
	 */
	cs = zsc->zsc_cs[0];
	s = splhigh();
	/* interrupt vector */
	zs_write_reg(cs, 2, zs_init_reg[2]);
	/* master interrupt control (enable) */
	zs_write_reg(cs, 9, zs_init_reg[9]);
	splx(s);
}

int
zs_print(void *aux, const char *name)
{
	struct zsc_attach_args *args = aux;

	if (name != NULL)
		printf("%s:", name);

	if (args->channel != -1)
		printf(" channel %d", args->channel);

	return UNCONF;
}

/*
 * Our ZS chips all share a common, autovectored interrupt,
 * so we have to look at all of them on each interrupt.
 */
int
zshard(void *arg)
{
	struct zsc_softc *zsc = arg;
	int rval;

	rval = zsc_intr_hard(zsc);
	if (rval != 0) {
		if (zsc->zsc_cs[0]->cs_softreq ||
		    zsc->zsc_cs[1]->cs_softreq)
			softintr_schedule(zsc->sc_si);
	}

	return rval;
}

/*
 * Similar scheme as for zshard (look at all of them)
 */
void
zssoft(void *arg)
{
	struct zsc_softc *zsc = arg;
	int s;

	/* Make sure we call the tty layer at spltty. */
	s = spltty();
	(void)zsc_intr_soft(zsc);
	splx(s);
}

/*
 * MD functions for setting the baud rate and control modes.
 */
int
zs_set_speed(struct zs_chanstate *cs, int bps)
{
	int tconst, real_bps;

	if (bps == 0)
		return (0);

#ifdef	DIAGNOSTIC
	if (cs->cs_brg_clk == 0)
		panic("zs_set_speed");
#endif

	tconst = BPS_TO_TCONST(cs->cs_brg_clk, bps);
	if (tconst < 0)
		return (EINVAL);

	/* Convert back to make sure we can do it. */
	real_bps = TCONST_TO_BPS(cs->cs_brg_clk, tconst);

#if 0	/* PCLK is too small, 9600bps really yields 9562 */
	/* XXX - Allow some tolerance here? */
	if (real_bps != bps)
		return (EINVAL);
#endif

	cs->cs_preg[12] = tconst;
	cs->cs_preg[13] = tconst >> 8;

	/* Caller will stuff the pending registers. */
	return (0);
}

int
zs_set_modes(struct zs_chanstate *cs, int cflag)
{
	int s;

	/*
	 * Output hardware flow control on the chip is horrendous:
	 * if carrier detect drops, the receiver is disabled, and if
	 * CTS drops, the transmitter is stoped IN MID CHARACTER!
	 * Therefore, NEVER set the HFC bit, and instead use the
	 * status interrupt to detect CTS changes.
	 */
	s = splzs();
	cs->cs_rr0_pps = 0;
	if ((cflag & (CLOCAL | MDMBUF)) != 0) {
		cs->cs_rr0_dcd = 0;
		if ((cflag & MDMBUF) == 0)
			cs->cs_rr0_pps = ZSRR0_DCD;
	} else
		cs->cs_rr0_dcd = ZSRR0_DCD;
	if ((cflag & CRTSCTS) != 0) {
		cs->cs_wr5_dtr = ZSWR5_DTR;
		cs->cs_wr5_rts = ZSWR5_RTS;
		cs->cs_rr0_cts = ZSRR0_CTS;
	} else if ((cflag & MDMBUF) != 0) {
		cs->cs_wr5_dtr = 0;
		cs->cs_wr5_rts = ZSWR5_DTR;
		cs->cs_rr0_cts = ZSRR0_DCD;
	} else {
		cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
		cs->cs_wr5_rts = 0;
		cs->cs_rr0_cts = 0;
	}
	splx(s);

	/* Caller will stuff the pending registers. */
	return (0);
}

/*
 * Read or write the chip with suitable delays.
 */

uint8_t
zs_read_reg(struct zs_chanstate *cs, uint8_t reg)
{
	uint8_t val;
	struct zs_channel *zsc = (struct zs_channel *)cs;

	bus_space_write_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, reg);
	bus_space_barrier(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, 1,
	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
	ZS_DELAY();
	val = bus_space_read_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR);
	ZS_DELAY();

	if ((zsc->cs_flags & ZSCFL_INVERT_WIRING) && reg == 0)
		val ^= ZSRR0_CTS | ZSRR0_DCD;

	return val;
}

void
zs_write_reg(struct zs_chanstate *cs, uint8_t reg, uint8_t val)
{
	struct zs_channel *zsc = (struct zs_channel *)cs;

	if ((zsc->cs_flags & ZSCFL_INVERT_WIRING) && reg == 5)
		val ^= ZSWR5_DTR | ZSWR5_RTS;

	bus_space_write_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, reg);
	bus_space_barrier(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, 1,
	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
	ZS_DELAY();
	bus_space_write_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, val);
	bus_space_barrier(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, 1,
	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
	ZS_DELAY();
}

uint8_t
zs_read_csr(struct zs_chanstate *cs)
{
	struct zs_channel *zsc = (struct zs_channel *)cs;
	uint8_t val;

	val = bus_space_read_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR);
	ZS_DELAY();

	if (zsc->cs_flags & ZSCFL_INVERT_WIRING)
		val ^= ZSRR0_CTS | ZSRR0_DCD;

	return val;
}

void
zs_write_csr(struct zs_chanstate *cs, uint8_t val)
{
	struct zs_channel *zsc = (struct zs_channel *)cs;

	bus_space_write_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, val);
	bus_space_barrier(zsc->cs_bustag, zsc->cs_regs, ZS_REG_CSR, 1,
	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
	ZS_DELAY();
}

uint8_t
zs_read_data(struct zs_chanstate *cs)
{
	struct zs_channel *zsc = (struct zs_channel *)cs;
	uint8_t val;

	val = bus_space_read_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_DATA);
	ZS_DELAY();
	return val;
}

void
zs_write_data(struct zs_chanstate *cs, uint8_t val)
{
	struct zs_channel *zsc = (struct zs_channel *)cs;

	bus_space_write_1(zsc->cs_bustag, zsc->cs_regs, ZS_REG_DATA, val);
	bus_space_barrier(zsc->cs_bustag, zsc->cs_regs, ZS_REG_DATA, 1,
	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
	ZS_DELAY();
}

void
zs_abort(struct zs_chanstate *cs)
{
#if defined(KGDB)
	zskgdb(cs);
#elif defined(DDB)
	Debugger();
#endif
}

/*********************************************************/
/*  Polled character I/O functions for console and KGDB  */
/*********************************************************/

struct zschan *
zs_get_chan_addr(int zs_unit, int channel)
{
#if 0
	static int dumped_addr = 0;
#endif
	struct zsdevice *addr = NULL;
	struct zschan *zc;

	switch (sys_config.system_type) {
	case SGI_IP20:
		switch (zs_unit) {
		case 0:
			addr = (struct zsdevice *)
			    PHYS_TO_XKPHYS(0x1fb80d00, CCA_NC);
			break;
		case 1:
			addr = (struct zsdevice *)
			    PHYS_TO_XKPHYS(0x1fb80d10, CCA_NC);
			break;
		}
		break;

	case SGI_IP22:
	case SGI_IP26:
	case SGI_IP28:
		if (zs_unit == 0)
			addr = (struct zsdevice *)
			    PHYS_TO_XKPHYS(0x1fbd9830, CCA_NC);
		break;
	}
	if (addr == NULL)
		panic("zs_get_chan_addr: bad zs_unit %d\n", zs_unit);

	/*
	 * We need to swap serial ports to match reality on
	 * non-keyboard channels.
	 */
	if (sys_config.system_type != SGI_IP20) {
		if (channel == 0)
			zc = &addr->zs_chan_b;
		else
			zc = &addr->zs_chan_a;
	} else {
		if (zs_unit == 0) {
			if (channel == 0)
				zc = &addr->zs_chan_a;
			else
				zc = &addr->zs_chan_b;
		} else {
			if (channel == 0)
				zc = &addr->zs_chan_b;
			else
				zc = &addr->zs_chan_a;
		}
	}

#if 0
	if (dumped_addr == 0) {
		dumped_addr++;
		printf("zs unit %d, channel %d had address %p\n",
		    zs_unit, channel, zc);
	}
#endif

	return (zc);
}

int
zs_getc(void *arg)
{
	register volatile struct zschan *zc = arg;
	register int s, c, rr0;

	s = splzs();
	/* Wait for a character to arrive. */
	do {
		rr0 = zc->zc_csr;
		ZS_DELAY();
	} while ((rr0 & ZSRR0_RX_READY) == 0);

	c = zc->zc_data;
	ZS_DELAY();
	splx(s);

	return (c);
}

/*
 * Polled output char.
 */
void
zs_putc(void *arg, int c)
{
	register volatile struct zschan *zc = arg;
	register int s, rr0;

	s = splzs();
	/* Wait for transmitter to become ready. */
	do {
		rr0 = zc->zc_csr;
		ZS_DELAY();
	} while ((rr0 & ZSRR0_TX_READY) == 0);

	zc->zc_data = c;

	/* inline bus_space_barrier() */
	mips_sync();
	if (sys_config.system_type != SGI_IP20) {
		(void)*(volatile uint32_t *)PHYS_TO_XKPHYS(HPC_BASE_ADDRESS_0 +
		    HPC3_INTRSTAT_40, CCA_NC);
	}

	ZS_DELAY();
	splx(s);
}

/***************************************************************/

static int  cons_port;

void
zscnprobe(struct consdev *cp)
{
	cp->cn_dev = makedev(zs_major, 0);
	cp->cn_pri = CN_DEAD;

	switch (sys_config.system_type) {
	case SGI_IP20:
	case SGI_IP22:
	case SGI_IP26:
	case SGI_IP28:
		if (strlen(bios_console) == 9 &&
		    strncmp(bios_console, "serial", 6) == 0)
			cp->cn_pri = CN_FORCED;
		else
			cp->cn_pri = CN_MIDPRI;
		break;
	}
}

void
zscninit(struct consdev *cn)
{
	if (strlen(bios_console) == 9 &&
	    strncmp(bios_console, "serial", 6) != 0)
		cons_port = bios_console[7] - '0';

	/* Mark this unit as the console */
	zs_consunit = 0;

	/* SGI hardware wires serial port 1 to channel B, port 2 to A */
	if (cons_port == 0)
		zs_conschan = 1;
	else
		zs_conschan = 0;
}

int
zscngetc(dev_t dev)
{
	struct zschan *zs;

	switch (sys_config.system_type) {
	case SGI_IP20:
		zs = zs_get_chan_addr(1, cons_port);
		break;
	case SGI_IP22:
	case SGI_IP26:
	case SGI_IP28:
	default:
		zs = zs_get_chan_addr(0, cons_port);
		break;
	}

	return zs_getc(zs);
}

void
zscnputc(dev_t dev, int c)
{
	struct zschan *zs;

	switch (sys_config.system_type) {
	case SGI_IP20:
		zs = zs_get_chan_addr(1, cons_port);
		break;
	case SGI_IP22:
	case SGI_IP26:
	case SGI_IP28:
	default:
		zs = zs_get_chan_addr(0, cons_port);
		break;
	}

	zs_putc(zs, c);
}

void
zscnpollc(dev_t dev, int on)
{
}


code: src/sys/arch/sgi/include

path: sys/arch/sgi/include/CVS/Repository


code:
/*	$OpenBSD: _float.h,v 1.1 2012/06/26 16:12:44 deraadt Exp $ */

#include <mips64/_float.h>


code:
/*	$OpenBSD: _types.h,v 1.3 2007/05/15 15:23:36 art Exp $ */

/* public domain */
#include <mips64/_types.h>


code:
/*	$OpenBSD: asm.h,v 1.5 2012/06/17 12:34:19 miod Exp $ */
#ifndef	_SGI_ASM_H_
#define	_SGI_ASM_H_

#include <mips64/asm.h>
#ifdef TGT_OCTANE
#include <sgi/sgi/ip30.h>
#endif

#ifdef MULTIPROCESSOR

#ifdef TGT_OCTANE
#include <sgi/xbow/xheartreg.h>

/* Returns the physical cpu identifier */
#define HW_GET_CPU_PRID(prid, tmp)				\
	LOAD_XKPHYS(tmp, CCA_NC);				\
	PTR_L	prid, (HEART_PIU_BASE + HEART_PRID)(tmp)	\

/* Return the cpu_info pointer - see locore.S for the logic behind this */
#define HW_GET_CPU_INFO(ci, tmp)			\
	HW_GET_CPU_PRID(ci, tmp);			\
	LOAD_XKPHYS(tmp, CCA_COHERENT_EXCLWRITE);	\
	PTR_SLL	ci, MPCONF_SHIFT;			\
	PTR_ADD	ci, MPCONF_BASE;			\
	or	tmp, ci;				\
	PTR_L	ci, (MPCONF_LEN - REGSZ)(tmp)
#endif

#endif

#endif	/* _SGI_ASM_H_ */


code:
/*	$OpenBSD: atomic.h,v 1.3 2011/03/23 16:54:36 pirofti Exp $	*/

/* Public Domain */

#ifndef _MACHINE_ATOMIC_H_
#define _MACHINE_ATOMIC_H_

#include <mips64/atomic.h>

#endif /* _MACHINE_ATOMIC_H_ */


code:
/*	$OpenBSD: autoconf.h,v 1.38 2012/06/24 16:26:04 miod Exp $ */

/*
 * Copyright (c) 2001-2003 Opsycon AB  (www.opsycon.se / www.opsycon.com)
 *
 * 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 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 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.
 *
 */

/*
 * Definitions used by autoconfiguration.
 */

#ifndef _MACHINE_AUTOCONF_H_
#define _MACHINE_AUTOCONF_H_

#include <machine/bus.h>

/*
 * Structure holding all misc config information.
 */
struct cpu_info;

struct sys_rec {
	int	system_type;
	int	system_subtype;		/* IP35 only */

	/* Serial console configuration. */
	struct mips_bus_space console_io;
};

extern struct sys_rec sys_config;

/*
 * Attachment information for mainbus child devices.
 */
struct mainbus_attach_args {
	const char	*maa_name;
	int16_t		 maa_nasid;
};

/*
 * Device physical location information.  Used to match console and boot
 * devices on IP27 and IP30 kernels.
 */
struct sgi_device_location {
	int16_t		nasid;		/* node identifier */
	uint		widget;		/* widget number */

	int		bus;		/* bus number if connected to PIC */
	int		device;		/* device number if PCI */
	int		fn;		/* function number if PCI */

	uint32_t	specific;	/* port on dual-scsibus controllers,
					   device id on serial controllers */
};

#include <mips64/autoconf.h>

void	enaddr_aton(const char *, u_int8_t *);
u_long	bios_getenvint(const char *);

struct device;

void	arcs_device_register(struct device *, void *);
void	dksc_device_register(struct device *, void *);
extern	void (*_device_register)(struct device *, void *);

void	ip22_setup(void);
void	ip22_post_autoconf(void);
void	ip27_setup(void);
void	ip27_autoconf(struct device *);
void	ip30_setup(void);
void	ip30_autoconf(struct device *);
void	ip32_setup(void);

extern char osloadpartition[256];
extern char osloadoptions[129];
extern int16_t masternasid;
extern int16_t currentnasid;

extern struct sgi_device_location console_output, console_input;

int	location_match(struct sgi_device_location *,
	    struct sgi_device_location *);

extern void (*md_halt)(int);
void	arcbios_halt(int);

#endif /* _MACHINE_AUTOCONF_H_ */


code:
/*	$OpenBSD: bus.h,v 1.26 2014/03/10 21:32:15 miod Exp $	*/

/*
 * Copyright (c) 2003-2004 Opsycon AB Sweden.  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 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 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.
 */

#ifndef _MACHINE_BUS_H_
#define _MACHINE_BUS_H_

#ifdef __STDC__
#define CAT(a,b)	a##b
#define CAT3(a,b,c)	a##b##c
#else
#define CAT(a,b)	a/**/b
#define CAT3(a,b,c)	a/**/b/**/c
#endif

/*
 * Bus access types.
 */
struct mips_bus_space;
typedef u_long bus_addr_t;
typedef u_long bus_size_t;
typedef u_long bus_space_handle_t;
typedef struct mips_bus_space *bus_space_tag_t;
typedef struct mips_bus_space bus_space_t;

struct mips_bus_space {
	bus_addr_t	bus_base;
	void		*bus_private;
	u_int8_t	(*_space_read_1)(bus_space_tag_t , bus_space_handle_t,
			  bus_size_t);
	void		(*_space_write_1)(bus_space_tag_t , bus_space_handle_t,
			  bus_size_t, u_int8_t);
	u_int16_t	(*_space_read_2)(bus_space_tag_t , bus_space_handle_t,
			  bus_size_t);
	void		(*_space_write_2)(bus_space_tag_t , bus_space_handle_t,
			  bus_size_t, u_int16_t);
	u_int32_t	(*_space_read_4)(bus_space_tag_t , bus_space_handle_t,
			  bus_size_t);
	void		(*_space_write_4)(bus_space_tag_t , bus_space_handle_t,
			  bus_size_t, u_int32_t);
	u_int64_t	(*_space_read_8)(bus_space_tag_t , bus_space_handle_t,
			  bus_size_t);
	void		(*_space_write_8)(bus_space_tag_t , bus_space_handle_t,
			  bus_size_t, u_int64_t);
	void		(*_space_read_raw_2)(bus_space_tag_t, bus_space_handle_t,
			  bus_addr_t, u_int8_t *, bus_size_t);
	void		(*_space_write_raw_2)(bus_space_tag_t, bus_space_handle_t,
			  bus_addr_t, const u_int8_t *, bus_size_t);
	void		(*_space_read_raw_4)(bus_space_tag_t, bus_space_handle_t,
			  bus_addr_t, u_int8_t *, bus_size_t);
	void		(*_space_write_raw_4)(bus_space_tag_t, bus_space_handle_t,
			  bus_addr_t, const u_int8_t *, bus_size_t);
	void		(*_space_read_raw_8)(bus_space_tag_t, bus_space_handle_t,
			  bus_addr_t, u_int8_t *, bus_size_t);
	void		(*_space_write_raw_8)(bus_space_tag_t, bus_space_handle_t,
			  bus_addr_t, const u_int8_t *, bus_size_t);
	int		(*_space_map)(bus_space_tag_t , bus_addr_t,
			  bus_size_t, int, bus_space_handle_t *);
	void		(*_space_unmap)(bus_space_tag_t, bus_space_handle_t,
			  bus_size_t);
	int		(*_space_subregion)(bus_space_tag_t, bus_space_handle_t,
			  bus_size_t, bus_size_t, bus_space_handle_t *);
	void *		(*_space_vaddr)(bus_space_tag_t, bus_space_handle_t);
	void		(*_space_barrier)(bus_space_tag_t, bus_space_handle_t,
			  bus_size_t, bus_size_t, int);
};

#define	bus_space_read_1(t, h, o) (*(t)->_space_read_1)((t), (h), (o))
#define	bus_space_read_2(t, h, o) (*(t)->_space_read_2)((t), (h), (o))
#define	bus_space_read_4(t, h, o) (*(t)->_space_read_4)((t), (h), (o))
#define	bus_space_read_8(t, h, o) (*(t)->_space_read_8)((t), (h), (o))

#define	bus_space_write_1(t, h, o, v) (*(t)->_space_write_1)((t), (h), (o), (v))
#define	bus_space_write_2(t, h, o, v) (*(t)->_space_write_2)((t), (h), (o), (v))
#define	bus_space_write_4(t, h, o, v) (*(t)->_space_write_4)((t), (h), (o), (v))
#define	bus_space_write_8(t, h, o, v) (*(t)->_space_write_8)((t), (h), (o), (v))

#define	bus_space_read_raw_multi_2(t, h, a, b, l) \
	(*(t)->_space_read_raw_2)((t), (h), (a), (b), (l))
#define	bus_space_read_raw_multi_4(t, h, a, b, l) \
	(*(t)->_space_read_raw_4)((t), (h), (a), (b), (l))
#define	bus_space_read_raw_multi_8(t, h, a, b, l) \
	(*(t)->_space_read_raw_8)((t), (h), (a), (b), (l))

#define	bus_space_write_raw_multi_2(t, h, a, b, l) \
	(*(t)->_space_write_raw_2)((t), (h), (a), (b), (l))
#define	bus_space_write_raw_multi_4(t, h, a, b, l) \
	(*(t)->_space_write_raw_4)((t), (h), (a), (b), (l))
#define	bus_space_write_raw_multi_8(t, h, a, b, l) \
	(*(t)->_space_write_raw_8)((t), (h), (a), (b), (l))

#define	bus_space_map(t, o, s, c, p) (*(t)->_space_map)((t), (o), (s), (c), (p))
#define	bus_space_unmap(t, h, s) (*(t)->_space_unmap)((t), (h), (s))
#define	bus_space_subregion(t, h, o, s, p) \
    (*(t)->_space_subregion)((t), (h), (o), (s), (p))

#define	BUS_SPACE_MAP_CACHEABLE		0x01
#define	BUS_SPACE_MAP_LINEAR		0x02
#define	BUS_SPACE_MAP_PREFETCHABLE	0x04

#define	bus_space_vaddr(t, h)	(*(t)->_space_vaddr)((t), (h))

/*----------------------------------------------------------------------------*/
#define bus_space_read_multi(n,m)					      \
static __inline void							      \
CAT(bus_space_read_multi_,n)(bus_space_tag_t bst, bus_space_handle_t bsh,     \
     bus_size_t o, CAT3(u_int,m,_t) *x, size_t cnt)			      \
{									      \
	while (cnt--)							      \
		*x++ = CAT(bus_space_read_,n)(bst, bsh, o);		      \
}

bus_space_read_multi(1,8)
bus_space_read_multi(2,16)
bus_space_read_multi(4,32)
bus_space_read_multi(8,64)

/*----------------------------------------------------------------------------*/
#define bus_space_read_region(n,m)					      \
static __inline void							      \
CAT(bus_space_read_region_,n)(bus_space_tag_t bst, bus_space_handle_t bsh,    \
     bus_addr_t ba, CAT3(u_int,m,_t) *x, size_t cnt)			      \
{									      \
	while (cnt--)							      \
		*x++ = CAT(bus_space_read_,n)(bst, bsh, ba++);		      \
}

bus_space_read_region(1,8)
bus_space_read_region(2,16)
bus_space_read_region(4,32)
bus_space_read_region(8,64)

/*----------------------------------------------------------------------------*/
#define bus_space_read_raw_region(n,m)					      \
static __inline void							      \
CAT(bus_space_read_raw_region_,n)(bus_space_tag_t bst,			      \
     bus_space_handle_t bsh,						      \
     bus_addr_t ba, u_int8_t *x, size_t cnt)				      \
{									      \
	cnt >>= ((n) >> 1);						      \
	while (cnt--) {							      \
		CAT(bus_space_read_raw_multi_,n)(bst, bsh, ba, x, (n));	      \
		ba += (n);						      \
		x += (n);						      \
	}								      \
}

bus_space_read_raw_region(2,16)
bus_space_read_raw_region(4,32)
bus_space_read_raw_region(8,64)

/*----------------------------------------------------------------------------*/
#define bus_space_write_multi(n,m)					      \
static __inline void							      \
CAT(bus_space_write_multi_,n)(bus_space_tag_t bst, bus_space_handle_t bsh,    \
     bus_size_t o, const CAT3(u_int,m,_t) *x, size_t cnt)		      \
{									      \
	while (cnt--) {							      \
		CAT(bus_space_write_,n)(bst, bsh, o, *x++);		      \
	}								      \
}

bus_space_write_multi(1,8)
bus_space_write_multi(2,16)
bus_space_write_multi(4,32)
bus_space_write_multi(8,64)

/*----------------------------------------------------------------------------*/
#define bus_space_write_region(n,m)					      \
static __inline void							      \
CAT(bus_space_write_region_,n)(bus_space_tag_t bst, bus_space_handle_t bsh,   \
     bus_addr_t ba, const CAT3(u_int,m,_t) *x, size_t cnt)		      \
{									      \
	while (cnt--) {							      \
		CAT(bus_space_write_,n)(bst, bsh, ba, *x++);		      \
		ba += sizeof(x);					      \
	}								      \
}

bus_space_write_region(1,8)
bus_space_write_region(2,16)
bus_space_write_region(4,32)
bus_space_write_region(8,64)

/*----------------------------------------------------------------------------*/
#define bus_space_write_raw_region(n,m)					      \
static __inline void							      \
CAT(bus_space_write_raw_region_,n)(bus_space_tag_t bst,			      \
     bus_space_handle_t bsh,						      \
     bus_addr_t ba, const u_int8_t *x, size_t cnt)			      \
{									      \
	cnt >>= ((n) >> 1);						      \
	while (cnt--) {							      \
		CAT(bus_space_write_raw_multi_,n)(bst, bsh, ba, x, (n));      \
		ba += (n);						      \
		x += (n);						      \
	}								      \
}

bus_space_write_raw_region(2,16)
bus_space_write_raw_region(4,32)
bus_space_write_raw_region(8,64)

/*----------------------------------------------------------------------------*/
#define bus_space_set_region(n,m)					      \
static __inline void							      \
CAT(bus_space_set_region_,n)(bus_space_tag_t bst, bus_space_handle_t bsh,     \
     bus_addr_t ba, CAT3(u_int,m,_t) x, size_t cnt)			      \
{									      \
	while (cnt--) {							      \
		CAT(bus_space_write_,n)(bst, bsh, ba, x);		      \
		ba += sizeof(x);					      \
	}								      \
}

bus_space_set_region(1,8)
bus_space_set_region(2,16)
bus_space_set_region(4,32)
bus_space_set_region(8,64)

/*----------------------------------------------------------------------------*/
static __inline void
bus_space_copy_1(void *v, bus_space_handle_t h1, bus_size_t o1,
	bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
{
	char *s = (char *)(h1 + o1);
	char *d = (char *)(h2 + o2);

	while (c--)
		*d++ = *s++;
}

static __inline void
bus_space_copy_2(void *v, bus_space_handle_t h1, bus_size_t o1,
	bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
{
	short *s = (short *)(h1 + o1);
	short *d = (short *)(h2 + o2);

	while (c--)
		*d++ = *s++;
}

static __inline void
bus_space_copy_4(void *v, bus_space_handle_t h1, bus_size_t o1,
	bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
{
	int *s = (int *)(h1 + o1);
	int *d = (int *)(h2 + o2);

	while (c--)
		*d++ = *s++;
}

static __inline void
bus_space_copy_8(void *v, bus_space_handle_t h1, bus_size_t o1,
	bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
{
	int64_t *s = (int64_t *)(h1 + o1);
	int64_t *d = (int64_t *)(h2 + o2);

	while (c--)
		*d++ = *s++;
}

/*----------------------------------------------------------------------------*/
/*
 * Bus read/write barrier methods.
 *
 *	void bus_space_barrier(bus_space_tag_t tag,
 *	    bus_space_handle_t bsh, bus_size_t offset,
 *	    bus_size_t len, int flags);
 *
 */
static __inline void
bus_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t offs,
    bus_size_t len, int flags)
{
	(*(t)->_space_barrier)(t, h, offs, len, flags);
}

#define BUS_SPACE_BARRIER_READ  0x01		/* force read barrier */
#define BUS_SPACE_BARRIER_WRITE 0x02		/* force write barrier */

#define	BUS_DMA_WAITOK		0x0000
#define	BUS_DMA_NOWAIT		0x0001
#define	BUS_DMA_ALLOCNOW	0x0002
#define	BUS_DMA_COHERENT	0x0008
#define	BUS_DMA_BUS1		0x0010	/* placeholders for bus functions... */
#define	BUS_DMA_BUS2		0x0020
#define	BUS_DMA_BUS3		0x0040
#define	BUS_DMA_BUS4		0x0080
#define	BUS_DMA_READ		0x0100	/* mapping is device -> memory only */
#define	BUS_DMA_WRITE		0x0200	/* mapping is memory -> device only */
#define	BUS_DMA_STREAMING	0x0400	/* hint: sequential, unidirectional */
#define	BUS_DMA_ZERO		0x0800	/* zero memory in dmamem_alloc */
#define	BUS_DMA_NOCACHE		0x1000

/* Forwards needed by prototypes below. */
struct mbuf;
struct proc;
struct uio;

#define	BUS_DMASYNC_POSTREAD	0x0001
#define BUS_DMASYNC_POSTWRITE	0x0002
#define BUS_DMASYNC_PREREAD	0x0004
#define BUS_DMASYNC_PREWRITE	0x0008

typedef struct machine_bus_dma_tag	*bus_dma_tag_t;
typedef struct machine_bus_dmamap	*bus_dmamap_t;

/*
 *	bus_dma_segment_t
 *
 *	Describes a single contiguous DMA transaction.  Values
 *	are suitable for programming into DMA registers.
 */
struct machine_bus_dma_segment {
	bus_addr_t	ds_addr;	/* DMA address */
	bus_size_t	ds_len;		/* length of transfer */

	paddr_t		_ds_paddr;	/* CPU address */
	vaddr_t		_ds_vaddr;	/* CPU address */
};
typedef struct machine_bus_dma_segment	bus_dma_segment_t;

/*
 *	bus_dma_tag_t
 *
 *	A machine-dependent opaque type describing the implementation of
 *	DMA for a given bus.
 */

struct machine_bus_dma_tag {
	void	*_cookie;		/* cookie used in the guts */

	/*
	 * DMA mapping methods.
	 */
	int	(*_dmamap_create)(bus_dma_tag_t , bus_size_t, int,
		    bus_size_t, bus_size_t, int, bus_dmamap_t *);
	void	(*_dmamap_destroy)(bus_dma_tag_t , bus_dmamap_t);
	int	(*_dmamap_load)(bus_dma_tag_t , bus_dmamap_t, void *,
		    bus_size_t, struct proc *, int);
	int	(*_dmamap_load_mbuf)(bus_dma_tag_t , bus_dmamap_t,
		    struct mbuf *, int);
	int	(*_dmamap_load_uio)(bus_dma_tag_t , bus_dmamap_t,
		    struct uio *, int);
	int	(*_dmamap_load_raw)(bus_dma_tag_t , bus_dmamap_t,
		    bus_dma_segment_t *, int, bus_size_t, int);
	int	(*_dmamap_load_buffer)(bus_dma_tag_t, bus_dmamap_t, void *,
		    bus_size_t, struct proc *, int, paddr_t *, int *, int);
	void	(*_dmamap_unload)(bus_dma_tag_t , bus_dmamap_t);
	void	(*_dmamap_sync)(bus_dma_tag_t , bus_dmamap_t,
		    bus_addr_t, bus_size_t, int);

	/*
	 * DMA memory utility functions.
	 */
	int	(*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
		    bus_size_t, bus_dma_segment_t *, int, int *, int);
	void	(*_dmamem_free)(bus_dma_tag_t, bus_dma_segment_t *, int);
	int	(*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
		    int, size_t, caddr_t *, int);
	void	(*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t);
	paddr_t	(*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
		    int, off_t, int, int);

	/*
	 * internal memory address translation information.
	 */
	bus_addr_t (*_pa_to_device)(paddr_t);
	paddr_t	(*_device_to_pa)(bus_addr_t);
	bus_addr_t _dma_mask;
};

#define	bus_dmamap_create(t, s, n, m, b, f, p)			\
	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
#define	bus_dmamap_destroy(t, p)				\
	(*(t)->_dmamap_destroy)((t), (p))
#define	bus_dmamap_load(t, m, b, s, p, f)			\
	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
#define	bus_dmamap_load_mbuf(t, m, b, f)			\
	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
#define	bus_dmamap_load_uio(t, m, u, f)				\
	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
#define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
#define	bus_dmamap_unload(t, p)					\
	(*(t)->_dmamap_unload)((t), (p))
#define	bus_dmamap_sync(t, p, a, l, o)				\
	(void)((t)->_dmamap_sync ?				\
	    (*(t)->_dmamap_sync)((t), (p), (a), (l), (o)) : (void)0)

#define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
#define	bus_dmamem_free(t, sg, n)				\
	(*(t)->_dmamem_free)((t), (sg), (n))
#define	bus_dmamem_map(t, sg, n, s, k, f)			\
	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
#define	bus_dmamem_unmap(t, k, s)				\
	(*(t)->_dmamem_unmap)((t), (k), (s))
#define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))

int	_dmamap_create(bus_dma_tag_t, bus_size_t, int,
	    bus_size_t, bus_size_t, int, bus_dmamap_t *);
void	_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
int	_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
	    bus_size_t, struct proc *, int);
int	_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t, struct mbuf *, int);
int	_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t, struct uio *, int);
int	_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t,
	    bus_dma_segment_t *, int, bus_size_t, int);
int	_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *,
	    bus_size_t, struct proc *, int, paddr_t *, int *, int);
void	_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
void	_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
	    bus_size_t, int);

int	_dmamem_alloc(bus_dma_tag_t, bus_size_t, bus_size_t,
	    bus_size_t, bus_dma_segment_t *, int, int *, int);
void	_dmamem_free(bus_dma_tag_t, bus_dma_segment_t *, int);
int	_dmamem_map(bus_dma_tag_t, bus_dma_segment_t *,
	    int, size_t, caddr_t *, int);
void	_dmamem_unmap(bus_dma_tag_t, caddr_t, size_t);
paddr_t	_dmamem_mmap(bus_dma_tag_t, bus_dma_segment_t *, int, off_t, int, int);
int	_dmamem_alloc_range(bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t,
	    bus_dma_segment_t *, int, int *, int, paddr_t, paddr_t);

/*
 *	bus_dmamap_t
 *
 *	Describes a DMA mapping.
 */
struct machine_bus_dmamap {
	/*
	 * PRIVATE MEMBERS: not for use by machine-independent code.
	 */
	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
	int		_dm_segcnt;	/* number of segs this map can map */
	bus_size_t	_dm_maxsegsz;	/* largest possible segment */
	bus_size_t	_dm_boundary;	/* don't cross this */
	int		_dm_flags;	/* misc. flags */

	void		*_dm_cookie;	/* cookie for bus-specific functions */

	/*
	 * PUBLIC MEMBERS: these are used by machine-independent code.
	 */
	bus_size_t	dm_mapsize;	/* size of the mapping */
	int		dm_nsegs;	/* # valid segments in mapping */
	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
};

#endif /* _MACHINE_BUS_H_ */


code:
/*	$OpenBSD: cdefs.h,v 1.3 2013/03/28 17:30:45 martynas Exp $ */

/* Use Mips generic include file */

#include <mips64/cdefs.h>


code:
/*	$OpenBSD: conf.h,v 1.1 2009/08/09 21:07:22 miod Exp $	*/
/* public domain */
#include <sys/conf.h>


code:
/*	$OpenBSD: cpu.h,v 1.15 2014/03/09 10:12:17 miod Exp $ */
/*-
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Ralph Campbell and Rick Macklem.
 *
 * 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.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 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) 1989 Digital Equipment Corporation.
 *	Permission to use, copy, modify, and distribute this software and
 *	its documentation for any purpose and without fee is hereby granted,
 *	provided that the above copyright notice appears in all copies.
 *	Digital Equipment Corporation makes no representations about the
 *	suitability of this software for any purpose.  It is provided "as is"
 *	without express or implied warranty.
 *
 *	from: @(#)cpu.h	8.4 (Berkeley) 1/4/94
 */

#ifndef _MACHINE_CPU_H_
#define _MACHINE_CPU_H_

#ifdef _KERNEL
#if defined(MULTIPROCESSOR) && !defined(_LOCORE)
struct cpu_info;
struct cpu_info *hw_getcurcpu(void);
void hw_setcurcpu(struct cpu_info *);
void hw_cpu_boot_secondary(struct cpu_info *);
void hw_cpu_hatch(struct cpu_info *);
void hw_cpu_spinup_trampoline(struct cpu_info *);
int  hw_ipi_intr_establish(int (*)(void *), u_long);
void hw_ipi_intr_set(u_long);
void hw_ipi_intr_clear(u_long);
#endif	/* MULTIPROCESSOR && !_LOCORE */

#endif/* _KERNEL */

#include <mips64/cpu.h>

#endif /* !_MACHINE_CPU_H_ */


code:
/*	$OpenBSD: cpustate.h,v 1.1 2004/08/06 21:12:18 pefo Exp $ */

#include <mips64/cpustate.h>


code:
/*	$OpenBSD: db_machdep.h,v 1.1 2004/08/06 21:12:19 pefo Exp $ */

/* Use Mips generic include file */

#include <mips64/db_machdep.h>


code:
/*	$OpenBSD: disklabel.h,v 1.6 2008/08/08 16:07:41 jsing Exp $	*/

/*
 * Copyright (c) 1994 Christopher G. Demetriou
 * 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Christopher G. Demetriou.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * 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 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 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.
 */

#ifndef _MACHINE_DISKLABEL_H_
#define _MACHINE_DISKLABEL_H_

#define LABELSECTOR		1
#define LABELOFFSET		0
#define	MAXPARTITIONS		16		/* number of partitions */

/*
 * SGI Volume Header.
 */

#define SGILABEL_MAGIC  0xbe5a941
#define SGI_SIZE_VOLDIR 15

/* Partition types. */
#define SGI_PTYPE_VOLHDR        0
#define SGI_PTYPE_RAW           3
#define SGI_PTYPE_BSD           4
#define SGI_PTYPE_VOLUME        6
#define SGI_PTYPE_EFS           7
#define SGI_PTYPE_LVOL          8
#define SGI_PTYPE_RLVOL         9
#define SGI_PTYPE_XFS           10
#define SGI_PTYPE_XFSLOG        11
#define SGI_PTYPE_XLV           12
#define SGI_PTYPE_XVM           13

/* Device parameters. */
struct devparms {
        u_int8_t        dp_skew;
        u_int8_t        dp_gap1;
        u_int8_t        dp_gap2;
        u_int8_t        dp_spares_cyl;
        u_int16_t       dp_cyls;
        u_int16_t       dp_shd0;
        u_int16_t       dp_trks0;
        u_int8_t        dp_ctq_depth;
        u_int8_t        dp_cylshi;
        u_int16_t       dp_unused;
        u_int16_t       dp_secs;
        u_int16_t       dp_secbytes;
        u_int16_t       dp_interleave;
        u_int32_t       dp_flags;
        u_int32_t       dp_datarate;
        u_int32_t       dp_nretries;
        u_int32_t       dp_mspw;
        u_int16_t       dp_xgap1;
        u_int16_t       dp_xsync;
        u_int16_t       dp_xrdly;
        u_int16_t       dp_xgap2;
        u_int16_t       dp_xrgate;
        u_int16_t       dp_xwcont;
} __packed;

/* SGI volume header. */
struct sgilabel {
	u_int32_t       magic;
	int16_t         root;
	int16_t         swap;
	char            bootfile[16];
	struct devparms dp;
	struct {
		char	name[8];
		int32_t	block;
		int32_t	bytes;
	} voldir[SGI_SIZE_VOLDIR];
	struct {
		int32_t	blocks;
		int32_t	first;
		int32_t	type;
	} partitions[MAXPARTITIONS];
	int32_t         checksum;
	int32_t         _pad;
} __packed;

#endif /* _MACHINE_DISKLABEL_H_ */


code:
/*	$OpenBSD: eisa_machdep.h,v 1.1 2012/03/28 20:44:23 miod Exp $	*/
/*	$NetBSD: eisa_machdep.h,v 1.4 1997/06/06 23:12:52 thorpej Exp $	*/

/*
 * Copyright (c) 1996 Christopher G. Demetriou.  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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Christopher G. Demetriou
 *	for the NetBSD Project.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * 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 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 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.
 */

/*
 * Machine-specific definitions for EISA autoconfiguration.
 */

/*
 * EISA spaces memory layout
 */

#define	EISA_IO_BASE	0x00080000
#define	EISA_IO_END	0x00090000

#define	EISA_MEM0_BASE	0x00100000
#define	EISA_MEM0_END	0x08000000

#define	EISA_MEM1_BASE	0x80000000
#define	EISA_MEM1_END	0x100000000UL

/*
 * Types provided to machine-independent EISA code.
 */
typedef void *eisa_chipset_tag_t;
typedef int eisa_intr_handle_t;

/*
 * Functions provided to machine-independent EISA code.
 */
void		eisa_attach_hook(struct device *, struct device *,
		    struct eisabus_attach_args *);
int		eisa_maxslots(eisa_chipset_tag_t);
int		eisa_intr_map(eisa_chipset_tag_t, u_int,
		    eisa_intr_handle_t *);
const char	*eisa_intr_string(eisa_chipset_tag_t, eisa_intr_handle_t);
void		*eisa_intr_establish(eisa_chipset_tag_t, eisa_intr_handle_t,
		    int, int, int (*)(void *), void *, char *);
void		eisa_intr_disestablish(eisa_chipset_tag_t, void *);


code:
/*	$OpenBSD: endian.h,v 1.1 2004/08/06 21:12:19 pefo Exp $	*/

#include <mips64/endian.h>


code:
/*	$OpenBSD: exec.h,v 1.8 2004/10/18 19:05:36 grange Exp $	*/

#include <mips64/exec.h>


code:
/*	$OpenBSD: fenv.h,v 1.2 2013/06/01 21:20:54 jasper Exp $	*/
/* public domain */
#include <mips64/fenv.h>


code:
/* $OpenBSD: fpu.h,v 1.1 2010/09/17 00:34:08 miod Exp $ */
/* public domain */
#include <mips64/fpu.h>


code:
/*	$OpenBSD: frame.h,v 1.1 2004/08/06 21:12:19 pefo Exp $ */

/* Use Mips generic include file */

#include <mips64/frame.h>


code:
/*	$OpenBSD: ieee.h,v 1.1 2004/08/06 21:12:19 pefo Exp $ */

/* Use Mips generic include file */

#include <mips64/ieee.h>


code:
/*	$OpenBSD: ieeefp.h,v 1.1 2004/08/06 21:12:19 pefo Exp $ */

/* Use Mips generic include file */

#include <mips64/ieeefp.h>


code:
/*	$OpenBSD: intr.h,v 1.44 2015/07/08 13:37:31 dlg Exp $ */

/*
 * Copyright (c) 2001-2004 Opsycon AB  (www.opsycon.se / www.opsycon.com)
 *
 * 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 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 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.
 *
 */

#ifndef _MACHINE_INTR_H_
#define _MACHINE_INTR_H_

/*
 * The interrupt level ipl is a logical level; per-platform interrupt
 * code will turn it into the appropriate hardware interrupt masks
 * values.
 *
 * Interrupt sources on the CPU are kept enabled regardless of the
 * current ipl value; individual hardware sources interrupting while
 * logically masked are masked on the fly, remembered as pending, and
 * unmasked at the first splx() opportunity.
 *
 * An exception to this rule is the clock interrupt. Clock interrupts
 * are always allowed to happen, but will (of course!) not be serviced
 * if logically masked.  The reason for this is that clocks usually sit on
 * INT5 and cannot be easily masked if external hardware masking is used.
 */

/* Interrupt priority `levels'; not mutually exclusive. */
#define	IPL_NONE	0	/* nothing */
#define	IPL_SOFTINT	1	/* soft interrupts */
#define	IPL_BIO		2	/* block I/O */
#define IPL_AUDIO	IPL_BIO
#define	IPL_NET		3	/* network */
#define	IPL_TTY		4	/* terminal */
#define	IPL_VM		5	/* memory allocation */
#define	IPL_CLOCK	6	/* clock */
#define	IPL_SCHED	IPL_CLOCK
#define	IPL_HIGH	7	/* everything */
#define	IPL_IPI         8       /* interprocessor interrupt */
#define	NIPLS		9	/* Number of levels */

#define IPL_MPFLOOR	IPL_TTY

/* Interrupt priority 'flags'. */
#define	IPL_MPSAFE	0	/* no "mpsafe" interrupts */

/* Interrupt sharing types. */
#define	IST_NONE	0	/* none */
#define	IST_PULSE	1	/* pulsed */
#define	IST_EDGE	2	/* edge-triggered */
#define	IST_LEVEL	3	/* level-triggered */

#define	SINTBIT(q)	(q)
#define	SINTMASK(q)	(1 << SINTBIT(q))

/* Soft interrupt masks. */

#define	IPL_SOFT	0
#define	IPL_SOFTCLOCK	1
#define	IPL_SOFTNET	2
#define	IPL_SOFTTTY	3

#define	SI_SOFT		0	/* for IPL_SOFT */
#define	SI_SOFTCLOCK	1	/* for IPL_SOFTCLOCK */
#define	SI_SOFTNET	2	/* for IPL_SOFTNET */
#define	SI_SOFTTTY	3	/* for IPL_SOFTTTY */

#define	SI_NQUEUES	4

#ifndef _LOCORE

#include <machine/mutex.h>
#include <sys/queue.h>

struct soft_intrhand {
	TAILQ_ENTRY(soft_intrhand) sih_list;
	void	(*sih_func)(void *);
	void	*sih_arg;
	struct soft_intrq *sih_siq;
	int	sih_pending;
};

struct soft_intrq {
	TAILQ_HEAD(, soft_intrhand) siq_list;
	int siq_si;
	struct mutex siq_mtx;
};

void	 softintr_disestablish(void *);
void	 softintr_dispatch(int);
void	*softintr_establish(int, void (*)(void *), void *);
void	 softintr_init(void);
void	 softintr_schedule(void *);

#define	splsoft()	splraise(IPL_SOFTINT)
#define splbio()	splraise(IPL_BIO)
#define splnet()	splraise(IPL_NET)
#define spltty()	splraise(IPL_TTY)
#define splaudio()	splraise(IPL_AUDIO)
#define splvm()		splraise(IPL_VM)
#define splclock()	splraise(IPL_CLOCK)
#define splsched()	splraise(IPL_SCHED)
#define splhigh()	splraise(IPL_HIGH)

#define splsoftclock()	splsoft()
#define splsoftnet()	splsoft()
#define splstatclock()	splhigh()

#define spllock()	splhigh()
#define spl0()		spllower(0)

void	splinit(void);

#define	splassert(X)
#define	splsoftassert(X)

/* Inlines */
static __inline void register_splx_handler(void (*)(int));

typedef void (int_f)(int);
extern int_f *splx_hand;

static __inline void
register_splx_handler(void(*handler)(int))
{
	splx_hand = handler;
}

int	splraise(int);
void	splx(int);
int	spllower(int);

/*
 * Interrupt control struct used by interrupt dispatchers
 * to hold interrupt handler info.
 */

#include <sys/evcount.h>

struct intrhand {
	struct	intrhand	*ih_next;
	int			(*ih_fun)(void *);
	void			*ih_arg;
	int			 ih_level;
	int			 ih_irq;
	struct evcount		 ih_count;
	int			 ih_flags;
#define	IH_ALLOCATED		0x01
};

/*
 * Low level interrupt dispatcher registration data.
 */

/* Schedule priorities for base interrupts (CPU) */
#define	INTPRI_IPI	0
#define	INTPRI_CLOCK	1
/* other values are system-specific */

#define NLOWINT	16		/* Number of low level registrations possible */

extern uint32_t idle_mask;

struct trap_frame;
void	set_intr(int, uint32_t, uint32_t(*)(uint32_t, struct trap_frame *));

uint32_t updateimask(uint32_t);
void	dosoftint(void);

#ifdef MULTIPROCESSOR
#if defined (TGT_OCTANE)
#define ENABLEIPI() updateimask(~CR_INT_2) /* enable IPI interrupt level */
#else
#error MULTIPROCESSOR kernel not supported on this configuration
#endif
#endif

#endif /* _LOCORE */

#endif /* _MACHINE_INTR_H_ */


code:
/*	$OpenBSD: kcore.h,v 1.1 2004/08/06 21:12:19 pefo Exp $ */

/* Use Mips generic include file */

#include <mips64/kcore.h>


code:
/*	$OpenBSD: limits.h,v 1.1 2004/08/06 21:12:19 pefo Exp $ */

/* Use Mips generic include file */

#include <mips64/limits.h>


code:
/*	$OpenBSD: loadfile_machdep.h,v 1.5 2015/07/17 20:44:39 miod Exp $ */
/*	$NetBSD: loadfile_machdep.h,v 1.2 2001/10/31 17:20:49 thorpej Exp $	 */

/*-
 * Copyright (c) 1999 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Christos Zoulas.
 *
 * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``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 FOUNDATION OR CONTRIBUTORS
 * 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 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.
 */

#define BOOT_ELF
#define ELFSIZE	64

#define LOAD_KERNEL		LOAD_ALL
#define COUNT_KERNEL		COUNT_ALL

#define LOADADDR(a)		(((u_long)(a)) + offset)
#define ALIGNENTRY(a)		((u_long)(a))
#define READ(f, b, c)		read((f), (void *)LOADADDR(b), (c))
#define BCOPY(s, d, c)		memcpy((void *)LOADADDR(d), (void *)(s), (c))
#define BZERO(d, c)		memset((void *)LOADADDR(d), 0, (c))
#define	WARN(a)			(void)(printf a, \
				    printf((errno ? ": %s\n" : "\n"), \
				    strerror(errno)))
#define PROGRESS(a)		(void) printf a
#define ALLOC(a)		alloc(a)
#define FREE(a, b)		free(a, b)

extern int check_phdr(void *);
#define	CHECK_PHDR(sz,phdr)	check_phdr(phdr)


code:
/*	$OpenBSD: lock.h,v 1.1 2007/05/01 18:56:31 miod Exp $	*/
/* public domain */
#include <mips64/lock.h>


code:
/*	$OpenBSD: memconf.h,v 1.3 2011/03/23 16:54:36 pirofti Exp $ */

#ifndef	_MACHINE_MEMCONF_H_
#define	_MACHINE_MEMCONF_H_

#define	MAXMEMSEGS	32

#include <mips64/memconf.h>

#endif	/* _MACHINE_MEMCONF_H_ */


code:
/*	$OpenBSD: mips_opcode.h,v 1.1 2004/08/06 21:12:19 pefo Exp $ */

/* Use Mips generic include file */

#include <mips64/mips_opcode.h>