code:
/* $OpenBSD: amptimer.c,v 1.4 2013/08/08 10:07:22 rapha Exp $ */
/*
 * Copyright (c) 2011 Dale Rahn <drahn@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/param.h>
#include <sys/systm.h>
#include <sys/queue.h>
#include <sys/malloc.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/timetc.h>
#include <sys/evcount.h>

#include <arm/cpufunc.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <arm/cortex/cortex.h>

/* offset from periphbase */
#define GTIMER_ADDR	0x200
#define GTIMER_SIZE	0x100

/* registers */
#define GTIMER_CNT_LOW		0x00
#define GTIMER_CNT_HIGH		0x04
#define GTIMER_CTRL		0x08
#define GTIMER_CTRL_AA		(1 << 3)
#define GTIMER_CTRL_IRQ		(1 << 2)
#define GTIMER_CTRL_COMP	(1 << 1)
#define GTIMER_CTRL_TIMER	(1 << 0)
#define GTIMER_STATUS		0x0c
#define GTIMER_STATUS_EVENT	(1 << 0)
#define GTIMER_CMP_LOW		0x10
#define GTIMER_CMP_HIGH		0x14
#define GTIMER_AUTOINC		0x18

/* offset from periphbase */
#define PTIMER_ADDR		0x600
#define PTIMER_SIZE		0x100

/* registers */
#define PTIMER_LOAD		0x0
#define PTIMER_CNT		0x4
#define PTIMER_CTRL		0x8
#define PTIMER_CTRL_ENABLE	(1<<0)
#define PTIMER_CTRL_AUTORELOAD	(1<<1)
#define PTIMER_CTRL_IRQEN	(1<<2)
#define PTIMER_STATUS		0xC
#define PTIMER_STATUS_EVENT	(1<<0)

#define TIMER_FREQUENCY		396 * 1000 * 1000 /* ARM core clock */
int32_t amptimer_frequency = TIMER_FREQUENCY;

u_int amptimer_get_timecount(struct timecounter *);

static struct timecounter amptimer_timecounter = {
	amptimer_get_timecount, NULL, 0x7fffffff, 0, "amptimer", 0, NULL
};

#define MAX_ARM_CPUS	8

struct amptimer_pcpu_softc {
	uint64_t 		pc_nexttickevent;
	uint64_t 		pc_nextstatevent;
	u_int32_t		pc_ticks_err_sum;
};

struct amptimer_softc {
	struct device		sc_dev;
	bus_space_tag_t		sc_iot;
	bus_space_handle_t	sc_ioh;
	bus_space_handle_t	sc_pioh;

	struct amptimer_pcpu_softc sc_pstat[MAX_ARM_CPUS];

	u_int32_t		sc_ticks_err_cnt;
	u_int32_t		sc_ticks_per_second;
	u_int32_t		sc_ticks_per_intr;
	u_int32_t		sc_statvar;
	u_int32_t		sc_statmin;

#ifdef AMPTIMER_DEBUG
	struct evcount		sc_clk_count;
	struct evcount		sc_stat_count;
#endif
};

int		amptimer_match(struct device *, void *, void *);
void		amptimer_attach(struct device *, struct device *, void *);
uint64_t	amptimer_readcnt64(struct amptimer_softc *sc);
int		amptimer_intr(void *);
void		amptimer_cpu_initclocks(void);
void		amptimer_delay(u_int);
void		amptimer_setstatclockrate(int stathz);
void		amptimer_set_clockrate(int32_t new_frequency);
void		amptimer_startclock(void);

/* hack - XXXX
 * gptimer connects directly to ampintc, not thru the generic
 * inteface because it uses an 'internal' interupt
 * not a peripheral interrupt.
 */
void	*ampintc_intr_establish(int, int, int (*)(void *), void *, char *);

struct cfattach amptimer_ca = {
	sizeof (struct amptimer_softc), amptimer_match, amptimer_attach
};

struct cfdriver amptimer_cd = {
	NULL, "amptimer", DV_DULL
};

uint64_t
amptimer_readcnt64(struct amptimer_softc *sc)
{
	uint32_t high0, high1, low;
	bus_space_tag_t iot = sc->sc_iot;
	bus_space_handle_t ioh = sc->sc_ioh;

	do {
		high0 = bus_space_read_4(iot, ioh, GTIMER_CNT_HIGH);
		low = bus_space_read_4(iot, ioh, GTIMER_CNT_LOW);
		high1 = bus_space_read_4(iot, ioh, GTIMER_CNT_HIGH);
	} while (high0 != high1);

	return ((((uint64_t)high1) << 32) | low);
}

int
amptimer_match(struct device *parent, void *cfdata, void *aux)
{
	if ((cpufunc_id() & CPU_ID_CORTEX_A9_MASK) == CPU_ID_CORTEX_A9)
		return (1);

	return 0;
}

void
amptimer_attach(struct device *parent, struct device *self, void *args)
{
	struct amptimer_softc *sc = (struct amptimer_softc *)self;
	struct cortex_attach_args *ia = args;
	bus_space_handle_t ioh, pioh;

	sc->sc_iot = ia->ca_iot;

	if (bus_space_map(sc->sc_iot, ia->ca_periphbase + GTIMER_ADDR,
	    GTIMER_SIZE, 0, &ioh))
		panic("amptimer_attach: bus_space_map global timer failed!");

	if (bus_space_map(sc->sc_iot, ia->ca_periphbase + PTIMER_ADDR,
	    PTIMER_SIZE, 0, &pioh))
		panic("amptimer_attach: bus_space_map priv timer failed!");

	sc->sc_ticks_per_second = amptimer_frequency;
	printf(": tick rate %d KHz\n", sc->sc_ticks_per_second /1000);

	sc->sc_ioh = ioh;
	sc->sc_pioh = pioh;

	/* disable global timer */
	bus_space_write_4(sc->sc_iot, ioh, GTIMER_CTRL, 0);

	/* XXX ??? reset counters to 0 - gives us uptime in the counter */
	bus_space_write_4(sc->sc_iot, ioh, GTIMER_CNT_LOW, 0);
	bus_space_write_4(sc->sc_iot, ioh, GTIMER_CNT_HIGH, 0);

	/* enable global timer */
	bus_space_write_4(sc->sc_iot, ioh, GTIMER_CTRL, GTIMER_CTRL_TIMER);

#if defined(USE_GTIMER_CMP)

	/* clear event */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_STATUS, 1);
#else
	bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_CTRL, 0);
	bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_STATUS,
	    PTIMER_STATUS_EVENT);
#endif

#ifdef AMPTIMER_DEBUG
	evcount_attach(&sc->sc_clk_count, "clock", NULL);
	evcount_attach(&sc->sc_stat_count, "stat", NULL);
#endif

	/*
	 * private timer and interrupts not enabled until
	 * timer configures
	 */

	arm_clock_register(amptimer_cpu_initclocks, amptimer_delay,
	    amptimer_setstatclockrate, amptimer_startclock);

	amptimer_timecounter.tc_frequency = sc->sc_ticks_per_second;
	amptimer_timecounter.tc_priv = sc;

	tc_init(&amptimer_timecounter);
}

u_int
amptimer_get_timecount(struct timecounter *tc)
{
	struct amptimer_softc *sc = amptimer_timecounter.tc_priv;
	return bus_space_read_4(sc->sc_iot, sc->sc_ioh, GTIMER_CNT_LOW);
}

int
amptimer_intr(void *frame)
{
	struct amptimer_softc	*sc = amptimer_cd.cd_devs[0];
	struct amptimer_pcpu_softc *pc = &sc->sc_pstat[CPU_INFO_UNIT(curcpu())];
	uint64_t		 now;
	uint64_t		 nextevent;
	uint32_t		 r, reg;
#if defined(USE_GTIMER_CMP)
	int			 skip = 1;
#else
	int64_t			 delay;
#endif
	int			 rc = 0;

	/*
	 * DSR - I know that the tick timer is 64 bits, but the following
	 * code deals with rollover, so there is no point in dealing
	 * with the 64 bit math, just let the 32 bit rollover
	 * do the right thing
	 */

	now = amptimer_readcnt64(sc);

	while (pc->pc_nexttickevent <= now) {
		pc->pc_nexttickevent += sc->sc_ticks_per_intr;
		pc->pc_ticks_err_sum += sc->sc_ticks_err_cnt;

		/* looping a few times is faster than divide */
		while (pc->pc_ticks_err_sum  > hz) {
			pc->pc_nexttickevent += 1;
			pc->pc_ticks_err_sum -= hz;
		}

#ifdef AMPTIMER_DEBUG
		sc->sc_clk_count.ec_count++;
#endif
		rc = 1;
		hardclock(frame);
	}
	while (pc->pc_nextstatevent <= now) {
		do {
			r = random() & (sc->sc_statvar -1);
		} while (r == 0); /* random == 0 not allowed */
		pc->pc_nextstatevent += sc->sc_statmin + r;

		/* XXX - correct nextstatevent? */
#ifdef AMPTIMER_DEBUG
		sc->sc_stat_count.ec_count++;
#endif
		rc = 1;
		statclock(frame);
	}

	if (pc->pc_nexttickevent < pc->pc_nextstatevent)
		nextevent = pc->pc_nexttickevent;
	else
		nextevent = pc->pc_nextstatevent;

#if defined(USE_GTIMER_CMP)
again:
	reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GTIMER_CTRL);
	reg &= ~GTIMER_CTRL_COMP;
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CTRL, reg);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CMP_LOW,
	    nextevent & 0xffffffff);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CMP_HIGH,
	    nextevent >> 32);
	reg |= GTIMER_CTRL_COMP;
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CTRL, reg);

	now = amptimer_readcnt64(sc);
	if (now >= nextevent) {
		nextevent = now + skip;
		skip += 1;
		goto again;
	}
#else
	/* clear old status */
	bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_STATUS,
	    PTIMER_STATUS_EVENT);

	delay = nextevent - now;
	if (delay < 0)
		delay = 1;

	reg = bus_space_read_4(sc->sc_iot, sc->sc_pioh, PTIMER_CTRL);
	if ((reg & (PTIMER_CTRL_ENABLE | PTIMER_CTRL_IRQEN)) !=
	    (PTIMER_CTRL_ENABLE | PTIMER_CTRL_IRQEN))
		bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_CTRL,
		    (PTIMER_CTRL_ENABLE | PTIMER_CTRL_IRQEN));

	bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_LOAD, delay);
#endif

	return (rc);
}

void
amptimer_set_clockrate(int32_t new_frequency)
{
	struct amptimer_softc	*sc = amptimer_cd.cd_devs[0];

	amptimer_frequency = new_frequency;

	if (sc == NULL)
		return;

	sc->sc_ticks_per_second = amptimer_frequency;
	amptimer_timecounter.tc_frequency = sc->sc_ticks_per_second;
	printf("amptimer0: adjusting clock: new tick rate %d KHz\n",
	    sc->sc_ticks_per_second /1000);
}

void
amptimer_cpu_initclocks()
{
	struct amptimer_softc	*sc = amptimer_cd.cd_devs[0];
	struct amptimer_pcpu_softc *pc = &sc->sc_pstat[CPU_INFO_UNIT(curcpu())];
	uint64_t		 next;
#if defined(USE_GTIMER_CMP)
	uint32_t		 reg;
#endif

	stathz = hz;
	profhz = hz * 10;

	if (sc->sc_ticks_per_second != amptimer_frequency) {
		amptimer_set_clockrate(amptimer_frequency);
	}

	amptimer_setstatclockrate(stathz);

	sc->sc_ticks_per_intr = sc->sc_ticks_per_second / hz;
	sc->sc_ticks_err_cnt = sc->sc_ticks_per_second % hz;
	pc->pc_ticks_err_sum = 0;

	/* establish interrupts */
	/* XXX - irq */
#if defined(USE_GTIMER_CMP)
	ampintc_intr_establish(27, IPL_CLOCK, amptimer_intr,
	    NULL, "tick");
#else
	ampintc_intr_establish(29, IPL_CLOCK, amptimer_intr,
	    NULL, "tick");
#endif

	next = amptimer_readcnt64(sc) + sc->sc_ticks_per_intr;
	pc->pc_nexttickevent = pc->pc_nextstatevent = next;

#if defined(USE_GTIMER_CMP)
	reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GTIMER_CTRL);
	reg &= ~GTIMER_CTRL_COMP;
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CTRL, reg);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CMP_LOW,
	    next & 0xffffffff);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CMP_HIGH,
	    next >> 32);
	reg |= GTIMER_CTRL_COMP | GTIMER_CTRL_IRQ;
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTIMER_CTRL, reg);
#else
	bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_CTRL,
	    (PTIMER_CTRL_ENABLE | PTIMER_CTRL_IRQEN));
	bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_LOAD,
	    sc->sc_ticks_per_intr);
