code:
/*	$OpenBSD: wdc_obio.c,v 1.30 2013/05/30 16:15:01 deraadt Exp $	*/
/*	$NetBSD: wdc_obio.c,v 1.15 2001/07/25 20:26:33 bouyer Exp $	*/

/*-
 * Copyright (c) 1998 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Charles M. Hannum and by Onno van der Linden.
 *
 * 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.
 */

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

#include <uvm/uvm_extern.h>

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

#include <dev/ofw/openfirm.h>
#include <dev/ata/atavar.h>
#include <dev/ata/atareg.h>
#include <dev/ic/wdcvar.h>

#include <macppc/dev/dbdma.h>

#define WDC_REG_NPORTS		8
#define WDC_AUXREG_OFFSET	0x16
#define WDC_DEFAULT_PIO_IRQ	13	/* XXX */
#define WDC_DEFAULT_DMA_IRQ	2	/* XXX */

#define WDC_OPTIONS_DMA 0x01

#define	WDC_DMALIST_MAX	32

struct wdc_obio_softc {
	struct wdc_softc sc_wdcdev;
	struct channel_softc *wdc_chanptr;
	struct channel_softc wdc_channel;

	bus_dma_tag_t sc_dmat;
	bus_dmamap_t sc_dmamap;
	dbdma_regmap_t *sc_dmareg;
	dbdma_command_t	*sc_dmacmd;
	dbdma_t sc_dbdma;

	void *sc_ih;
	int sc_use_dma;
	bus_size_t sc_cmdsize;
	size_t sc_dmasize;
};

u_int8_t wdc_obio_read_reg(struct channel_softc *, enum wdc_regs);
void wdc_obio_write_reg(struct channel_softc *, enum wdc_regs, u_int8_t);

struct channel_softc_vtbl wdc_obio_vtbl = {
	wdc_obio_read_reg,
	wdc_obio_write_reg,
	wdc_default_lba48_write_reg,
	wdc_default_read_raw_multi_2,
	wdc_default_write_raw_multi_2,
	wdc_default_read_raw_multi_4,
	wdc_default_write_raw_multi_4
};

int	wdc_obio_probe(struct device *, void *, void *);
void	wdc_obio_attach(struct device *, struct device *, void *);
int	wdc_obio_detach(struct device *, int);

struct cfattach wdc_obio_ca = {
	sizeof(struct wdc_obio_softc), wdc_obio_probe, wdc_obio_attach,
	wdc_obio_detach
};

int	wdc_obio_dma_init(void *, int, int, void *, size_t, int);
void	wdc_obio_dma_start(void *, int, int);
int	wdc_obio_dma_finish(void *, int, int, int);
void	wdc_obio_adjust_timing(struct channel_softc *);
void	wdc_obio_ata4_adjust_timing(struct channel_softc *);
void	wdc_obio_ata6_adjust_timing(struct channel_softc *);

int
wdc_obio_probe(struct device *parent, void *match, void *aux)
{
	struct confargs *ca = aux;
	char compat[32];

	if (ca->ca_nreg < 8)
		return 0;

	/* XXX should not use name */
	if (strcmp(ca->ca_name, "ATA") == 0 ||
	    strncmp(ca->ca_name, "ata", 3) == 0 ||
	    strcmp(ca->ca_name, "ide") == 0)
		return 1;

	bzero(compat, sizeof(compat));
	OF_getprop(ca->ca_node, "compatible", compat, sizeof(compat));
	if (strcmp(compat, "heathrow-ata") == 0 ||
	    strcmp(compat, "keylargo-ata") == 0)
		return 1;

	return 0;
}

void
wdc_obio_attach(struct device *parent, struct device *self, void *aux)
{
	struct wdc_obio_softc *sc = (void *)self;
	struct confargs *ca = aux;
	struct channel_softc *chp = &sc->wdc_channel;
	int intr, error;
	bus_addr_t cmdbase;

	sc->sc_use_dma = 0;
	if (ca->ca_nreg >= 16)
		sc->sc_use_dma = 1;	/* Enable dma */

	sc->sc_dmat = ca->ca_dmat;
	if ((error = bus_dmamap_create(sc->sc_dmat,
	    WDC_DMALIST_MAX * DBDMA_COUNT_MAX, WDC_DMALIST_MAX,
	    DBDMA_COUNT_MAX, NBPG, BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
		printf(": cannot create dma map, error = %d\n", error);
		return;
	}

	if (ca->ca_nintr >= 4 && ca->ca_nreg >= 8) {
		intr = ca->ca_intr[0];
		printf(" irq %d", intr);
	} else if (ca->ca_nintr == -1) {
		intr = WDC_DEFAULT_PIO_IRQ;
		printf(" irq property not found; using %d", intr);
	} else {
		printf(": couldn't get irq property\n");
		return;
	}

	if (sc->sc_use_dma)
		printf(": DMA");

	printf("\n");

	chp->cmd_iot = chp->ctl_iot = ca->ca_iot;
	chp->_vtbl = &wdc_obio_vtbl;

	cmdbase = ca->ca_reg[0];
	sc->sc_cmdsize = ca->ca_reg[1];

	if (bus_space_map(chp->cmd_iot, cmdbase, sc->sc_cmdsize, 0,
	    &chp->cmd_ioh) || bus_space_subregion(chp->cmd_iot, chp->cmd_ioh,
	    /* WDC_AUXREG_OFFSET<<4 */ 0x160, 1, &chp->ctl_ioh)) {
		printf("%s: couldn't map registers\n",
			sc->sc_wdcdev.sc_dev.dv_xname);
		return;
	}
	chp->data32iot = chp->cmd_iot;
	chp->data32ioh = chp->cmd_ioh;

	sc->sc_ih = mac_intr_establish(parent, intr, IST_LEVEL, IPL_BIO,
	    wdcintr, chp, sc->sc_wdcdev.sc_dev.dv_xname);

	sc->sc_wdcdev.set_modes = wdc_obio_adjust_timing;
	if (sc->sc_use_dma) {
		sc->sc_dbdma = dbdma_alloc(sc->sc_dmat, WDC_DMALIST_MAX + 1);
		sc->sc_dmacmd = sc->sc_dbdma->d_addr;

		sc->sc_dmareg = mapiodev(ca->ca_baseaddr + ca->ca_reg[2],
		    sc->sc_dmasize = ca->ca_reg[3]);

		sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA;
		sc->sc_wdcdev.DMA_cap = 2;
		if (strcmp(ca->ca_name, "ata-4") == 0) {
			sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA |
			    WDC_CAPABILITY_MODE;
			sc->sc_wdcdev.UDMA_cap = 4;
			sc->sc_wdcdev.set_modes = wdc_obio_ata4_adjust_timing;
		}
		if (strcmp(ca->ca_name, "ata-6") == 0) {
			sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA |
			    WDC_CAPABILITY_MODE;
			sc->sc_wdcdev.UDMA_cap = 5;
			sc->sc_wdcdev.set_modes = wdc_obio_ata6_adjust_timing;
		}
	}
	sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16;
	sc->sc_wdcdev.PIO_cap = 4;
	sc->wdc_chanptr = chp;
	sc->sc_wdcdev.channels = &sc->wdc_chanptr;
	sc->sc_wdcdev.nchannels = 1;
	sc->sc_wdcdev.dma_arg = sc;
	sc->sc_wdcdev.dma_init = wdc_obio_dma_init;
	sc->sc_wdcdev.dma_start = wdc_obio_dma_start;
	sc->sc_wdcdev.dma_finish = wdc_obio_dma_finish;
	chp->channel = 0;
	chp->wdc = &sc->sc_wdcdev;

	chp->ch_queue = wdc_alloc_queue();
	if (chp->ch_queue == NULL) {
		printf("%s: cannot allocate channel queue",
		sc->sc_wdcdev.sc_dev.dv_xname);
		return;
	}

	wdcattach(chp);
	sc->sc_wdcdev.set_modes(chp);
	wdc_print_current_modes(chp);
}

int
wdc_obio_detach(struct device *self, int flags)
{
	struct wdc_obio_softc *sc = (struct wdc_obio_softc *)self;
	struct channel_softc *chp = &sc->wdc_channel;
	int error;

	if ((error = wdcdetach(chp, flags)) != 0)
		return (error);

	wdc_free_queue(chp->ch_queue);

	if (sc->sc_use_dma) {
		unmapiodev((void *)sc->sc_dmareg, sc->sc_dmasize);
		dbdma_free(sc->sc_dbdma);
	}
	mac_intr_disestablish(NULL, sc->sc_ih);

	bus_space_unmap(chp->cmd_iot, chp->cmd_ioh, sc->sc_cmdsize);
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap);

	return (0);
}

/* Multiword DMA transfer timings */
struct ide_timings {
	int cycle;	/* minimum cycle time [ns] */
	int active;	/* minimum command active time [ns] */
};

static const struct ide_timings pio_timing[] = {
	{ 600, 165 },    /* Mode 0 */
	{ 383, 125 },    /*      1 */
	{ 240, 100 },    /*      2 */
	{ 180,  80 },    /*      3 */
	{ 120,  70 }     /*      4 */
};

static const struct ide_timings dma_timing[] = {
	{ 480, 215 },	/* Mode 0 */
	{ 150,  80 },	/* Mode 1 */
	{ 120,  70 },	/* Mode 2 */
};

static const struct ide_timings udma_timing[] = {
	{114,   0},     /* Mode 0 */
	{ 75,   0},     /* Mode 1 */
	{ 55,   0},     /* Mode 2 */
	{ 45, 100},     /* Mode 3 */
	{ 25, 100}      /* Mode 4 */
};

/* these number _guessed_ from linux driver. */
static u_int32_t kauai_pio_timing[] = {
	/*600*/	0x08000a92,	/* Mode 0 */
	/*360*/	0x08000492,	/* Mode 1 */
	/*240*/	0x0800038b,	/* Mode 2 */
	/*180*/	0x05000249,	/* Mode 3 */
	/*120*/	0x04000148	/* Mode 4 */

};
static u_int32_t kauai_dma_timing[] = {
	/*480*/	0x00618000,	/* Mode 0 */
	/*360*/	0x00492000,	/* Mode 1 */
	/*240*/	0x00149000	/* Mode 2 */ /* fw value */
};
static u_int32_t kauai_udma_timing[] = {
	/*120*/	0x000070c0,	/* Mode 0 */
	/* 90*/	0x00005d80,	/* Mode 1 */
	/* 60*/	0x00004a60,	/* Mode 2 */
	/* 45*/	0x00003a50,	/* Mode 3 */
	/* 30*/	0x00002a30,	/* Mode 4 */
	/* 20*/	0x00002921	/* Mode 5 */
};

#define	TIME_TO_TICK(time)	howmany((time), 30)
#define	PIO_REC_OFFSET	4
#define	PIO_REC_MIN	1
#define	PIO_ACT_MIN	1
#define	DMA_REC_OFFSET	1
#define	DMA_REC_MIN	1
#define	DMA_ACT_MIN	1

#define	ATA4_TIME_TO_TICK(time)	howmany((time) * 1000, 7500)

#define CONFIG_REG (0x200)		/* IDE access timing register */
#define KAUAI_ULTRA_CONFIG (0x210)	/* secondary config register (kauai)*/

#define KAUAI_PIO_MASK		0xff000fff
#define KAUAI_DMA_MASK		0x00fff000
#define KAUAI_UDMA_MASK		0x0000ffff
#define KAUAI_UDMA_EN		0x00000001

void
wdc_obio_adjust_timing(struct channel_softc *chp)
{
	struct ata_drive_datas *drvp;
	u_int conf;
	int drive;
	int piomode = -1, dmamode = -1;
	int min_cycle, min_active;
	int cycle_tick, act_tick, inact_tick, half_tick;

	for (drive = 0; drive < 2; drive++) {
		drvp = &chp->ch_drive[drive];
		if ((drvp->drive_flags & DRIVE) == 0)
			continue;
		if (piomode == -1 || piomode > drvp->PIO_mode)
			piomode = drvp->PIO_mode;
		if (drvp->drive_flags & DRIVE_DMA)
			if (dmamode == -1 || dmamode > drvp->DMA_mode)
				dmamode = drvp->DMA_mode;
	}
	if (piomode == -1)
		return; /* No drive */
	for (drive = 0; drive < 2; drive++) {
		drvp = &chp->ch_drive[drive];
		if (drvp->drive_flags & DRIVE) {
			drvp->PIO_mode = piomode;
			if (drvp->drive_flags & DRIVE_DMA)
				drvp->DMA_mode = dmamode;
		}
	}
	min_cycle = pio_timing[piomode].cycle;
	min_active = pio_timing[piomode].active;

	cycle_tick = TIME_TO_TICK(min_cycle);
	act_tick = TIME_TO_TICK(min_active);
	if (act_tick < PIO_ACT_MIN)
		act_tick = PIO_ACT_MIN;
	inact_tick = cycle_tick - act_tick - PIO_REC_OFFSET;
	if (inact_tick < PIO_REC_MIN)
		inact_tick = PIO_REC_MIN;
	/* mask: 0x000007ff */
	conf = (inact_tick << 5) | act_tick;
	if (dmamode != -1) {
		/* there are active DMA mode */

		min_cycle = dma_timing[dmamode].cycle;
		min_active = dma_timing[dmamode].active;
		cycle_tick = TIME_TO_TICK(min_cycle);
		act_tick = TIME_TO_TICK(min_active);
		inact_tick = cycle_tick - act_tick - DMA_REC_OFFSET;
		if (inact_tick < DMA_REC_MIN)
			inact_tick = DMA_REC_MIN;
		half_tick = 0;	/* XXX */
		/* mask: 0xfffff800 */
		conf |=
		    (half_tick << 21) |
		    (inact_tick << 16) | (act_tick << 11);
	}
	bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, CONFIG_REG, conf);
#if 0
	printf("conf = 0x%x, cyc = %d (%d ns), act = %d (%d ns), inact = %d\n",
	    conf, cycle_tick, min_cycle, act_tick, min_active, inact_tick);
#endif
}