#endif
}

void
amptimer_delay(u_int usecs)
{
	struct amptimer_softc	*sc = amptimer_cd.cd_devs[0];
	u_int32_t		clock, oclock, delta, delaycnt;
	volatile int		j;
	int			csec, usec;

	if (usecs > (0x80000000 / (sc->sc_ticks_per_second))) {
		csec = usecs / 10000;
		usec = usecs % 10000;

		delaycnt = (sc->sc_ticks_per_second / 100) * csec +
		    (sc->sc_ticks_per_second / 100) * usec / 10000;
	} else {
		delaycnt = sc->sc_ticks_per_second * usecs / 1000000;
	}
	if (delaycnt <= 1)
		for (j = 100; j > 0; j--)
			;

	oclock = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GTIMER_CNT_LOW);
	while (1) {
		for (j = 100; j > 0; j--)
			;
		clock = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
		    GTIMER_CNT_LOW);
		delta = clock - oclock;
		if (delta > delaycnt)
			break;
	}
}

void
amptimer_setstatclockrate(int newhz)
{
	struct amptimer_softc	*sc = amptimer_cd.cd_devs[0];
	int			 minint, statint;
	int			 s;

	s = splclock();

	statint = sc->sc_ticks_per_second / newhz;
	/* calculate largest 2^n which is smaller that just over half statint */
	sc->sc_statvar = 0x40000000; /* really big power of two */
	minint = statint / 2 + 100;
	while (sc->sc_statvar > minint)
		sc->sc_statvar >>= 1;

	sc->sc_statmin = statint - (sc->sc_statvar >> 1);

	splx(s);

	/*
	 * XXX this allows the next stat timer to occur then it switches
	 * to the new frequency. Rather than switching instantly.
	 */
}

void
amptimer_startclock(void)
{
	struct amptimer_softc	*sc = amptimer_cd.cd_devs[0];
	struct amptimer_pcpu_softc *pc = &sc->sc_pstat[CPU_INFO_UNIT(curcpu())];
	uint64_t nextevent;

	nextevent = amptimer_readcnt64(sc) + sc->sc_ticks_per_intr;
	pc->pc_nexttickevent = pc->pc_nextstatevent = nextevent;

	bus_space_write_4(sc->sc_iot, sc->sc_pioh, PTIMER_LOAD,
		sc->sc_ticks_per_intr);
}


code:
/* $OpenBSD: arml2cc.c,v 1.4 2015/05/20 00:39:16 jsg Exp $ */
/*
 * Copyright (c) 2013 Patrick Wildt <patrick@blueri.se>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/queue.h>
#include <sys/malloc.h>
#include <sys/device.h>
#include <sys/evcount.h>
#include <sys/socket.h>
#include <sys/timeout.h>
#include <machine/intr.h>
#include <machine/bus.h>
#include <arm/cpufunc.h>
#include <arm/cortex/cortex.h>
#include <arm/cortex/smc.h>

#define PL310_ERRATA_727915

/* offset from periphbase */
#define L2C_ADDR			0x2000
#define L2C_SIZE			0x1000

/* registers */
#define L2C_CACHE_ID			0x000
#define L2C_CACHE_TYPE			0x004
#define L2C_CTL				0x100
#define L2C_AUXCTL			0x104
#define L2C_TAG_RAM_CTL			0x108
#define L2C_DATA_RAM_CTL		0x10c
#define L2C_EVC_CTR_CTL			0x200
#define L2C_EVC_CTR0_CTL		0x204
#define L2C_EVC_CTR1_CTL		0x208
#define L2C_EVC_CTR0_VAL		0x20c
#define L2C_EVC_CTR1_VAL		0x210
#define L2C_INT_MASK			0x214
#define L2C_INT_MASK_STS		0x218
#define L2C_INT_RAW_STS			0x21c
#define L2C_INT_CLR			0x220
#define L2C_CACHE_SYNC			0x730
#define L2C_INV_PA			0x770
#define L2C_INV_WAY			0x77c
#define L2C_CLEAN_PA			0x7b0
#define L2C_CLEAN_INDEX			0x7b8
#define L2C_CLEAN_WAY			0x7bc
#define L2C_CLEAN_INV_PA		0x7f0
#define L2C_CLEAN_INV_INDEX		0x7f8
#define L2C_CLEAN_INV_WAY		0x7fc
#define L2C_D_LOCKDOWN0			0x900
#define L2C_I_LOCKDOWN0			0x904
#define L2C_D_LOCKDOWN1			0x908
#define L2C_I_LOCKDOWN1			0x90c
#define L2C_D_LOCKDOWN2			0x910
#define L2C_I_LOCKDOWN2			0x914
#define L2C_D_LOCKDOWN3			0x918
#define L2C_I_LOCKDOWN3			0x91c
#define L2C_D_LOCKDOWN4			0x920
#define L2C_I_LOCKDOWN4			0x924
#define L2C_D_LOCKDOWN5			0x928
#define L2C_I_LOCKDOWN5			0x92c
#define L2C_D_LOCKDOWN6			0x930
#define L2C_I_LOCKDOWN6			0x934
#define L2C_D_LOCKDOWN7			0x938
#define L2C_I_LOCKDOWN7			0x93c
#define L2C_LOCKDOWN_LINE_EN		0x950
#define L2C_UNLOCK_WAY			0x954
#define L2C_ADDR_FILTER_START		0xc00
#define L2C_ADDR_FILTER_END		0xc04
#define L2C_DEBUG_CTL			0xf40
#define L2C_PREFETCH_CTL		0xf60
#define L2C_POWER_CTL			0xf80

#define L2C_CACHE_ID_RELEASE_MASK	0x3f
#define L2C_CACHE_TYPE_LINESIZE		0x3
#define L2C_AUXCTL_ASSOC_SHIFT		16
#define L2C_AUXCTL_ASSOC_MASK		0x1

#define roundup2(size, unit) (((size) + (unit) - 1) & ~((unit) - 1))

struct arml2cc_softc {
	struct device		sc_dev;
	bus_space_tag_t		sc_iot;
	bus_space_handle_t	sc_ioh;
	uint32_t		sc_enabled;
	uint32_t		sc_waymask;
	uint32_t		sc_dcache_line_size;
};

struct arml2cc_softc *arml2cc_sc;

int arml2cc_match(struct device *, void *, void *);
void arml2cc_attach(struct device *parent, struct device *self, void *args);
void arml2cc_enable(struct arml2cc_softc *);
void arml2cc_disable(struct arml2cc_softc *);
void arml2cc_sdcache_wbinv_all(void);
void arml2cc_sdcache_wbinv_range(vaddr_t, paddr_t, psize_t);
void arml2cc_sdcache_inv_range(vaddr_t, paddr_t, psize_t);
void arml2cc_sdcache_wb_range(vaddr_t, paddr_t, psize_t);
void arml2cc_cache_range_op(paddr_t, psize_t, bus_size_t);
void arml2cc_cache_way_op(struct arml2cc_softc *, bus_size_t, uint32_t);
void arml2cc_cache_op(struct arml2cc_softc *, bus_size_t, uint32_t);
void arml2cc_cache_sync(struct arml2cc_softc *);

struct cfattach armliicc_ca = {
	sizeof (struct arml2cc_softc), arml2cc_match, arml2cc_attach
};

struct cfdriver armliicc_cd = {
	NULL, "armliicc", DV_DULL
};

int
arml2cc_match(struct device *parent, void *cfdata, void *aux)
{
	if ((cpufunc_id() & CPU_ID_CORTEX_A9_MASK) == CPU_ID_CORTEX_A9)
		return (1);

	return (0);
}

void
arml2cc_attach(struct device *parent, struct device *self, void *args)
{
	struct cortex_attach_args *ia = args;
	struct arml2cc_softc *sc = (struct arml2cc_softc *) self;

	sc->sc_iot = ia->ca_iot;
	if (bus_space_map(sc->sc_iot, ia->ca_periphbase + L2C_ADDR,
	    L2C_SIZE, 0, &sc->sc_ioh))
		panic("arml2cc_attach: bus_space_map failed!");

	printf(": rtl %d", bus_space_read_4(sc->sc_iot, sc->sc_ioh,
	    L2C_CACHE_ID) & 0x3f);

	arml2cc_sc = sc;

	if (bus_space_read_4(sc->sc_iot, sc->sc_ioh, L2C_CTL))
		panic("L2 Cache controller was already enabled\n");

	sc->sc_dcache_line_size = 32 << (bus_space_read_4(sc->sc_iot, sc->sc_ioh, L2C_CACHE_TYPE) & L2C_CACHE_TYPE_LINESIZE);
	sc->sc_waymask = (8 << ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, L2C_AUXCTL)
			    >> L2C_AUXCTL_ASSOC_SHIFT) & L2C_AUXCTL_ASSOC_MASK)) - 1;
	printf(" waymask: 0x%08x\n", sc->sc_waymask);

	arml2cc_enable(sc);
	sc->sc_enabled = 1;

	arml2cc_sdcache_wbinv_all();

	cpufuncs.cf_sdcache_wbinv_all = arml2cc_sdcache_wbinv_all;
	cpufuncs.cf_sdcache_wbinv_range = arml2cc_sdcache_wbinv_range;
	cpufuncs.cf_sdcache_inv_range = arml2cc_sdcache_inv_range;
	cpufuncs.cf_sdcache_wb_range = arml2cc_sdcache_wb_range;
}

void
arml2cc_enable(struct arml2cc_softc *sc)
{
	int s;
	s = splhigh();

	platform_smc_write(sc->sc_iot, sc->sc_ioh, L2C_CTL, SMC_L2_CTL,
	    1);

	arml2cc_cache_way_op(sc, L2C_INV_WAY, sc->sc_waymask);
	arml2cc_cache_sync(sc);

	splx(s);
}

void
arml2cc_disable(struct arml2cc_softc *sc)
{
	int s;
	s = splhigh();

	arml2cc_cache_way_op(sc, L2C_CLEAN_INV_WAY, sc->sc_waymask);
	arml2cc_cache_sync(sc);

	platform_smc_write(sc->sc_iot, sc->sc_ioh, L2C_CTL, SMC_L2_CTL, 0);

	splx(s);
}

void
arml2cc_cache_op(struct arml2cc_softc *sc, bus_size_t off, uint32_t val)
{
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, val);
	while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, off) & 1) {
		/* spin */
	}
}

void
arml2cc_cache_way_op(struct arml2cc_softc *sc, bus_size_t off, uint32_t way_mask)
{
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, way_mask);
	while (bus_space_read_4(sc->sc_iot, sc->sc_ioh, off) & way_mask) {
		/* spin */
	}
}

void
arml2cc_cache_sync(struct arml2cc_softc *sc)
{
	/* ARM Errata 753970 */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, 0x740, 0xffffffff);
}

void
arml2cc_cache_range_op(paddr_t pa, psize_t len, bus_size_t cache_op)
{
	struct arml2cc_softc * const sc = arml2cc_sc;
	size_t line_size = sc->sc_dcache_line_size;
	size_t line_mask = line_size - 1;
	paddr_t endpa;

	endpa = pa + len;
	pa = pa & ~line_mask;

	// printf("l2inv op %x %08x %08x incr %d %d\n", cache_op, pa, endpa, line_size, len);
	while (endpa > pa) {
		arml2cc_cache_op(sc, cache_op, pa);
		pa += line_size;
	}
}

void
arml2cc_sdcache_wbinv_all(void)
{
	struct arml2cc_softc *sc = arml2cc_sc;
	if (sc == NULL || !sc->sc_enabled)
		return;

#ifdef PL310_ERRATA_727915
	platform_smc_write(sc->sc_iot, sc->sc_ioh, L2C_DEBUG_CTL, SMC_L2_DBG, 3);
#endif

	bus_space_write_4(sc->sc_iot, sc->sc_ioh, L2C_CLEAN_INV_WAY, sc->sc_waymask);
	while(bus_space_read_4(sc->sc_iot, sc->sc_ioh, L2C_CLEAN_INV_WAY) & sc->sc_waymask);

#ifdef PL310_ERRATA_727915
	platform_smc_write(sc->sc_iot, sc->sc_ioh, L2C_DEBUG_CTL, SMC_L2_DBG, 0);
#endif

	arml2cc_cache_sync(sc);
}
void
arml2cc_sdcache_wbinv_range(vaddr_t va, paddr_t pa, psize_t len)
{
	struct arml2cc_softc *sc = arml2cc_sc;
	if (sc == NULL || !sc->sc_enabled)
		return;

#ifdef PL310_ERRATA_727915
	platform_smc_write(sc->sc_iot, sc->sc_ioh, L2C_DEBUG_CTL, SMC_L2_DBG, 3);
#endif

	arml2cc_cache_range_op(pa, len, L2C_CLEAN_INV_PA);
	arml2cc_cache_sync(sc);

#ifdef PL310_ERRATA_727915
	platform_smc_write(sc->sc_iot, sc->sc_ioh, L2C_DEBUG_CTL, SMC_L2_DBG, 0);
#endif
}

void
arml2cc_sdcache_inv_range(vaddr_t va, paddr_t pa, psize_t len)
{
	struct arml2cc_softc *sc = arml2cc_sc;
	if (sc == NULL || !sc->sc_enabled)
		return;
	arml2cc_cache_range_op(pa, len, L2C_INV_PA);
	arml2cc_cache_sync(sc);
}

void
arml2cc_sdcache_wb_range(vaddr_t va, paddr_t pa, psize_t len)
{
	struct arml2cc_softc *sc = arml2cc_sc;
	if (sc == NULL || !sc->sc_enabled)
		return;
	arml2cc_cache_range_op(pa, len, L2C_CLEAN_PA);
	arml2cc_cache_sync(sc);
}

license: unknown


code:
/*	$OpenBSD: cortex.c,v 1.3 2015/05/29 05:48:07 jsg Exp $	*/
/* $NetBSD: mainbus.c,v 1.3 2001/06/13 17:52:43 nathanw Exp $ */

/*
 * Copyright (c) 1994,1995 Mark Brinicombe.
 * Copyright (c) 1994 Brini.
 * 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 Brini.
 * 4. The name of the company nor the name of the author may be used to
 *    endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
 *
 * RiscBSD kernel project
 *
 * mainbus.c
 *
 * mainbus configuration
 *
 * Created      : 15/12/94
 */

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <arm/cpufunc.h>
#include <arm/armv7/armv7var.h>
#include <arm/cortex/cortex.h>

struct arm32_bus_dma_tag cortex_bus_dma_tag = {
	0,
	0,
	NULL,
	_bus_dmamap_create,
	_bus_dmamap_destroy,
	_bus_dmamap_load,
	_bus_dmamap_load_mbuf,
	_bus_dmamap_load_uio,
	_bus_dmamap_load_raw,
	_bus_dmamap_unload,
	_bus_dmamap_sync,
	_bus_dmamem_alloc,
	_bus_dmamem_free,
	_bus_dmamem_map,
	_bus_dmamem_unmap,
	_bus_dmamem_mmap,
};

/* Prototypes for functions provided */

int  cortexmatch(struct device *, void *, void *);
void cortexattach(struct device *, struct device *, void *);
int  cortexprint(void *aux, const char *cortex);
int cortexsearch(struct device *,  void *, void *);

/* attach and device structures for the device */

struct cfattach cortex_ca = {
	sizeof(struct device), cortexmatch, cortexattach, NULL,
	config_activate_children
};

struct cfdriver cortex_cd = {
	NULL, "cortex", DV_DULL
};

/*
 * int cortexmatch(struct device *parent, struct cfdata *cf, void *aux)
 */

int
cortexmatch(struct device *parent, void *cf, void *aux)
{
	int cputype = cpufunc_id();

	if ((cputype & CPU_ID_CORTEX_A7_MASK) == CPU_ID_CORTEX_A7 ||
	    (cputype & CPU_ID_CORTEX_A9_MASK) == CPU_ID_CORTEX_A9 ||
	    (cputype & CPU_ID_CORTEX_A15_MASK) == CPU_ID_CORTEX_A15 ||
	    (cputype & CPU_ID_CORTEX_A17_MASK) == CPU_ID_CORTEX_A17) {
		if (armv7_periphbase())
			return (1);
	}

	return (0);
}

/*
 * void cortexattach(struct device *parent, struct device *self, void *aux)
 *
 * probe and attach all children
 */

void
cortexattach(struct device *parent, struct device *self, void *aux)
{
	printf("\n");

	config_search(cortexsearch, self, aux);
}

int
cortexsearch(struct device *parent, void *vcf, void *aux)
{
	struct cortex_attach_args ca;
	struct cfdata *cf = vcf;

	ca.ca_name = cf->cf_driver->cd_name;
	ca.ca_iot = &armv7_bs_tag;
	ca.ca_dmat = &cortex_bus_dma_tag;
	ca.ca_periphbase = armv7_periphbase();

	/* allow for devices to be disabled in UKC */
	if ((*cf->cf_attach->ca_match)(parent, cf, &ca) == 0)
		return 0;

	config_attach(parent, cf, &ca, cortexprint);
	return 1;
}

/*
 * int cortexprint(void *aux, const char *cortex)
 *
 * print routine used during config of children
 */

int
cortexprint(void *aux, const char *cortex)
{
	struct cortex_attach_args *ca = aux;

	if (cortex != NULL)
		printf("%s at %s", ca->ca_name, cortex);

	return (UNCONF);
}


code:
/*	$OpenBSD: cortex.h,v 1.1 2013/05/01 00:16:26 patrick Exp $	*/
/* $NetBSD: mainbus.h,v 1.1 2001/02/24 19:38:02 reinoud Exp $ */

/*
 * Copyright (c) 1994,1995 Mark Brinicombe.
 * Copyright (c) 1994 Brini.
 * 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 Brini.
 * 4. The name of the company nor the name of the author may be used to
 *    endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
 *
 * RiscBSD kernel project
 *
 * mainbus.h
 *
 * mainbus configuration
 *
 * Created      : 15/12/94
 */

/*
 * cortex driver attach arguments
 */

struct cortex_attach_args {
	char *ca_name;
	bus_space_tag_t ca_iot;
	bus_dma_tag_t ca_dmat;
	uint32_t ca_periphbase;
};


code:
#	$OpenBSD: files.cortex,v 1.3 2013/09/09 14:31:54 patrick Exp $

# ARM core
device	cortex {}
attach	cortex at mainbus
file	arch/arm/cortex/cortex.c		cortex

device	ampintc
attach	ampintc at cortex
file	arch/arm/cortex/ampintc.c		ampintc

device	amptimer
attach	amptimer at cortex
file	arch/arm/cortex/amptimer.c		amptimer

device	agtimer
attach	agtimer at cortex
file	arch/arm/cortex/agtimer.c		agtimer

device	armliicc
attach	armliicc at cortex
file	arch/arm/cortex/arml2cc.c		armliicc


code:
/*	$OpenBSD: smc.h,v 1.1 2013/05/01 14:09:50 patrick Exp $	*/
/*
 * Copyright (c) 2013 Dale Rahn <drahn@dalerahn.com>
 *
 * 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.
 */

/* SMC interface for hardware */

#ifdef _KERNEL

/* XXX these defines go here ? */
#define SMC_L2_DBG	0x100
#define SMC_L2_CTL	0x102

void platform_smc_write(bus_space_tag_t, bus_space_handle_t, bus_size_t,
    uint32_t, uint32_t);

#endif /* _KERNEL */


code: src/sys/arch/arm/include

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


code:
/*	$OpenBSD: _float.h,v 1.1 2012/06/26 16:12:43 deraadt 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. 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, Berkeley and its contributors.
 * 4. 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.
 */

#ifndef _MACHINE__FLOAT_H_
#define _MACHINE__FLOAT_H_

#define __FLT_RADIX		2		/* b */
#define __FLT_ROUNDS		__flt_rounds()
#define __FLT_EVAL_METHOD	0		/* no promotions */

#define __FLT_MANT_DIG		24		/* p */
#define __FLT_EPSILON		1.19209290E-7F	/* b**(1-p) */
#define __FLT_DIG		6		/* floor((p-1)*log10(b))+(b == 10) */
#define __FLT_MIN_EXP		(-125)		/* emin */
#define __FLT_MIN		1.17549435E-38F	/* b**(emin-1) */
#define __FLT_MIN_10_EXP	(-37)		/* ceil(log10(b**(emin-1))) */
#define __FLT_MAX_EXP		128		/* emax */
#define __FLT_MAX		3.40282347E+38F	/* (1-b**(-p))*b**emax */
#define __FLT_MAX_10_EXP	38		/* floor(log10((1-b**(-p))*b**emax)) */

#define __DBL_MANT_DIG		53
#define __DBL_EPSILON		2.2204460492503131E-16
#define __DBL_DIG		15
#define __DBL_MIN_EXP		(-1021)
#define __DBL_MIN		2.2250738585072014E-308
#define __DBL_MIN_10_EXP	(-307)
#define __DBL_MAX_EXP		1024
#define __DBL_MAX		1.7976931348623157E+308
#define __DBL_MAX_10_EXP	308

#define __LDBL_MANT_DIG		DBL_MANT_DIG
#define __LDBL_EPSILON		DBL_EPSILON
#define __LDBL_DIG		DBL_DIG
#define __LDBL_MIN_EXP		DBL_MIN_EXP
#define __LDBL_MIN		DBL_MIN
#define __LDBL_MIN_10_EXP	DBL_MIN_10_EXP
#define __LDBL_MAX_EXP		DBL_MAX_EXP
#define __LDBL_MAX		DBL_MAX
#define __LDBL_MAX_10_EXP	DBL_MAX_10_EXP

#define __DECIMAL_DIG		17

#endif /* _MACHINE__FLOAT_H_ */


code:
/*	$OpenBSD: _types.h,v 1.16 2014/03/19 05:14:13 guenther Exp $	*/

/*-
 * Copyright (c) 1990, 1993
 *	The Regents of the University of California.  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. 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.
 *
 *	@(#)types.h	8.3 (Berkeley) 1/5/94
 *	@(#)ansi.h	8.2 (Berkeley) 1/4/94
 */

#ifndef _ARM__TYPES_H_
#define _ARM__TYPES_H_

#if defined(_KERNEL)
typedef struct label_t {
	long val[11];
} label_t;
#endif

/*
 * _ALIGN(p) rounds p (pointer or byte index) up to a correctly-aligned
 * value for all data types (int, long, ...).   The result is an
 * unsigned long and must be cast to any desired pointer type.
 *
 * _ALIGNED_POINTER is a boolean macro that checks whether an address
 * is valid to fetch data elements of type t from on this architecture.
 * This does not reflect the optimal alignment, just the possibility
 * (within reasonable limits).
 */
#define	_ALIGNBYTES		(sizeof(int) - 1)
#define	_STACKALIGNBYTES	7
#define	_ALIGN(p)		(((unsigned long)(p) + _ALIGNBYTES) & ~_ALIGNBYTES)
#define	_ALIGNED_POINTER(p,t)	((((unsigned long)(p)) & (sizeof(t) - 1)) == 0)

/* 7.18.1.1 Exact-width integer types */
typedef	signed char		__int8_t;
typedef	unsigned char		__uint8_t;
typedef	short			__int16_t;
typedef	unsigned short		__uint16_t;
typedef	int			__int32_t;
typedef	unsigned int		__uint32_t;
/* LONGLONG */
typedef	long long		__int64_t;
/* LONGLONG */
typedef	unsigned long long	__uint64_t;

/* 7.18.1.2 Minimum-width integer types */
typedef	__int8_t		__int_least8_t;
typedef	__uint8_t		__uint_least8_t;
typedef	__int16_t		__int_least16_t;
typedef	__uint16_t		__uint_least16_t;
typedef	__int32_t		__int_least32_t;
typedef	__uint32_t		__uint_least32_t;
typedef	__int64_t		__int_least64_t;
typedef	__uint64_t		__uint_least64_t;

/* 7.18.1.3 Fastest minimum-width integer types */
typedef	__int32_t		__int_fast8_t;
typedef	__uint32_t		__uint_fast8_t;
typedef	__int32_t		__int_fast16_t;
typedef	__uint32_t		__uint_fast16_t;
typedef	__int32_t		__int_fast32_t;
typedef	__uint32_t		__uint_fast32_t;
typedef	__int64_t		__int_fast64_t;
typedef	__uint64_t		__uint_fast64_t;
#define	__INT_FAST8_MIN		INT32_MIN
#define	__INT_FAST16_MIN	INT32_MIN
#define	__INT_FAST32_MIN	INT32_MIN
#define	__INT_FAST64_MIN	INT64_MIN
#define	__INT_FAST8_MAX		INT32_MAX
#define	__INT_FAST16_MAX	INT32_MAX
#define	__INT_FAST32_MAX	INT32_MAX
#define	__INT_FAST64_MAX	INT64_MAX
#define	__UINT_FAST8_MAX	UINT32_MAX
#define	__UINT_FAST16_MAX	UINT32_MAX
#define	__UINT_FAST32_MAX	UINT32_MAX
#define	__UINT_FAST64_MAX	UINT64_MAX