void
wdc_obio_ata4_adjust_timing(struct channel_softc *chp)
{
	struct ata_drive_datas *drvp;
	u_int conf;
	int drive;
	int piomode = -1, dmamode = -1;
	int min_cycle, min_active;
	int cycle_tick, act_tick, inact_tick;
	int udmamode = -1;

	for (drive = 0; drive < 2; drive++) {
		drvp = &chp->ch_drive[drive];
		if ((drvp->drive_flags & DRIVE) == 0)
			continue;
		if (piomode == -1 || piomode > drvp->PIO_mode)
			piomode = drvp->PIO_mode;
		if (drvp->drive_flags & DRIVE_DMA)
			if (dmamode == -1 || dmamode > drvp->DMA_mode)
				dmamode = drvp->DMA_mode;
		if (drvp->drive_flags & DRIVE_UDMA) {
			if (udmamode == -1 || udmamode > drvp->UDMA_mode)
				udmamode = drvp->UDMA_mode;
		} else
			udmamode = -2;
	}
	if (piomode == -1)
		return; /* No drive */
	for (drive = 0; drive < 2; drive++) {
		drvp = &chp->ch_drive[drive];
		if (drvp->drive_flags & DRIVE) {
			drvp->PIO_mode = piomode;
			if (drvp->drive_flags & DRIVE_DMA)
				drvp->DMA_mode = dmamode;
			if (drvp->drive_flags & DRIVE_UDMA) {
				if (udmamode == -2)
					drvp->drive_flags &= ~DRIVE_UDMA;
				else
					drvp->UDMA_mode = udmamode;
			}
		}
	}

	if (udmamode == -2)
		udmamode = -1;

	min_cycle = pio_timing[piomode].cycle;
	min_active = pio_timing[piomode].active;

	cycle_tick = ATA4_TIME_TO_TICK(min_cycle);
	act_tick = ATA4_TIME_TO_TICK(min_active);
	inact_tick = cycle_tick - act_tick;
	/* mask: 0x000003ff */
	conf = (inact_tick << 5) | act_tick;
	if (dmamode != -1) {
		/* there are active  DMA mode */

		min_cycle = dma_timing[dmamode].cycle;
		min_active = dma_timing[dmamode].active;
		cycle_tick = ATA4_TIME_TO_TICK(min_cycle);
		act_tick = ATA4_TIME_TO_TICK(min_active);
		inact_tick = cycle_tick - act_tick;
		/* mask: 0x001ffc00 */
		conf |= (act_tick << 10) | (inact_tick << 15);
	}
	if (udmamode != -1) {
		min_cycle = udma_timing[udmamode].cycle;
		min_active = udma_timing[udmamode].active;
		act_tick = ATA4_TIME_TO_TICK(min_active);
		cycle_tick = ATA4_TIME_TO_TICK(min_cycle);
		/* mask: 0x1ff00000 */
		conf |= (cycle_tick << 21) | (act_tick << 25) | 0x100000;
	}

	bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, CONFIG_REG, conf);
#if 0
	printf("ata4 conf = 0x%x, cyc = %d (%d ns), act = %d (%d ns), inact = %d\n",
	    conf, cycle_tick, min_cycle, act_tick, min_active, inact_tick);
#endif
}

void
wdc_obio_ata6_adjust_timing(struct channel_softc *chp)
{
	struct ata_drive_datas *drvp;
	u_int conf, conf1;
	int drive;
	int piomode = -1, dmamode = -1;
	int udmamode = -1;

	for (drive = 0; drive < 2; drive++) {
		drvp = &chp->ch_drive[drive];
		if ((drvp->drive_flags & DRIVE) == 0)
			continue;
		if (piomode == -1 || piomode > drvp->PIO_mode)
			piomode = drvp->PIO_mode;
		if (drvp->drive_flags & DRIVE_DMA) {
			if (dmamode == -1 || dmamode > drvp->DMA_mode)
				dmamode = drvp->DMA_mode;
		}
		if (drvp->drive_flags & DRIVE_UDMA) {
			if (udmamode == -1 || udmamode > drvp->UDMA_mode)
				udmamode = drvp->UDMA_mode;
		} else
			udmamode = -2;
	}
	if (piomode == -1)
		return; /* No drive */
	for (drive = 0; drive < 2; drive++) {
		drvp = &chp->ch_drive[drive];
		if (drvp->drive_flags & DRIVE) {
			drvp->PIO_mode = piomode;
			if (drvp->drive_flags & DRIVE_DMA)
				drvp->DMA_mode = dmamode;
			if (drvp->drive_flags & DRIVE_UDMA) {
				if (udmamode == -2)
					drvp->drive_flags &= ~DRIVE_UDMA;
				else
					drvp->UDMA_mode = udmamode;
			}
		}
	}

	if (udmamode == -2)
		udmamode = -1;

	conf = bus_space_read_4(chp->cmd_iot, chp->cmd_ioh, CONFIG_REG);
	conf1 = bus_space_read_4(chp->cmd_iot, chp->cmd_ioh,
	    KAUAI_ULTRA_CONFIG);

	conf = (conf & ~KAUAI_PIO_MASK) | kauai_pio_timing[piomode];

	if (dmamode != -1)
		conf = (conf & ~KAUAI_DMA_MASK) | kauai_dma_timing[dmamode];
	if (udmamode != -1)
		conf1 = (conf1 & ~KAUAI_UDMA_MASK) |
		    kauai_udma_timing[udmamode] | KAUAI_UDMA_EN;
	else
		conf1 = conf1 & ~KAUAI_UDMA_EN;

	bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, CONFIG_REG, conf);
	bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, KAUAI_ULTRA_CONFIG,
	    conf1);
}

int
wdc_obio_dma_init(void *v, int channel, int drive, void *databuf,
    size_t datalen, int flags)
{
	struct wdc_obio_softc *sc = v;
	dbdma_command_t *cmdp;
	u_int cmd;
	int i, error;

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, databuf,
	    datalen, NULL, BUS_DMA_NOWAIT)) != 0)
		return (error);

	cmdp = sc->sc_dmacmd;
	cmd = (flags & WDC_DMA_READ) ? DBDMA_CMD_IN_MORE : DBDMA_CMD_OUT_MORE;

	for (i = 0; i < sc->sc_dmamap->dm_nsegs; i++, cmdp++) {
		if (i + 1 == sc->sc_dmamap->dm_nsegs)
			cmd = (flags & WDC_DMA_READ) ? DBDMA_CMD_IN_LAST :
			    DBDMA_CMD_OUT_LAST;

		DBDMA_BUILD(cmdp, cmd, 0, sc->sc_dmamap->dm_segs[i].ds_len,
		    sc->sc_dmamap->dm_segs[i].ds_addr,
		    DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
	}

	DBDMA_BUILD(cmdp, DBDMA_CMD_STOP, 0, 0, 0,
		DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);

	return 0;
}

void
wdc_obio_dma_start(void *v, int channel, int drive)
{
	struct wdc_obio_softc *sc = v;

	dbdma_start(sc->sc_dmareg, sc->sc_dbdma);
}

int
wdc_obio_dma_finish(void *v, int channel, int drive, int force)
{
	struct wdc_obio_softc *sc = v;

	dbdma_stop(sc->sc_dmareg);
	bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap);
	return 0;
}

/* read register code
 * this allows the registers to be spaced by 0x10, instead of 0x1.
 * mac hardware (obio) requires this.
 */

u_int8_t
wdc_obio_read_reg(struct channel_softc *chp, enum wdc_regs reg)
{
#ifdef DIAGNOSTIC
	if (reg & _WDC_WRONLY) {
		printf ("wdc_obio_read_reg: reading from a write-only register %d\n", reg);
	}
#endif

	if (reg & _WDC_AUX)
		return (bus_space_read_1(chp->ctl_iot, chp->ctl_ioh,
		    (reg & _WDC_REGMASK) << 4));
	else
		return (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
		    (reg & _WDC_REGMASK) << 4));
}

void
wdc_obio_write_reg(struct channel_softc *chp, enum wdc_regs reg, u_int8_t val)
{
#ifdef DIAGNOSTIC
	if (reg & _WDC_RDONLY) {
		printf ("wdc_obio_write_reg: writing to a read-only register %d\n", reg);
	}
#endif

	if (reg & _WDC_AUX)
		bus_space_write_1(chp->ctl_iot, chp->ctl_ioh,
		    (reg & _WDC_REGMASK) << 4, val);
	else
		bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
		    (reg & _WDC_REGMASK) << 4, val);
}


code:
/* $OpenBSD: xlights.c,v 1.7 2015/06/24 11:58:06 mpi Exp $ */
/*
 * Copyright (c) 2007 Gordon Willem Klok <gwk@openbsd,org>
 *
 * 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/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/device.h>
#include <sys/kthread.h>
#include <sys/timeout.h>
#include <dev/ofw/openfirm.h>

#include <machine/bus.h>
#include <machine/autoconf.h>
#include <macppc/dev/dbdma.h>
#include <macppc/dev/i2sreg.h>
#include <macppc/pci/macobio.h>

struct xlights_softc {
	struct device 			sc_dev;
	int				sc_node;
	int				sc_intr;
	uint32_t			sc_freq;
	int 				sc_dmasts;

	u_char				*sc_reg;
	dbdma_regmap_t 			*sc_dma;
	bus_dma_tag_t			sc_dmat;
	bus_dmamap_t			sc_bufmap;
	bus_dma_segment_t       	sc_bufseg[1];
	dbdma_t				sc_dbdma;
	dbdma_command_t			*sc_dmacmd;
	uint32_t			*sc_buf;
	uint32_t			*sc_bufpos;

	struct timeout 			sc_tmo;
};

int xlights_match(struct device *, void *, void *);
void xlights_attach(struct device *, struct device *, void *);
int xlights_intr(void *);
void xlights_startdma(struct xlights_softc *);
void xlights_deferred(void *);
void xlights_theosDOT(void *);
void xlights_timeout(void *);

struct cfattach xlights_ca = {
	sizeof(struct xlights_softc), xlights_match,
	xlights_attach
};

struct cfdriver xlights_cd = {
	NULL, "xlights", DV_DULL
};

#define BL_BUFSZ PAGE_SIZE
#define BL_DBDMA_CMDS 2

int
xlights_match(struct device *parent, void *arg, void *aux)
{
	struct confargs *ca = aux;
	int soundbus, soundchip, error;
	char compat[32];

	if (strcmp(ca->ca_name, "i2s") != 0)
		return 0;
	if ((soundbus = OF_child(ca->ca_node)) == 0)
		return 0;
	if ((soundchip = OF_child(soundbus)) == 0)
		return 0;

	error = OF_getprop(soundchip, "virtual", compat, sizeof(compat));
	if (error == -1) {
		error = OF_getprop(soundchip, "name", compat,
		    sizeof(compat));

		if (error == -1 || (strcmp(compat, "lightshow")) != 0)
			return 0;
	}

	/* we require at least 4 registers */
	if (ca->ca_nreg / sizeof(int) < 4)
		return 0;
	/* we require at least 3 interrupts */
	if (ca->ca_nintr / sizeof(int) < 6)
		return 0;

	return 1;
}