/* 7.18.1.4 Integer types capable of holding object pointers */
typedef	long			__intptr_t;
typedef	unsigned long		__uintptr_t;

/* 7.18.1.5 Greatest-width integer types */
typedef	__int64_t		__intmax_t;
typedef	__uint64_t		__uintmax_t;

/* Register size */
typedef long			__register_t;

/* VM system types */
typedef unsigned long		__vaddr_t;
typedef unsigned long		__paddr_t;
typedef unsigned long		__vsize_t;
typedef unsigned long		__psize_t;

/* Standard system types */
typedef double			__double_t;
typedef float			__float_t;
typedef long			__ptrdiff_t;
typedef	unsigned long		__size_t;
typedef	long			__ssize_t;
#if defined(__GNUC__) && __GNUC__ >= 3
typedef	__builtin_va_list	__va_list;
#else
typedef	char *			__va_list;
#endif

/* Wide character support types */
#ifndef __cplusplus
typedef	int			__wchar_t;
#endif
typedef int			__wint_t;
typedef	int			__rune_t;
typedef	void *			__wctrans_t;
typedef	void *			__wctype_t;

#endif	/* _ARM__TYPES_H_ */


code:
/*	$OpenBSD: apmvar.h,v 1.4 2015/02/07 22:16:52 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 _ARM_APMVAR_H_
#define _ARM_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 /* _ARM_APMVAR_H_ */


code:
/*	$OpenBSD: armreg.h,v 1.16 2015/05/29 05:48:07 jsg Exp $	*/
/*	$NetBSD: armreg.h,v 1.27 2003/09/06 08:43:02 rearnsha Exp $	*/

/*
 * Copyright (c) 1998, 2001 Ben Harris
 * Copyright (c) 1994-1996 Mark Brinicombe.
 * Copyright (c) 1994 Brini.
 * All rights reserved.
 *
 * This code is derived from software written for Brini by Mark Brinicombe
 *
 * 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 Brini.
 * 4. The name of the company nor the name of the author may be used to
 *    endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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.
 */

#ifndef _ARM_ARMREG_H
#define _ARM_ARMREG_H

/*
 * ARM Process Status Register
 *
 * The picture in early ARM manuals looks like this:
 *       3 3 2 2 2 2
 *       1 0 9 8 7 6                                   8 7 6 5 4       0
 *      +-+-+-+-+-+-------------------------------------+-+-+-+---------+
 *      |N|Z|C|V|Q|                reserved             |I|F|T|M M M M M|
 *      | | | | | |                                     | | | |4 3 2 1 0|
 *      +-+-+-+-+-+-------------------------------------+-+-+-+---------+
 *
 * The picture in the ARMv7-A manuals looks like this:
 *       3 3 2 2 2 2 2 2 2     2 1     1 1         1
 *       1 0 9 8 7 6 5 4 3     0 9     6 5         0 9 8 7 6 5 4       0
 *      +-+-+-+-+-+---+-+-------+-------+-----------+-+-+-+-+-+---------+
 *      |N|Z|C|V|Q|I I|J|reserv-|G G G G|I I I I I I|E|A|I|F|T|M M M M M|
 *      | | | | | |T T| |ed     |E E E E|T T T T T T| | | | | |         |
 *      | | | | | |1 0| |       |3 2 1 0|7 6 5 4 3 2| | | | | |4 3 2 1 0|
 *      +-+-+-+-+-+---+-+-------+-------+-----------+-+-+-+-+-+---------+
 *      | flags 'f'     | status 's'    | extension 'x' | control 'c'   |
 */

#define PSR_FLAGS 0xf0000000	/* flags */
#define PSR_N_bit (1U << 31)	/* negative */
#define PSR_Z_bit (1 << 30)	/* zero */
#define PSR_C_bit (1 << 29)	/* carry */
#define PSR_V_bit (1 << 28)	/* overflow */

#define PSR_Q_bit (1 << 27)	/* saturation */

#define I32_bit (1 << 7)	/* IRQ disable */
#define F32_bit (1 << 6)	/* FIQ disable */

#define PSR_T_bit (1 << 5)	/* Thumb state */
#define PSR_J_bit (1 << 24)	/* Java mode */

#define PSR_MODE	0x0000001f	/* mode mask */
#define PSR_USR26_MODE	0x00000000
#define PSR_FIQ26_MODE	0x00000001
#define PSR_IRQ26_MODE	0x00000002
#define PSR_SVC26_MODE	0x00000003
#define PSR_USR32_MODE	0x00000010
#define PSR_FIQ32_MODE	0x00000011
#define PSR_IRQ32_MODE	0x00000012
#define PSR_SVC32_MODE	0x00000013
#define PSR_ABT32_MODE	0x00000017
#define PSR_UND32_MODE	0x0000001b
#define PSR_SYS32_MODE	0x0000001f
#define PSR_32_MODE	0x00000010

#define PSR_IN_USR_MODE(psr)	(!((psr) & 3))		/* XXX */

/*
 * Co-processor 15:  The system control co-processor.
 */

#define ARM_CP15_CPU_ID		0

/*
 * The CPU ID register is theoretically structured, but the definitions of
 * the fields keep changing.
 */

/* The high-order byte is always the implementor */
#define CPU_ID_IMPLEMENTOR_MASK	0xff000000
#define CPU_ID_ARM_LTD		0x41000000 /* 'A' */
#define CPU_ID_DEC		0x44000000 /* 'D' */
#define CPU_ID_INTEL		0x69000000 /* 'i' */
#define CPU_ID_TI		0x54000000 /* 'T' */

/* How to decide what format the CPUID is in. */
#define CPU_ID_ISOLD(x)		(((x) & 0x0000f000) == 0x00000000)
#define CPU_ID_IS7(x)		(((x) & 0x0000f000) == 0x00007000)
#define CPU_ID_ISNEW(x)		(!CPU_ID_ISOLD(x) && !CPU_ID_IS7(x))

/* On ARM3 and ARM6, this byte holds the foundry ID. */
#define CPU_ID_FOUNDRY_MASK	0x00ff0000
#define CPU_ID_FOUNDRY_VLSI	0x00560000

/* On ARM7 it holds the architecture and variant (sub-model) */
#define CPU_ID_7ARCH_MASK	0x00800000
#define CPU_ID_7ARCH_V3		0x00000000
#define CPU_ID_7ARCH_V4T	0x00800000
#define CPU_ID_7VARIANT_MASK	0x007f0000

/* On more recent ARMs, it does the same, but in a different format */
#define CPU_ID_ARCH_MASK	0x000f0000
#define CPU_ID_ARCH_V3		0x00000000
#define CPU_ID_ARCH_V4		0x00010000
#define CPU_ID_ARCH_V4T		0x00020000
#define CPU_ID_ARCH_V5		0x00030000
#define CPU_ID_ARCH_V5T		0x00040000
#define CPU_ID_ARCH_V5TE	0x00050000
#define CPU_ID_ARCH_V6		0x00070000
#define CPU_ID_ARCH_V7		0x00080000
#define CPU_ID_VARIANT_MASK	0x00f00000

/* Next three nybbles are part number */
#define CPU_ID_PARTNO_MASK	0x0000fff0

/* Intel XScale has sub fields in part number */
#define CPU_ID_XSCALE_COREGEN_MASK	0x0000e000 /* core generation */
#define CPU_ID_XSCALE_COREREV_MASK	0x00001c00 /* core revision */
#define CPU_ID_XSCALE_PRODUCT_MASK	0x000003f0 /* product number */

/* And finally, the revision number. */
#define CPU_ID_REVISION_MASK	0x0000000f

/* Individual CPUs are probably best IDed by everything but the revision. */
#define CPU_ID_CPU_MASK		0xfffffff0

/* Fake CPU IDs for ARMs without CP15 */
#define CPU_ID_ARM2		0x41560200
#define CPU_ID_ARM250		0x41560250

/* Pre-ARM7 CPUs -- [15:12] == 0 */
#define CPU_ID_ARM3		0x41560300
#define CPU_ID_ARM600		0x41560600
#define CPU_ID_ARM610		0x41560610
#define CPU_ID_ARM620		0x41560620

/* ARM7 CPUs -- [15:12] == 7 */
#define CPU_ID_ARM700		0x41007000 /* XXX This is a guess. */
#define CPU_ID_ARM710		0x41007100
#define CPU_ID_ARM7500		0x41027100 /* XXX This is a guess. */
#define CPU_ID_ARM710A		0x41047100 /* inc ARM7100 */
#define CPU_ID_ARM7500FE	0x41077100
#define CPU_ID_ARM710T		0x41807100
#define CPU_ID_ARM720T		0x41807200
#define CPU_ID_ARM740T8K	0x41807400 /* XXX no MMU, 8KB cache */
#define CPU_ID_ARM740T4K	0x41817400 /* XXX no MMU, 4KB cache */

/* Post-ARM7 CPUs */
#define CPU_ID_ARM810		0x41018100
#define CPU_ID_ARM920T		0x41129200
#define CPU_ID_ARM922T		0x41029220
#define CPU_ID_ARM926EJS	0x41069260
#define CPU_ID_ARM940T		0x41029400 /* XXX no MMU */
#define CPU_ID_ARM946ES		0x41049460 /* XXX no MMU */
#define CPU_ID_ARM966ES		0x41049660 /* XXX no MMU */
#define CPU_ID_ARM966ESR1	0x41059660 /* XXX no MMU */
#define CPU_ID_ARM1020E		0x4115a200 /* (AKA arm10 rev 1) */
#define CPU_ID_ARM1022ES	0x4105a220
#define CPU_ID_ARM1026EJS	0x4106a260
#define CPU_ID_ARM1136JS	0x4107b360
#define CPU_ID_ARM1136JSR1	0x4117b360
#define CPU_ID_SA110		0x4401a100
#define CPU_ID_SA1100		0x4401a110
#define CPU_ID_TI925T		0x54029250
#define CPU_ID_SA1110		0x6901b110
#define CPU_ID_IXP1200		0x6901c120
#define CPU_ID_80200		0x69052000
#define CPU_ID_PXA250		0x69052100 /* sans core revision */
#define CPU_ID_PXA210		0x69052120
#define CPU_ID_PXA250A		0x69052100 /* 1st version Core */
#define CPU_ID_PXA210A		0x69052120 /* 1st version Core */
#define CPU_ID_PXA250B		0x69052900 /* 3rd version Core */
#define CPU_ID_PXA210B		0x69052920 /* 3rd version Core */
#define CPU_ID_PXA250C		0x69052d00 /* 4th version Core */
#define CPU_ID_PXA210C		0x69052d20 /* 4th version Core */
#define CPU_ID_80219_400        0x69052e20
#define CPU_ID_80219_600        0x69052e30
#define CPU_ID_PXA27X		0x69054110
#define CPU_ID_80321_400	0x69052420
#define CPU_ID_80321_600	0x69052430
#define CPU_ID_80321_400_B0	0x69052c20
#define CPU_ID_80321_600_B0	0x69052c30
#define CPU_ID_IXP425_533	0x690541c0
#define CPU_ID_IXP425_400	0x690541d0
#define CPU_ID_IXP425_266	0x690541f0
#define CPU_ID_CORTEX_A5	0x410fc050
#define CPU_ID_CORTEX_A5_MASK	0xff0ffff0
#define CPU_ID_CORTEX_A7	0x410fc070
#define CPU_ID_CORTEX_A7_MASK	0xff0ffff0
#define CPU_ID_CORTEX_A8_R1	0x411fc080
#define CPU_ID_CORTEX_A8_R2	0x412fc080
#define CPU_ID_CORTEX_A8_R3	0x413fc080
#define CPU_ID_CORTEX_A8	0x410fc080
#define CPU_ID_CORTEX_A8_MASK	0xff0ffff0
#define CPU_ID_CORTEX_A9	0x410fc090
#define CPU_ID_CORTEX_A9_R1	0x411fc090
#define CPU_ID_CORTEX_A9_R2	0x412fc090
#define CPU_ID_CORTEX_A9_R3	0x413fc090
#define CPU_ID_CORTEX_A9_R4	0x414fc090
#define CPU_ID_CORTEX_A9_MASK	0xff0ffff0
#define CPU_ID_CORTEX_A15	0x410fc0f0
#define CPU_ID_CORTEX_A15_R1	0x411fc0f0
#define CPU_ID_CORTEX_A15_R2	0x412fc0f0
#define CPU_ID_CORTEX_A15_R3	0x413fc0f0
#define CPU_ID_CORTEX_A15_R4	0x414fc0f0
#define CPU_ID_CORTEX_A15_MASK	0xff0ffff0
#define CPU_ID_CORTEX_A17	0x410fc0e0
#define CPU_ID_CORTEX_A17_R1	0x411fc0e0
#define CPU_ID_CORTEX_A17_MASK	0xff0ffff0
#define CPU_ID_CORTEX_A53	0x410fd030
#define CPU_ID_CORTEX_A53_R1	0x411fd030
#define CPU_ID_CORTEX_A53_MASK	0xff0ffff0
#define CPU_ID_CORTEX_A57	0x410fd070
#define CPU_ID_CORTEX_A57_R1	0x411fd070
#define CPU_ID_CORTEX_A57_MASK	0xff0ffff0
#define CPU_ID_CORTEX_A72	0x410fd080
#define CPU_ID_CORTEX_A72_R1	0x411fd080
#define CPU_ID_CORTEX_A57_MASK	0xff0ffff0