void
xlights_attach(struct device *parent, struct device *self, void *aux)
{
	struct xlights_softc *sc = (struct xlights_softc *)self;
	struct confargs *ca = aux;
	int nseg, error, intr[6];
	u_int32_t reg[4];
	int type;

	sc->sc_node = OF_child(ca->ca_node);

	OF_getprop(sc->sc_node, "reg", reg, sizeof(reg));
	ca->ca_reg[0] += ca->ca_baseaddr;
	ca->ca_reg[2] += ca->ca_baseaddr;

	if ((sc->sc_reg = mapiodev(ca->ca_reg[0], ca->ca_reg[1])) == NULL) {
		printf(": cannot map registers\n");
		return;
	}
	sc->sc_dmat = ca->ca_dmat;

	if ((sc->sc_dma = mapiodev(ca->ca_reg[2], ca->ca_reg[3])) == NULL) {
		printf(": cannot map DMA registers\n");
		goto nodma;
	}

	if ((sc->sc_dbdma = dbdma_alloc(sc->sc_dmat, BL_DBDMA_CMDS)) == NULL) {
		printf(": cannot alloc DMA descriptors\n");
		goto nodbdma;
	 }
	sc->sc_dmacmd = sc->sc_dbdma->d_addr;

	if ((error = bus_dmamem_alloc(sc->sc_dmat, BL_BUFSZ, 0, 0,
		sc->sc_bufseg, 1, &nseg, BUS_DMA_NOWAIT))) {
		printf(": cannot allocate DMA mem (%d)\n", error);
		goto nodmamem;
	}

	if ((error = bus_dmamem_map(sc->sc_dmat, sc->sc_bufseg, nseg,
	    BL_BUFSZ, (caddr_t *)&sc->sc_buf, BUS_DMA_NOWAIT))) {
		printf(": cannot map DMA mem (%d)\n", error);
		goto nodmamap;
	}
	sc->sc_bufpos = sc->sc_buf;

	if ((error = bus_dmamap_create(sc->sc_dmat, BL_BUFSZ, 1, BL_BUFSZ, 0,
	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_bufmap))) {
		printf(": cannot create DMA map (%d)\n", error);
		goto nodmacreate;
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_bufmap, sc->sc_buf,
	    BL_BUFSZ, NULL, BUS_DMA_NOWAIT))) {
		printf(": cannot load DMA map (%d)\n", error);
		goto nodmaload;
	}
	/* XXX: Should probably extract this from the clock data
	 * property of the soundchip node */
	sc->sc_freq = 16384;

	OF_getprop(sc->sc_node, "interrupts", intr, sizeof(intr));
	/* output interrupt */
	sc->sc_intr = intr[2];
	type = intr[3] ? IST_LEVEL : IST_EDGE;

	printf(": irq %d\n", sc->sc_intr);

	macobio_enable(I2SClockOffset, I2S0EN);
	out32rb(sc->sc_reg + I2S_INT, I2S_INT_CLKSTOPPEND);
	macobio_disable(I2SClockOffset, I2S0CLKEN);
	for (error = 0; error < 1000; error++) {
		if (in32rb(sc->sc_reg + I2S_INT) & I2S_INT_CLKSTOPPEND) {
			error = 0;
			break;
		}
		delay(1);
	}
	if (error) {
		printf("%s: i2s timeout\n", sc->sc_dev.dv_xname);
		goto nodmaload;
	}

	mac_intr_establish(parent, sc->sc_intr, intr[3] ? IST_LEVEL :
	    type, IPL_TTY, xlights_intr, sc, sc->sc_dev.dv_xname);

	out32rb(sc->sc_reg + I2S_FORMAT, CLKSRC_VS);
	macobio_enable(I2SClockOffset, I2S0CLKEN);

	kthread_create_deferred(xlights_deferred, sc);
	timeout_set(&sc->sc_tmo, xlights_timeout, sc);
	return;
nodmaload:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_bufmap);
nodmacreate:
	bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_buf, BL_BUFSZ);
nodmamap:
	bus_dmamem_free(sc->sc_dmat, sc->sc_bufseg, nseg);
nodmamem:
	dbdma_free(sc->sc_dbdma);
nodbdma:
	unmapiodev((void *)sc->sc_dma, ca->ca_reg[3]);
nodma:
	unmapiodev(sc->sc_reg, ca->ca_reg[1]);
}

void
xlights_deferred(void *v)
{
	struct xlights_softc *sc = (struct xlights_softc *)v;

	kthread_create(xlights_theosDOT, v, NULL, sc->sc_dev.dv_xname);
}

/*
 * xserv has two rows of leds laid out as follows
 *	25 26 27 28 29 30 31 00
 *	17 18 19 20 21 22 23 24
 */

char ledfollow_0[16] = {	25, 26, 27, 28, 29, 30, 31, 00,
				24, 23, 22, 21, 20, 19, 18, 17 };
char ledfollow_1[16] = {	17, 25, 26, 27, 28, 29, 30, 31,
				00, 24, 23, 22, 21, 20, 19, 18 };
char ledfollow_2[16] = {	18, 17, 25, 26, 27, 28, 29, 30,
				31, 00, 24, 23, 22, 21, 20, 19 };
void
xlights_theosDOT(void *v)
{
	struct xlights_softc *sc = (struct xlights_softc *)v;
	uint32_t *p;
	int k, nsamp;
	int ledpos, ledpos_high, ledpos_med, ledpos_dim;
	uint32_t val;

	while (1) {
		/*
		 * ldavg 0  - .5 sec ->  (8192 / 16)
		 * ldavg 1  - 1 sec ->   (16384 / 16)
		 * ldavg 2  - 1.5 sec -> (24576 / 16)
		 */
		nsamp = sc->sc_freq +
		    sc->sc_freq / FSCALE * averunnable.ldavg[0];
		nsamp /= 16; /* scale, per led */
		nsamp /= 4; /* scale, why?, sizeof(uint32_t)? */
		for (ledpos = 0; ledpos < 16; ledpos++) {
			ledpos_high	= ledfollow_0[ledpos];
			ledpos_med	= ledfollow_1[ledpos];
			ledpos_dim	= ledfollow_2[ledpos];
			p = sc->sc_bufpos;

			for (k = 0; k < nsamp;) {
				if (p - sc->sc_buf <
				    BL_BUFSZ / sizeof(uint32_t)) {
					val =  (1 << ledpos_high);
					if ((k % 4) == 0)
						val |=  (1 << ledpos_med);
					if ((k % 16) == 0)
						val |=  (1 << ledpos_dim);
					*p = val;

					p++;
					k++;
				} else {
					xlights_startdma(sc);
					while (sc->sc_dmasts)
						tsleep(sc->sc_buf, PWAIT,
						    "blinken", 0);
					p = sc->sc_buf;
				}
			}
			sc->sc_bufpos = p;
		}
	}
}