/* ARM3-specific coprocessor 15 registers */
#define ARM3_CP15_FLUSH		1
#define ARM3_CP15_CONTROL	2
#define ARM3_CP15_CACHEABLE	3
#define ARM3_CP15_UPDATEABLE	4
#define ARM3_CP15_DISRUPTIVE	5

/* ARM3 Control register bits */
#define ARM3_CTL_CACHE_ON	0x00000001
#define ARM3_CTL_SHARED		0x00000002
#define ARM3_CTL_MONITOR	0x00000004

/*
 * Post-ARM3 CP15 registers:
 *
 *	1	Control register
 *
 *	2	Translation Table Base
 *
 *	3	Domain Access Control
 *
 *	4	Reserved
 *
 *	5	Fault Status
 *
 *	6	Fault Address
 *
 *	7	Cache/write-buffer Control
 *
 *	8	TLB Control
 *
 *	9	Cache Lockdown
 *
 *	10	TLB Lockdown
 *
 *	11	Reserved
 *
 *	12	Reserved
 *
 *	13	Process ID (for FCSE)
 *
 *	14	Reserved
 *
 *	15	Implementation Dependent
 */

/* Some of the definitions below need cleaning up for V3/V4 architectures */

/* CPU control register (CP15 register 1) */
#define CPU_CONTROL_MMU_ENABLE	0x00000001 /* M: MMU/Protection unit enable */
#define CPU_CONTROL_AFLT_ENABLE	0x00000002 /* A: Alignment fault enable */
#define CPU_CONTROL_DC_ENABLE	0x00000004 /* C: IDC/DC enable */
#define CPU_CONTROL_WBUF_ENABLE 0x00000008 /* W: Write buffer enable */
#define CPU_CONTROL_32BP_ENABLE 0x00000010 /* P: 32-bit exception handlers */
#define CPU_CONTROL_32BD_ENABLE 0x00000020 /* D: 32-bit addressing */
#define CPU_CONTROL_LABT_ENABLE 0x00000040 /* L: Late abort enable */
#define CPU_CONTROL_BEND_ENABLE 0x00000080 /* B: Big-endian mode */
#define CPU_CONTROL_SYST_ENABLE 0x00000100 /* S: System protection bit */
#define CPU_CONTROL_ROM_ENABLE	0x00000200 /* R: ROM protection bit */
#define CPU_CONTROL_CPCLK	0x00000400 /* F: Implementation defined */
#define CPU_CONTROL_BPRD_ENABLE 0x00000800 /* Z: Branch prediction enable */
#define CPU_CONTROL_IC_ENABLE   0x00001000 /* I: IC enable */
#define CPU_CONTROL_VECRELOC	0x00002000 /* V: Vector relocation */
#define CPU_CONTROL_ROUNDROBIN	0x00004000 /* RR: Predictable replacement */
#define CPU_CONTROL_V4COMPAT	0x00008000 /* L4: ARMv4 compat LDR R15 etc */

/* below were added by V6 */
#define CPU_CONTROL_FI		(1<<21) /* FI: fast interrupts */
#define CPU_CONTROL_U		(1<<22) /* U: Unaligned */
#define CPU_CONTROL_VE		(1<<24) /* VE: Vector enable */
#define CPU_CONTROL_EE		(1<<25) /* EE: Exception Endianness */
#define CPU_CONTROL_L2		(1<<25) /* L2: L2 cache enable */

/* added with v7 */
#define CPU_CONTROL_NMFI	(1<<27) /* NMFI: Non Maskable fast interrupt */
#define CPU_CONTROL_TRE		(1<<28) /* TRE: TEX Remap Enable */
#define CPU_CONTROL_AFE		(1<<29) /* AFE: Access Flag Enable */
#define CPU_CONTROL_TE		(1<<30) /* TE: Thumb Exception Enable */

#define CPU_CONTROL_IDC_ENABLE	CPU_CONTROL_DC_ENABLE

/* XScale Auxillary Control Register (CP15 register 1, opcode2 1) */
#define XSCALE_AUXCTL_K		0x00000001 /* dis. write buffer coalescing */
#define XSCALE_AUXCTL_P		0x00000002 /* ECC protect page table access */
#define XSCALE_AUXCTL_MD_WB_RA	0x00000000 /* mini-D$ wb, read-allocate */
#define XSCALE_AUXCTL_MD_WB_RWA	0x00000010 /* mini-D$ wb, read/write-allocate */
#define XSCALE_AUXCTL_MD_WT	0x00000020 /* mini-D$ wt, read-allocate */
#define XSCALE_AUXCTL_MD_MASK	0x00000030

/* Cache type register definitions */
#define CPU_CT_ISIZE(x)		((x) & 0xfff)		/* I$ info */
#define CPU_CT_DSIZE(x)		(((x) >> 12) & 0xfff)	/* D$ info */
#define CPU_CT_S		(1U << 24)		/* split cache */
#define CPU_CT_CTYPE(x)		(((x) >> 25) & 0xf)	/* cache type */

#define CPU_CT_CTYPE_WT		0	/* write-through */
#define CPU_CT_CTYPE_WB1	1	/* write-back, clean w/ read */
#define CPU_CT_CTYPE_WB2	2	/* w/b, clean w/ cp15,7 */
#define CPU_CT_CTYPE_WB6	6	/* w/b, cp15,7, lockdown fmt A */
#define CPU_CT_CTYPE_WB7	7	/* w/b, cp15,7, lockdown fmt B */

#define CPU_CT_xSIZE_LEN(x)	((x) & 0x3)		/* line size */
#define CPU_CT_xSIZE_M		(1U << 2)		/* multiplier */
#define CPU_CT_xSIZE_ASSOC(x)	(((x) >> 3) & 0x7)	/* associativity */
#define CPU_CT_xSIZE_SIZE(x)	(((x) >> 6) & 0x7)	/* size */

/* Fault status register definitions */

#define FAULT_USER      0x20

#define FAULT_WRTBUF_0  0x00 /* Vector Exception */
#define FAULT_WRTBUF_1  0x02 /* Terminal Exception */
#define FAULT_BUSERR_0  0x04 /* External Abort on Linefetch -- Section */
#define FAULT_BUSERR_1  0x06 /* External Abort on Linefetch -- Page */
#define FAULT_BUSERR_2  0x08 /* External Abort on Non-linefetch -- Section */
#define FAULT_BUSERR_3  0x0a /* External Abort on Non-linefetch -- Page */
#define FAULT_BUSTRNL1  0x0c /* External abort on Translation -- Level 1 */
#define FAULT_BUSTRNL2  0x0e /* External abort on Translation -- Level 2 */
#define FAULT_ALIGN_0   0x01 /* Alignment */
#define FAULT_ALIGN_1   0x03 /* Alignment */
#define FAULT_TRANS_S   0x05 /* Translation -- Section */
#define FAULT_TRANS_P   0x07 /* Translation -- Page */
#define FAULT_DOMAIN_S  0x09 /* Domain -- Section */
#define FAULT_DOMAIN_P  0x0b /* Domain -- Page */
#define FAULT_PERM_S    0x0d /* Permission -- Section */
#define FAULT_PERM_P    0x0f /* Permission -- Page */

#define FAULT_IMPRECISE	0x400	/* Imprecise exception (XSCALE) */

#define	FAULT_EXT	0x00001000	/* external abort */
#define	FAULT_WNR	0x00000800	/* write fault */

#define	FAULT_TYPE(fsr)		((fsr) & 0x0f)
#define	FAULT_TYPE_V7(fsr)	(((fsr) & 0x0f) | (((fsr) & 0x00000400) >> 6))

/*
 * Address of the vector page, low and high versions.
 */
#define ARM_VECTORS_LOW		0x00000000U
#define ARM_VECTORS_HIGH	0xffff0000U

/*
 * ARM Instructions
 *
 *       3 3 2 2 2
 *       1 0 9 8 7                                                     0
 *      +-------+-------------------------------------------------------+
 *      | cond  |              instruction dependant                    |
 *      |c c c c|                                                       |
 *      +-------+-------------------------------------------------------+
 */

#define INSN_SIZE		4		/* Always 4 bytes */
#define INSN_COND_MASK		0xf0000000	/* Condition mask */
#define INSN_COND_AL		0xe0000000	/* Always condition */

#endif


code:
/*	$OpenBSD: asm.h,v 1.4 2013/03/28 17:41:04 martynas Exp $	*/
/*	$NetBSD: asm.h,v 1.4 2001/07/16 05:43:32 matt Exp $	*/

/*
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * William Jolitz.
 *
 * 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.
 *
 *	from: @(#)asm.h	5.5 (Berkeley) 5/7/91
 */

#ifndef _ARM_ASM_H_
#define _ARM_ASM_H_

#ifdef __ELF__
# define _C_LABEL(x)	x
#else
# ifdef __STDC__
#  define _C_LABEL(x)	_ ## x
# else
#  define _C_LABEL(x)	_/**/x
# endif
#endif
#define	_ASM_LABEL(x)	x

#ifdef __STDC__
# define __CONCAT(x,y)	x ## y
# define __STRING(x)	#x
#else
# define __CONCAT(x,y)	x/**/y
# define __STRING(x)	"x"
#endif

#ifndef _ALIGN_TEXT
# define _ALIGN_TEXT .align 0
#endif

/*
 * gas/arm uses @ as a single comment character and thus cannot be used here
 * Instead it recognised the # instead of an @ symbols in .type directives
 * We define a couple of macros so that assembly code will not be dependant
 * on one or the other.
 */
#define _ASM_TYPE_FUNCTION	#function
#define _ASM_TYPE_OBJECT	#object
#define _ENTRY(x) \
	.text; _ALIGN_TEXT; .globl x; .type x,_ASM_TYPE_FUNCTION; x:

#ifdef GPROF
# ifdef __ELF__
#  define _PROF_PROLOGUE	\
	mov ip, lr; bl __mcount
# else
#  define _PROF_PROLOGUE	\
	mov ip,lr; bl mcount
# endif
#else
# define _PROF_PROLOGUE
#endif

#define	ENTRY(y)	_ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
#define	ENTRY_NP(y)	_ENTRY(_C_LABEL(y))
#define	ASENTRY(y)	_ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
#define	ASENTRY_NP(y)	_ENTRY(_ASM_LABEL(y))

#define	ASMSTR		.asciz

#if defined(__ELF__) && defined(__PIC__)
#ifdef __STDC__
#define	PIC_SYM(x,y)	x ## ( ## y ## )
#else
#define	PIC_SYM(x,y)	x/**/(/**/y/**/)
#endif
#else
#define	PIC_SYM(x,y)	x
#endif

#ifdef __ELF__
#define RCSID(x)	.section ".ident"; .asciz x
#else
#define RCSID(x)	.text; .asciz x
#endif

#ifdef __ELF__
#define	STRONG_ALIAS(alias,sym)						\
	.global alias;							\
	alias = sym
#define	WEAK_ALIAS(alias,sym)						\
	.weak alias;							\
	alias = sym
#endif

#ifdef __STDC__
#define	WARN_REFERENCES(sym,msg)					\
	.stabs msg ## ,30,0,0,0 ;					\
	.stabs __STRING(_C_LABEL(sym)) ## ,1,0,0,0
#elif defined(__ELF__)
#define	WARN_REFERENCES(sym,msg)					\
	.stabs msg,30,0,0,0 ;						\
	.stabs __STRING(sym),1,0,0,0
#else
#define	WARN_REFERENCES(sym,msg)					\
	.stabs msg,30,0,0,0 ;						\
	.stabs __STRING(_/**/sym),1,0,0,0
#endif /* __STDC__ */

#endif /* !_ARM_ASM_H_ */


code:
/*	$OpenBSD: atomic.h,v 1.11 2015/06/29 04:16:32 jsg Exp $	*/

/* Public Domain */

#ifndef _ARM_ATOMIC_H_
#define _ARM_ATOMIC_H_

#if defined(_KERNEL)

#include <arm/cpufunc.h>

/*
 * on pre-v6 arm processors, it is necessary to disable interrupts if
 * in the kernel and atomic updates are necessary without full mutexes
*
 * eventually it would be interesting to have these functions
 * support the V6/V7+ atomic instructions ldrex/strex if available
 * on the CPU.
 */

static inline unsigned int
_atomic_cas_uint(volatile unsigned int *uip, unsigned int o, unsigned int n)
{
	unsigned int cpsr;
	unsigned int rv;

	cpsr = disable_interrupts(I32_bit|F32_bit);
	rv = *uip;
	if (rv == o)
		*uip = n;
	restore_interrupts(cpsr);

	return (rv);
}
#define atomic_cas_uint(_p, _o, _n) _atomic_cas_uint((_p), (_o), (_n))

static inline unsigned int
_atomic_cas_ulong(volatile unsigned long *uip, unsigned long o, unsigned long n)
{
	unsigned int cpsr;
	unsigned long rv;

	cpsr = disable_interrupts(I32_bit|F32_bit);
	rv = *uip;
	if (rv == o)
		*uip = n;
	restore_interrupts(cpsr);

	return (rv);
}
#define atomic_cas_ulong(_p, _o, _n) _atomic_cas_ulong((_p), (_o), (_n))

static inline void *
_atomic_cas_ptr(volatile void *uip, void *o, void *n)
{
	unsigned int cpsr;
	void * volatile *uipp = (void * volatile *)uip;
	void *rv;

	cpsr = disable_interrupts(I32_bit|F32_bit);
	rv = *uipp;
	if (rv == o)
		*uipp = n;
	restore_interrupts(cpsr);

	return (rv);
}
#define atomic_cas_ptr(_p, _o, _n) _atomic_cas_ptr((_p), (_o), (_n))

static inline unsigned int
_atomic_swap_uint(volatile unsigned int *uip, unsigned int n)
{
	unsigned int cpsr;
	unsigned int rv;

	cpsr = disable_interrupts(I32_bit|F32_bit);
	rv = *uip;
	*uip = n;
	restore_interrupts(cpsr);

	return (rv);
}
#define atomic_swap_uint(_p, _n) _atomic_swap_uint((_p), (_n))

static inline unsigned long
_atomic_swap_ulong(volatile unsigned long *uip, unsigned long n)
{
	unsigned int cpsr;
	unsigned long rv;

	cpsr = disable_interrupts(I32_bit|F32_bit);
	rv = *uip;
	*uip = n;
	restore_interrupts(cpsr);

	return (rv);
}
#define atomic_swap_ulong(_p, _n) _atomic_swap_ulong((_p), (_n))

static inline void *
_atomic_swap_ptr(volatile void *uip, void *n)
{
	unsigned int cpsr;
	void * volatile *uipp = (void * volatile *)uip;
	void *rv;

	cpsr = disable_interrupts(I32_bit|F32_bit);
	rv = *uipp;
	*uipp = n;
	restore_interrupts(cpsr);

	return (rv);
}
#define atomic_swap_ptr(_p, _n) _atomic_swap_ptr((_p), (_n))

static inline unsigned int
_atomic_add_int_nv(volatile unsigned int *uip, unsigned int v)
{
	unsigned int cpsr;
	unsigned int rv;

	cpsr = disable_interrupts(I32_bit|F32_bit);
	rv = *uip + v;
	*uip = rv;
	restore_interrupts(cpsr);

	return (rv);
}
#define atomic_add_int_nv(_p, _v) _atomic_add_int_nv((_p), (_v))

static inline unsigned long
_atomic_add_long_nv(volatile unsigned long *uip, unsigned long v)
{
	unsigned int cpsr;
	unsigned long rv;

	cpsr = disable_interrupts(I32_bit|F32_bit);
	rv = *uip + v;
	*uip = rv;
	restore_interrupts(cpsr);

	return (rv);
}
#define atomic_add_long_nv(_p, _v) _atomic_add_long_nv((_p), (_v))

static inline unsigned int
_atomic_sub_int_nv(volatile unsigned int *uip, unsigned int v)
{
	unsigned int cpsr;
	unsigned int rv;

	cpsr = disable_interrupts(I32_bit|F32_bit);
	rv = *uip - v;
	*uip = rv;
	restore_interrupts(cpsr);

	return (rv);
}
#define atomic_sub_int_nv(_p, _v) _atomic_sub_int_nv((_p), (_v))

static inline unsigned long
_atomic_sub_long_nv(volatile unsigned long *uip, unsigned long v)
{
	unsigned int cpsr;
	unsigned long rv;

	cpsr = disable_interrupts(I32_bit|F32_bit);
	rv = *uip - v;
	*uip = rv;
	restore_interrupts(cpsr);

	return (rv);
}
#define atomic_sub_long_nv(_p, _v) _atomic_sub_long_nv((_p), (_v))

static inline void
atomic_setbits_int(volatile unsigned int *uip, unsigned int v)
{
	unsigned int cpsr;

	cpsr = disable_interrupts(I32_bit|F32_bit);
	*uip |= v;
	restore_interrupts(cpsr);
}

static inline void
atomic_clearbits_int(volatile unsigned int *uip, unsigned int v)
{
	unsigned int cpsr;

	cpsr = disable_interrupts(I32_bit|F32_bit);
	*uip &= ~v;
	restore_interrupts(cpsr);
}

#if defined(CPU_ARMv7)
#define __membar(_f) do { __asm __volatile(_f ::: "memory"); } while (0)

#define membar_enter()		__membar("dmb sy")
#define membar_exit()		__membar("dmb sy")
#define membar_producer()	__membar("dmb st")
#define membar_consumer()	__membar("dmb sy")
#define membar_sync()		__membar("dmb sy")

#define virtio_membar_producer()	__membar("dmb st")
#define virtio_membar_consumer()	__membar("dmb sy")
#define virtio_membar_sync()		__membar("dmb sy")
#endif /* CPU_ARMv7 */

#endif /* defined(_KERNEL) */
#endif /* _ARM_ATOMIC_H_ */


code:
/*	$OpenBSD: bus.h,v 1.14 2011/03/23 16:54:34 pirofti Exp $	*/
/*	$NetBSD: bus.h,v 1.12 2003/10/23 15:03:24 scw Exp $	*/

/*-
 * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
 * NASA Ames Research Center.
 *
 * 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.
 */

/*
 * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
 * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by Christopher G. Demetriou
 *	for the NetBSD Project.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _ARM_BUS_H_
#define _ARM_BUS_H_

/*
 * Addresses (in bus space).
 */
typedef u_long bus_addr_t;
typedef u_long bus_size_t;

/*
 * Access methods for bus space.
 */
typedef struct bus_space *bus_space_tag_t;
typedef u_long bus_space_handle_t;

/*
 *	int bus_space_map  (bus_space_tag_t t, bus_addr_t addr,
 *	    bus_size_t size, int flags, bus_space_handle_t *bshp);
 *
 * Map a region of bus space.
 */

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

struct bus_space {
	/* cookie */
	void		*bs_cookie;

	/* mapping/unmapping */
	int		(*bs_map) (void *, bus_addr_t, bus_size_t,
			    int, bus_space_handle_t *);
	void		(*bs_unmap) (void *, bus_space_handle_t,
			    bus_size_t);
	int		(*bs_subregion) (void *, bus_space_handle_t,
			    bus_size_t, bus_size_t, bus_space_handle_t *);

	/* allocation/deallocation */
	int		(*bs_alloc) (void *, bus_addr_t, bus_addr_t,
			    bus_size_t, bus_size_t, bus_size_t, int,
			    bus_addr_t *, bus_space_handle_t *);
	void		(*bs_free) (void *, bus_space_handle_t,
			    bus_size_t);

	/* get kernel virtual address */
	void *		(*bs_vaddr) (void *, bus_space_handle_t);

	/* mmap bus space for user */
	paddr_t		(*bs_mmap) (void *, bus_addr_t, off_t, int, int);

	/* barrier */
	void		(*bs_barrier) (void *, bus_space_handle_t,
			    bus_size_t, bus_size_t, int);

	/* read (single) */
	u_int8_t	(*bs_r_1) (void *, bus_space_handle_t,
			    bus_size_t);
	u_int16_t	(*bs_r_2) (void *, bus_space_handle_t,
			    bus_size_t);
	u_int32_t	(*bs_r_4) (void *, bus_space_handle_t,
			    bus_size_t);
	u_int64_t	(*bs_r_8) (void *, bus_space_handle_t,
			    bus_size_t);

	/* read multiple */
	void		(*bs_rm_1) (void *, bus_space_handle_t,
			    bus_size_t, u_int8_t *, bus_size_t);
	void		(*bs_rm_2) (void *, bus_space_handle_t,
			    bus_size_t, u_int16_t *, bus_size_t);
	void		(*bs_rm_4) (void *, bus_space_handle_t,
			    bus_size_t, u_int32_t *, bus_size_t);
	void		(*bs_rm_8) (void *, bus_space_handle_t,
			    bus_size_t, u_int64_t *, bus_size_t);

	/* read region */
	void		(*bs_rr_1) (void *, bus_space_handle_t,
			    bus_size_t, u_int8_t *, bus_size_t);
	void		(*bs_rr_2) (void *, bus_space_handle_t,
			    bus_size_t, u_int16_t *, bus_size_t);
	void		(*bs_rr_4) (void *, bus_space_handle_t,
			    bus_size_t, u_int32_t *, bus_size_t);
	void		(*bs_rr_8) (void *, bus_space_handle_t,
			    bus_size_t, u_int64_t *, bus_size_t);

	/* write (single) */
	void		(*bs_w_1) (void *, bus_space_handle_t,
			    bus_size_t, u_int8_t);
	void		(*bs_w_2) (void *, bus_space_handle_t,
			    bus_size_t, u_int16_t);
	void		(*bs_w_4) (void *, bus_space_handle_t,
			    bus_size_t, u_int32_t);
	void		(*bs_w_8) (void *, bus_space_handle_t,
			    bus_size_t, u_int64_t);

	/* write multiple */
	void		(*bs_wm_1) (void *, bus_space_handle_t,
			    bus_size_t, const u_int8_t *, bus_size_t);
	void		(*bs_wm_2) (void *, bus_space_handle_t,
			    bus_size_t, const u_int16_t *, bus_size_t);
	void		(*bs_wm_4) (void *, bus_space_handle_t,
			    bus_size_t, const u_int32_t *, bus_size_t);
	void		(*bs_wm_8) (void *, bus_space_handle_t,
			    bus_size_t, const u_int64_t *, bus_size_t);

	/* write region */
	void		(*bs_wr_1) (void *, bus_space_handle_t,
			    bus_size_t, const u_int8_t *, bus_size_t);
	void		(*bs_wr_2) (void *, bus_space_handle_t,
			    bus_size_t, const u_int16_t *, bus_size_t);
	void		(*bs_wr_4) (void *, bus_space_handle_t,
			    bus_size_t, const u_int32_t *, bus_size_t);
	void		(*bs_wr_8) (void *, bus_space_handle_t,
			    bus_size_t, const u_int64_t *, bus_size_t);

	/* set multiple */
	void		(*bs_sm_1) (void *, bus_space_handle_t,
			    bus_size_t, u_int8_t, bus_size_t);
	void		(*bs_sm_2) (void *, bus_space_handle_t,
			    bus_size_t, u_int16_t, bus_size_t);
	void		(*bs_sm_4) (void *, bus_space_handle_t,
			    bus_size_t, u_int32_t, bus_size_t);
	void		(*bs_sm_8) (void *, bus_space_handle_t,
			    bus_size_t, u_int64_t, bus_size_t);

	/* set region */
	void		(*bs_sr_1) (void *, bus_space_handle_t,
			    bus_size_t, u_int8_t, bus_size_t);
	void		(*bs_sr_2) (void *, bus_space_handle_t,
			    bus_size_t, u_int16_t, bus_size_t);
	void		(*bs_sr_4) (void *, bus_space_handle_t,
			    bus_size_t, u_int32_t, bus_size_t);
	void		(*bs_sr_8) (void *, bus_space_handle_t,
			    bus_size_t, u_int64_t, bus_size_t);