void
xlights_startdma(struct xlights_softc *sc)
{
	dbdma_command_t *cmdp = sc->sc_dmacmd;

	sc->sc_dmasts = 1;
	timeout_add(&sc->sc_tmo, 250);

	DBDMA_BUILD(cmdp, DBDMA_CMD_OUT_LAST, 0,
	    sc->sc_bufmap->dm_segs[0].ds_len,
	    sc->sc_bufmap->dm_segs[0].ds_addr, DBDMA_INT_ALWAYS,
	    DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
	cmdp++;

	DBDMA_BUILD(cmdp, DBDMA_CMD_STOP, 0, 0, 0, DBDMA_INT_NEVER,
	    DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);

	dbdma_start(sc->sc_dma, sc->sc_dbdma);
}

void
xlights_timeout(void *v)
{
	struct xlights_softc *sc = (struct xlights_softc *)v;

	dbdma_reset(sc->sc_dma);
	timeout_del(&sc->sc_tmo);
	sc->sc_dmasts = 0;
	wakeup(sc->sc_buf);
}

int
xlights_intr(void *v)
{
	struct xlights_softc *sc = (struct xlights_softc *)v;
	int status;
	dbdma_command_t *cmd;

	cmd = sc->sc_dmacmd;
	status = dbdma_ld16(&cmd->d_status);
	if (sc->sc_dmasts) {
		sc->sc_dmasts = 0;
		timeout_del(&sc->sc_tmo);
		wakeup(sc->sc_buf);
		return (1);
	}
	return (0);
}

license: unknown


code:
/*	$OpenBSD: zs.c,v 1.24 2015/05/07 02:17:16 jsg Exp $	*/
/*	$NetBSD: zs.c,v 1.17 2001/06/19 13:42:15 wiz Exp $	*/

/*
 * Copyright (c) 1996, 1998 Bill Studenmund
 * Copyright (c) 1995 Gordon W. Ross
 * 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.
 * 4. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Gordon Ross
 *
 * 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.
 */

/*
 * 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.
 * Sun keyboard/mouse uses the zskbd/zsms slaves.
 * Other ports use their own mice & keyboard slaves.
 *
 * Credits & history:
 *
 * With NetBSD 1.1, port-mac68k started using a port of the port-sparc
 * (port-sun3?) zs.c driver (which was in turn based on code in the
 * Berkeley 4.4 Lite release). Bill Studenmund did the port, with
 * help from Allen Briggs and Gordon Ross <gwr@netbsd.org>. Noud de
 * Brouwer field-tested the driver at a local ISP.
 *
 * Bill Studenmund and Gordon Ross then ported the machine-independent
 * z8530 driver to work with port-mac68k. NetBSD 1.2 contained an
 * intermediate version (mac68k using a local, patched version of
 * the m.i. drivers), with NetBSD 1.3 containing a full version.
 */

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

#include <dev/cons.h>
#include <dev/ofw/openfirm.h>
#include <dev/ic/z8530reg.h>

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

#include "zsc.h"	/* get the # of zs chips defined */

/*
 * Some warts needed by z8530tty.c -
 */
int zs_def_cflag = (CREAD | CS8 | HUPCL);
int zs_major = 7;

struct zsdevice {
	/* Yes, they are backwards. */
	struct	zschan zs_chan_b;
	struct	zschan zs_chan_a;
};

/* Flags from cninit() */
static int zs_hwflags[NZSC][2];
/* Default speed for each channel */
static int zs_defspeed[NZSC][2] = {
	{ 38400,	/* tty00 */
	  38400 },	/* tty01 */
};

/* console stuff */
void	*zs_conschan = 0;
#ifdef	ZS_CONSOLE_ABORT
int	zs_cons_canabort = 1;
#else
int	zs_cons_canabort = 0;
#endif /* ZS_CONSOLE_ABORT*/

/* device to which the console is attached--if serial. */
/* Mac stuff */

int zs_get_speed(struct zs_chanstate *);

/*
 * Even though zsparam will set up the clock multiples, etc., we
 * still set them here as: 1) mice & keyboards don't use zsparam,
 * and 2) the console stuff uses these defaults before device
 * attach.
 */

static u_char zs_init_reg[16] = {
	0,	/* 0: CMD (reset, etc.) */
	ZSWR1_RIE | ZSWR1_TIE | ZSWR1_SIE, 	/* 1: No interrupts yet. ??? */
	0,	/* IVECT */
	ZSWR3_RX_8 | ZSWR3_RX_ENABLE,
	ZSWR4_CLK_X16 | ZSWR4_ONESB | ZSWR4_EVENP,
	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,
	((PCLK/32)/38400)-2,	/*12: BAUDLO (default=38400) */
	0,			/*13: BAUDHI (default=38400) */
	ZSWR14_BAUD_ENA,
	ZSWR15_BREAK_IE,
};

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

struct cfdriver zsc_cd = {
	NULL, "zsc", DV_TTY
};

/* Definition of the driver for autoconfig. */
int	zsc_match(struct device *, void *, void *);
void	zsc_attach(struct device *, struct device *, void *);
int	zsc_print(void *, const char *name);

/* Power management hooks */
int  zs_enable (struct zs_chanstate *);
void zs_disable (struct zs_chanstate *);

struct cfattach zsc_ca = {
	sizeof(struct zsc_softc), zsc_match, zsc_attach
};

int zshard(void *);
void zssoft(void *);
#ifdef ZS_TXDMA
int zs_txdma_int(void *);
#endif

/*
 * Is the zs chip present?
 */
int
zsc_match(struct device *parent, void *match, void *aux)
{
	struct confargs *ca = aux;
	struct cfdata *cf = match;

	if (strcmp(ca->ca_name, "escc") != 0)
		return 0;

	if (ca->ca_nreg < 8)
		return 0;

	if (cf->cf_unit > 1)
		return 0;

	return 1;
}

/*
 * Attach a found zs.
 *
 * Match slave number to zs unit number, so that misconfiguration will
 * not set up the keyboard as ttya, etc.
 */
void
zsc_attach(struct device *parent, struct device *self, void *aux)
{
	struct zsc_softc *zsc = (void *)self;
	struct confargs *ca = aux;
	struct zsc_attach_args zsc_args;
	volatile struct zschan *zc;
	struct xzs_chanstate *xcs;
	struct zs_chanstate *cs;
	struct zsdevice *zsd;
	int zsc_unit, channel;
	int s;
	int node, intr[3][3];
	u_int regs[16];

	zsc_unit = zsc->zsc_dev.dv_unit;

	zsd = mapiodev(ca->ca_baseaddr + ca->ca_reg[0], ca->ca_reg[1]);
	node = OF_child(ca->ca_node);	/* ch-a */

	for (channel = 0; channel < 2; channel++) {
		if (OF_getprop(node, "AAPL,interrupts",
			       intr[channel], sizeof(intr[0])) == -1 &&
		    OF_getprop(node, "interrupts",
			       intr[channel], sizeof(intr[0])) == -1) {
			printf(": cannot find interrupt property\n");
			return;
		}

		if (OF_getprop(node, "reg", regs, sizeof(regs)) < 24) {
			printf(": cannot find reg property\n");
			return;
		}
		regs[2] += ca->ca_baseaddr;
		regs[4] += ca->ca_baseaddr;
#ifdef ZS_TXDMA
		zsc->zsc_txdmareg[channel] = mapiodev(regs[2], regs[3]);
		zsc->zsc_txdmacmd[channel] =
			dbdma_alloc(sizeof(dbdma_command_t) * 3);
		memset(zsc->zsc_txdmacmd[channel], 0,
			sizeof(dbdma_command_t) * 3);
		dbdma_reset(zsc->zsc_txdmareg[channel]);
#endif
		node = OF_peer(node);	/* ch-b */
	}

	printf(": irq %d,%d\n", intr[0][0], intr[1][0]);

	/*
	 * Initialize software state for each channel.
	 */
	for (channel = 0; channel < 2; channel++) {
		zsc_args.channel = channel;
		zsc_args.hwflags = zs_hwflags[zsc_unit][channel];
		xcs = &zsc->xzsc_xcs_store[channel];
		cs  = &xcs->xzs_cs;
		zsc->zsc_cs[channel] = cs;

		cs->cs_channel = channel;
		cs->cs_private = NULL;
		cs->cs_ops = &zsops_null;

		zc = (channel == 0) ? &zsd->zs_chan_a : &zsd->zs_chan_b;

		cs->cs_reg_csr  = &zc->zc_csr;
		cs->cs_reg_data = &zc->zc_data;

		memcpy(cs->cs_creg, zs_init_reg, 16);
		memcpy(cs->cs_preg, zs_init_reg, 16);

		/* Current BAUD rate generator clock. */
		/* RTxC is 230400*16, so use 230400 */
		cs->cs_brg_clk = PCLK / 16;
		if (zsc_args.hwflags & ZS_HWFLAG_CONSOLE)
			cs->cs_defspeed = zs_get_speed(cs);
		else
			cs->cs_defspeed =
			    zs_defspeed[zsc_unit][channel];
		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;
		cs->cs_wr5_rts = 0;

#ifdef __notyet__
		cs->cs_slave_type = ZS_SLAVE_NONE;
#endif

		/* Define BAUD rate stuff. */
		xcs->cs_clocks[0].clk = PCLK;
		xcs->cs_clocks[0].flags = ZSC_RTXBRG | ZSC_RTXDIV;
		xcs->cs_clocks[1].flags =
			ZSC_RTXBRG | ZSC_RTXDIV | ZSC_VARIABLE | ZSC_EXTERN;
		xcs->cs_clocks[2].flags = ZSC_TRXDIV | ZSC_VARIABLE;
		xcs->cs_clock_count = 3;
		if (channel == 0) {
			/*xcs->cs_clocks[1].clk = mac68k_machine.modem_dcd_clk;*/
			/*xcs->cs_clocks[2].clk = mac68k_machine.modem_cts_clk;*/
			xcs->cs_clocks[1].clk = 0;
			xcs->cs_clocks[2].clk = 0;
		} else {
			xcs->cs_clocks[1].flags = ZSC_VARIABLE;
			/*
			 * Yes, we aren't defining ANY clock source enables for the
			 * printer's DCD clock in. The hardware won't let us
			 * use it. But a clock will freak out the chip, so we
			 * let you set it, telling us to bar interrupts on the line.
			 */
			/*xcs->cs_clocks[1].clk = mac68k_machine.print_dcd_clk;*/
			/*xcs->cs_clocks[2].clk = mac68k_machine.print_cts_clk;*/
			xcs->cs_clocks[1].clk = 0;
			xcs->cs_clocks[2].clk = 0;
		}
		if (xcs->cs_clocks[1].clk)
			zsc_args.hwflags |= ZS_HWFLAG_NO_DCD;
		if (xcs->cs_clocks[2].clk)
			zsc_args.hwflags |= ZS_HWFLAG_NO_CTS;

		/* Set defaults in our "extended" chanstate. */
		xcs->cs_csource = 0;
		xcs->cs_psource = 0;
		xcs->cs_cclk_flag = 0;  /* Nothing fancy by default */
		xcs->cs_pclk_flag = 0;

		/*
		 * We used to disable chip interrupts here, but we now
		 * do that in zscnprobe, just in case MacOS left the chip on.
		 */

		xcs->cs_chip = 0;

		/* Stash away a copy of the final H/W flags. */
		xcs->cs_hwflags = zsc_args.hwflags;

		/*
		 * Look for a child driver for this channel.
		 * The child attach will setup the hardware.
		 */
		if (!config_found(self, (void *)&zsc_args, zsc_print)) {
			/* No sub-driver.  Just reset it. */
			u_char reset = (channel == 0) ?
				ZSWR9_A_RESET : ZSWR9_B_RESET;
			s = splzs();
			zs_write_reg(cs, 9, reset);
			splx(s);
		}
	}

	/* XXX - Now safe to install interrupt handlers. */
	mac_intr_establish(parent, intr[0][0], IST_LEVEL, IPL_TTY,
	    zshard, NULL, "zs0");
	mac_intr_establish(parent, intr[1][0], IST_LEVEL, IPL_TTY,
	    zshard, NULL, "zs1");
#ifdef ZS_TXDMA
	mac_intr_establish(parent, intr[0][1], IST_LEVEL, IPL_TTY,
	    zs_txdma_int, (void *)0, "zsdma0");
	mac_intr_establish(parent, intr[1][1], IST_LEVEL, IPL_TTY,
	    zs_txdma_int, (void *)1, "zsdma1");
#endif
	zsc->zsc_softintr = softintr_establish(IPL_SOFTTTY, zssoft, zsc);
	if (zsc->zsc_softintr == NULL)
		panic("zsattach: could not establish soft interrupt");

	/*
	 * Set the master interrupt enable and interrupt vector.
	 * (common to both channels, do it on A)
	 */
	cs = zsc->zsc_cs[0];
	s = splzs();
	/* 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);

	/* connect power management for port 0 */
	cs->enable = zs_enable;
	cs->disable = zs_disable;
}

int
zsc_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;
}

int
zsmdioctl(struct zs_chanstate *cs, u_long cmd, caddr_t data)
{
	switch (cmd) {
	default:
		return (-1);
	}
	return (0);
}

void
zsmd_setclock(struct zs_chanstate *cs)
{
#ifdef NOTYET
	struct xzs_chanstate *xcs = (void *)cs;

	if (cs->cs_channel != 0)
		return;

	/*
	 * If the new clock has the external bit set, then select the
	 * external source.
	 */
	via_set_modem((xcs->cs_pclk_flag & ZSC_EXTERN) ? 1 : 0);
#endif
}

static int zssoftpending;

/*
 * 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;
	int unit, rval;

	rval = 0;
	for (unit = 0; unit < zsc_cd.cd_ndevs; unit++) {
		zsc = zsc_cd.cd_devs[unit];
		if (zsc == NULL)
			continue;
		rval |= zsc_intr_hard(zsc);
		if (zsc->zsc_cs[0]->cs_softreq)
		{
			/* zsc_req_softint(zsc); */
			/* We are at splzs here, so no need to lock. */
			if (zssoftpending == 0) {
				zssoftpending = 1;
				softintr_schedule(zsc->zsc_softintr);
			}
		}
	}
	return (rval);
}

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

	/* This is not the only ISR on this IPL. */
	if (zssoftpending == 0)
		return;

	/*
	 * The soft intr. bit will be set by zshard only if
	 * the variable zssoftpending is zero.
	 */
	zssoftpending = 0;

	for (unit = 0; unit < zsc_cd.cd_ndevs; ++unit) {
		zsc = zsc_cd.cd_devs[unit];
		if (zsc == NULL)
			continue;
		(void) zsc_intr_soft(zsc);
	}
}

#ifdef ZS_TXDMA
int
zs_txdma_int(arg)
	void *arg;
{
	int ch = (int)arg;
	struct zsc_softc *zsc;
	struct zs_chanstate *cs;
	int unit = 0;			/* XXX */
	extern int zstty_txdma_int();

	zsc = zsc_cd.cd_devs[unit];
	if (zsc == NULL)
		panic("zs_txdma_int");

	cs = zsc->zsc_cs[ch];
	zstty_txdma_int(cs);

	if (cs->cs_softreq) {
		if (zssoftpending == 0) {
			zssoftpending = 1;
			softintr_schedule(zsc->zsc_softintr);
		}
	}
	return 1;
}

void
zs_dma_setup(cs, pa, len)
	struct zs_chanstate *cs;
	caddr_t pa;
	int len;
{
	struct zsc_softc *zsc;
	dbdma_command_t *cmdp;
	int ch = cs->cs_channel;

	zsc = zsc_cd.cd_devs[ch];
	cmdp = zsc->zsc_txdmacmd[ch];

	DBDMA_BUILD(cmdp, DBDMA_CMD_OUT_LAST, 0, len, kvtop(pa),
		DBDMA_INT_ALWAYS, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);
	cmdp++;
	DBDMA_BUILD(cmdp, DBDMA_CMD_STOP, 0, 0, 0,
		DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER);

	__asm volatile("eieio");

	dbdma_start(zsc->zsc_txdmareg[ch], zsc->zsc_txdmacmd[ch]);
}
#endif

/*
 * Compute the current baud rate given a ZS channel.
 * XXX Assume internal BRG.
 */
int
zs_get_speed(cs)
	struct zs_chanstate *cs;
{
	int tconst;

	tconst = zs_read_reg(cs, 12);
	tconst |= zs_read_reg(cs, 13) << 8;
	return TCONST_TO_BPS(cs->cs_brg_clk, tconst);
}

#ifndef ZS_TOLERANCE
#define ZS_TOLERANCE 51
/* 5% in tenths of a %, plus 1 so that exactly 5% will be ok. */
#endif