	/* copy */
	void		(*bs_c_1) (void *, bus_space_handle_t, bus_size_t,
			    bus_space_handle_t, bus_size_t, bus_size_t);
	void		(*bs_c_2) (void *, bus_space_handle_t, bus_size_t,
			    bus_space_handle_t, bus_size_t, bus_size_t);
	void		(*bs_c_4) (void *, bus_space_handle_t, bus_size_t,
			    bus_space_handle_t, bus_size_t, bus_size_t);
	void		(*bs_c_8) (void *, bus_space_handle_t, bus_size_t,
			    bus_space_handle_t, bus_size_t, bus_size_t);
};

/*
 * Utility macros; INTERNAL USE ONLY.
 */
#define	__bs_c(a,b)		__CONCAT(a,b)
#define	__bs_opname(op,size)	__bs_c(__bs_c(__bs_c(bs_,op),_),size)

#define	__bs_rs(sz, t, h, o)						\
	(*(t)->__bs_opname(r,sz))((t)->bs_cookie, h, o)
#define	__bs_ws(sz, t, h, o, v)						\
	(*(t)->__bs_opname(w,sz))((t)->bs_cookie, h, o, v)
#define	__bs_nonsingle(type, sz, t, h, o, a, c)				\
	(*(t)->__bs_opname(type,sz))((t)->bs_cookie, h, o, a, c)
#define	__bs_set(type, sz, t, h, o, v, c)				\
	(*(t)->__bs_opname(type,sz))((t)->bs_cookie, h, o, v, c)
#define	__bs_copy(sz, t, h1, o1, h2, o2, cnt)				\
	(*(t)->__bs_opname(c,sz))((t)->bs_cookie, h1, o1, h2, o2, cnt)

/*
 * Mapping and unmapping operations.
 */
#define	bus_space_map(t, a, s, c, hp)					\
	(*(t)->bs_map)((t)->bs_cookie, (a), (s), (c), (hp))
#define	bus_space_unmap(t, h, s)					\
	(*(t)->bs_unmap)((t)->bs_cookie, (h), (s))
#define	bus_space_subregion(t, h, o, s, hp)				\
	(*(t)->bs_subregion)((t)->bs_cookie, (h), (o), (s), (hp))

/*
 * Allocation and deallocation operations.
 */
#define	bus_space_alloc(t, rs, re, s, a, b, c, ap, hp)			\
	(*(t)->bs_alloc)((t)->bs_cookie, (rs), (re), (s), (a), (b),	\
	    (c), (ap), (hp))
#define	bus_space_free(t, h, s)						\
	(*(t)->bs_free)((t)->bs_cookie, (h), (s))

/*
 * Get kernel virtual address for ranges mapped BUS_SPACE_MAP_LINEAR.
 */
#define	bus_space_vaddr(t, h)						\
	(*(t)->bs_vaddr)((t)->bs_cookie, (h))

/*
 * MMap bus space for a user application.
 */
#define bus_space_mmap(t, a, o, p, f)					\
	(*(t)->bs_mmap)((t)->bs_cookie, (a), (o), (p), (f))

/*
 * Bus barrier operations.
 */
#define	bus_space_barrier(t, h, o, l, f)				\
	(*(t)->bs_barrier)((t)->bs_cookie, (h), (o), (l), (f))

#define	BUS_SPACE_BARRIER_READ	0x01
#define	BUS_SPACE_BARRIER_WRITE	0x02

/*
 * Bus read (single) operations.
 */
#define	bus_space_read_1(t, h, o)	__bs_rs(1,(t),(h),(o))
#define	bus_space_read_2(t, h, o)	__bs_rs(2,(t),(h),(o))
#define	bus_space_read_4(t, h, o)	__bs_rs(4,(t),(h),(o))
#define	bus_space_read_8(t, h, o)	__bs_rs(8,(t),(h),(o))

/*
 * Bus read multiple operations.
 */
#define	bus_space_read_multi_1(t, h, o, a, c)				\
	__bs_nonsingle(rm,1,(t),(h),(o),(a),(c))
#define	bus_space_read_multi_2(t, h, o, a, c)				\
	__bs_nonsingle(rm,2,(t),(h),(o),(a),(c))
#define	bus_space_read_multi_4(t, h, o, a, c)				\
	__bs_nonsingle(rm,4,(t),(h),(o),(a),(c))
#define	bus_space_read_multi_8(t, h, o, a, c)				\
	__bs_nonsingle(rm,8,(t),(h),(o),(a),(c))

/*
 * Bus read region operations.
 */
#define	bus_space_read_region_1(t, h, o, a, c)				\
	__bs_nonsingle(rr,1,(t),(h),(o),(a),(c))
#define	bus_space_read_region_2(t, h, o, a, c)				\
	__bs_nonsingle(rr,2,(t),(h),(o),(a),(c))
#define	bus_space_read_region_4(t, h, o, a, c)				\
	__bs_nonsingle(rr,4,(t),(h),(o),(a),(c))
#define	bus_space_read_region_8(t, h, o, a, c)				\
	__bs_nonsingle(rr,8,(t),(h),(o),(a),(c))

/*
 * Bus write (single) operations.
 */
#define	bus_space_write_1(t, h, o, v)	__bs_ws(1,(t),(h),(o),(v))
#define	bus_space_write_2(t, h, o, v)	__bs_ws(2,(t),(h),(o),(v))
#define	bus_space_write_4(t, h, o, v)	__bs_ws(4,(t),(h),(o),(v))
#define	bus_space_write_8(t, h, o, v)	__bs_ws(8,(t),(h),(o),(v))

/*
 * Bus write multiple operations.
 */
#define	bus_space_write_multi_1(t, h, o, a, c)				\
	__bs_nonsingle(wm,1,(t),(h),(o),(a),(c))
#define	bus_space_write_multi_2(t, h, o, a, c)				\
	__bs_nonsingle(wm,2,(t),(h),(o),(a),(c))
#define	bus_space_write_multi_4(t, h, o, a, c)				\
	__bs_nonsingle(wm,4,(t),(h),(o),(a),(c))
#define	bus_space_write_multi_8(t, h, o, a, c)				\
	__bs_nonsingle(wm,8,(t),(h),(o),(a),(c))

/*
 * Bus write region operations.
 */
#define	bus_space_write_region_1(t, h, o, a, c)				\
	__bs_nonsingle(wr,1,(t),(h),(o),(a),(c))
#define	bus_space_write_region_2(t, h, o, a, c)				\
	__bs_nonsingle(wr,2,(t),(h),(o),(a),(c))
#define	bus_space_write_region_4(t, h, o, a, c)				\
	__bs_nonsingle(wr,4,(t),(h),(o),(a),(c))
#define	bus_space_write_region_8(t, h, o, a, c)				\
	__bs_nonsingle(wr,8,(t),(h),(o),(a),(c))

/*
 * Set multiple operations.
 */
#define	bus_space_set_multi_1(t, h, o, v, c)				\
	__bs_set(sm,1,(t),(h),(o),(v),(c))
#define	bus_space_set_multi_2(t, h, o, v, c)				\
	__bs_set(sm,2,(t),(h),(o),(v),(c))
#define	bus_space_set_multi_4(t, h, o, v, c)				\
	__bs_set(sm,4,(t),(h),(o),(v),(c))
#define	bus_space_set_multi_8(t, h, o, v, c)				\
	__bs_set(sm,8,(t),(h),(o),(v),(c))

/*
 * Set region operations.
 */
#define	bus_space_set_region_1(t, h, o, v, c)				\
	__bs_set(sr,1,(t),(h),(o),(v),(c))
#define	bus_space_set_region_2(t, h, o, v, c)				\
	__bs_set(sr,2,(t),(h),(o),(v),(c))
#define	bus_space_set_region_4(t, h, o, v, c)				\
	__bs_set(sr,4,(t),(h),(o),(v),(c))
#define	bus_space_set_region_8(t, h, o, v, c)				\
	__bs_set(sr,8,(t),(h),(o),(v),(c))

/*
 * Copy operations.
 */
#define	bus_space_copy_1(t, h1, o1, h2, o2, c)				\
	__bs_copy(1, t, h1, o1, h2, o2, c)
#define	bus_space_copy_2(t, h1, o1, h2, o2, c)				\
	__bs_copy(2, t, h1, o1, h2, o2, c)
#define	bus_space_copy_4(t, h1, o1, h2, o2, c)				\
	__bs_copy(4, t, h1, o1, h2, o2, c)
#define	bus_space_copy_8(t, h1, o1, h2, o2, c)				\
	__bs_copy(8, t, h1, o1, h2, o2, c)

/*
 * Macros to provide prototypes for all the functions used in the
 * bus_space structure
 */

#define bs_map_proto(f)							\
int	__bs_c(f,_bs_map) (void *t, bus_addr_t addr,		\
	    bus_size_t size, int flags, bus_space_handle_t *bshp);

#define bs_unmap_proto(f)						\
void	__bs_c(f,_bs_unmap) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t size);

#define bs_subregion_proto(f)						\
int	__bs_c(f,_bs_subregion) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, bus_size_t size, 			\
	    bus_space_handle_t *nbshp);

#define bs_alloc_proto(f)						\
int	__bs_c(f,_bs_alloc) (void *t, bus_addr_t rstart,		\
	    bus_addr_t rend, bus_size_t size, bus_size_t align,		\
	    bus_size_t boundary, int flags, bus_addr_t *addrp,	\
	    bus_space_handle_t *bshp);

#define bs_free_proto(f)						\
void	__bs_c(f,_bs_free) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t size);

#define bs_vaddr_proto(f)						\
void *	__bs_c(f,_bs_vaddr) (void *t, bus_space_handle_t bsh);

#define bs_mmap_proto(f)						\
paddr_t	__bs_c(f,_bs_mmap) (void *, bus_addr_t, off_t, int, int);

#define bs_barrier_proto(f)						\
void	__bs_c(f,_bs_barrier) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, bus_size_t len, int flags);

#define	bs_r_1_proto(f)							\
u_int8_t	__bs_c(f,_bs_r_1) (void *t, bus_space_handle_t bsh,	\
		    bus_size_t offset);

#define	bs_r_2_proto(f)							\
u_int16_t	__bs_c(f,_bs_r_2) (void *t, bus_space_handle_t bsh,	\
		    bus_size_t offset);

#define	bs_r_4_proto(f)							\
u_int32_t	__bs_c(f,_bs_r_4) (void *t, bus_space_handle_t bsh,	\
		    bus_size_t offset);

#define	bs_r_8_proto(f)							\
u_int64_t	__bs_c(f,_bs_r_8) (void *t, bus_space_handle_t bsh,	\
		    bus_size_t offset);

#define	bs_w_1_proto(f)							\
void	__bs_c(f,_bs_w_1) (void *t, bus_space_handle_t bsh,		\
	    bus_size_t offset, u_int8_t value);

#define	bs_w_2_proto(f)							\
void	__bs_c(f,_bs_w_2) (void *t, bus_space_handle_t bsh,		\
	    bus_size_t offset, u_int16_t value);

#define	bs_w_4_proto(f)							\
void	__bs_c(f,_bs_w_4) (void *t, bus_space_handle_t bsh,		\
	    bus_size_t offset, u_int32_t value);

#define	bs_w_8_proto(f)							\
void	__bs_c(f,_bs_w_8) (void *t, bus_space_handle_t bsh,		\
	    bus_size_t offset, u_int64_t value);

#define	bs_rm_1_proto(f)						\
void	__bs_c(f,_bs_rm_1) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int8_t *addr, bus_size_t count);

#define	bs_rm_2_proto(f)						\
void	__bs_c(f,_bs_rm_2) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int16_t *addr, bus_size_t count);

#define	bs_rm_4_proto(f)						\
void	__bs_c(f,_bs_rm_4) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int32_t *addr, bus_size_t count);

#define	bs_rm_8_proto(f)						\
void	__bs_c(f,_bs_rm_8) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int64_t *addr, bus_size_t count);

#define	bs_wm_1_proto(f)						\
void	__bs_c(f,_bs_wm_1) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, const u_int8_t *addr, bus_size_t count);

#define	bs_wm_2_proto(f)						\
void	__bs_c(f,_bs_wm_2) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, const u_int16_t *addr, bus_size_t count);

#define	bs_wm_4_proto(f)						\
void	__bs_c(f,_bs_wm_4) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, const u_int32_t *addr, bus_size_t count);

#define	bs_wm_8_proto(f)						\
void	__bs_c(f,_bs_wm_8) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, const u_int64_t *addr, bus_size_t count);

#define	bs_rr_1_proto(f)						\
void	__bs_c(f, _bs_rr_1) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int8_t *addr, bus_size_t count);

#define	bs_rr_2_proto(f)						\
void	__bs_c(f, _bs_rr_2) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int16_t *addr, bus_size_t count);