/*
 * Search through the signal sources in the channel, and
 * pick the best one for the baud rate requested. Return
 * a -1 if not achievable in tolerance. Otherwise return 0
 * and fill in the values.
 *
 * This routine draws inspiration from the Atari port's zs.c
 * driver in NetBSD 1.1 which did the same type of source switching.
 * Tolerance code inspired by comspeed routine in isa/com.c.
 *
 * By Bill Studenmund, 1996-05-12
 */
int
zs_set_speed(cs, bps)
	struct zs_chanstate *cs;
	int bps;	/* bits per second */
{
	struct xzs_chanstate *xcs = (void *)cs;
	int i, tc, tc0 = 0, tc1, s, sf = 0;
	int src, rate0, rate1, err, tol;

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

	src = -1;		/* no valid source yet */
	tol = ZS_TOLERANCE;

	/*
	 * Step through all the sources and see which one matches
	 * the best. A source has to match BETTER than tol to be chosen.
	 * Thus if two sources give the same error, the first one will be
	 * chosen. Also, allow for the possability that one source might run
	 * both the BRG and the direct divider (i.e. RTxC).
	 */
	for (i = 0; i < xcs->cs_clock_count; i++) {
		if (xcs->cs_clocks[i].clk <= 0)
			continue;	/* skip non-existent or bad clocks */
		if (xcs->cs_clocks[i].flags & ZSC_BRG) {
			/* check out BRG at /16 */
			tc1 = BPS_TO_TCONST(xcs->cs_clocks[i].clk >> 4, bps);
			if (tc1 >= 0) {
				rate1 = TCONST_TO_BPS(xcs->cs_clocks[i].clk >> 4, tc1);
				err = abs(((rate1 - bps)*1000)/bps);
				if (err < tol) {
					tol = err;
					src = i;
					sf = xcs->cs_clocks[i].flags & ~ZSC_DIV;
					tc0 = tc1;
					rate0 = rate1;
				}
			}
		}
		if (xcs->cs_clocks[i].flags & ZSC_DIV) {
			/*
			 * Check out either /1, /16, /32, or /64
			 * Note: for /1, you'd better be using a synchronized
			 * clock!
			 */
			int b0 = xcs->cs_clocks[i].clk, e0 = abs(b0-bps);
			int b1 = b0 >> 4, e1 = abs(b1-bps);
			int b2 = b1 >> 1, e2 = abs(b2-bps);
			int b3 = b2 >> 1, e3 = abs(b3-bps);

			if (e0 < e1 && e0 < e2 && e0 < e3) {
				err = e0;
				rate1 = b0;
				tc1 = ZSWR4_CLK_X1;
			} else if (e0 > e1 && e1 < e2  && e1 < e3) {
				err = e1;
				rate1 = b1;
				tc1 = ZSWR4_CLK_X16;
			} else if (e0 > e2 && e1 > e2 && e2 < e3) {
				err = e2;
				rate1 = b2;
				tc1 = ZSWR4_CLK_X32;
			} else {
				err = e3;
				rate1 = b3;
				tc1 = ZSWR4_CLK_X64;
			}

			err = (err * 1000)/bps;
			if (err < tol) {
				tol = err;
				src = i;
				sf = xcs->cs_clocks[i].flags & ~ZSC_BRG;
				tc0 = tc1;
				rate0 = rate1;
			}
		}
	}
#ifdef ZSMACDEBUG
	printf("Checking for rate %d. Found source #%d.\n",bps, src);
#endif
	if (src == -1)
		return (EINVAL); /* no can do */

	/*
	 * The M.I. layer likes to keep cs_brg_clk current, even though
	 * we are the only ones who should be touching the BRG's rate.
	 *
	 * Note: we are assuming that any ZSC_EXTERN signal source comes in
	 * on the RTxC pin. Correct for the mac68k obio zsc.
	 */
	if (sf & ZSC_EXTERN)
		cs->cs_brg_clk = xcs->cs_clocks[i].clk >> 4;
	else
		cs->cs_brg_clk = PCLK / 16;

	/*
	 * Now we have a source, so set it up.
	 */
	s = splzs();
	xcs->cs_psource = src;
	xcs->cs_pclk_flag = sf;
	bps = rate0;
	if (sf & ZSC_BRG) {
		cs->cs_preg[4] = ZSWR4_CLK_X16;
		cs->cs_preg[11]= ZSWR11_RXCLK_BAUD | ZSWR11_TXCLK_BAUD;
		if (sf & ZSC_PCLK) {
			cs->cs_preg[14] = ZSWR14_BAUD_ENA | ZSWR14_BAUD_FROM_PCLK;
		} else {
			cs->cs_preg[14] = ZSWR14_BAUD_ENA;
		}
		tc = tc0;
	} else {
		cs->cs_preg[4] = tc0;
		if (sf & ZSC_RTXDIV) {
			cs->cs_preg[11] = ZSWR11_RXCLK_RTXC | ZSWR11_TXCLK_RTXC;
		} else {
			cs->cs_preg[11] = ZSWR11_RXCLK_TRXC | ZSWR11_TXCLK_TRXC;
		}
		cs->cs_preg[14]= 0;
		tc = 0xffff;
	}
	/* Set the BAUD rate divisor. */
	cs->cs_preg[12] = tc;
	cs->cs_preg[13] = tc >> 8;
	splx(s);

#ifdef ZSMACDEBUG
	printf("Rate is %7d, tc is %7d, source no. %2d, flags %4x\n", \
	    bps, tc, src, sf);
	printf("Registers are: 4 %x, 11 %x, 14 %x\n\n",
		cs->cs_preg[4], cs->cs_preg[11], cs->cs_preg[14]);
#endif

	cs->cs_preg[5] |= ZSWR5_RTS;	/* Make sure the drivers are on! */

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

int
zs_set_modes(cs, cflag)
	struct zs_chanstate *cs;
	int cflag;
{
	struct xzs_chanstate *xcs = (void*)cs;
	int s;

	/*
	 * Make sure we don't enable hfc on a signal line we're ignoring.
	 * As we enable CTS interrupts only if we have CRTSCTS or CDTRCTS,
	 * this code also effectivly turns off ZSWR15_CTS_IE.
	 *
	 * Also, disable DCD interrupts if we've been told to ignore
	 * the DCD pin. Happens on mac68k because the input line for
	 * DCD can also be used as a clock input.  (Just set CLOCAL.)
	 *
	 * If someone tries to turn an invalid flow mode on, Just Say No
	 * (Suggested by gwr)
	 */
	if (xcs->cs_hwflags & ZS_HWFLAG_NO_DCD) {
		if (cflag & MDMBUF)
			return (EINVAL);
		cflag |= CLOCAL;
	}
#if 0
	if ((xcs->cs_hwflags & ZS_HWFLAG_NO_CTS) && (cflag & CRTSCTS))
		return (EINVAL);
#endif

	/*
	 * Output hardware flow control on the chip is horrendous:
	 * if carrier detect drops, the receiver is disabled, and if
	 * CTS drops, the transmitter is stopped IN MID CHARACTER!
	 * Therefore, NEVER set the HFC bit, and instead use the
	 * status interrupt to detect CTS changes.
	 */
	s = splzs();
	if ((cflag & (CLOCAL | MDMBUF)) != 0)
		cs->cs_rr0_dcd = 0;
	else
		cs->cs_rr0_dcd = ZSRR0_DCD;
	/*
	 * The mac hardware only has one output, DTR (HSKo in Mac
	 * parlance). In HFC mode, we use it for the functions
	 * typically served by RTS and DTR on other ports, so we
	 * have to fake the upper layer out some.
	 *
	 * CRTSCTS we use CTS as an input which tells us when to shut up.
	 * We make no effort to shut up the other side of the connection.
	 * DTR is used to hang up the modem.
	 *
	 * In CDTRCTS, we use CTS to tell us to stop, but we use DTR to
	 * shut up the other side.
	 */
	if ((cflag & CRTSCTS) != 0) {
		cs->cs_wr5_dtr = ZSWR5_DTR;
		cs->cs_wr5_rts = 0;
		cs->cs_rr0_cts = ZSRR0_CTS;
#if 0
	} else if ((cflag & CDTRCTS) != 0) {
		cs->cs_wr5_dtr = 0;
		cs->cs_wr5_rts = ZSWR5_DTR;
		cs->cs_rr0_cts = ZSRR0_CTS;
#endif
	} 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;
		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.
 * MacII hardware has the delay built in.
 * No need for extra delay. :-) However, some clock-chirped
 * macs, or zsc's on serial add-on boards might need it.
 */
#define	ZS_DELAY()

u_char
zs_read_reg(cs, reg)
	struct zs_chanstate *cs;
	u_char reg;
{
	u_char val;

	out8(cs->cs_reg_csr, reg);
	ZS_DELAY();
	val = in8(cs->cs_reg_csr);
	ZS_DELAY();
	return val;
}

void
zs_write_reg(cs, reg, val)
	struct zs_chanstate *cs;
	u_char reg, val;
{
	out8(cs->cs_reg_csr, reg);
	ZS_DELAY();
	out8(cs->cs_reg_csr, val);
	ZS_DELAY();
}

u_char
zs_read_csr(cs)
	struct zs_chanstate *cs;
{
	u_char val;

	val = in8(cs->cs_reg_csr);
	ZS_DELAY();
	/* make up for the fact CTS is wired backwards */
	val ^= ZSRR0_CTS;
	return val;
}

void
zs_write_csr(cs, val)
	struct zs_chanstate *cs;
	u_char val;
{
	/* Note, the csr does not write CTS... */
	out8(cs->cs_reg_csr, val);
	ZS_DELAY();
}

u_char
zs_read_data(cs)
	struct zs_chanstate *cs;
{
	u_char val;

	val = in8(cs->cs_reg_data);
	ZS_DELAY();
	return val;
}

void
zs_write_data(cs, val)
	struct zs_chanstate *cs;
	u_char val;
{
	out8(cs->cs_reg_data, val);
	ZS_DELAY();
}

/*
 * Power management hooks for zsopen() and zsclose().
 * We use them to power on/off the ports, if necessary.
 * This should be modified to turn on/off modem in PBG4, etc.
 */
void macobio_modem_power(int enable);

int
zs_enable(cs)
	struct zs_chanstate *cs;
{
	macobio_modem_power(1); /* Whee */
	cs->enabled = 1;
	return(0);
}

void
zs_disable(cs)
	struct zs_chanstate *cs;
{
	macobio_modem_power(0); /* Whee */
	cs->enabled = 0;
}

/****************************************************************
 * Console support functions (powermac specific!)
 * Note: this code is allowed to know about the layout of
 * the chip registers, and uses that to keep things simple.
 * XXX - I think I like the mvme167 code better. -gwr
 * XXX - Well :-P  :-)  -wrs
 ****************************************************************/

cons_decl(zs);

void	zs_putc(volatile struct zschan *, int);
int	zs_getc(volatile struct zschan *);
extern int	zsopen( dev_t dev, int flags, int mode, struct proc *p);

static int stdin, stdout;

/*
 * Console functions.
 */

/*
 * zscnprobe is the routine which gets called as the kernel is trying to
 * figure out where the console should be. Each io driver which might
 * be the console (as defined in mac68k/conf.c) gets probed. The probe
 * fills in the consdev structure. Important parts are the device #,
 * and the console priority. Values are CN_DEAD (don't touch me),
 * CN_LOWPRI (I'm here, but elsewhere might be better), CN_MIDPRI
 * (the video, better than CN_LOWPRI), and CN_HIGHPRI (pick me!)
 *
 * As the mac's a bit different, we do extra work here. We mainly check
 * to see if we have serial echo going on. Also chould check for default
 * speeds.
 */

/*
 * Polled input char.
 */
int
zs_getc(zc)
	register volatile struct zschan *zc;
{
	register int s, c, rr0;

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

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

	return (c);
}

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

	s = splhigh();
	/* Wait for transmitter to become ready. */
	do {
		rr0 = in8(&zc->zc_csr);
		ZS_DELAY();
	} while (((rr0 & ZSRR0_TX_READY) == 0) && (wait++ < 1000000));

	if ((rr0 & ZSRR0_TX_READY) != 0) {
		out8(&zc->zc_data, c);
		ZS_DELAY();
	}
	splx(s);
}

/*
 * Polled console input putchar.
 */
int
zscngetc(dev)
	dev_t dev;
{
	register volatile struct zschan *zc = zs_conschan;
	register int c;

	if (zc) {
		c = zs_getc(zc);
	} else {
		char ch = 0;
		OF_read(stdin, &ch, 1);
		c = ch;
	}
	return c;
}

/*
 * Polled console output putchar.
 */
void
zscnputc(dev, c)
	dev_t dev;
	int c;
{
	register volatile struct zschan *zc = zs_conschan;

	if (zc) {
		zs_putc(zc, c);
	} else {
		char ch = c;
		OF_write(stdout, &ch, 1);
	}
}

void
zscnprobe(cp)
	struct consdev *cp;
{
	int chosen, pkg;
	int unit = 0;
	int maj;
	char name[16];

	if ((chosen = OF_finddevice("/chosen")) == -1)
		return;

	if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) == -1)
		return;
	if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) == -1)
		return;

	if ((pkg = OF_instance_to_package(stdin)) == -1)
		return;

	bzero(name, sizeof(name));
	if (OF_getprop(pkg, "device_type", name, sizeof(name)) == -1)
		return;

	if (strcmp(name, "serial") != 0)
		return;

	bzero(name, sizeof(name));
	if (OF_getprop(pkg, "name", name, sizeof(name)) == -1)
		return;

	if (strcmp(name, "ch-b") == 0)
		unit = 1;

	/* locate the major number */
	for (maj = 0; maj < nchrdev; maj++)
		if (cdevsw[maj].d_open == zsopen)
			break;

	cp->cn_dev = makedev(maj, unit);
	cp->cn_pri = CN_HIGHPRI;
}

void
zscninit(cp)
	struct consdev *cp;
{
	int escc, escc_ch, obio;
	unsigned int zs_offset, zs_size;
	int ch = 0;
	u_int32_t reg[5];
	char name[16];

	if ((escc_ch = OF_instance_to_package(stdin)) == -1)
		return;

	bzero(name, sizeof(name));
	if (OF_getprop(escc_ch, "name", name, sizeof(name)) == -1)
		return;

	if (strcmp(name, "ch-b") == 0)
		ch = 1;

	if (OF_getprop(escc_ch, "reg", reg, sizeof(reg)) < 8)
		return;
	zs_offset = reg[0];
	zs_size   = reg[1];

	escc = OF_parent(escc_ch);
	obio = OF_parent(escc);

	if (OF_getprop(obio, "assigned-addresses", reg, sizeof(reg)) < 12)
		return;
	zs_conschan = mapiodev(reg[2] + zs_offset, zs_size);

	zs_hwflags[0][ch] = ZS_HWFLAG_CONSOLE;
}

void
zs_abort(struct zs_chanstate *channel)
{
	volatile struct zschan *zc = zs_conschan;
	int rr0;

	/* Wait for end of break to avoid PROM abort. */
	/* XXX - Limit the wait? */
	do {
		rr0 = zc->zc_csr;
		ZS_DELAY();
	} while (rr0 & ZSRR0_BREAK);

#if defined(DDB)
	{
		extern int db_active;

		if (!db_active)
			Debugger();
	}
#endif
}

/* copied from sparc - XXX? */
void
zscnpollc(dev, on)
        dev_t dev;
	int on;
{
	/*
	 * Need to tell zs driver to acknowledge all interrupts or we get
	 * annoying spurious interrupt messages.  This is because mucking
	 * with spl() levels during polling does not prevent interrupts from
	 * being generated.
	 */

#if 0
	if (on)
		swallow_zsintrs++;
	else
		swallow_zsintrs--;
#endif
}


path: sys/arch/macppc/include/CVS/Entries


code: src/sys/arch/macppc/include

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


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

#include <powerpc/_float.h>


code:
/*	$OpenBSD: _types.h,v 1.1 2006/01/06 18:50:09 millert Exp $	*/

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


code:
/*	$OpenBSD: apmvar.h,v 1.8 2015/02/07 08:31:44 miod Exp $	*/

/*
 *  Copyright (c) 2001 Alexander Guy
 *  Copyright (c) 1995 John T. Kohl
 *  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.
 *
 */
#ifndef _MACHINE_APMVAR_H_
#define _MACHINE_APMVAR_H_

#include <sys/ioccom.h>

/* Advanced Power Management (v1.0 and v1.1 specification)
 * functions/defines/etc.
 */

/* These definitions make up the heart of the user-land interface
 * to the APM devices.
 */

#define		APM_AC_OFF		0x00
#define		APM_AC_ON		0x01
#define		APM_AC_BACKUP		0x02
#define		APM_AC_UNKNOWN		0xff
#define		APM_BATT_HIGH		0x00
#define		APM_BATT_LOW		0x01
#define		APM_BATT_CRITICAL	0x02
#define		APM_BATT_CHARGING	0x03
#define		APM_BATT_UNKNOWN	0xff
#define		APM_BATT_LIFE_UNKNOWN	0xff

#define		APM_NOEVENT		0x0000
#define		APM_STANDBY_REQ		0x0001
#define		APM_SUSPEND_REQ		0x0002
#define		APM_NORMAL_RESUME	0x0003
#define		APM_CRIT_RESUME		0x0004 /* suspend/resume happened
						  without us */
#define		APM_BATTERY_LOW		0x0005
#define		APM_POWER_CHANGE	0x0006
#define		APM_UPDATE_TIME		0x0007
#define		APM_CRIT_SUSPEND_REQ	0x0008
#define		APM_USER_STANDBY_REQ	0x0009
#define		APM_USER_SUSPEND_REQ	0x000A
#define		APM_SYS_STANDBY_RESUME	0x000B
#define		APM_CAPABILITY_CHANGE	0x000C	/* apm v1.2 */
#define		APM_USER_HIBERNATE_REQ	0x000D
#define		APM_EVENT_MASK		0xffff

#define	APM_EVENT_COMPOSE(t,i)	((((i) & 0x7fff) << 16)|((t) & APM_EVENT_MASK))
#define	APM_EVENT_TYPE(e)	((e) & APM_EVENT_MASK)
#define	APM_EVENT_INDEX(e)	((e) >> 16)

/*
 * LP (Laptop Package)
 *
 * Copyright (C) 1994 by HOSOKAWA Tatsumi <hosokawa@mt.cs.keio.ac.jp>
 *
 * This software may be used, modified, copied, and distributed, in
 * both source and binary form provided that the above copyright and
 * these terms are retained. Under no circumstances is the author
 * responsible for the proper functioning of this software, nor does
 * the author assume any responsibility for damages incurred with its
 * use.
 *
 * Sep., 1994	Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
 */

#define APM_BATTERY_ABSENT 4

struct apm_power_info {
	u_char battery_state;
	u_char ac_state;
	u_char battery_life;
	u_char spare1;
	u_int minutes_left;		/* estimate */
	u_int spare2[6];
};

struct apm_ctl {
	u_int dev;
	u_int mode;
};

#define	APM_IOC_REJECT	_IOW('A', 0, struct apm_event_info) /* reject request # */
#define	APM_IOC_STANDBY	_IO('A', 1)	/* put system into standby */
#define	APM_IOC_SUSPEND	_IO('A', 2)	/* put system into suspend */
#define	APM_IOC_GETPOWER _IOR('A', 3, struct apm_power_info) /* fetch battery state */
#define	APM_IOC_DEV_CTL	_IOW('A', 5, struct apm_ctl) /* put device into mode */
#define APM_IOC_PRN_CTL _IOW('A', 6, int ) /* driver power status msg */
#define		APM_PRINT_ON	0	/* driver power status displayed */
#define		APM_PRINT_OFF	1	/* driver power status not displayed */
#define		APM_PRINT_PCT	2	/* driver power status only displayed
					   if the percentage changes */
#define	APM_IOC_STANDBY_REQ	_IO('A', 7)	/* request standby */
#define	APM_IOC_SUSPEND_REQ	_IO('A', 8)	/* request suspend */
#define	APM_IOC_HIBERNATE	_IO('A', 9)	/* put system into hibernate */

#endif /* _MACHINE_APMVAR_H_ */


code:
/*	$OpenBSD: asm.h,v 1.1 2001/09/01 15:49:06 drahn Exp $	*/

#include <powerpc/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 <powerpc/atomic.h>

#endif /* _MACHINE_ATOMIC_H_ */


code:
/*	$OpenBSD: autoconf.h,v 1.12 2015/04/02 11:12:24 mpi Exp $ */

/*
 * Copyright (c) 1997 Per Fogelstrom
 *
 * 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.
 *
 */
/*
 * Machine-dependent structures of autoconfiguration
 */

#ifndef _MACHINE_AUTOCONF_H_
#define _MACHINE_AUTOCONF_H_

#include <machine/bus.h>

struct confargs {
	char	*ca_name;
	bus_space_tag_t ca_iot;
	bus_dma_tag_t ca_dmat;
	u_int32_t ca_node;
	int ca_nreg;
	u_int32_t *ca_reg;
	int ca_nintr;
	int32_t *ca_intr;
	u_int ca_baseaddr;

};

void	set_clockintr(void (*)(struct clockframe *));
void	set_iointr(void (*)(void *, int));
int	badaddr(void *, u_int32_t);
void calc_delayconst(void);

typedef int (time_read_t)(time_t *sec);
typedef int (time_write_t)(time_t sec);

extern time_read_t *time_read;
extern time_write_t *time_write;

typedef int mac_intr_handle_t;
typedef void     *(intr_establish_t)(void *, mac_intr_handle_t,
    int, int, int (*func)(void *), void *, const char *);
typedef void     (intr_disestablish_t)(void *, void *);
struct cpu_info;
typedef void     (intr_send_ipi_t)(struct cpu_info *, int);

intr_establish_t mac_intr_establish;
intr_disestablish_t mac_intr_disestablish;
extern intr_establish_t *intr_establish_func;
extern intr_disestablish_t *intr_disestablish_func;
extern intr_send_ipi_t *intr_send_ipi_func;

#endif /* _MACHINE_AUTOCONF_H_ */


code:
/*	$OpenBSD: bus.h,v 1.24 2015/01/24 20:59:42 kettenis Exp $	*/

/*
 * Copyright (c) 1997 Per Fogelstrom.  All rights reserved.
 * Copyright (c) 1996 Niklas Hallqvist.  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.
 */

#ifndef _MACHINE_BUS_H_
#define _MACHINE_BUS_H_

#include <machine/pio.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.
 */
typedef u_long bus_addr_t;
typedef u_long bus_size_t;
typedef u_long bus_space_handle_t;
typedef struct ppc_bus_space *bus_space_tag_t;

struct ppc_bus_space {
	u_int32_t	bus_base;
	u_int32_t	bus_size;
	u_int8_t	bus_io;		/* IO or memory */
};
#define POWERPC_BUS_TAG_BASE(x)  ((x)->bus_base)

extern struct ppc_bus_space ppc_isa_io, ppc_isa_mem;

/*
 * Access methods for bus resources
 */
int	bus_space_map(bus_space_tag_t t, bus_addr_t addr,
	    bus_size_t size, int flags, bus_space_handle_t *bshp);
void	bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
	    bus_size_t size);
int	bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
	    bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
int	bus_space_alloc(bus_space_tag_t tag, bus_addr_t rstart,
	    bus_addr_t rend, bus_size_t size, bus_size_t alignment,
	    bus_size_t boundary, int flags, bus_addr_t *addrp,
	    bus_space_handle_t *handlep);
void	bus_space_free(bus_space_tag_t tag, bus_space_handle_t handle,
	    bus_size_t size);
paddr_t	bus_space_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int);

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

/*
 *	void *bus_space_vaddr(bus_space_tag_t, bus_space_handle_t);
 *
 * Get the kernel virtual address for the mapped bus space.
 * Only allowed for regions mapped with BUS_SPACE_MAP_LINEAR.
 */
#define bus_space_vaddr(t, h) ((void *)(h))