#define	bs_rr_4_proto(f)						\
void	__bs_c(f, _bs_rr_4) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int32_t *addr, bus_size_t count);

#define	bs_rr_8_proto(f)						\
void	__bs_c(f, _bs_rr_8) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int64_t *addr, bus_size_t count);

#define	bs_wr_1_proto(f)						\
void	__bs_c(f, _bs_wr_1) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, const u_int8_t *addr, bus_size_t count);

#define	bs_wr_2_proto(f)						\
void	__bs_c(f, _bs_wr_2) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, const u_int16_t *addr, bus_size_t count);

#define	bs_wr_4_proto(f)						\
void	__bs_c(f, _bs_wr_4) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, const u_int32_t *addr, bus_size_t count);

#define	bs_wr_8_proto(f)						\
void	__bs_c(f, _bs_wr_8) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, const u_int64_t *addr, bus_size_t count);

#define	bs_sm_1_proto(f)						\
void	__bs_c(f,_bs_sm_1) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int8_t value, bus_size_t count);

#define	bs_sm_2_proto(f)						\
void	__bs_c(f,_bs_sm_2) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int16_t value, bus_size_t count);

#define	bs_sm_4_proto(f)						\
void	__bs_c(f,_bs_sm_4) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int32_t value, bus_size_t count);

#define	bs_sm_8_proto(f)						\
void	__bs_c(f,_bs_sm_8) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int64_t value, bus_size_t count);

#define	bs_sr_1_proto(f)						\
void	__bs_c(f,_bs_sr_1) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int8_t value, bus_size_t count);

#define	bs_sr_2_proto(f)						\
void	__bs_c(f,_bs_sr_2) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int16_t value, bus_size_t count);

#define	bs_sr_4_proto(f)						\
void	__bs_c(f,_bs_sr_4) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int32_t value, bus_size_t count);

#define	bs_sr_8_proto(f)						\
void	__bs_c(f,_bs_sr_8) (void *t, bus_space_handle_t bsh,	\
	    bus_size_t offset, u_int64_t value, bus_size_t count);

#define	bs_c_1_proto(f)							\
void	__bs_c(f,_bs_c_1) (void *t, bus_space_handle_t bsh1,	\
	    bus_size_t offset1, bus_space_handle_t bsh2,		\
	    bus_size_t offset2, bus_size_t count);

#define	bs_c_2_proto(f)							\
void	__bs_c(f,_bs_c_2) (void *t, bus_space_handle_t bsh1,	\
	    bus_size_t offset1, bus_space_handle_t bsh2,		\
	    bus_size_t offset2, bus_size_t count);

#define	bs_c_4_proto(f)							\
void	__bs_c(f,_bs_c_4) (void *t, bus_space_handle_t bsh1,	\
	    bus_size_t offset1, bus_space_handle_t bsh2,		\
	    bus_size_t offset2, bus_size_t count);

#define	bs_c_8_proto(f)							\
void	__bs_c(f,_bs_c_8) (void *t, bus_space_handle_t bsh1,	\
	    bus_size_t offset1, bus_space_handle_t bsh2,		\
	    bus_size_t offset2, bus_size_t count);

#define bs_protos(f)		\
bs_map_proto(f);		\
bs_unmap_proto(f);		\
bs_subregion_proto(f);		\
bs_alloc_proto(f);		\
bs_free_proto(f);		\
bs_vaddr_proto(f);		\
bs_mmap_proto(f);		\
bs_barrier_proto(f);		\
bs_r_1_proto(f);		\
bs_r_2_proto(f);		\
bs_r_4_proto(f);		\
bs_r_8_proto(f);		\
bs_w_1_proto(f);		\
bs_w_2_proto(f);		\
bs_w_4_proto(f);		\
bs_w_8_proto(f);		\
bs_rm_1_proto(f);		\
bs_rm_2_proto(f);		\
bs_rm_4_proto(f);		\
bs_rm_8_proto(f);		\
bs_wm_1_proto(f);		\
bs_wm_2_proto(f);		\
bs_wm_4_proto(f);		\
bs_wm_8_proto(f);		\
bs_rr_1_proto(f);		\
bs_rr_2_proto(f);		\
bs_rr_4_proto(f);		\
bs_rr_8_proto(f);		\
bs_wr_1_proto(f);		\
bs_wr_2_proto(f);		\
bs_wr_4_proto(f);		\
bs_wr_8_proto(f);		\
bs_sm_1_proto(f);		\
bs_sm_2_proto(f);		\
bs_sm_4_proto(f);		\
bs_sm_8_proto(f);		\
bs_sr_1_proto(f);		\
bs_sr_2_proto(f);		\
bs_sr_4_proto(f);		\
bs_sr_8_proto(f);		\
bs_c_1_proto(f);		\
bs_c_2_proto(f);		\
bs_c_4_proto(f);		\
bs_c_8_proto(f);

/* Bus Space DMA macros */

/*
 * Flags used in various bus DMA methods.
 */
#define	BUS_DMA_WAITOK		0x000	/* safe to sleep (pseudo-flag) */
#define	BUS_DMA_NOWAIT		0x001	/* not safe to sleep */
#define	BUS_DMA_ALLOCNOW	0x002	/* perform resource allocation now */
#define	BUS_DMA_COHERENT	0x004	/* hint: map memory DMA coherent */
#define	BUS_DMA_STREAMING	0x008	/* hint: sequential, unidirectional */
#define	BUS_DMA_BUS1		0x010	/* placeholders for bus functions... */
#define	BUS_DMA_BUS2		0x020
#define	BUS_DMA_BUS3		0x040
#define	BUS_DMA_BUS4		0x080
#define	BUS_DMA_READ		0x100	/* mapping is device -> memory only */
#define	BUS_DMA_WRITE		0x200	/* mapping is memory -> device only */
#define	BUS_DMA_NOCACHE		0x400	/* hint: map non-cached memory */
#define	BUS_DMA_ZERO		0x800	/* dmamem_alloc returns zeroed mem */

/*
 * Private flags stored in the DMA map.
 */
#define	ARM32_DMAMAP_COHERENT	0x10000	/* no cache flush necessary on sync */

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

/*
 * Operations performed by bus_dmamap_sync().
 */
#define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
#define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
#define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
#define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */

typedef struct arm32_bus_dma_tag	*bus_dma_tag_t;
typedef struct arm32_bus_dmamap		*bus_dmamap_t;

#define BUS_DMA_TAG_VALID(t)    ((t) != (bus_dma_tag_t)0)

/*
 *	bus_dma_segment_t
 *
 *	Describes a single contiguous DMA transaction.  Values
 *	are suitable for programming into DMA registers.
 */
struct arm32_bus_dma_segment {
	/*
	 * PUBLIC MEMBERS: these are used by machine-independent code.
	 */
	bus_addr_t	ds_addr;	/* DMA address */
	bus_size_t	ds_len;		/* length of transfer */
	/*
	 * PRIVATE MEMBERS: not for use by machine-independent code.
	 */
	bus_addr_t	_ds_vaddr;	/* Virtual mapped address
					 * Used by bus_dmamem_sync() */
};
typedef struct arm32_bus_dma_segment	bus_dma_segment_t;

/*
 *	arm32_dma_range
 *
 *	This structure describes a valid DMA range.
 */
struct arm32_dma_range {
	bus_addr_t	dr_sysbase;	/* system base address */
	bus_addr_t	dr_busbase;	/* appears here on bus */
	bus_size_t	dr_len;		/* length of range */
};

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

struct arm32_bus_dma_tag {
	/*
	 * DMA range for this tag.  If the page doesn't fall within
	 * one of these ranges, an error is returned.  The caller
	 * may then decide what to do with the transfer.  If the
	 * range pointer is NULL, it is ignored.
	 */
	struct arm32_dma_range *_ranges;
	int _nranges;

	/*
	 * Opaque cookie for use by back-end.
	 */
	void *_cookie;

	/*
	 * 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);
	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, o, l, ops)			\
	(void)((t)->_dmamap_sync ?				\
	    (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)

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

/*
 *	bus_dmamap_t
 *
 *	Describes a DMA mapping.
 */
struct arm32_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_origbuf;	/* pointer to original buffer */
	int		_dm_buftype;	/* type of buffer */
	struct proc	*_dm_proc;	/* proc that owns the mapping */

	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 */
};

#ifdef _ARM32_BUS_DMA_PRIVATE

/* _dm_buftype */
#define	ARM32_BUFTYPE_INVALID		0
#define	ARM32_BUFTYPE_LINEAR		1
#define	ARM32_BUFTYPE_MBUF		2
#define	ARM32_BUFTYPE_UIO		3

int	arm32_dma_range_intersect(struct arm32_dma_range *, int,
	    paddr_t pa, psize_t size, paddr_t *pap, psize_t *sizep);

int	_bus_dmamap_create (bus_dma_tag_t, bus_size_t, int, bus_size_t,
	    bus_size_t, int, bus_dmamap_t *);
void	_bus_dmamap_destroy (bus_dma_tag_t, bus_dmamap_t);
int	_bus_dmamap_load (bus_dma_tag_t, bus_dmamap_t, void *,
	    bus_size_t, struct proc *, int);
int	_bus_dmamap_load_mbuf (bus_dma_tag_t, bus_dmamap_t,
	    struct mbuf *, int);
int	_bus_dmamap_load_uio (bus_dma_tag_t, bus_dmamap_t,
	    struct uio *, int);
int	_bus_dmamap_load_raw (bus_dma_tag_t, bus_dmamap_t,
	    bus_dma_segment_t *, int, bus_size_t, int);
void	_bus_dmamap_unload (bus_dma_tag_t, bus_dmamap_t);
void	_bus_dmamap_sync (bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
	    bus_size_t, int);

int	_bus_dmamem_alloc (bus_dma_tag_t tag, bus_size_t size,
	    bus_size_t alignment, bus_size_t boundary,
	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
void	_bus_dmamem_free (bus_dma_tag_t tag, bus_dma_segment_t *segs,
	    int nsegs);
int	_bus_dmamem_map (bus_dma_tag_t tag, bus_dma_segment_t *segs,
	    int nsegs, size_t size, caddr_t *kvap, int flags);
void	_bus_dmamem_unmap (bus_dma_tag_t tag, caddr_t kva,
	    size_t size);
paddr_t	_bus_dmamem_mmap (bus_dma_tag_t tag, bus_dma_segment_t *segs,
	    int nsegs, off_t off, int prot, int flags);

int	_bus_dmamem_alloc_range (bus_dma_tag_t tag, bus_size_t size,
	    bus_size_t alignment, bus_size_t boundary,
	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
	    vaddr_t low, vaddr_t high);
#endif /* _ARM32_BUS_DMA_PRIVATE */
/* 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_read_raw_region_N(bus_space_tag_t tag,
 *	    bus_space_handle_t bsh, bus_size_t offset,
 *	    u_int8_t *addr, size_t count);
 *
 * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space
 * described by tag/handle and starting at `offset' and copy into
 * buffer provided.  The buffer must have proper alignment for the N byte
 * wide entities.  Furthermore possible byte-swapping should be done by
 * these functions.
 */

#define	bus_space_read_raw_region_2(t, h, o, a, c) \
    bus_space_read_region_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1)
#define	bus_space_read_raw_region_4(t, h, o, a, c) \
    bus_space_read_region_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2)

#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_int8_t *addr, size_t count);
 *
 * Write `count' bytes in 2, 4 or 8 byte wide quantities to bus space
 * described by tag/handle and starting at `offset' from the
 * buffer provided.  The buffer must have proper alignment for the N byte
 * wide entities.  Furthermore possible byte-swapping should be done by
 * these functions.
 */

#define	bus_space_write_raw_region_2(t, h, o, a, c) \
    bus_space_write_region_2((t), (h), (o), (const u_int16_t *)(a), (c) >> 1)
#define	bus_space_write_raw_region_4(t, h, o, a, c) \
    bus_space_write_region_4((t), (h), (o), (const u_int32_t *)(a), (c) >> 2)

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

#endif /* _ARM_BUS_H_ */


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

#ifndef	_ARM_CDEFS_H_
#define	_ARM_CDEFS_H_

#define __strong_alias(alias,sym)					\
	__asm__(".global " __STRING(alias) " ; " __STRING(alias)	\
	    " = " __STRING(sym))
#define __weak_alias(alias,sym)						\
	__asm__(".weak " __STRING(alias) " ; " __STRING(alias)		\
	    " = " __STRING(sym))
#define	__warn_references(sym,msg)					\
	__asm__(".section .gnu.warning." __STRING(sym)			\
	    " ; .ascii \"" msg "\" ; .text")

#endif /* !_ARM_CDEFS_H_ */