#define bus_space_read(n,m)						      \
static __inline CAT3(u_int,m,_t)					      \
CAT(bus_space_read_,n)(bus_space_tag_t bst, bus_space_handle_t bsh,	      \
     bus_addr_t ba)							      \
{									      \
	return CAT3(in,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (ba)));      \
}

bus_space_read(1,8)
bus_space_read(2,16)
bus_space_read(4,32)

#define	bus_space_read_8	!!! bus_space_read_8 unimplemented !!!

#define bus_space_write(n,m)						      \
static __inline void							      \
CAT(bus_space_write_,n)(bus_space_tag_t bst, bus_space_handle_t bsh,	      \
     bus_addr_t ba, CAT3(u_int,m,_t) x)					      \
{									      \
	CAT3(out,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (ba)), x);	      \
}

bus_space_write(1,8)
bus_space_write(2,16)
bus_space_write(4,32)

#define	bus_space_write_8	!!! bus_space_write_8 unimplemented !!!

#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 ba, CAT3(u_int,m,_t) *buf, bus_size_t cnt)		      \
{									      \
	while (cnt--)							      \
		*buf++ = CAT(bus_space_read_,n)(bst, bsh, ba);		      \
}

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

#define	bus_space_read_multi_8	!!! bus_space_read_multi_8 not implemented !!!

#define	bus_space_write_multi_8	!!! bus_space_write_multi_8 not implemented !!!

#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 ba, const CAT3(u_int,m,_t) *buf, bus_size_t cnt)		      \
{									      \
	while (cnt--)							      \
		CAT(bus_space_write_,n)(bst, bsh, ba, *buf++);		      \
}

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

#define	bus_space_write_multi_8	!!! bus_space_write_multi_8 not implemented !!!

/*
 *	void bus_space_read_region_N(bus_space_tag_t tag,
 *	    bus_space_handle_t bsh, bus_size_t offset,
 *	    u_intN_t *addr, size_t count);
 *
 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
 * described by tag/handle and starting at `offset' and copy into
 * buffer provided.
 */
#define __BA(t, h, o) ((void *)((h) + (o)))

static __inline void
bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
	bus_size_t offset, u_int8_t *addr, size_t count)
{
	volatile u_int8_t *s = __BA(tag, bsh, offset);

	while (count--)
		*addr++ = *s++;
	__asm volatile("eieio; sync");
}

static __inline void
bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
	bus_size_t offset, u_int16_t *addr, size_t count)
{
	volatile u_int16_t *s = __BA(tag, bsh, offset);

	while (count--)
		__asm volatile("lhbrx %0, 0, %1" :
			"=r"(*addr++) : "r"(s++));
	__asm volatile("eieio; sync");
}

static __inline void
bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
	bus_size_t offset, u_int32_t *addr, size_t count)
{
	volatile u_int32_t *s = __BA(tag, bsh, offset);

	while (count--)
		__asm volatile("lwbrx %0, 0, %1" :
			"=r"(*addr++) : "r"(s++));
	__asm volatile("eieio; sync");
}

#if 0	/* Cause a link error for bus_space_read_region_8 */
#define	bus_space_read_region_8		!!! unimplemented !!!
#endif

/*
 *	void bus_space_write_region_N(bus_space_tag_t tag,
 *	    bus_space_handle_t bsh, bus_size_t offset,
 *	    const u_intN_t *addr, size_t count);
 *
 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
 * to bus space described by tag/handle starting at `offset'.
 */

static __inline void
bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
	bus_size_t offset, const u_int8_t *addr, size_t count)
{
	volatile u_int8_t *d = __BA(tag, bsh, offset);

	while (count--)
		*d++ = *addr++;
	__asm volatile("eieio; sync");
}

static __inline void
bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
	bus_size_t offset, const u_int16_t *addr, size_t count)
{
	volatile u_int16_t *d = __BA(tag, bsh, offset);

	while (count--)
		__asm volatile("sthbrx %0, 0, %1" ::
			"r"(*addr++), "r"(d++));
	__asm volatile("eieio; sync");
}

static __inline void
bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
	bus_size_t offset, const u_int32_t *addr, size_t count)
{
	volatile u_int32_t *d = __BA(tag, bsh, offset);

	while (count--)
		__asm volatile("stwbrx %0, 0, %1" ::
			"r"(*addr++), "r"(d++));
	__asm volatile("eieio; sync");
}

#if 0
#define	bus_space_write_region_8 !!! bus_space_write_region_8 unimplemented !!!
#endif

/*
 *	void bus_space_read_raw_region_N(bus_space_tag_t tag,
 *	    bus_space_handle_t bsh, bus_size_t offset,
 *	    u_intN_t *addr, size_t count);
 *
 * Read `count' bytes from bus space described by tag/handle and starting
 * at `offset' and copy into buffer provided w/o bus-host byte swapping.
 */

static __inline void
bus_space_read_raw_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
	bus_size_t offset, u_int8_t *addr, size_t count)
{
	volatile u_int16_t *s = __BA(tag, bsh, offset);
	u_int16_t *laddr = (void *)addr;

	count = count >> 1;

	while (count--)
		*laddr++ = *s++;
	__asm volatile("eieio; sync");
}

static __inline void
bus_space_read_raw_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
	bus_size_t offset, u_int8_t *addr, size_t count)
{
	volatile u_int32_t *s = __BA(tag, bsh, offset);
	u_int32_t *laddr = (void *)addr;

	count = count >> 2;

	while (count--)
		*laddr++ = *s++;
	__asm volatile("eieio; sync");
}

#if 0	/* Cause a link error for bus_space_read_raw_region_8 */
#define	bus_space_read_raw_region_8	\
    !!! bus_space_read_raw_region_8		unimplemented !!!
#endif

/*
 *	void bus_space_write_raw_region_N(bus_space_tag_t tag,
 *	    bus_space_handle_t bsh, bus_size_t offset,
 *	    const u_intN_t *addr, size_t count);
 *
 * Write `count' bytes from the buffer provided to bus space described
 * by tag/handle starting at `offset' w/o host-bus byte swapping.
 */

static __inline void
bus_space_write_raw_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
	bus_size_t offset, const u_int8_t *addr, size_t count)
{
	volatile u_int16_t *d = __BA(tag, bsh, offset);
	const u_int16_t *laddr = (void *)addr;

	count = count >> 1;

	while (count--)
		*d++ = *laddr++;
	__asm volatile("eieio; sync");
}

static __inline void
bus_space_write_raw_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
	bus_size_t offset, const u_int8_t *addr, size_t count)
{
	volatile u_int32_t *d = __BA(tag, bsh, offset);
	const u_int32_t *laddr = (void *)addr;

	count = count >> 2;

	while (count--)
		*d++ = *laddr++;
	__asm volatile("eieio; sync");
}

#if 0
#define	bus_space_write_raw_region_8 \
    !!! bus_space_write_raw_region_8 unimplemented !!!
#endif

/*
 *	void bus_space_set_multi_N(bus_space_tag_t tag,
 *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
 *	    size_t count);
 *
 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
 * by tag/handle/offset `count' times.
 */
static __inline void bus_space_set_multi_1(bus_space_tag_t,
	bus_space_handle_t, bus_size_t, u_int8_t, size_t);
static __inline void bus_space_set_multi_2(bus_space_tag_t,
	bus_space_handle_t, bus_size_t, u_int16_t, size_t);
static __inline void bus_space_set_multi_4(bus_space_tag_t,
	bus_space_handle_t, bus_size_t, u_int32_t, size_t);

static __inline void
bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
    bus_size_t offset, u_int8_t val, size_t count)
{
	volatile u_int8_t *d = __BA(tag, bsh, offset);

	while (count--)
		*d = val;
	__asm__ volatile("eieio; sync");
}

static __inline void
bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
    bus_size_t offset, u_int16_t val, size_t count)
{
	volatile u_int16_t *d = __BA(tag, bsh, offset);

	while (count--)
		__asm__ volatile("sthbrx %0, 0, %1" ::
			"r"(val), "r"(d));
	__asm__ volatile("eieio; sync");
}

static __inline void
bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
    bus_size_t offset, u_int32_t val, size_t count)
{
	volatile u_int32_t *d = __BA(tag, bsh, offset);

	while (count--)
		__asm__ volatile("stwbrx %0, 0, %1" ::
			"r"(val), "r"(d));
	__asm__ volatile("eieio; sync");
}

#define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!

/* These are OpenBSD extensions to the general NetBSD bus interface.  */
void
bus_space_read_raw_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
	bus_addr_t ba, u_int8_t *dst, bus_size_t size);
void
bus_space_read_raw_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
	bus_addr_t ba, u_int8_t *dst, bus_size_t size);
#define	bus_space_read_raw_multi_8 \
    !!! bus_space_read_raw_multi_8 not implemented !!!

void
bus_space_write_raw_multi_2(bus_space_tag_t bst, bus_space_handle_t bsh,
	bus_addr_t ba, const u_int8_t *src, bus_size_t size);
void
bus_space_write_raw_multi_4(bus_space_tag_t bst, bus_space_handle_t bsh,
	bus_addr_t ba, const u_int8_t *src, bus_size_t size);
#define	bus_space_write_raw_multi_8 \
    !!! bus_space_write_raw_multi_8 not implemented !!!

void
bus_space_set_region_1(bus_space_tag_t bst, bus_space_handle_t h, bus_size_t o,
    u_int8_t val, bus_size_t c);
void
bus_space_set_region_2(bus_space_tag_t bst, bus_space_handle_t h, bus_size_t o,
    u_int16_t val, bus_size_t c);
void
bus_space_set_region_4(bus_space_tag_t bst, bus_space_handle_t h, bus_size_t o,
    u_int32_t val, bus_size_t c);
#define	bus_space_set_region_8 \
    !!! bus_space_set_region_8 not implemented !!!

void
bus_space_copy_1(void *v, bus_space_handle_t h1, bus_space_handle_t h2,
    bus_size_t o1, bus_size_t o2, bus_size_t c);
void
bus_space_copy_2(void *v, bus_space_handle_t h1, bus_space_handle_t h2,
    bus_size_t o1, bus_size_t o2, bus_size_t c);
void
bus_space_copy_4(void *v, bus_space_handle_t h1, bus_space_handle_t h2,
    bus_size_t o1, bus_size_t o2, bus_size_t c);
#define	bus_space_copy_8 \
    !!! bus_space_copy_8 not implemented !!!

/*
 * 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);
 *
 * Note: powerpc does not currently implement barriers, but we must
 * provide the flags to MI code.
 * the processor does have eieio which is effectively the barrier
 * operator, however due to how memory is mapped this should? not
 * be required.
 */
#define bus_space_barrier(t, h, o, l, f)	\
	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
#define BUS_SPACE_BARRIER_READ  0x01		/* force read barrier */
#define BUS_SPACE_BARRIER_WRITE 0x02		/* force write barrier */

#define	BUS_DMA_WAITOK		0x0000	/* safe to sleep (pseudo-flag) */
#define	BUS_DMA_NOWAIT		0x0001	/* not safe to sleep */
#define	BUS_DMA_ALLOCNOW	0x0002	/* perform resource allocation now */
#define	BUS_DMA_COHERENT	0x0008	/* hint: map memory DMA coherent */
#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	/* map memory uncached */

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

#define BUS_DMASYNC_POSTREAD	0x01
#define BUS_DMASYNC_POSTWRITE	0x02
#define BUS_DMASYNC_PREREAD	0x04
#define BUS_DMASYNC_PREWRITE	0x08

typedef struct powerpc_bus_dma_tag	*bus_dma_tag_t;
typedef struct powerpc_bus_dmamap	*bus_dmamap_t;

/*
 *	bus_dma_segment_t
 *
 *	Describes a single contiguous DMA transaction.  Values
 *	are suitable for programming into DMA registers.
 */
struct powerpc_bus_dma_segment {
	bus_addr_t	ds_addr;	/* DMA address */
	bus_size_t	ds_len;		/* length of transfer */
};
typedef struct powerpc_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 powerpc_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);
	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);
	int	(*_dmamem_alloc_range)(bus_dma_tag_t, bus_size_t, bus_size_t,
		    bus_size_t, bus_dma_segment_t *, int, int *, int,
		    bus_addr_t, bus_addr_t);
	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);
};

#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)->_cookie, (s), (a), (b), (sg), (n), (r), (f))
#define	bus_dmamem_alloc_range(t, s, a, b, sg, n, r, f, l, h)	\
	(*(t)->_dmamem_alloc_range)((t), (s), (a), (b), (sg),	\
		(n), (r), (f), (l), (h))
#define	bus_dmamem_free(t, sg, n)				\
	(*(t)->_dmamem_free)((t)->_cookie, (sg), (n))
#define	bus_dmamem_map(t, sg, n, s, k, f)			\
	(*(t)->_dmamem_map)((t)->_cookie, (sg), (n), (s), (k), (f))
#define	bus_dmamem_unmap(t, k, s)				\
	(*(t)->_dmamem_unmap)((t)->_cookie, (k), (s))
#define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
	(*(t)->_dmamem_mmap)((t)->_cookie, (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);
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);
int	_dmamem_alloc_range( bus_dma_tag_t, bus_size_t, bus_size_t,
	    bus_size_t, bus_dma_segment_t *, int, int *, int,
	    bus_addr_t, bus_addr_t);
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);

/*
 *	bus_dmamap_t
 *
 *	Describes a DMA mapping.
 */
struct powerpc_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.1 2001/09/01 15:49:06 drahn Exp $	*/

#include <powerpc/cdefs.h>


code:
/*	$OpenBSD: conf.h,v 1.14 2011/07/04 16:52:41 nicm Exp $	*/
/*	$NetBSD: conf.h,v 1.2 1996/05/05 19:28:34 christos Exp $	*/

/*
 * Copyright (c) 1996 Christos Zoulas.  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 Christos Zoulas.
 * 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.
 */

#include <sys/conf.h>

#define	mmread	mmrw
#define	mmwrite	mmrw
cdev_decl(mm);

/* open, close, write, ioctl, kqueue */
#define cdev_apm_init(c,n) { \
        dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
        (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
	(dev_type_stop((*))) enodev, 0, selfalse, \
	(dev_type_mmap((*))) enodev, 0, 0, dev_init(c,n,kqfilter) }

cdev_decl(apm);
cdev_decl(zs);

/* open, close, ioctl */
#define cdev_openprom_init(c,n) { \
	dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
	(dev_type_write((*))) enodev, dev_init(c,n,ioctl), \
	(dev_type_stop((*))) nullop, 0, selfalse, \
	(dev_type_mmap((*))) enodev }

cdev_decl(openprom);


code:
/*	$OpenBSD: cpu.h,v 1.14 2013/10/09 17:43:50 mpi Exp $	*/
/*	$NetBSD: cpu.h,v 1.1 1996/09/30 16:34:21 ws Exp $	*/

/*
 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
 * Copyright (C) 1995, 1996 TooLs GmbH.
 * 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 TooLs GmbH.
 * 4. The name of TooLs GmbH may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_CPU_H_
#define	_MACHINE_CPU_H_

/*
 * CTL_MACHDEP definitions.
 */
#define CPU_ALLOWAPERTURE	1	/* allow mmap of /dev/xf86 */
#define CPU_ALTIVEC		2	/* altivec is present */
#define CPU_MAXID		3	/* number of valid machdep ids */

#define	CTL_MACHDEP_NAMES { \
	{ 0, 0 }, \
	{ "allowaperture", CTLTYPE_INT }, \
	{ "altivec", CTLTYPE_INT }, \
}

#ifdef _KERNEL

#include <powerpc/cpu.h>

/* Frequency scaling */
#define FREQ_FULL	0
#define FREQ_HALF	1
#define FREQ_QUARTER	2	/* Supported only on IBM 970MP */

extern u_int32_t	ppc_curfreq;
extern u_int32_t	ppc_maxfreq;
extern int		ppc_altivec;

extern void (*ppc64_slew_voltage)(u_int);

extern u_int32_t	ticks_per_sec;
extern u_int32_t 	ns_per_tick;

#endif /* _KERNEL */
#endif /* _MACHINE_CPU_H_ */


code:
/*	$OpenBSD: db_machdep.h,v 1.6 2008/09/16 04:20:42 drahn Exp $	*/

#define DB_MACHINE_COMMANDS
#include <powerpc/db_machdep.h>


code:
/*	$OpenBSD: disklabel.h,v 1.14 2007/06/20 18:15:45 deraadt 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		/* sector containing label */
#define	LABELOFFSET	0		/* offset of label in sector */
#define	MAXPARTITIONS	16		/* number of partitions */

/* HFS/DPME */

/* partition map structure from Inside Macintosh: Devices, SCSI Manager
 * pp. 13-14.  The partition map always begins on physical block 1.
 *
 * With the exception of block 0, all blocks on the disk must belong to
 * exactly one partition.  The partition map itself belongs to a partition
 * of type `APPLE_PARTITION_MAP', and is not limited in size by anything
 * other than available disk space.  The partition map is not necessarily
 * the first partition listed.
 */
struct part_map_entry {
#define PART_ENTRY_MAGIC        0x504d
	u_int16_t       pmSig;          /* partition signature */
	u_int16_t       pmSigPad;       /* (reserved) */
	u_int32_t       pmMapBlkCnt;    /* number of blocks in partition map */
	u_int32_t       pmPyPartStart;  /* first physical block of partition */
	u_int32_t       pmPartBlkCnt;   /* number of blocks in partition */
	char            pmPartName[32]; /* partition name */
	char            pmPartType[32]; /* partition type */
	u_int32_t       pmLgDataStart;  /* first logical block of data area */
	u_int32_t       pmDataCnt;      /* number of blocks in data area */
	u_int32_t       pmPartStatus;   /* partition status information */
	u_int32_t       pmLgBootStart;  /* first logical block of boot code */
	u_int32_t       pmBootSize;     /* size of boot code, in bytes */
	u_int32_t       pmBootLoad;     /* boot code load address */
	u_int32_t       pmBootLoad2;    /* (reserved) */
	u_int32_t       pmBootEntry;    /* boot code entry point */
	u_int32_t       pmBootEntry2;   /* (reserved) */
	u_int32_t       pmBootCksum;    /* boot code checksum */
	char            pmProcessor[16]; /* processor type (e.g. "68020") */
	u_int8_t        pmBootArgs[128]; /* A/UX boot arguments */
	/* we do not index the disk image as an array,
	 * leave out the on disk padding
	 */
#if 0
	u_int8_t        pad[248];       /* pad to end of block */
#endif
};

#define PART_TYPE_DRIVER        "APPLE_DRIVER"
#define PART_TYPE_DRIVER43      "APPLE_DRIVER43"
#define PART_TYPE_DRIVERATA     "APPLE_DRIVER_ATA"
#define PART_TYPE_DRIVERIOKIT   "APPLE_DRIVER_IOKIT"
#define PART_TYPE_FWDRIVER      "APPLE_FWDRIVER"
#define PART_TYPE_FWB_COMPONENT "FWB DRIVER COMPONENTS"
#define PART_TYPE_FREE          "APPLE_FREE"
#define PART_TYPE_MAC           "APPLE_HFS"
#define PART_TYPE_OPENBSD       "OPENBSD"

#endif /* _MACHINE_DISKLABEL_H_ */


code:
/*	$OpenBSD: endian.h,v 1.1 2001/09/01 15:49:06 drahn Exp $	*/

#include <powerpc/endian.h>


code:
/*	$OpenBSD: exec.h,v 1.1 2001/09/01 15:49:06 drahn Exp $	*/

#include <powerpc/exec.h>


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


code:
/*	$OpenBSD: fpu.h,v 1.1 2001/09/01 15:49:06 drahn Exp $	*/

#include <powerpc/fpu.h>


code:
/*	$OpenBSD: frame.h,v 1.1 2001/09/01 15:49:06 drahn Exp $	*/

#include <powerpc/frame.h>


code:
/*	$OpenBSD: ieee.h,v 1.1 2001/09/01 15:49:06 drahn Exp $	*/

#include <powerpc/ieee.h>


code:
/*	$OpenBSD: ieeefp.h,v 1.1 2001/09/01 15:49:06 drahn Exp $	*/

#include <powerpc/ieeefp.h>


code:
/*	$OpenBSD: intr.h,v 1.9 2014/04/01 20:27:14 mpi Exp $	*/

#include <powerpc/intr.h>

#ifndef _LOCORE
extern int intr_shared_edge;

void install_extint(void (*handler)(void));
void openpic_set_priority(int, int);
#endif


code:
/*	$OpenBSD: ipkdb.h,v 1.1 2001/09/01 15:49:06 drahn Exp $	*/

#include <powerpc/ipkdb.h>


code:
/*	$OpenBSD: kbio.h,v 1.1 2001/09/01 15:49:06 drahn Exp $	*/

#include <powerpc/kbio.h>


code:
/*	$OpenBSD: kcore.h,v 1.1 2001/09/01 15:49:06 drahn Exp $	*/

#include <powerpc/kcore.h>


code:
/*	$OpenBSD: limits.h,v 1.1 2001/09/01 15:49:06 drahn Exp $	*/

#include <powerpc/limits.h>


code:
/*	$OpenBSD: loadfile_machdep.h,v 1.4 2015/07/17 20:44:39 miod Exp $	*/
/*	$NetBSD: loadfile_machdep.h,v 1.1 1999/04/29 03:17:12 tsubai 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 32

#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)


code:
/*	$OpenBSD: lock.h,v 1.1 2007/03/20 20:59:53 kettenis Exp $	*/

#include <powerpc/lock.h>


code:
/*	$OpenBSD: mplock.h,v 1.3 2015/06/26 11:15:32 dlg Exp $	*/

#include <powerpc/mplock.h>


code:
/*	$OpenBSD: mutex.h,v 1.1 2007/03/22 19:26:28 kettenis Exp $	*/

#include <powerpc/mutex.h>


code:
/*	$OpenBSD: openpromio.h,v 1.1 2007/11/12 19:23:26 kettenis Exp $	*/
/*	$NetBSD: openpromio.h,v 1.1.1.1 1998/06/20 04:58:52 eeh Exp $ */

/*
 * Copyright (c) 1992, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This software was developed by the Computer Systems Engineering group
 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
 * contributed to Berkeley.
 *
 * All advertising materials mentioning features or use of this software
 * must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Lawrence Berkeley Laboratory.
 *
 * 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.
 *
 *	@(#)openpromio.h	8.1 (Berkeley) 6/11/93
 */

struct opiocdesc {
	int	op_nodeid;		/* passed or returned node id */
	int	op_namelen;		/* length of op_name */
	char	*op_name;		/* pointer to field name */
	int	op_buflen;		/* length of op_buf (value-result) */
	char	*op_buf;		/* pointer to field value */
};

#define	OPIOCGET	_IOWR('O', 1, struct opiocdesc) /* get openprom field */
#define	OPIOCSET	_IOW('O', 2, struct opiocdesc) /* set openprom field */
#define	OPIOCNEXTPROP	_IOWR('O', 3, struct opiocdesc) /* get next property */
#define	OPIOCGETOPTNODE	_IOR('O', 4, int)	/* get openprom field */
#define	OPIOCGETNEXT	_IOWR('O', 5, int)	/* get next node of node */
#define	OPIOCGETCHILD	_IOWR('O', 6, int)	/* get first child of node */


code:
/*	$OpenBSD: param.h,v 1.6 2014/04/07 16:29:06 deraadt Exp $	*/

/*-
 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
 * Copyright (C) 1995, 1996 TooLs GmbH.
 * 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 TooLs GmbH.
 * 4. The name of TooLs GmbH may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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_PARAM_H_
#define	_MACHINE_PARAM_H_

#ifdef	_KERNEL
#ifndef	_LOCORE
#include <machine/cpu.h>
#endif	/* _LOCORE */
#endif

#include <powerpc/param.h>

#define	MACHINE		"macppc"
#define	_MACHINE	macppc

#define	KERNBASE	0x100000

#define	MSGBUFSIZE	(4 * PAGE_SIZE)

#endif /* _MACHINE_PARAM_H_ */


code:
/*	$OpenBSD: pcb.h,v 1.1 2001/09/01 15:49:06 drahn Exp $	*/

#include <powerpc/pcb.h>