Gateworks Avila board support:

o ixp425 support
o NPE network driver (requires Intel microcode)
o h/w qmgr support
o True IDE compact flash over expansion bus
o pci (ath and hifn795x parts tested)
o xscale watchdog timer
o ds1672 RTC on i2c bus
o ad7418 voltage + temp monitoring on i2c bus
o uart

Work done together with cognet, kevlo, and jmg.  Parts of
the ixp425 support obtaine/derived from netbsd.

Reviewed by:	cognet, imp
MFC after:	1 month
This commit is contained in:
Sam Leffler 2006-11-19 23:55:23 +00:00
parent faad47108d
commit e67f80fd20
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=164426
32 changed files with 10134 additions and 1 deletions

View File

@ -1015,7 +1015,6 @@ set_cpufuncs()
#ifdef CPU_XSCALE_IXP425
if (cputype == CPU_ID_IXP425_533 || cputype == CPU_ID_IXP425_400 ||
cputype == CPU_ID_IXP425_266) {
ixp425_icu_init();
cpufuncs = xscale_cpufuncs;
#if defined(PERFCTRS)

View File

@ -0,0 +1,556 @@
/*-
* Copyright (c) 2006 Sam Leffler, Errno Consulting
* 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,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* Compact Flash Support for the Avila Gateworks XScale boards.
* There are 1 or 2 optional CF slots operated in "True IDE" mode.
* Registers are on the Expansion Bus connected to CS1. Interrupts
* are tied to GPIO pin 12. No DMA, just PIO.
*
* See also http://www.intel.com/design/network/applnots/302456.htm.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/time.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
#include <sys/endian.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h>
#include <sys/ata.h>
#include <sys/sema.h>
#include <sys/taskqueue.h>
#include <vm/uma.h>
#include <dev/ata/ata-all.h>
#include <ata_if.h>
#define AVILA_IDE_GPIN 12 /* GPIO pin # */
#define AVILA_IDE_IRQ IXP425_INT_GPIO_12
#define AVILA_IDE_CTRL 0x1e /* control register */
struct ata_avila_softc {
device_t sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_exp_ioh; /* Exp Bus config registers */
bus_space_handle_t sc_ioh; /* CS1 data registers */
struct bus_space sc_expbus_tag;
struct resource sc_ata; /* hand-crafted for ATA */
int sc_rid; /* rid for IRQ */
struct resource *sc_irq; /* IRQ resource */
void *sc_ih; /* interrupt handler */
struct {
void (*cb)(void *);
void *arg;
} sc_intr[1]; /* NB: 1/channel */
};
static void ata_avila_intr(void *);
bs_protos(ata);
static void ata_bs_rm_2_s(void *, bus_space_handle_t, bus_size_t,
u_int16_t *, bus_size_t);
static void ata_bs_wm_2_s(void *, bus_space_handle_t, bus_size_t,
const u_int16_t *, bus_size_t);
static int
ata_avila_probe(device_t dev)
{
/* XXX any way to check? */
device_set_desc_copy(dev, "Gateworks Avila IDE/CF Controller");
return 0;
}
static int
ata_avila_attach(device_t dev)
{
struct ata_avila_softc *sc = device_get_softc(dev);
struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
sc->sc_dev = dev;
/* NB: borrow from parent */
sc->sc_iot = sa->sc_iot;
sc->sc_exp_ioh = sa->sc_exp_ioh;
if (bus_space_map(sc->sc_iot,
IXP425_EXP_BUS_CS1_HWBASE, IXP425_EXP_BUS_CS1_SIZE, 0, &sc->sc_ioh))
panic("%s: unable to map Expansion Bus CS1 window", __func__);
/*
* Craft special resource for ATA bus space ops
* that go through the expansion bus and require
* special hackery to ena/dis 16-bit operations.
*
* XXX probably should just make this generic for
* accessing the expansion bus.
*/
sc->sc_expbus_tag.bs_cookie = sc; /* NB: backpointer */
/* read single */
sc->sc_expbus_tag.bs_r_1 = ata_bs_r_1,
sc->sc_expbus_tag.bs_r_2 = ata_bs_r_2,
/* read multiple */
sc->sc_expbus_tag.bs_rm_2 = ata_bs_rm_2,
sc->sc_expbus_tag.bs_rm_2_s = ata_bs_rm_2_s,
/* write (single) */
sc->sc_expbus_tag.bs_w_1 = ata_bs_w_1,
sc->sc_expbus_tag.bs_w_2 = ata_bs_w_2,
/* write multiple */
sc->sc_expbus_tag.bs_wm_2 = ata_bs_wm_2,
sc->sc_expbus_tag.bs_wm_2_s = ata_bs_wm_2_s,
rman_set_bustag(&sc->sc_ata, &sc->sc_expbus_tag);
rman_set_bushandle(&sc->sc_ata, sc->sc_ioh);
GPIO_CONF_WRITE_4(sa, IXP425_GPIO_GPOER,
GPIO_CONF_READ_4(sa, IXP425_GPIO_GPOER) | (1<<AVILA_IDE_GPIN));
/* interrupt is active low */
GPIO_CONF_WRITE_4(sa, GPIO_TYPE_REG(AVILA_IDE_GPIN),
GPIO_CONF_READ_4(sa, GPIO_TYPE_REG(AVILA_IDE_GPIN) |
GPIO_TYPE(AVILA_IDE_GPIN, GPIO_TYPE_ACT_LOW)));
/* clear ISR */
GPIO_CONF_WRITE_4(sa, IXP425_GPIO_GPISR, (1<<AVILA_IDE_GPIN));
/* configure CS1 window, leaving timing unchanged */
EXP_BUS_WRITE_4(sc, EXP_TIMING_CS1_OFFSET,
EXP_BUS_READ_4(sc, EXP_TIMING_CS1_OFFSET) |
EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
/* setup interrupt */
sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_rid,
AVILA_IDE_IRQ, AVILA_IDE_IRQ, 1, RF_ACTIVE);
if (!sc->sc_irq)
panic("Unable to allocate irq %u.\n", AVILA_IDE_IRQ);
bus_setup_intr(dev, sc->sc_irq,
INTR_TYPE_BIO | INTR_MPSAFE | INTR_ENTROPY,
ata_avila_intr, sc, &sc->sc_ih);
/* attach channel on this controller */
device_add_child(dev, "ata", devclass_find_free_unit(ata_devclass, 0));
bus_generic_attach(dev);
return 0;
}
static int
ata_avila_detach(device_t dev)
{
struct ata_avila_softc *sc = device_get_softc(dev);
device_t *children;
int nc;
/* XXX quiesce gpio? */
/* detach & delete all children */
if (device_get_children(dev, &children, &nc) == 0) {
if (nc > 0)
device_delete_child(dev, children[0]);
free(children, M_TEMP);
}
bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih);
bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid, sc->sc_irq);
return 0;
}
static void
ata_avila_intr(void *xsc)
{
struct ata_avila_softc *sc = xsc;
if (sc->sc_intr[0].cb != NULL)
sc->sc_intr[0].cb(sc->sc_intr[0].arg);
}
static struct resource *
ata_avila_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct ata_avila_softc *sc = device_get_softc(dev);
KASSERT(type == SYS_RES_IRQ && *rid == ATA_IRQ_RID,
("type %u rid %u start %lu end %lu count %lu flags %u",
type, *rid, start, end, count, flags));
/* doesn't matter what we return so reuse the real thing */
return sc->sc_irq;
}
static int
ata_avila_release_resource(device_t dev, device_t child, int type, int rid,
struct resource *r)
{
KASSERT(type == SYS_RES_IRQ && rid == ATA_IRQ_RID,
("type %u rid %u", type, rid));
return 0;
}
static int
ata_avila_setup_intr(device_t dev, device_t child, struct resource *irq,
int flags, driver_intr_t *function, void *argument,
void **cookiep)
{
struct ata_avila_softc *sc = device_get_softc(dev);
int unit = ((struct ata_channel *)device_get_softc(child))->unit;
KASSERT(unit == 0, ("unit %d", unit));
sc->sc_intr[unit].cb = function;
sc->sc_intr[unit].arg = argument;
*cookiep = sc;
return 0;
}
static int
ata_avila_teardown_intr(device_t dev, device_t child, struct resource *irq,
void *cookie)
{
struct ata_avila_softc *sc = device_get_softc(dev);
int unit = ((struct ata_channel *)device_get_softc(child))->unit;
KASSERT(unit == 0, ("unit %d", unit));
sc->sc_intr[unit].cb = NULL;
sc->sc_intr[unit].arg = NULL;
return 0;
}
/*
* Bus space accessors for CF-IDE PIO operations.
*/
/*
* Enable/disable 16-bit ops on the expansion bus.
*/
static void __inline
enable_16(struct ata_avila_softc *sc)
{
EXP_BUS_WRITE_4(sc, EXP_TIMING_CS1_OFFSET,
EXP_BUS_READ_4(sc, EXP_TIMING_CS1_OFFSET) &~ EXP_BYTE_EN);
DELAY(100); /* XXX? */
}
static void __inline
disable_16(struct ata_avila_softc *sc)
{
DELAY(100); /* XXX? */
EXP_BUS_WRITE_4(sc, EXP_TIMING_CS1_OFFSET,
EXP_BUS_READ_4(sc, EXP_TIMING_CS1_OFFSET) | EXP_BYTE_EN);
}
uint8_t
ata_bs_r_1(void *t, bus_space_handle_t h, bus_size_t o)
{
struct ata_avila_softc *sc = t;
return bus_space_read_1(sc->sc_iot, h, o);
}
void
ata_bs_w_1(void *t, bus_space_handle_t h, bus_size_t o, u_int8_t v)
{
struct ata_avila_softc *sc = t;
bus_space_write_1(sc->sc_iot, h, o, v);
}
uint16_t
ata_bs_r_2(void *t, bus_space_handle_t h, bus_size_t o)
{
struct ata_avila_softc *sc = t;
uint16_t v;
enable_16(sc);
v = bus_space_read_2(sc->sc_iot, h, o);
disable_16(sc);
return v;
}
void
ata_bs_w_2(void *t, bus_space_handle_t h, bus_size_t o, uint16_t v)
{
struct ata_avila_softc *sc = t;
enable_16(sc);
bus_space_write_2(sc->sc_iot, h, o, v);
disable_16(sc);
}
void
ata_bs_rm_2(void *t, bus_space_handle_t h, bus_size_t o,
u_int16_t *d, bus_size_t c)
{
struct ata_avila_softc *sc = t;
enable_16(sc);
bus_space_read_multi_2(sc->sc_iot, h, o, d, c);
disable_16(sc);
}
void
ata_bs_wm_2(void *t, bus_space_handle_t h, bus_size_t o,
const u_int16_t *d, bus_size_t c)
{
struct ata_avila_softc *sc = t;
enable_16(sc);
bus_space_write_multi_2(sc->sc_iot, h, o, d, c);
disable_16(sc);
}
/* XXX workaround ata driver by (incorrectly) byte swapping stream cases */
void
ata_bs_rm_2_s(void *t, bus_space_handle_t h, bus_size_t o,
u_int16_t *d, bus_size_t c)
{
struct ata_avila_softc *sc = t;
uint16_t v;
bus_size_t i;
enable_16(sc);
#if 1
for (i = 0; i < c; i++) {
v = bus_space_read_2(sc->sc_iot, h, o);
d[i] = bswap16(v);
}
#else
bus_space_read_multi_stream_2(sc->sc_iot, h, o, d, c);
#endif
disable_16(sc);
}
void
ata_bs_wm_2_s(void *t, bus_space_handle_t h, bus_size_t o,
const u_int16_t *d, bus_size_t c)
{
struct ata_avila_softc *sc = t;
bus_size_t i;
enable_16(sc);
#if 1
for (i = 0; i < c; i++)
bus_space_write_2(sc->sc_iot, h, o, bswap16(d[i]));
#else
bus_space_write_multi_stream_2(sc->sc_iot, h, o, d, c);
#endif
disable_16(sc);
}
static device_method_t ata_avila_methods[] = {
/* device interface */
DEVMETHOD(device_probe, ata_avila_probe),
DEVMETHOD(device_attach, ata_avila_attach),
DEVMETHOD(device_detach, ata_avila_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* bus methods */
DEVMETHOD(bus_alloc_resource, ata_avila_alloc_resource),
DEVMETHOD(bus_release_resource, ata_avila_release_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_setup_intr, ata_avila_setup_intr),
DEVMETHOD(bus_teardown_intr, ata_avila_teardown_intr),
{ 0, 0 }
};
devclass_t ata_avila_devclass;
static driver_t ata_avila_driver = {
"ata_avila",
ata_avila_methods,
sizeof(struct ata_avila_softc),
};
DRIVER_MODULE(ata_avila, ixp, ata_avila_driver, ata_avila_devclass, 0, 0);
MODULE_VERSION(ata_avila, 1);
MODULE_DEPEND(ata_avila, ata, 1, 1, 1);
static int
avila_channel_probe(device_t dev)
{
struct ata_channel *ch = device_get_softc(dev);
ch->unit = 0;
ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE;
device_set_desc_copy(dev, "ATA channel 0");
return ata_probe(dev);
}
static int
avila_channel_attach(device_t dev)
{
struct ata_avila_softc *sc = device_get_softc(device_get_parent(dev));
struct ata_channel *ch = device_get_softc(dev);
int i;
for (i = 0; i < ATA_MAX_RES; i++)
ch->r_io[i].res = &sc->sc_ata;
ch->r_io[ATA_DATA].offset = ATA_DATA;
ch->r_io[ATA_FEATURE].offset = ATA_FEATURE;
ch->r_io[ATA_COUNT].offset = ATA_COUNT;
ch->r_io[ATA_SECTOR].offset = ATA_SECTOR;
ch->r_io[ATA_CYL_LSB].offset = ATA_CYL_LSB;
ch->r_io[ATA_CYL_MSB].offset = ATA_CYL_MSB;
ch->r_io[ATA_DRIVE].offset = ATA_DRIVE;
ch->r_io[ATA_COMMAND].offset = ATA_COMMAND;
ch->r_io[ATA_ERROR].offset = ATA_FEATURE;
/* NB: should be used only for ATAPI devices */
ch->r_io[ATA_IREASON].offset = ATA_COUNT;
ch->r_io[ATA_STATUS].offset = ATA_COMMAND;
/* alias this; required by ata_generic_status */
ch->r_io[ATA_ALTSTAT].offset = ch->r_io[ATA_STATUS].offset;
/* NB: the control register is special */
ch->r_io[ATA_CONTROL].offset = AVILA_IDE_CTRL;
/* NB: by convention this points at the base of registers */
ch->r_io[ATA_IDX_ADDR].offset = 0;
ata_generic_hw(dev);
return ata_attach(dev);
}
/* XXX override ata_generic_reset to handle non-standard status */
static void
avila_channel_reset(device_t dev)
{
struct ata_channel *ch = device_get_softc(dev);
u_int8_t ostat0 = 0, stat0 = 0;
u_int8_t err = 0, lsb = 0, msb = 0;
int mask = 0, timeout;
/* do we have any signs of ATA/ATAPI HW being present ? */
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_MASTER);
DELAY(10);
ostat0 = ATA_IDX_INB(ch, ATA_STATUS);
if ((ostat0 & 0xf8) != 0xf8 && ostat0 != 0xa5) {
stat0 = ATA_S_BUSY;
mask |= 0x01;
}
if (bootverbose)
device_printf(dev, "%s: reset tp1 mask=%02x ostat0=%02x\n",
__func__, mask, ostat0);
/* if nothing showed up there is no need to get any further */
/* XXX SOS is that too strong?, we just might loose devices here */
ch->devices = 0;
if (!mask)
return;
/* reset (both) devices on this channel */
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA | ATA_MASTER);
DELAY(10);
ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_IDS | ATA_A_RESET);
ata_udelay(10000);
ATA_IDX_OUTB(ch, ATA_CONTROL, ATA_A_IDS);
ata_udelay(100000);
ATA_IDX_INB(ch, ATA_ERROR);
/* wait for BUSY to go inactive */
for (timeout = 0; timeout < 310; timeout++) {
if ((mask & 0x01) && (stat0 & ATA_S_BUSY)) {
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
DELAY(10);
err = ATA_IDX_INB(ch, ATA_ERROR);
lsb = ATA_IDX_INB(ch, ATA_CYL_LSB);
msb = ATA_IDX_INB(ch, ATA_CYL_MSB);
stat0 = ATA_IDX_INB(ch, ATA_STATUS);
if (bootverbose)
device_printf(dev,
"%s: stat0=0x%02x err=0x%02x lsb=0x%02x "
"msb=0x%02x\n", __func__,
stat0, err, lsb, msb);
if (stat0 == err && lsb == err && msb == err &&
timeout > (stat0 & ATA_S_BUSY ? 100 : 10))
mask &= ~0x01;
if (!(stat0 & ATA_S_BUSY)) {
if ((err & 0x7f) == ATA_E_ILI || err == 0) {
if (lsb == ATAPI_MAGIC_LSB &&
msb == ATAPI_MAGIC_MSB) {
ch->devices |= ATA_ATAPI_MASTER;
} else if (stat0 & ATA_S_READY) {
ch->devices |= ATA_ATA_MASTER;
}
} else if ((stat0 & 0x0f) &&
err == lsb && err == msb) {
stat0 |= ATA_S_BUSY;
}
}
}
if (mask == 0x00) /* nothing to wait for */
break;
/* wait for master */
if (!(stat0 & ATA_S_BUSY) || (stat0 == 0xff && timeout > 10))
break;
ata_udelay(100000);
}
if (bootverbose)
device_printf(dev, "%s: reset tp2 stat0=%02x devices=0x%b\n",
__func__, stat0, ch->devices,
"\20\4ATAPI_SLAVE\3ATAPI_MASTER\2ATA_SLAVE\1ATA_MASTER");
}
static device_method_t avila_channel_methods[] = {
/* device interface */
DEVMETHOD(device_probe, avila_channel_probe),
DEVMETHOD(device_attach, avila_channel_attach),
DEVMETHOD(device_detach, ata_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, ata_suspend),
DEVMETHOD(device_resume, ata_resume),
DEVMETHOD(ata_reset, avila_channel_reset),
{ 0, 0 }
};
driver_t avila_channel_driver = {
"ata",
avila_channel_methods,
sizeof(struct ata_channel),
};
DRIVER_MODULE(ata, ata_avila, avila_channel_driver, ata_devclass, 0, 0);

View File

@ -0,0 +1,545 @@
/* $NetBSD: hpc_machdep.c,v 1.70 2003/09/16 08:18:22 agc Exp $ */
/*-
* Copyright (c) 1994-1998 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.
*
* RiscBSD kernel project
*
* machdep.c
*
* Machine dependant functions for kernel setup
*
* This file needs a lot of work.
*
* Created : 17/09/94
*/
#include "opt_msgbuf.h"
#include "opt_ddb.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#define _ARM32_BUS_DMA_PRIVATE
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
#include <sys/signalvar.h>
#include <sys/imgact.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
#include <sys/linker.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/pcpu.h>
#include <sys/proc.h>
#include <sys/ptrace.h>
#include <sys/cons.h>
#include <sys/bio.h>
#include <sys/bus.h>
#include <sys/buf.h>
#include <sys/exec.h>
#include <sys/kdb.h>
#include <sys/msgbuf.h>
#include <machine/reg.h>
#include <machine/cpu.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pager.h>
#include <vm/vm_map.h>
#include <vm/vnode_pager.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#include <machine/undefined.h>
#include <machine/machdep.h>
#include <machine/metadata.h>
#include <machine/armreg.h>
#include <machine/bus.h>
#include <sys/reboot.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h>
#define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */
#define KERNEL_PT_IO 1
#define KERNEL_PT_IO_NUM 3
#define KERNEL_PT_BEFOREKERN KERNEL_PT_IO + KERNEL_PT_IO_NUM
#define KERNEL_PT_AFKERNEL KERNEL_PT_BEFOREKERN + 1 /* L2 table for mapping after kernel */
#define KERNEL_PT_AFKERNEL_NUM 9
/* this should be evenly divisable by PAGE_SIZE / L2_TABLE_SIZE_REAL (or 4) */
#define NUM_KERNEL_PTS (KERNEL_PT_AFKERNEL + KERNEL_PT_AFKERNEL_NUM)
/* Define various stack sizes in pages */
#define IRQ_STACK_SIZE 1
#define ABT_STACK_SIZE 1
#ifdef IPKDB
#define UND_STACK_SIZE 2
#else
#define UND_STACK_SIZE 1
#endif
extern u_int data_abort_handler_address;
extern u_int prefetch_abort_handler_address;
extern u_int undefined_handler_address;
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
extern void *_end;
extern vm_offset_t sa1_cache_clean_addr;
extern int *end;
struct pcpu __pcpu;
struct pcpu *pcpup = &__pcpu;
/* Physical and virtual addresses for some global pages */
vm_paddr_t phys_avail[10];
vm_paddr_t dump_avail[4];
vm_offset_t physical_pages;
vm_offset_t clean_sva, clean_eva;
struct pv_addr systempage;
struct pv_addr msgbufpv;
struct pv_addr irqstack;
struct pv_addr undstack;
struct pv_addr abtstack;
struct pv_addr kernelstack;
struct pv_addr minidataclean;
static struct trapframe proc0_tf;
/* Static device mappings. */
static const struct pmap_devmap ixp425_devmap[] = {
/* Physical/Virtual address for I/O space */
{
IXP425_IO_VBASE,
IXP425_IO_HWBASE,
IXP425_IO_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
/* Expansion Bus */
{
IXP425_EXP_VBASE,
IXP425_EXP_HWBASE,
IXP425_EXP_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
/* IXP425 PCI Configuration */
{
IXP425_PCI_VBASE,
IXP425_PCI_HWBASE,
IXP425_PCI_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
/* SDRAM Controller */
{
IXP425_MCU_VBASE,
IXP425_MCU_HWBASE,
IXP425_MCU_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
/* PCI Memory Space */
{
IXP425_PCI_MEM_VBASE,
IXP425_PCI_MEM_HWBASE,
IXP425_PCI_MEM_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
/* NPE-A Memory Space */
{
IXP425_NPE_A_VBASE,
IXP425_NPE_A_HWBASE,
IXP425_NPE_A_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
/* NPE-B Memory Space */
{
IXP425_NPE_B_VBASE,
IXP425_NPE_B_HWBASE,
IXP425_NPE_B_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
/* NPE-C Memory Space */
{
IXP425_NPE_C_VBASE,
IXP425_NPE_C_HWBASE,
IXP425_NPE_C_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
/* MAC-A Memory Space */
{
IXP425_MAC_A_VBASE,
IXP425_MAC_A_HWBASE,
IXP425_MAC_A_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
/* MAC-B Memory Space */
{
IXP425_MAC_B_VBASE,
IXP425_MAC_B_HWBASE,
IXP425_MAC_B_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
/* Q-Mgr Memory Space */
{
IXP425_QMGR_VBASE,
IXP425_QMGR_HWBASE,
IXP425_QMGR_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE,
},
{
0,
0,
0,
0,
0,
}
};
#define SDRAM_START 0x10000000
#ifdef DDB
extern vm_offset_t ksym_start, ksym_end;
#endif
extern vm_offset_t xscale_cache_clean_addr;
void *
initarm(void *arg, void *arg2)
{
struct pv_addr kernel_l1pt;
int loop;
u_int l1pagetable;
vm_offset_t freemempos;
vm_offset_t freemem_pt;
vm_offset_t afterkern;
vm_offset_t freemem_after;
vm_offset_t lastaddr;
#ifdef DDB
vm_offset_t zstart = 0, zend = 0;
#endif
int i = 0;
uint32_t fake_preload[35];
uint32_t memsize;
i = 0;
set_cpufuncs();
fake_preload[i++] = MODINFO_NAME;
fake_preload[i++] = strlen("elf kernel") + 1;
strcpy((char*)&fake_preload[i++], "elf kernel");
i += 2;
fake_preload[i++] = MODINFO_TYPE;
fake_preload[i++] = strlen("elf kernel") + 1;
strcpy((char*)&fake_preload[i++], "elf kernel");
i += 2;
fake_preload[i++] = MODINFO_ADDR;
fake_preload[i++] = sizeof(vm_offset_t);
fake_preload[i++] = KERNBASE + 0x00200000;
fake_preload[i++] = MODINFO_SIZE;
fake_preload[i++] = sizeof(uint32_t);
fake_preload[i++] = (uint32_t)&end - KERNBASE - 0x00200000;
#ifdef DDB
if (*(uint32_t *)KERNVIRTADDR == MAGIC_TRAMP_NUMBER) {
fake_preload[i++] = MODINFO_METADATA|MODINFOMD_SSYM;
fake_preload[i++] = sizeof(vm_offset_t);
fake_preload[i++] = *(uint32_t *)(KERNVIRTADDR + 4);
fake_preload[i++] = MODINFO_METADATA|MODINFOMD_ESYM;
fake_preload[i++] = sizeof(vm_offset_t);
fake_preload[i++] = *(uint32_t *)(KERNVIRTADDR + 8);
lastaddr = *(uint32_t *)(KERNVIRTADDR + 8);
zend = lastaddr;
zstart = *(uint32_t *)(KERNVIRTADDR + 4);
ksym_start = zstart;
ksym_end = zend;
} else
#endif
lastaddr = (vm_offset_t)&end;
fake_preload[i++] = 0;
fake_preload[i] = 0;
preload_metadata = (void *)fake_preload;
pcpu_init(pcpup, 0, sizeof(struct pcpu));
PCPU_SET(curthread, &thread0);
#define KERNEL_TEXT_BASE (KERNBASE + 0x00200000)
freemempos = 0x10200000;
/* Define a macro to simplify memory allocation */
#define valloc_pages(var, np) \
alloc_pages((var).pv_pa, (np)); \
(var).pv_va = (var).pv_pa + 0xb0000000;
#define alloc_pages(var, np) \
freemempos -= (np * PAGE_SIZE); \
(var) = freemempos; \
memset((char *)(var), 0, ((np) * PAGE_SIZE));
while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0)
freemempos -= PAGE_SIZE;
valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) {
valloc_pages(kernel_pt_table[loop],
L2_TABLE_SIZE / PAGE_SIZE);
} else {
kernel_pt_table[loop].pv_pa = freemempos +
(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) *
L2_TABLE_SIZE_REAL;
kernel_pt_table[loop].pv_va =
kernel_pt_table[loop].pv_pa + 0xb0000000;
}
}
freemem_pt = freemempos;
freemempos = 0x10100000;
/*
* Allocate a page for the system page mapped to V0x00000000
* This page will just contain the system vectors and can be
* shared by all processes.
*/
valloc_pages(systempage, 1);
/* Allocate stacks for all modes */
valloc_pages(irqstack, IRQ_STACK_SIZE);
valloc_pages(abtstack, ABT_STACK_SIZE);
valloc_pages(undstack, UND_STACK_SIZE);
valloc_pages(kernelstack, KSTACK_PAGES);
alloc_pages(minidataclean.pv_pa, 1);
valloc_pages(msgbufpv, round_page(MSGBUF_SIZE) / PAGE_SIZE);
#ifdef ARM_USE_SMALL_ALLOC
freemempos -= PAGE_SIZE;
freemem_pt = trunc_page(freemem_pt);
freemem_after = freemempos - ((freemem_pt - 0x10100000) /
PAGE_SIZE) * sizeof(struct arm_small_page);
arm_add_smallalloc_pages((void *)(freemem_after + 0xb0000000)
, (void *)0xc0100000, freemem_pt - 0x10100000, 1);
freemem_after -= ((freemem_after - 0x10001000) / PAGE_SIZE) *
sizeof(struct arm_small_page);
arm_add_smallalloc_pages((void *)(freemem_after + 0xb0000000)
, (void *)0xc0001000, trunc_page(freemem_after) - 0x10001000, 0);
freemempos = trunc_page(freemem_after);
freemempos -= PAGE_SIZE;
#endif
/*
* Allocate memory for the l1 and l2 page tables. The scheme to avoid
* wasting memory by allocating the l1pt on the first 16k memory was
* taken from NetBSD rpc_machdep.c. NKPT should be greater than 12 for
* this to work (which is supposed to be the case).
*/
/*
* Now we start construction of the L1 page table
* We start by mapping the L2 page tables into the L1.
* This means that we can replace L1 mappings later on if necessary
*/
l1pagetable = kernel_l1pt.pv_va;
/* Map the L2 pages tables in the L1 page table */
pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00100000 - 1),
&kernel_pt_table[KERNEL_PT_SYS]);
pmap_link_l2pt(l1pagetable, IXP425_IO_VBASE,
&kernel_pt_table[KERNEL_PT_IO]);
pmap_link_l2pt(l1pagetable, IXP425_MCU_VBASE,
&kernel_pt_table[KERNEL_PT_IO + 1]);
pmap_link_l2pt(l1pagetable, IXP425_PCI_MEM_VBASE,
&kernel_pt_table[KERNEL_PT_IO + 2]);
pmap_link_l2pt(l1pagetable, KERNBASE,
&kernel_pt_table[KERNEL_PT_BEFOREKERN]);
pmap_map_chunk(l1pagetable, KERNBASE, SDRAM_START, 0x100000,
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
pmap_map_chunk(l1pagetable, KERNBASE + 0x100000, SDRAM_START + 0x100000,
0x100000, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
pmap_map_chunk(l1pagetable, KERNBASE + 0x200000, SDRAM_START + 0x200000,
(((uint32_t)(lastaddr) - KERNBASE - 0x200000) + L1_S_SIZE) & ~(L1_S_SIZE - 1),
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
freemem_after = ((int)lastaddr + PAGE_SIZE) & ~(PAGE_SIZE - 1);
afterkern = round_page(((vm_offset_t)lastaddr + L1_S_SIZE) & ~(L1_S_SIZE
- 1));
for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) {
pmap_link_l2pt(l1pagetable, afterkern + i * 0x00100000,
&kernel_pt_table[KERNEL_PT_AFKERNEL + i]);
}
pmap_map_entry(l1pagetable, afterkern, minidataclean.pv_pa,
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
#ifdef ARM_USE_SMALL_ALLOC
if ((freemem_after + 2 * PAGE_SIZE) <= afterkern) {
arm_add_smallalloc_pages((void *)(freemem_after),
(void*)(freemem_after + PAGE_SIZE),
afterkern - (freemem_after + PAGE_SIZE), 0);
}
#endif
/* Map the Mini-Data cache clean area. */
xscale_setup_minidata(l1pagetable, afterkern,
minidataclean.pv_pa);
/* Map the vector page. */
pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
pmap_devmap_bootstrap(l1pagetable, ixp425_devmap);
/*
* Give the XScale global cache clean code an appropriately
* sized chunk of unmapped VA space starting at 0xff000000
* (our device mappings end before this address).
*/
xscale_cache_clean_addr = 0xff000000U;
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
setttb(kernel_l1pt.pv_pa);
cpu_tlb_flushID();
cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));
/*
* Pages were allocated during the secondary bootstrap for the
* stacks for different CPU modes.
* We must now set the r13 registers in the different CPU modes to
* point to these stacks.
* Since the ARM stacks use STMFD etc. we must set r13 to the top end
* of the stack memory.
*/
set_stackptr(PSR_IRQ32_MODE,
irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
set_stackptr(PSR_ABT32_MODE,
abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
set_stackptr(PSR_UND32_MODE,
undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
/*
* We must now clean the cache again....
* Cleaning may be done by reading new data to displace any
* dirty data in the cache. This will have happened in setttb()
* but since we are boot strapping the addresses used for the read
* may have just been remapped and thus the cache could be out
* of sync. A re-clean after the switch will cure this.
* After booting there are no gross reloations of the kernel thus
* this problem will not occur after initarm().
*/
cpu_idcache_wbinv_all();
/*
* Fetch the SDRAM start/size from the ixp425 SDRAM configration
* registers.
*/
cninit();
memsize = ixp425_sdram_size();
physmem = memsize / PAGE_SIZE;
/* Set stack for exception handlers */
data_abort_handler_address = (u_int)data_abort_handler;
prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
undefined_handler_address = (u_int)undefinedinstruction_bounce;
undefined_init();
#ifdef KSE
proc_linkup(&proc0, &ksegrp0, &thread0);
#else
proc_linkup(&proc0, &thread0);
#endif
thread0.td_kstack = kernelstack.pv_va;
thread0.td_pcb = (struct pcb *)
(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
thread0.td_pcb->pcb_flags = 0;
thread0.td_frame = &proc0_tf;
pcpup->pc_curpcb = thread0.td_pcb;
/* Enable MMU, I-cache, D-cache, write buffer. */
arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
pmap_curmaxkvaddr = afterkern + PAGE_SIZE;
dump_avail[0] = 0x10000000;
dump_avail[1] = 0x10000000 + memsize;
dump_avail[2] = 0;
dump_avail[3] = 0;
pmap_bootstrap(pmap_curmaxkvaddr,
0xd0000000, &kernel_l1pt);
msgbufp = (void*)msgbufpv.pv_va;
msgbufinit(msgbufp, MSGBUF_SIZE);
mutex_init();
i = 0;
#ifdef ARM_USE_SMALL_ALLOC
phys_avail[i++] = 0x10000000;
phys_avail[i++] = 0x10001000; /*
*XXX: Gross hack to get our
* pages in the vm_page_array
. */
#endif
phys_avail[i++] = round_page(virtual_avail - KERNBASE + SDRAM_START);
phys_avail[i++] = trunc_page(0x10000000 + memsize - 1);
phys_avail[i++] = 0;
phys_avail[i] = 0;
/* Do basic tuning, hz etc */
init_param1();
init_param2(physmem);
kdb_init();
return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
sizeof(struct pcb)));
}

View File

@ -0,0 +1,4 @@
#$FreeBSD$
arm/xscale/ixp425/avila_machdep.c standard
arm/xscale/ixp425/avila_ata.c optional avila_ata
arm/xscale/ixp425/ixdp425_pci.c optional pci

View File

@ -0,0 +1,41 @@
#$FreeBSD$
arm/arm/cpufunc_asm_xscale.S standard
arm/arm/irq_dispatch.S standard
arm/xscale/ixp425/ixp425.c standard
arm/xscale/ixp425/ixp425_mem.c standard
arm/xscale/ixp425/ixp425_space.c standard
arm/xscale/ixp425/ixp425_timer.c standard
arm/xscale/ixp425/ixp425_wdog.c optional ixpwdog
arm/xscale/ixp425/ixp425_iic.c optional ixpiic
arm/xscale/ixp425/ixp425_pci.c optional pci
arm/xscale/ixp425/ixp425_pci_asm.S optional pci
arm/xscale/ixp425/ixp425_pci_space.c optional pci
arm/xscale/ixp425/uart_cpu_ixp425.c optional uart
arm/xscale/ixp425/uart_bus_ixp425.c optional uart
arm/xscale/ixp425/ixp425_a4x_space.c optional uart
arm/xscale/ixp425/ixp425_a4x_io.S optional uart
dev/uart/uart_dev_ns8250.c optional uart
#
# NPE-based Ethernet support (requires qmgr also). Note the
# firmware images must be downloaded from the Intel web site.
#
arm/xscale/ixp425/if_npe.c optional npe
arm/xscale/ixp425/ixp425_npe.c optional npe
ixp425_npe_fw.c optional npe_fw \
compile-with "${AWK} -f $S/tools/fw_stub.awk IxNpeMicrocode.dat:npe_fw -mnpe -c${.TARGET}" \
no-implicit-rule before-depend local \
clean "ixp425_npe_fw.c"
#
# NB: ld encodes the path in the binary symbols generated for the
# firmware image so link the file to the object directory to
# get known values for reference in the _fw.c file.
#
IxNpeMicrocode.fwo optional npe_fw \
dependency "$S/arm/xscale/ixp425/IxNpeMicrocode.dat" \
compile-with "ln -sf $S/arm/xscale/ixp425/IxNpeMicrocode.dat ${.OBJDIR}; ${LD} -b binary -d -warn-common -r -d -o ${.TARGET} IxNpeMicrocode.dat" \
no-implicit-rule \
clean "IxNpeMicrocode.dat IxNpeMicrocode.fwo"
#
# Q-Manager support
#
arm/xscale/ixp425/ixp425_qmgr.c optional qmgr

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,288 @@
/*-
* Copyright (c) 2006 Sam Leffler, Errno Consulting
* 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,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
*
* $FreeBSD$
*/
/*
* Copyright (c) 2001-2005, Intel Corporation.
* 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 Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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_XSCALE_IF_NPEREG_H
#define ARM_XSCALE_IF_NPEREG_H
/*
* NPE/NPE tx/rx descriptor format. This is just the area
* shared with ucode running in the NPE; the driver-specific
* state is defined in the driver. The shared area must be
* cacheline-aligned. We allocate NPE_MAXSEG "descriptors"
* per buffer; this allows us to do minimal s/g. The number
* of descriptors can be expanded but doing so uses memory
* so should be done with care.
*
* The driver sets up buffers in uncached memory.
*/
#define NPE_MAXSEG 3 /* empirically selected */
struct npehwbuf {
struct { /* NPE shared area, cacheline aligned */
uint32_t next; /* phys addr of next segment */
uint32_t len; /* buffer/segment length (bytes) */
uint32_t data; /* phys addr of data segment */
uint32_t pad[5]; /* pad to cacheline */
} ix_ne[NPE_MAXSEG];
};
/* NPE ID's */
#define NPE_A 0
#define NPE_B 1
#define NPE_C 2
#define NPE_MAX (NPE_C+1)
#define NPE_PORTS_MAX 2 /* logical ports */
#define NPE_FRAME_SIZE_DEFAULT 1536
#define NPE_FRAME_SIZE_MAX (65536-64)
#define NPE_FRAME_SIZE_MIN 64
/*
* Queue Manager-related definitions.
*
* These define the layout of 32-bit Q entries passed
* between the host cpu and the NPE's.
*/
#define NPE_QM_Q_NPE(e) (((e)>>0)&0x3) /* NPE ID */
#define NPE_QM_Q_PORT(e) (((e)>>3)&0x1) /* Port ID */
#define NPE_QM_Q_PRIO(e) (((e)>>0)&0x3) /* 802.1d priority */
#define NPE_QM_Q_ADDR(e) ((e)&0xfffffffe0) /* phys address */
/*
* Host->NPE requests written to the shared mailbox.
* The NPE writes the same value back as an ACK.
*/
#define NPE_GETSTATUS 0x00 /* get firmware revision */
#define NPE_SETPORTADDRESS 0x01 /* set port id and mac address */
#define NPE_GETMACADDRDB 0x02 /* upload filter database */
#define NPE_SETMACADDRDB 0x03 /* download filter database */
#define NPE_GETSTATS 0x04 /* get statistics */
#define NPE_RESETSTATS 0x05 /* reset stats + return result */
#define NPE_SETMAXFRAME 0x06 /* configure max tx/rx frame lengths */
#define NPE_SETRXTAGMODE 0x07 /* configure VLAN rx operating mode */
#define NPE_SETDEFRXVID 0x08 /* set def VLAN tag + traffic class */
#define NPE_SETRXQOSENTRY 0x0b /* map user pri -> QoS class+rx qid */
#define NPE_SETFIREWALLMODE 0x0e /* config firewall services */
#define NPE_SETLOOPBACK 0x12 /* enable/disable loopback */
/* ... XXX more */
#define NPE_MAC_MSGID_SHL 24
#define NPE_MAC_PORTID_SHL 16
/*
* MAC register definitions; see section
* 15.2 of the Intel Developers Manual.
*/
#define NPE_MAC_TX_CNTRL1 0x000
#define NPE_MAC_TX_CNTRL2 0x004
#define NPE_MAC_RX_CNTRL1 0x010
#define NPE_MAC_RX_CNTRL2 0x014
#define NPE_MAC_RANDOM_SEED 0x020
#define NPE_MAC_THRESH_P_EMPTY 0x030
#define NPE_MAC_THRESH_P_FULL 0x038
#define NPE_MAC_BUF_SIZE_TX 0x040
#define NPE_MAC_TX_DEFER 0x050
#define NPE_MAC_RX_DEFER 0x054
#define NPE_MAC_TX_TWO_DEFER_1 0x060
#define NPE_MAC_TX_TWO_DEFER_2 0x064
#define NPE_MAC_SLOT_TIME 0x070
#define NPE_MAC_MDIO_CMD_1 0x080
#define NPE_MAC_MDIO_CMD_2 0x084
#define NPE_MAC_MDIO_CMD_3 0x088
#define NPE_MAC_MDIO_CMD_4 0x08c
#define NPE_MAC_MDIO_STS_1 0x090
#define NPE_MAC_MDIO_STS_2 0x094
#define NPE_MAC_MDIO_STS_3 0x098
#define NPE_MAC_MDIO_STS_4 0x09c
#define NPE_MAC_ADDR_MASK_1 0x0A0
#define NPE_MAC_ADDR_MASK_2 0x0A4
#define NPE_MAC_ADDR_MASK_3 0x0A8
#define NPE_MAC_ADDR_MASK_4 0x0AC
#define NPE_MAC_ADDR_MASK_5 0x0B0
#define NPE_MAC_ADDR_MASK_6 0x0B4
#define NPE_MAC_ADDR_1 0x0C0
#define NPE_MAC_ADDR_2 0x0C4
#define NPE_MAC_ADDR_3 0x0C8
#define NPE_MAC_ADDR_4 0x0CC
#define NPE_MAC_ADDR_5 0x0D0
#define NPE_MAC_ADDR_6 0x0D4
#define NPE_MAC_INT_CLK_THRESH 0x0E0
#define NPE_MAC_UNI_ADDR_1 0x0F0
#define NPE_MAC_UNI_ADDR_2 0x0F4
#define NPE_MAC_UNI_ADDR_3 0x0F8
#define NPE_MAC_UNI_ADDR_4 0x0FC
#define NPE_MAC_UNI_ADDR_5 0x100
#define NPE_MAC_UNI_ADDR_6 0x104
#define NPE_MAC_CORE_CNTRL 0x1FC
#define NPE_MAC_ADDR_MASK(i) (NPE_MAC_ADDR_MASK_1 + ((i)<<2))
#define NPE_MAC_ADDR(i) (NPE_MAC_ADDR_1 + ((i)<<2))
#define NPE_MAC_UNI_ADDR(i) (NPE_MAC_UNI_ADDR_1 + ((i)<<2))
/*
* Bit definitions
*/
/* TX Control Register 1*/
#define NPE_TX_CNTRL1_TX_EN 0x01 /* enable TX engine */
#define NPE_TX_CNTRL1_DUPLEX 0x02 /* select half duplex */
#define NPE_TX_CNTRL1_RETRY 0x04 /* auto-retry on collision */
#define NPE_TX_CNTRL1_PAD_EN 0x08 /* pad frames <64 bytes */
#define NPE_TX_CNTRL1_FCS_EN 0x10 /* append FCS */
#define NPE_TX_CNTRL1_2DEFER 0x20 /* select 2-part deferral */
#define NPE_TX_CNTRL1_RMII 0x40
/* TX Control Register 2 */
#define NPE_TX_CNTRL2_RETRIES_MASK 0xf /* max retry count */
/* RX Control Register 1 */
#define NPE_RX_CNTRL1_RX_EN 0x01 /* enable RX engine */
#define NPE_RX_CNTRL1_PADSTRIP_EN 0x02 /* strip frame padding */
#define NPE_RX_CNTRL1_CRC_EN 0x04 /* include CRC in RX frame */
#define NPE_RX_CNTRL1_PAUSE_EN 0x08 /* detect Pause frames */
#define NPE_RX_CNTRL1_LOOP_EN 0x10 /* loopback tx/rx */
#define NPE_RX_CNTRL1_ADDR_FLTR_EN 0x20 /* enable address filtering */
#define NPE_RX_CNTRL1_RX_RUNT_EN 0x40 /* enable RX of runt frames */
#define NPE_RX_CNTRL1_BCAST_DIS 0x80 /* discard broadcast frames */
/* RX Control Register 2 */
#define NPE_RX_CNTRL2_DEFER_EN 0x01
/* Core Control Register */
#define NPE_CORE_RESET 0x01 /* MAC reset state */
#define NPE_CORE_RX_FIFO_FLUSH 0x02 /* flush RX FIFO */
#define NPE_CORE_TX_FIFO_FLUSH 0x04 /* flush TX FIFO */
#define NPE_CORE_SEND_JAM 0x08 /* send JAM on packet RX */
#define NPE_CORE_MDC_EN 0x10 /* IXP42X drives MDC clock */
/*
* Stat block returned by NPE with NPE_GETSTATS msg.
*/
struct npestats {
uint32_t dot3StatsAlignmentErrors;
uint32_t dot3StatsFCSErrors;
uint32_t dot3StatsInternalMacReceiveErrors;
uint32_t RxOverrunDiscards;
uint32_t RxLearnedEntryDiscards;
uint32_t RxLargeFramesDiscards;
uint32_t RxSTPBlockedDiscards;
uint32_t RxVLANTypeFilterDiscards;
uint32_t RxVLANIdFilterDiscards;
uint32_t RxInvalidSourceDiscards;
uint32_t RxBlackListDiscards;
uint32_t RxWhiteListDiscards;
uint32_t RxUnderflowEntryDiscards;
uint32_t dot3StatsSingleCollisionFrames;
uint32_t dot3StatsMultipleCollisionFrames;
uint32_t dot3StatsDeferredTransmissions;
uint32_t dot3StatsLateCollisions;
uint32_t dot3StatsExcessiveCollisions;
uint32_t dot3StatsInternalMacTransmitErrors;
uint32_t dot3StatsCarrierSenseErrors;
uint32_t TxLargeFrameDiscards;
uint32_t TxVLANIdFilterDiscards;
};
/*
* Default values
*/
#define NPE_MAC_INT_CLK_THRESH_DEFAULT 0x1
#define NPE_MAC_RESET_DELAY 1
/* This value applies to RMII */
#define NPE_MAC_SLOT_TIME_RMII_DEFAULT 0xFF
/*
* MII definitions - these have been verified against the LXT971 and LXT972 PHYs
*/
#define NPE_MII_REG_SHL 16
#define NPE_MII_ADDR_SHL 21
/* NB: shorthands for mii bus mdio routines */
#define NPE_MAC_MDIO_CMD NPE_MAC_MDIO_CMD_1
#define NPE_MAC_MDIO_STS NPE_MAC_MDIO_STS_1
#define NPE_MII_GO (1<<31)
#define NPE_MII_WRITE (1<<26)
#define NPE_MII_TIMEOUT_10TH_SECS 5
#define NPE_MII_10TH_SEC_IN_MILLIS 100
#define NPE_MII_READ_FAIL (1<<31)
#define NPE_MII_PHY_DEF_DELAY 300 /* max delay before link up, etc. */
#define NPE_MII_PHY_NO_DELAY 0x0 /* do not delay */
#define NPE_MII_PHY_NULL 0xff /* PHY is not present */
#define NPE_MII_PHY_DEF_ADDR 0x0 /* default PHY's logical address */
/* Register definition */
#define NPE_MII_CTRL_REG 0x0 /* Control Register */
#define NPE_MII_STAT_REG 0x1 /* Status Register */
#define NPE_MII_PHY_ID1_REG 0x2 /* PHY identifier 1 Register */
#define NPE_MII_PHY_ID2_REG 0x3 /* PHY identifier 2 Register */
#define NPE_MII_AN_ADS_REG 0x4 /* Auto-Negotiation */
/* Advertisement Register */
#define NPE_MII_AN_PRTN_REG 0x5 /* Auto-Negotiation */
/* partner ability Register */
#define NPE_MII_AN_EXP_REG 0x6 /* Auto-Negotiation */
/* Expansion Register */
#define NPE_MII_AN_NEXT_REG 0x7 /* Auto-Negotiation */
/* next-page transmit Register */
#endif /* ARM_XSCALE_IF_NPEREG_H */

View File

@ -0,0 +1,169 @@
/* $NetBSD: ixdp425_pci.c,v 1.5 2005/12/11 12:17:09 christos Exp $ */
/*
* Copyright (c) 2003
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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 Ichiro FUKUHARA.
* 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 ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#define _ARM32_BUS_DMA_PRIVATE
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/rman.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h>
#include <arm/xscale/ixp425/ixp425_intr.h>
#include <arm/xscale/ixp425/ixdp425reg.h>
void
ixp425_md_attach(device_t dev)
{
struct ixp425_softc *sc = device_get_softc(device_get_parent(dev));
struct ixppcib_softc *pci_sc = device_get_softc(dev);
uint32_t reg;
/* PCI Reset Assert */
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR);
reg &= ~(1U << GPIO_PCI_RESET);
GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg & ~(1U << GPIO_PCI_RESET));
/* PCI Clock Disable */
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR);
reg &= ~GPCLKR_MUX14;
GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg & ~GPCLKR_MUX14);
/*
* set GPIO Direction
* Output: PCI_CLK, PCI_RESET
* Input: PCI_INTA, PCI_INTB, PCI_INTC, PCI_INTD
*/
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER);
reg &= ~(1U << GPIO_PCI_CLK);
reg &= ~(1U << GPIO_PCI_RESET);
reg |= ((1U << GPIO_PCI_INTA) | (1U << GPIO_PCI_INTB) |
(1U << GPIO_PCI_INTC) | (1U << GPIO_PCI_INTD));
GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER, reg);
/*
* Set GPIO interrupt type
* PCI_INT_A, PCI_INTB, PCI_INT_C, PCI_INT_D: Active Low
*/
reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTA));
reg &= ~GPIO_TYPE(GPIO_PCI_INTA, GPIO_TYPE_MASK);
reg |= GPIO_TYPE(GPIO_PCI_INTA, GPIO_TYPE_ACT_LOW);
GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTA), reg);
reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTB));
reg &= ~GPIO_TYPE(GPIO_PCI_INTB, GPIO_TYPE_MASK);
reg |= GPIO_TYPE(GPIO_PCI_INTB, GPIO_TYPE_ACT_LOW);
GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTB), reg);
reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTC));
reg &= ~GPIO_TYPE(GPIO_PCI_INTC, GPIO_TYPE_MASK);
reg |= GPIO_TYPE(GPIO_PCI_INTC, GPIO_TYPE_ACT_LOW);
GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTC), reg);
reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTD));
reg &= ~GPIO_TYPE(GPIO_PCI_INTD, GPIO_TYPE_MASK);
reg |= GPIO_TYPE(GPIO_PCI_INTD, GPIO_TYPE_ACT_LOW);
GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTD), reg);
/* clear ISR */
GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPISR,
(1U << GPIO_PCI_INTA) | (1U << GPIO_PCI_INTB) |
(1U << GPIO_PCI_INTC) | (1U << GPIO_PCI_INTD));
/* wait 1ms to satisfy "minimum reset assertion time" of the PCI spec */
DELAY(1000);
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR);
GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg |
(0xf << GPCLKR_CLK0DC_SHIFT) | (0xf << GPCLKR_CLK0TC_SHIFT));
/* PCI Clock Enable */
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR);
reg |= GPCLKR_MUX14;
GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg | GPCLKR_MUX14);
/*
* wait 100us to satisfy "minimum reset assertion time from clock stable
* requirement of the PCI spec
*/
DELAY(100);
/* PCI Reset deassert */
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR);
reg |= 1U << GPIO_PCI_RESET;
GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg | (1U << GPIO_PCI_RESET));
pci_sc->sc_irq_rman.rm_type = RMAN_ARRAY;
pci_sc->sc_irq_rman.rm_descr = "IXP425 PCI IRQs";
CTASSERT(PCI_INT_D < PCI_INT_A);
/* XXX this overlaps the irq's setup in ixp425_attach */
if (rman_init(&pci_sc->sc_irq_rman) != 0 ||
rman_manage_region(&pci_sc->sc_irq_rman, PCI_INT_D, PCI_INT_A) != 0)
panic("ixp425_md_attach: failed to set up IRQ rman");
}
#define IXP425_MAX_DEV 4
#define IXP425_MAX_LINE 4
int
ixp425_md_route_interrupt(device_t bridge, device_t device, int pin)
{
static int ixp425_pci_table[IXP425_MAX_DEV][IXP425_MAX_LINE] =
{
{PCI_INT_A, PCI_INT_B, PCI_INT_C, PCI_INT_D},
{PCI_INT_B, PCI_INT_C, PCI_INT_D, PCI_INT_A},
{PCI_INT_C, PCI_INT_D, PCI_INT_A, PCI_INT_B},
{PCI_INT_D, PCI_INT_A, PCI_INT_B, PCI_INT_C},
};
int dev;
dev = pci_get_slot(device);
if (bootverbose)
device_printf(bridge, "routing pin %d for %s\n", pin,
device_get_nameunit(device));
if (pin >= 1 && pin <= IXP425_MAX_LINE &&
dev >= 1 && dev <= IXP425_MAX_DEV) {
return (ixp425_pci_table[dev - 1][pin - 1]);
} else
printf("ixppcib: no mapping for %d/%d/%d\n",
pci_get_bus(device), dev, pci_get_function(device));
return (-1);
}

View File

@ -0,0 +1,54 @@
/* $NetBSD: ixdp425reg.h,v 1.6 2005/12/11 12:17:09 christos Exp $ */
/*
* Copyright (c) 2003
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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 Ichiro FUKUHARA.
* 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 ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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.
*/
/* $FreeBSD$ */
#ifndef _IXDP425REG_H_
#define _IXDP425REG_H_
/* GPIOs */
#define GPIO_PCI_CLK 14
#define GPIO_PCI_RESET 13
#define GPIO_PCI_INTA 11
#define GPIO_PCI_INTB 10
#define GPIO_PCI_INTC 9
#define GPIO_PCI_INTD 8
#define GPIO_I2C_SDA 7
#define GPIO_I2C_SDA_BIT (1U << 7)
#define GPIO_I2C_SCL 6
#define GPIO_I2C_SCL_BIT (1U << 6)
/* Interrupt */
#define PCI_INT_A IXP425_INT_GPIO_11
#define PCI_INT_B IXP425_INT_GPIO_10
#define PCI_INT_C IXP425_INT_GPIO_9
#define PCI_INT_D IXP425_INT_GPIO_8
#endif /* _IXDP425REG_H_ */

View File

@ -0,0 +1,369 @@
/* $NetBSD: ixp425.c,v 1.10 2005/12/11 12:16:51 christos Exp $ */
/*
* Copyright (c) 2003
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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 Ichiro FUKUHARA.
* 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 ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#define _ARM32_BUS_DMA_PRIVATE
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/rman.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h>
#include <arm/xscale/ixp425/ixp425_intr.h>
#include <dev/pci/pcireg.h>
volatile uint32_t intr_enabled;
uint32_t intr_steer = 0;
struct ixp425_softc *ixp425_softc = NULL;
static int ixp425_probe(device_t);
static void ixp425_identify(driver_t *, device_t);
static int ixp425_attach(device_t);
static struct {
uint32_t hwbase;
uint32_t size;
uint32_t vbase;
} hwvtrans[] = {
{ IXP425_IO_HWBASE, IXP425_IO_SIZE, IXP425_IO_VBASE },
{ IXP425_EXP_HWBASE, IXP425_EXP_SIZE, IXP425_EXP_VBASE },
{ IXP425_PCI_HWBASE, IXP425_PCI_SIZE, IXP425_PCI_VBASE },
{ IXP425_PCI_MEM_HWBASE,IXP425_PCI_MEM_SIZE, IXP425_PCI_MEM_VBASE },
#if 0
{ IXP425_PCI_IO_HWBASE, IXP425_PCI_IO_SIZE, IXP425_PCI_IO_VBASE },
#endif
{ IXP425_MCU_HWBASE, IXP425_MCU_SIZE, IXP425_MCU_VBASE },
{ IXP425_QMGR_HWBASE, IXP425_QMGR_SIZE, IXP425_QMGR_VBASE },
{ IXP425_NPE_A_HWBASE, IXP425_NPE_A_SIZE, IXP425_NPE_A_VBASE },
{ IXP425_NPE_B_HWBASE, IXP425_NPE_B_SIZE, IXP425_NPE_B_VBASE },
{ IXP425_NPE_C_HWBASE, IXP425_NPE_C_SIZE, IXP425_NPE_C_VBASE },
{ IXP425_MAC_A_HWBASE, IXP425_MAC_A_SIZE, IXP425_MAC_A_VBASE },
{ IXP425_MAC_B_HWBASE, IXP425_MAC_B_SIZE, IXP425_MAC_B_VBASE },
/* Gateworks Avila IDE/CF is mapped here */
{ IXP425_EXP_BUS_CS1_HWBASE, IXP425_EXP_BUS_SIZE,
IXP425_EXP_BUS_CS1_VBASE },
};
static int
getvbase(uint32_t hwbase, uint32_t size, uint32_t *vbase)
{
int i;
for (i = 0; i < sizeof hwvtrans / sizeof *hwvtrans; i++) {
if (hwbase >= hwvtrans[i].hwbase &&
hwbase + size <= hwvtrans[i].hwbase + hwvtrans[i].size) {
*vbase = hwbase - hwvtrans[i].hwbase + hwvtrans[i].vbase;
return (0);
}
}
return (ENOENT);
}
struct arm32_dma_range *
bus_dma_get_range(void)
{
return (NULL);
}
int
bus_dma_get_range_nb(void)
{
return (0);
}
static __inline u_int32_t
ixp425_irq2gpio_bit(int irq)
{
static const uint8_t int2gpio[32] __attribute__ ((aligned(32))) = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* INT#0 -> INT#5 */
0x00, 0x01, /* GPIO#0 -> GPIO#1 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* INT#8 -> INT#13 */
0xff, 0xff, 0xff, 0xff, 0xff, /* INT#14 -> INT#18 */
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* GPIO#2 -> GPIO#7 */
0x08, 0x09, 0x0a, 0x0b, 0x0c, /* GPIO#8 -> GPIO#12 */
0xff, 0xff /* INT#30 -> INT#31 */
};
return (1U << int2gpio[irq]);
}
void
arm_mask_irq(uintptr_t nb)
{
intr_enabled &= ~(1 << nb);
ixp425_set_intrmask();
/*XXX; If it's a GPIO interrupt, ACK it know. Can it be a problem ?*/
if ((1 << nb) & IXP425_INT_GPIOMASK)
IXPREG(IXP425_GPIO_VBASE + IXP425_GPIO_GPISR) =
ixp425_irq2gpio_bit(nb);
}
void
arm_unmask_irq(uintptr_t nb)
{
intr_enabled |= (1 << nb);
ixp425_set_intrmask();
}
static __inline uint32_t
ixp425_irq_read(void)
{
return IXPREG(IXP425_INT_STATUS) & intr_enabled;
}
int
arm_get_next_irq(void)
{
int irq;
if ((irq = ixp425_irq_read()))
return (ffs(irq) - 1);
return (-1);
}
void
cpu_reset(void)
{
bus_space_write_4(&ixp425_bs_tag, IXP425_TIMER_VBASE,
IXP425_OST_WDOG_KEY, OST_WDOG_KEY_MAJICK);
bus_space_write_4(&ixp425_bs_tag, IXP425_TIMER_VBASE,
IXP425_OST_WDOG, 0);
bus_space_write_4(&ixp425_bs_tag, IXP425_TIMER_VBASE,
IXP425_OST_WDOG_ENAB, OST_WDOG_ENAB_RST_ENA |
OST_WDOG_ENAB_CNT_ENA);
printf("Reset failed!\n");
for(;;);
}
static void
ixp425_identify(driver_t *driver, device_t parent)
{
BUS_ADD_CHILD(parent, 0, "ixp", 0);
}
static int
ixp425_probe(device_t dev)
{
device_set_desc(dev, "Intel IXP425");
return (0);
}
static int
ixp425_attach(device_t dev)
{
struct ixp425_softc *sc;
sc = device_get_softc(dev);
sc->sc_iot = &ixp425_bs_tag;
KASSERT(ixp425_softc == NULL, ("ixp425_attach called twice?"));
ixp425_softc = sc;
intr_enabled = 0;
ixp425_set_intrmask();
ixp425_set_intrsteer();
sc->sc_irq_rman.rm_type = RMAN_ARRAY;
sc->sc_irq_rman.rm_descr = "IXP425 IRQs";
if (rman_init(&sc->sc_irq_rman) != 0 ||
rman_manage_region(&sc->sc_irq_rman, 0, 31) != 0)
panic("ixp425_attach: failed to set up IRQ rman");
sc->sc_mem_rman.rm_type = RMAN_ARRAY;
sc->sc_mem_rman.rm_descr = "IXP425 Memory";
if (rman_init(&sc->sc_mem_rman) != 0 ||
rman_manage_region(&sc->sc_mem_rman, 0, ~0) != 0)
panic("ixp425_attach: failed to set up IRQ rman");
device_add_child(dev, "pcib", 0);
device_add_child(dev, "ixpclk", 0);
device_add_child(dev, "ixpwdog", 0);
device_add_child(dev, "ixpiic", 0);
device_add_child(dev, "uart", 0);
/* XXX these are optional, what if they are not configured? */
device_add_child(dev, "ixpqmgr", 0);
device_add_child(dev, "npe", 0); /* NPE-B */
device_add_child(dev, "npe", 1); /* NPE-C */
device_add_child(dev, "ata_avila", 0); /* XXX */
if (bus_space_map(sc->sc_iot, IXP425_GPIO_HWBASE, IXP425_GPIO_SIZE,
0, &sc->sc_gpio_ioh))
panic("ixp425_attach: unable to map GPIO registers");
if (bus_space_map(sc->sc_iot, IXP425_EXP_HWBASE, IXP425_EXP_SIZE,
0, &sc->sc_exp_ioh))
panic("ixp425_attach: unable to map Expansion Bus registers");
bus_generic_probe(dev);
bus_generic_attach(dev);
return (0);
}
static struct resource *
ixp425_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct ixp425_softc *sc = device_get_softc(dev);
struct rman *rmanp;
struct resource *rv;
uint32_t vbase;
int isuart = (start == 0 && end == ~0); /* XXX how to do this right? */
rv = NULL;
switch (type) {
case SYS_RES_IRQ:
rmanp = &sc->sc_irq_rman;
if (isuart) {
if (device_get_unit(dev) == 0)
start = IXP425_INT_UART0;
else
start = IXP425_INT_UART1;
end = start;
}
break;
case SYS_RES_MEMORY:
rmanp = &sc->sc_mem_rman;
if (isuart) {
if (device_get_unit(dev) == 0)
start = IXP425_UART0_HWBASE;
else
start = IXP425_UART1_HWBASE;
end = start + 0x1000;
}
if (getvbase(start, end - start, &vbase))
return (rv);
break;
default:
return (rv);
}
rv = rman_reserve_resource(rmanp, start, end, count, flags, child);
if (rv != NULL) {
rman_set_rid(rv, *rid);
if (type == SYS_RES_MEMORY) {
rman_set_bustag(rv,
isuart ? &ixp425_a4x_bs_tag : sc->sc_iot);
rman_set_bushandle(rv, vbase);
}
}
return (rv);
}
static int
ixp425_setup_intr(device_t dev, device_t child,
struct resource *ires, int flags, driver_intr_t *intr, void *arg,
void **cookiep)
{
uint32_t mask;
int i;
if (flags & INTR_TYPE_TTY) {
/* XXX: wrong. */
if (device_get_unit(dev) == 0)
rman_set_start(ires, IXP425_INT_UART0);
else
rman_set_start(ires, IXP425_INT_UART1);
rman_set_end(ires, rman_get_start(ires));
}
BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, intr, arg,
cookiep);
mask = 0;
for (i = rman_get_start(ires); i <= rman_get_end(ires); i++)
mask |= 1 << i;
intr_enabled |= mask;
ixp425_set_intrmask();
return (0);
}
static int
ixp425_teardown_intr(device_t dev, device_t child, struct resource *res,
void *cookie)
{
uint32_t mask;
int i;
mask = 0;
for (i = rman_get_start(res); i <= rman_get_end(res); i++)
mask |= 1 << i;
intr_enabled &= ~mask;
ixp425_set_intrmask();
return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
}
static device_method_t ixp425_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ixp425_probe),
DEVMETHOD(device_attach, ixp425_attach),
DEVMETHOD(device_identify, ixp425_identify),
/* Bus interface */
DEVMETHOD(bus_alloc_resource, ixp425_alloc_resource),
DEVMETHOD(bus_setup_intr, ixp425_setup_intr),
DEVMETHOD(bus_teardown_intr, ixp425_teardown_intr),
{0, 0},
};
static driver_t ixp425_driver = {
"ixp",
ixp425_methods,
sizeof(struct ixp425_softc),
};
static devclass_t ixp425_devclass;
DRIVER_MODULE(ixp, nexus, ixp425_driver, ixp425_devclass, 0, 0);

View File

@ -0,0 +1,142 @@
/* $NetBSD: ixp425_a4x_io.S,v 1.2 2005/12/11 12:16:51 christos Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Steve C. Woodford for Wasabi Systems, Inc.
*
* 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 for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* 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.
*/
/*
* There are simple bus space functions for IO registers mapped at
* 32-bit aligned positions. offset is multiplied by 4.
*
* Based loosely on pxa2x0_a2x_io.S
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* bus_space I/O functions with offset*4
*/
/*
* Read single
*/
ENTRY(a4x_bs_r_1)
ldr r0, [r1, r2, LSL #2]
and r0, r0, #0xff
mov pc, lr
ENTRY(a4x_bs_r_2)
ldr r0, [r1, r2, LSL #2]
mov r1, #0xff
orr r1, r1, r1, lsl #8
and r0, r0, r1
mov pc, lr
ENTRY(a4x_bs_r_4)
ldr r0, [r1, r2, LSL #2]
mov pc, lr
/*
* Write single
*/
ENTRY(a4x_bs_w_1)
and r3, r3, #0xff
str r3, [r1, r2, LSL #2]
mov pc, lr
ENTRY(a4x_bs_w_2)
mov r0, #0xff
orr r0, r0, r0, lsl #8
and r3, r3, r0
str r3, [r1, r2, LSL #2]
mov pc, lr
ENTRY(a4x_bs_w_4)
str r3, [r1, r2, LSL #2]
mov pc, lr
/*
* Read multiple
*/
ENTRY(a4x_bs_rm_1)
add r0, r1, r2, lsl #2
ldr r2, [sp, #0]
mov r1, r3
teq r2, #0
moveq pc, lr
1: ldr r3, [r0]
subs r2, r2, #1
strb r3, [r1], #1
bne 1b
mov pc, lr
ENTRY(a4x_bs_rm_2)
add r0, r1, r2, lsl #2
ldr r2, [sp, #0]
mov r1, r3
teq r2, #0
moveq pc, lr
1: ldr r3, [r0]
subs r2, r2, #1
strh r3, [r1], #2
bne 1b
mov pc, lr
/*
* Write multiple
*/
ENTRY(a4x_bs_wm_1)
add r0, r1, r2, lsl #2
ldr r2, [sp, #0]
mov r1, r3
teq r2, #0
moveq pc, lr
1: ldrb r3, [r1], #1
subs r2, r2, #1
str r3, [r0]
bne 1b
mov pc, lr
ENTRY(a4x_bs_wm_2)
add r0, r1, r2, lsl #2
ldr r2, [sp, #0]
mov r1, r3
teq r2, #0
moveq pc, lr
1: ldrh r3, [r1], #2
subs r2, r2, #1
str r3, [r0]
bne 1b
mov pc, lr

View File

@ -0,0 +1,116 @@
/* $NetBSD: ixp425_a4x_space.c,v 1.2 2005/12/11 12:16:51 christos Exp $ */
/*
* Copyright 2003 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Steve C. Woodford for Wasabi Systems, Inc.
*
* 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 for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* 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.
*/
/*
* Bus space tag for 8/16-bit devices on 32-bit bus.
* all registers are located at the address of multiple of 4.
*
* Based on pxa2x0_a4x_space.c
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <machine/pcb.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/pmap.h>
#include <vm/vm_page.h>
#include <vm/vm_extern.h>
#include <machine/bus.h>
/* Prototypes for all the bus_space structure functions */
bs_protos(ixp425);
bs_protos(a4x);
bs_protos(generic);
bs_protos(generic_armv4);
struct bus_space ixp425_a4x_bs_tag = {
/* cookie */
.bs_cookie = (void *) 0,
/* mapping/unmapping */
.bs_map = ixp425_bs_map,
.bs_unmap = ixp425_bs_unmap,
.bs_subregion = ixp425_bs_subregion,
/* allocation/deallocation */
.bs_alloc = ixp425_bs_alloc, /* XXX not implemented */
.bs_free = ixp425_bs_free, /* XXX not implemented */
/* barrier */
.bs_barrier = ixp425_bs_barrier,
/* read (single) */
.bs_r_1 = a4x_bs_r_1,
.bs_r_2 = a4x_bs_r_2,
.bs_r_4 = a4x_bs_r_4,
/* read multiple */
.bs_rm_1 = a4x_bs_rm_1,
.bs_rm_2 = a4x_bs_rm_2,
/* read region */
/* XXX not implemented */
/* write (single) */
.bs_w_1 = a4x_bs_w_1,
.bs_w_2 = a4x_bs_w_2,
.bs_w_4 = a4x_bs_w_4,
/* write multiple */
.bs_wm_1 = a4x_bs_wm_1,
.bs_wm_2 = a4x_bs_wm_2,
/* write region */
/* XXX not implemented */
/* set multiple */
/* XXX not implemented */
/* set region */
/* XXX not implemented */
/* copy */
/* XXX not implemented */
};

View File

@ -0,0 +1,193 @@
/*
* Copyright (c) 2006 Kevin Lo. 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 for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/uio.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h>
#include <arm/xscale/ixp425/ixdp425reg.h>
#include <dev/iicbus/iiconf.h>
#include <dev/iicbus/iicbus.h>
#include "iicbb_if.h"
#define I2C_DELAY 10
/* bit clr/set shorthands */
#define GPIO_CONF_CLR(sc, reg, mask) \
GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, reg) &~ (mask))
#define GPIO_CONF_SET(sc, reg, mask) \
GPIO_CONF_WRITE_4(sc, reg, GPIO_CONF_READ_4(sc, reg) | (mask))
struct ixpiic_softc {
device_t sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_gpio_ioh;
device_t iicbb;
};
static struct ixpiic_softc *ixpiic_sc = NULL;
static int
ixpiic_probe(device_t dev)
{
device_set_desc(dev, "IXP425 GPIO-Based I2C Interface");
return (0);
}
static int
ixpiic_attach(device_t dev)
{
struct ixpiic_softc *sc = device_get_softc(dev);
struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
ixpiic_sc = sc;
sc->sc_dev = dev;
sc->sc_iot = sa->sc_iot;
sc->sc_gpio_ioh = sa->sc_gpio_ioh;
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER,
GPIO_I2C_SCL_BIT | GPIO_I2C_SDA_BIT);
GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR,
GPIO_I2C_SCL_BIT | GPIO_I2C_SDA_BIT);
/* add generic bit-banging code */
if ((sc->iicbb = device_add_child(dev, "iicbb", -1)) == NULL)
device_printf(dev, "could not add iicbb\n");
/* probe and attach the bit-banging code */
device_probe_and_attach(sc->iicbb);
return (0);
}
static int
ixpiic_callback(device_t dev, int index, caddr_t *data)
{
return (0);
}
static int
ixpiic_getscl(device_t dev)
{
struct ixpiic_softc *sc = ixpiic_sc;
uint32_t reg;
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
return (reg & GPIO_I2C_SCL_BIT);
}
static int
ixpiic_getsda(device_t dev)
{
struct ixpiic_softc *sc = ixpiic_sc;
uint32_t reg;
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR);
return (reg & GPIO_I2C_SDA_BIT);
}
static void
ixpiic_setsda(device_t dev, char val)
{
struct ixpiic_softc *sc = ixpiic_sc;
GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SDA_BIT);
if (val)
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
else
GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT);
DELAY(I2C_DELAY);
}
static void
ixpiic_setscl(device_t dev, char val)
{
struct ixpiic_softc *sc = ixpiic_sc;
GPIO_CONF_CLR(sc, IXP425_GPIO_GPOUTR, GPIO_I2C_SCL_BIT);
if (val)
GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
else
GPIO_CONF_CLR(sc, IXP425_GPIO_GPOER, GPIO_I2C_SCL_BIT);
DELAY(I2C_DELAY);
}
static int
ixpiic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
{
/* reset bus */
ixpiic_setsda(dev, 1);
ixpiic_setscl(dev, 1);
return (IIC_ENOADDR);
}
static device_method_t ixpiic_methods[] = {
/* device interface */
DEVMETHOD(device_probe, ixpiic_probe),
DEVMETHOD(device_attach, ixpiic_attach),
/* iicbb interface */
DEVMETHOD(iicbb_callback, ixpiic_callback),
DEVMETHOD(iicbb_setsda, ixpiic_setsda),
DEVMETHOD(iicbb_setscl, ixpiic_setscl),
DEVMETHOD(iicbb_getsda, ixpiic_getsda),
DEVMETHOD(iicbb_getscl, ixpiic_getscl),
DEVMETHOD(iicbb_reset, ixpiic_reset),
{ 0, 0 }
};
static driver_t ixpiic_driver = {
"ixpiic",
ixpiic_methods,
sizeof(struct ixpiic_softc),
};
static devclass_t ixpiic_devclass;
DRIVER_MODULE(ixpiic, ixp, ixpiic_driver, ixpiic_devclass, 0, 0);

View File

@ -0,0 +1,149 @@
/* $NetBSD: ixp425_intr.h,v 1.6 2005/12/24 20:06:52 perry Exp $ */
/*
* Copyright (c) 2001, 2002 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* 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 for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* 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.
*
* $FreeBSD$
*
*/
#ifndef _IXP425_INTR_H_
#define _IXP425_INTR_H_
#define ARM_IRQ_HANDLER _C_LABEL(ixp425_intr_dispatch)
#ifndef _LOCORE
#include <machine/armreg.h>
#include <machine/cpufunc.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#define IXPREG(reg) *((__volatile u_int32_t*) (reg))
void ixp425_do_pending(void);
extern __volatile uint32_t intr_enabled;
extern uint32_t intr_steer;
static __inline void __attribute__((__unused__))
ixp425_set_intrmask(void)
{
IXPREG(IXP425_INT_ENABLE) = intr_enabled & IXP425_INT_HWMASK;
}
static __inline void
ixp425_set_intrsteer(void)
{
IXPREG(IXP425_INT_SELECT) = intr_steer & IXP425_INT_HWMASK;
}
#define INT_SWMASK \
((1U << IXP425_INT_bit31) | (1U << IXP425_INT_bit30) | \
(1U << IXP425_INT_bit14) | (1U << IXP425_INT_bit11))
#if 0
static __inline void __attribute__((__unused__))
ixp425_splx(int new)
{
extern __volatile uint32_t intr_enabled;
extern __volatile int current_spl_level;
extern __volatile int ixp425_ipending;
extern void ixp425_do_pending(void);
int oldirqstate, hwpend;
/* Don't let the compiler re-order this code with preceding code */
__insn_barrier();
current_spl_level = new;
hwpend = (ixp425_ipending & IXP425_INT_HWMASK) & ~new;
if (hwpend != 0) {
oldirqstate = disable_interrupts(I32_bit);
intr_enabled |= hwpend;
ixp425_set_intrmask();
restore_interrupts(oldirqstate);
}
if ((ixp425_ipending & INT_SWMASK) & ~new)
ixp425_do_pending();
}
static __inline int __attribute__((__unused__))
ixp425_splraise(int ipl)
{
extern __volatile int current_spl_level;
extern int ixp425_imask[];
int old;
old = current_spl_level;
current_spl_level |= ixp425_imask[ipl];
/* Don't let the compiler re-order this code with subsequent code */
__insn_barrier();
return (old);
}
static __inline int __attribute__((__unused__))
ixp425_spllower(int ipl)
{
extern __volatile int current_spl_level;
extern int ixp425_imask[];
int old = current_spl_level;
ixp425_splx(ixp425_imask[ipl]);
return(old);
}
#endif
#if !defined(EVBARM_SPL_NOINLINE)
#define splx(new) ixp425_splx(new)
#define _spllower(ipl) ixp425_spllower(ipl)
#define _splraise(ipl) ixp425_splraise(ipl)
void _setsoftintr(int);
#else
int _splraise(int);
int _spllower(int);
void splx(int);
void _setsoftintr(int);
#endif /* ! EVBARM_SPL_NOINLINE */
#endif /* _LOCORE */
#endif /* _IXP425_INTR_H_ */

View File

@ -0,0 +1,85 @@
/* $NetBSD: ixp425_mem.c,v 1.2 2005/12/11 12:16:51 christos Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Steve C. Woodford for Wasabi Systems, Inc.
*
* 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 for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h>
static uint32_t sdram_64bit[] = {
0x00800000, /* 8M: One 2M x 32 chip */
0x01000000, /* 16M: Two 2M x 32 chips */
0x01000000, /* 16M: One 4M x 32 chip */
0x02000000, /* 32M: Two 4M x 32 chips */
0, 0, 0, 0
};
static uint32_t sdram_other[] = {
0x02000000, /* 32M: Two 8M x 16 chips */
0x04000000, /* 64M: Four 8M x 16 chips */
0x04000000, /* 64M: Two 16M x 16 chips */
0x08000000, /* 128M: Four 16M x 16 chips */
0x08000000, /* 128M: Two 32M x 16 chips */
0x10000000, /* 256M: Four 32M x 16 chips */
0, 0
};
#define MCU_REG_READ(x) (*(volatile uint32_t *)(IXP425_MCU_VBASE + (x)))
uint32_t
ixp425_sdram_size(void)
{
uint32_t size, sdr_config;
sdr_config = MCU_REG_READ(MCU_SDR_CONFIG);
if (sdr_config & MCU_SDR_CONFIG_64MBIT)
size = sdram_64bit[MCU_SDR_CONFIG_MCONF(sdr_config)];
else
size = sdram_other[MCU_SDR_CONFIG_MCONF(sdr_config)];
if (size == 0) {
printf("** SDR_CONFIG retuns unknown value, using 32M\n");
size = 32 * 1024 * 1024;
}
return (size);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,434 @@
/*-
* Copyright (c) 2006 Sam Leffler, Errno Consulting
* 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,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
*
* $FreeBSD$
*/
/*-
* Copyright (c) 2001-2005, Intel Corporation.
* 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 Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _IXP425_NPEREG_H_
#define _IXP425_NPEREG_H_
/* signature found as 1st word in a microcode image library */
#define IX_NPEDL_IMAGEMGR_SIGNATURE 0xDEADBEEF
/* marks end of header in a microcode image library */
#define IX_NPEDL_IMAGEMGR_END_OF_HEADER 0xFFFFFFFF
/*
* Intel (R) IXP400 Software NPE Image ID Definition
*
* Definition of NPE Image ID to be passed to ixNpeDlNpeInitAndStart()
* as input of type uint32_t which has the following fields format:
*
* Field [Bit Location]
* -----------------------------------
* Device ID [31 - 28]
* NPE ID [27 - 24]
* NPE Functionality ID [23 - 16]
* Major Release Number [15 - 8]
* Minor Release Number [7 - 0]
*/
#define IX_NPEDL_NPEID_FROM_IMAGEID_GET(imageId) \
(((imageId) >> 24) & 0xf)
#define IX_NPEDL_DEVICEID_FROM_IMAGEID_GET(imageId) \
(((imageId) >> 28) & 0xf)
#define IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId) \
(((imageId) >> 16) & 0xff)
#define IX_NPEDL_MAJOR_FROM_IMAGEID_GET(imageId) \
(((imageId) >> 8) & 0xff)
#define IX_NPEDL_MINOR_FROM_IMAGEID_GET(imageId) \
(((imageId) >> 0) & 0xff)
/*
* Instruction and Data Memory Size (in words) for each NPE
*/
#ifndef __ixp46X
#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEA 4096
#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEB 2048
#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEC 2048
#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA 2048
#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB 2048
#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC 2048
#else
#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEA 4096
#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEB 4096
#define IX_NPEDL_INS_MEMSIZE_WORDS_NPEC 4096
#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEA 4096
#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEB 4096
#define IX_NPEDL_DATA_MEMSIZE_WORDS_NPEC 4096
#endif
/* BAR offsets */
#define IX_NPEDL_REG_OFFSET_EXAD 0x00000000 /* Execution Address */
#define IX_NPEDL_REG_OFFSET_EXDATA 0x00000004 /* Execution Data */
#define IX_NPEDL_REG_OFFSET_EXCTL 0x00000008 /* Execution Control */
#define IX_NPEDL_REG_OFFSET_EXCT 0x0000000C /* Execution Count */
#define IX_NPEDL_REG_OFFSET_AP0 0x00000010 /* Action Point 0 */
#define IX_NPEDL_REG_OFFSET_AP1 0x00000014 /* Action Point 1 */
#define IX_NPEDL_REG_OFFSET_AP2 0x00000018 /* Action Point 2 */
#define IX_NPEDL_REG_OFFSET_AP3 0x0000001C /* Action Point 3 */
#define IX_NPEDL_REG_OFFSET_WFIFO 0x00000020 /* Watchpoint FIFO */
#define IX_NPEDL_REG_OFFSET_WC 0x00000024 /* Watch Count */
#define IX_NPEDL_REG_OFFSET_PROFCT 0x00000028 /* Profile Count */
#define IX_NPEDL_REG_OFFSET_STAT 0x0000002C /* Messaging Status */
#define IX_NPEDL_REG_OFFSET_CTL 0x00000030 /* Messaging Control */
#define IX_NPEDL_REG_OFFSET_MBST 0x00000034 /* Mailbox Status */
#define IX_NPEDL_REG_OFFSET_FIFO 0x00000038 /* Message FIFO */
/*
* Reset value for Mailbox (MBST) register
* NOTE that if used, it should be complemented with an NPE intruction
* to clear the Mailbox at the NPE side as well
*/
#define IX_NPEDL_REG_RESET_MBST 0x0000F0F0
#define IX_NPEDL_MASK_WFIFO_VALID 0x80000000 /* VALID bit */
#define IX_NPEDL_MASK_STAT_OFNE 0x00010000 /* OFNE bit */
#define IX_NPEDL_MASK_STAT_IFNE 0x00080000 /* IFNE bit */
/*
* EXCTL (Execution Control) Register commands
*/
#define IX_NPEDL_EXCTL_CMD_NPE_STEP 0x01 /* Step 1 instruction */
#define IX_NPEDL_EXCTL_CMD_NPE_START 0x02 /* Start execution */
#define IX_NPEDL_EXCTL_CMD_NPE_STOP 0x03 /* Stop execution */
#define IX_NPEDL_EXCTL_CMD_NPE_CLR_PIPE 0x04 /* Clear ins pipeline */
/*
* Read/write operations use address in EXAD and data in EXDATA.
*/
#define IX_NPEDL_EXCTL_CMD_RD_INS_MEM 0x10 /* Read ins memory */
#define IX_NPEDL_EXCTL_CMD_WR_INS_MEM 0x11 /* Write ins memory */
#define IX_NPEDL_EXCTL_CMD_RD_DATA_MEM 0x12 /* Read data memory */
#define IX_NPEDL_EXCTL_CMD_WR_DATA_MEM 0x13 /* Write data memory */
#define IX_NPEDL_EXCTL_CMD_RD_ECS_REG 0x14 /* Read ECS register */
#define IX_NPEDL_EXCTL_CMD_WR_ECS_REG 0x15 /* Write ECS register */
#define IX_NPEDL_EXCTL_CMD_CLR_PROFILE_CNT 0x0C /* Clear Profile Count register */
/*
* EXCTL (Execution Control) Register status bit masks
*/
#define IX_NPEDL_EXCTL_STATUS_RUN 0x80000000
#define IX_NPEDL_EXCTL_STATUS_STOP 0x40000000
#define IX_NPEDL_EXCTL_STATUS_CLEAR 0x20000000
#define IX_NPEDL_EXCTL_STATUS_ECS_K 0x00800000 /* pipeline Klean */
/*
* Executing Context Stack (ECS) level registers
*/
#define IX_NPEDL_ECS_BG_CTXT_REG_0 0x00 /* reg 0 @ bg ctx */
#define IX_NPEDL_ECS_BG_CTXT_REG_1 0x01 /* reg 1 @ bg ctx */
#define IX_NPEDL_ECS_BG_CTXT_REG_2 0x02 /* reg 2 @ bg ctx */
#define IX_NPEDL_ECS_PRI_1_CTXT_REG_0 0x04 /* reg 0 @ pri 1 ctx */
#define IX_NPEDL_ECS_PRI_1_CTXT_REG_1 0x05 /* reg 1 @ pri 1 ctx */
#define IX_NPEDL_ECS_PRI_1_CTXT_REG_2 0x06 /* reg 2 @ pri 1 ctx */
#define IX_NPEDL_ECS_PRI_2_CTXT_REG_0 0x08 /* reg 0 @ pri 2 ctx */
#define IX_NPEDL_ECS_PRI_2_CTXT_REG_1 0x09 /* reg 1 @ pri 2 ctx */
#define IX_NPEDL_ECS_PRI_2_CTXT_REG_2 0x0A /* reg 2 @ pri 2 ctx */
#define IX_NPEDL_ECS_DBG_CTXT_REG_0 0x0C /* reg 0 @ debug ctx */
#define IX_NPEDL_ECS_DBG_CTXT_REG_1 0x0D /* reg 1 @ debug ctx */
#define IX_NPEDL_ECS_DBG_CTXT_REG_2 0x0E /* reg 2 @ debug ctx */
#define IX_NPEDL_ECS_INSTRUCT_REG 0x11 /* Instruction reg */
/*
* Execution Access register reset values
*/
#define IX_NPEDL_ECS_BG_CTXT_REG_0_RESET 0xA0000000
#define IX_NPEDL_ECS_BG_CTXT_REG_1_RESET 0x01000000
#define IX_NPEDL_ECS_BG_CTXT_REG_2_RESET 0x00008000
#define IX_NPEDL_ECS_PRI_1_CTXT_REG_0_RESET 0x20000080
#define IX_NPEDL_ECS_PRI_1_CTXT_REG_1_RESET 0x01000000
#define IX_NPEDL_ECS_PRI_1_CTXT_REG_2_RESET 0x00008000
#define IX_NPEDL_ECS_PRI_2_CTXT_REG_0_RESET 0x20000080
#define IX_NPEDL_ECS_PRI_2_CTXT_REG_1_RESET 0x01000000
#define IX_NPEDL_ECS_PRI_2_CTXT_REG_2_RESET 0x00008000
#define IX_NPEDL_ECS_DBG_CTXT_REG_0_RESET 0x20000000
#define IX_NPEDL_ECS_DBG_CTXT_REG_1_RESET 0x00000000
#define IX_NPEDL_ECS_DBG_CTXT_REG_2_RESET 0x001E0000
#define IX_NPEDL_ECS_INSTRUCT_REG_RESET 0x1003C00F
/*
* Masks used to read/write particular bits in Execution Access registers
*/
#define IX_NPEDL_MASK_ECS_REG_0_ACTIVE 0x80000000 /* Active bit */
#define IX_NPEDL_MASK_ECS_REG_0_NEXTPC 0x1FFF0000 /* NextPC bits */
#define IX_NPEDL_MASK_ECS_REG_0_LDUR 0x00000700 /* LDUR bits */
#define IX_NPEDL_MASK_ECS_REG_1_CCTXT 0x000F0000 /* NextPC bits */
#define IX_NPEDL_MASK_ECS_REG_1_SELCTXT 0x0000000F
#define IX_NPEDL_MASK_ECS_DBG_REG_2_IF 0x00100000 /* IF bit */
#define IX_NPEDL_MASK_ECS_DBG_REG_2_IE 0x00080000 /* IE bit */
/*
* Bit-Offsets from LSB of particular bit-fields in Execution Access registers.
*/
#define IX_NPEDL_OFFSET_ECS_REG_0_NEXTPC 16
#define IX_NPEDL_OFFSET_ECS_REG_0_LDUR 8
#define IX_NPEDL_OFFSET_ECS_REG_1_CCTXT 16
#define IX_NPEDL_OFFSET_ECS_REG_1_SELCTXT 0
/*
* NPE core & co-processor instruction templates to load into NPE Instruction
* Register, for read/write of NPE register file registers.
*/
/*
* Read an 8-bit NPE internal logical register
* and return the value in the EXDATA register (aligned to MSB).
* NPE Assembler instruction: "mov8 d0, d0 &&& DBG_WrExec"
*/
#define IX_NPEDL_INSTR_RD_REG_BYTE 0x0FC00000
/*
* Read a 16-bit NPE internal logical register
* and return the value in the EXDATA register (aligned to MSB).
* NPE Assembler instruction: "mov16 d0, d0 &&& DBG_WrExec"
*/
#define IX_NPEDL_INSTR_RD_REG_SHORT 0x0FC08010
/*
* Read a 16-bit NPE internal logical register
* and return the value in the EXDATA register.
* NPE Assembler instruction: "mov32 d0, d0 &&& DBG_WrExec"
*/
#define IX_NPEDL_INSTR_RD_REG_WORD 0x0FC08210
/*
* Write an 8-bit NPE internal logical register.
* NPE Assembler instruction: "mov8 d0, #0"
*/
#define IX_NPEDL_INSTR_WR_REG_BYTE 0x00004000
/*
* Write a 16-bit NPE internal logical register.
* NPE Assembler instruction: "mov16 d0, #0"
*/
#define IX_NPEDL_INSTR_WR_REG_SHORT 0x0000C000
/*
* Write a 16-bit NPE internal logical register.
* NPE Assembler instruction: "cprd32 d0 &&& DBG_RdInFIFO"
*/
#define IX_NPEDL_INSTR_RD_FIFO 0x0F888220
/*
* Reset Mailbox (MBST) register
* NPE Assembler instruction: "mov32 d0, d0 &&& DBG_ClearM"
*/
#define IX_NPEDL_INSTR_RESET_MBOX 0x0FAC8210
/*
* Bit-offsets from LSB, of particular bit-fields in an NPE instruction
*/
#define IX_NPEDL_OFFSET_INSTR_SRC 4 /* src operand */
#define IX_NPEDL_OFFSET_INSTR_DEST 9 /* dest operand */
#define IX_NPEDL_OFFSET_INSTR_COPROC 18 /* coprocessor ins */
/*
* Masks used to read/write particular bits of an NPE Instruction
*/
/**
* Mask the bits of 16-bit data value (least-sig 5 bits) to be used in
* SRC field of immediate-mode NPE instruction
*/
#define IX_NPEDL_MASK_IMMED_INSTR_SRC_DATA 0x1F
/**
* Mask the bits of 16-bit data value (most-sig 11 bits) to be used in
* COPROC field of immediate-mode NPE instruction
*/
#define IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA 0xFFE0
/**
* LSB offset of the bit-field of 16-bit data value (most-sig 11 bits)
* to be used in COPROC field of immediate-mode NPE instruction
*/
#define IX_NPEDL_OFFSET_IMMED_INSTR_COPROC_DATA 5
/**
* Number of left-shifts required to align most-sig 11 bits of 16-bit
* data value into COPROC field of immediate-mode NPE instruction
*/
#define IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA \
(IX_NPEDL_OFFSET_INSTR_COPROC - IX_NPEDL_OFFSET_IMMED_INSTR_COPROC_DATA)
/**
* LDUR value used with immediate-mode NPE Instructions by the NpeDl
* for writing to NPE internal logical registers
*/
#define IX_NPEDL_WR_INSTR_LDUR 1
/**
* LDUR value used with NON-immediate-mode NPE Instructions by the NpeDl
* for reading from NPE internal logical registers
*/
#define IX_NPEDL_RD_INSTR_LDUR 0
/**
* NPE internal Context Store registers.
*/
typedef enum
{
IX_NPEDL_CTXT_REG_STEVT = 0, /**< identifies STEVT */
IX_NPEDL_CTXT_REG_STARTPC, /**< identifies STARTPC */
IX_NPEDL_CTXT_REG_REGMAP, /**< identifies REGMAP */
IX_NPEDL_CTXT_REG_CINDEX, /**< identifies CINDEX */
IX_NPEDL_CTXT_REG_MAX /**< Total number of Context Store registers */
} IxNpeDlCtxtRegNum;
/*
* NPE Context Store register logical addresses
*/
#define IX_NPEDL_CTXT_REG_ADDR_STEVT 0x0000001B
#define IX_NPEDL_CTXT_REG_ADDR_STARTPC 0x0000001C
#define IX_NPEDL_CTXT_REG_ADDR_REGMAP 0x0000001E
#define IX_NPEDL_CTXT_REG_ADDR_CINDEX 0x0000001F
/*
* NPE Context Store register reset values
*/
/**
* Reset value of STEVT NPE internal Context Store register
* (STEVT = off, 0x80)
*/
#define IX_NPEDL_CTXT_REG_RESET_STEVT 0x80
/**
* Reset value of STARTPC NPE internal Context Store register
* (STARTPC = 0x0000)
*/
#define IX_NPEDL_CTXT_REG_RESET_STARTPC 0x0000
/**
* Reset value of REGMAP NPE internal Context Store register
* (REGMAP = d0->p0, d8->p2, d16->p4)
*/
#define IX_NPEDL_CTXT_REG_RESET_REGMAP 0x0820
/**
* Reset value of CINDEX NPE internal Context Store register
* (CINDEX = 0)
*/
#define IX_NPEDL_CTXT_REG_RESET_CINDEX 0x00
/*
* Numeric range of context levels available on an NPE
*/
#define IX_NPEDL_CTXT_NUM_MIN 0
#define IX_NPEDL_CTXT_NUM_MAX 15
/**
* Number of Physical registers currently supported
* Initial NPE implementations will have a 32-word register file.
* Later implementations may have a 64-word register file.
*/
#define IX_NPEDL_TOTAL_NUM_PHYS_REG 32
/**
* LSB-offset of Regmap number in Physical NPE register address, used
* for Physical To Logical register address mapping in the NPE
*/
#define IX_NPEDL_OFFSET_PHYS_REG_ADDR_REGMAP 1
/**
* Mask to extract a logical NPE register address from a physical
* register address, used for Physical To Logical address mapping
*/
#define IX_NPEDL_MASK_PHYS_REG_ADDR_LOGICAL_ADDR 0x1
/*
* NPE Message/Mailbox interface.
*/
#define IX_NPESTAT IX_NPEDL_REG_OFFSET_STAT /* status register */
#define IX_NPECTL IX_NPEDL_REG_OFFSET_CTL /* control register */
#define IX_NPEFIFO IX_NPEDL_REG_OFFSET_FIFO /* FIFO register */
/* control register */
#define IX_NPECTL_OFE 0x00010000 /* output fifo enable */
#define IX_NPECTL_IFE 0x00020000 /* input fifo enable */
#define IX_NPECTL_OFWE 0x01000000 /* output fifo write enable */
#define IX_NPECTL_IFWE 0x02000000 /* input fifo write enable */
/* status register */
#define IX_NPESTAT_OFNE 0x00010000 /* output fifo not empty */
#define IX_NPESTAT_IFNF 0x00020000 /* input fifo not full */
#define IX_NPESTAT_OFNF 0x00040000 /* output fifo not full */
#define IX_NPESTAT_IFNE 0x00080000 /* input fifo not empty */
#define IX_NPESTAT_MBINT 0x00100000 /* Mailbox interrupt */
#define IX_NPESTAT_IFINT 0x00200000 /* input fifo interrupt */
#define IX_NPESTAT_OFINT 0x00400000 /* output fifo interrupt */
#define IX_NPESTAT_WFINT 0x00800000 /* watch fifo interrupt */
#endif /* _IXP425_NPEREG_H_ */

View File

@ -0,0 +1,96 @@
/*-
* Copyright (c) 2006 Sam Leffler. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _IXP425_NPEVAR_H_
#define _IXP425_NPEVAR_H_
/*
* Intel (R) IXP400 Software NPE Image ID Definition
*
* Firmware Id's for current firmware image. These are typed by
* NPE ID and the feature set. Not all features are available
* on all NPE's.
*
* HSS-0: supports 32 channelized and 4 packetized.
* HSS-0 + ATM + SPHY:
* For HSS, 16/32 channelized and 4/0 packetized.
* For ATM, AAL5, AAL0 and OAM for UTOPIA SPHY, 1 logical port, 32 VCs.
* Fast Path support.
* HSS-0 + ATM + MPHY:
* For HSS, 16/32 channelized and 4/0 packetized.
* For ATM, AAL5, AAL0 and OAM for UTOPIA MPHY, 1 logical port, 32 VCs.
* Fast Path support.
* ATM-Only:
* AAL5, AAL0 and OAM for UTOPIA MPHY, 12 logical ports, 32 VCs.
* Fast Path support.
* HSS-2:
* HSS-0 and HSS-1.
* Each HSS port supports 32 channelized and 4 packetized.
* ETH: Ethernet Rx/Tx which includes:
* MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL
* ETH+VLAN Ethernet Rx/Tx which includes:
* MAC_FILTERING, MAC_LEARNING, SPANNING_TREE, FIREWALL, VLAN_QOS
* ETH+VLAN+HDR: Ethernet Rx/Tx which includes:
* SPANNING_TREE, FIREWALL, VLAN_QOS, HEADER_CONVERSION
*/
/* XXX not right, revise */
/* NPE A Firmware Image Id's */
#define NPEFW_A_HSS0 0x00010000 /* HSS-0: 32 chan+4 packet */
#define NPEFW_A_HSS0_ATM_S_1 0x00020000 /* HSS-0+ATM UTOPIA SPHY (1 port) */
#define NPEFW_A_HSS0_ATM_M_1 0x00020000 /* HSS-0+ATM UTOPIA MPHY (1 port) */
#define NPEFW_A_ATM_M_12 0x00040000 /* ATM UTOPIA MPHY (12 ports) */
#define NPEFW_A_DMA 0x00150100 /* DMA only */
#define NPEFW_A_HSS2 0x00090000 /* HSS-0 + HSS-1 */
#define NPEFW_A_ETH 0x10800200 /* Basic Ethernet */
#define NPEFW_A_ETH_VLAN 0x10810200 /* NPEFW_A_ETH + VLAN QoS */
#define NPEFW_A_ETH_VLAN_HDR 0x10820200 /* NPEFW_A_ETH_VLAN + Hdr conv */
/* XXX ... more not included */
/* NPE B Firmware Image Id's */
#define NPEFW_B_ETH 0x01000200 /* Basic Ethernet */
#define NPEFW_B_ETH_VLAN 0x01010200 /* NPEFW_B_ETH + VLAN QoS */
#define NPEFW_B_ETH_VLAN_HDR 0x01020201 /* NPEFW_B_ETH_VLAN + Hdr conv */
#define NPEFW_B_DMA 0x01020100 /* DMA only */
/* XXX ... more not include */
#define IXP425_NPE_B_IMAGEID 0x01000200
#define IXP425_NPE_C_IMAGEID 0x02000200
struct ixpnpe_softc;
struct ixpnpe_softc *ixpnpe_attach(device_t);
void ixpnpe_detach(struct ixpnpe_softc *);
int ixpnpe_stopandreset(struct ixpnpe_softc *);
int ixpnpe_start(struct ixpnpe_softc *);
int ixpnpe_stop(struct ixpnpe_softc *);
int ixpnpe_init(struct ixpnpe_softc *,
const char *imageName, uint32_t imageId);
int ixpnpe_getfunctionality(struct ixpnpe_softc *sc);
int ixpnpe_sendmsg(struct ixpnpe_softc *, const uint32_t msg[2]);
int ixpnpe_recvmsg(struct ixpnpe_softc *, uint32_t msg[2]);
int ixpnpe_sendandrecvmsg(struct ixpnpe_softc *, const uint32_t send[2],
uint32_t recv[2]);
#endif /* _IXP425_NPEVAR_H_ */

View File

@ -0,0 +1,455 @@
/* $NetBSD: ixp425_pci.c,v 1.5 2006/04/10 03:36:03 simonb Exp $ */
/*
* Copyright (c) 2003
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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 Ichiro FUKUHARA.
* 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 ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/pcb.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_extern.h>
#include <machine/pmap.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h>
#include <dev/pci/pcib_private.h>
#include "pcib_if.h"
#include <dev/pci/pcireg.h>
extern struct ixp425_softc *ixp425_softc;
#define PCI_CSR_WRITE_4(sc, reg, data) \
bus_write_4(sc->sc_csr, reg, data)
#define PCI_CSR_READ_4(sc, reg) \
bus_read_4(sc->sc_csr, reg)
#define PCI_CONF_LOCK(s) (s) = disable_interrupts(I32_bit)
#define PCI_CONF_UNLOCK(s) restore_interrupts((s))
static device_probe_t ixppcib_probe;
static device_attach_t ixppcib_attach;
static bus_read_ivar_t ixppcib_read_ivar;
static bus_write_ivar_t ixppcib_write_ivar;
static bus_setup_intr_t ixppcib_setup_intr;
static bus_teardown_intr_t ixppcib_teardown_intr;
static bus_alloc_resource_t ixppcib_alloc_resource;
static bus_activate_resource_t ixppcib_activate_resource;
static bus_deactivate_resource_t ixppcib_deactivate_resource;
static bus_release_resource_t ixppcib_release_resource;
static pcib_maxslots_t ixppcib_maxslots;
static pcib_read_config_t ixppcib_read_config;
static pcib_write_config_t ixppcib_write_config;
static pcib_route_interrupt_t ixppcib_route_interrupt;
static int
ixppcib_probe(device_t dev)
{
device_set_desc(dev, "IXP425 PCI Bus");
return (0);
}
static void
ixp425_pci_conf_reg_write(struct ixppcib_softc *sc, uint32_t reg,
uint32_t data)
{
PCI_CSR_WRITE_4(sc,
PCI_CRP_AD_CBE, ((reg & ~3) | COMMAND_CRP_WRITE));
PCI_CSR_WRITE_4(sc,
PCI_CRP_AD_WDATA, data);
}
static int
ixppcib_attach(device_t dev)
{
int rid;
struct ixppcib_softc *sc;
sc = device_get_softc(dev);
rid = 0;
sc->sc_csr = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
IXP425_PCI_HWBASE, IXP425_PCI_HWBASE + IXP425_PCI_SIZE,
IXP425_PCI_SIZE, RF_ACTIVE);
if (sc->sc_csr == NULL)
panic("cannot allocate PCI CSR registers");
ixp425_md_attach(dev);
/* always setup the base, incase another OS messes w/ it */
PCI_CSR_WRITE_4(sc, PCI_PCIMEMBASE, 0x48494a4b);
rid = 0;
sc->sc_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
IXP425_PCI_MEM_HWBASE, IXP425_PCI_MEM_HWBASE + IXP425_PCI_MEM_SIZE,
IXP425_PCI_MEM_SIZE, RF_ACTIVE);
if (sc->sc_mem == NULL)
panic("cannot allocate PCI MEM space");
/*
* Initialize the bus space tags.
*/
ixp425_io_bs_init(&sc->sc_pci_iot, sc);
ixp425_mem_bs_init(&sc->sc_pci_memt, sc);
sc->sc_dev = dev;
/* Initialize memory and i/o rmans. */
sc->sc_io_rman.rm_type = RMAN_ARRAY;
sc->sc_io_rman.rm_descr = "IXP425 PCI I/O Ports";
if (rman_init(&sc->sc_io_rman) != 0 ||
rman_manage_region(&sc->sc_io_rman, 0,
IXP425_PCI_IO_SIZE) != 0) {
panic("ixppcib_probe: failed to set up I/O rman");
}
sc->sc_mem_rman.rm_type = RMAN_ARRAY;
sc->sc_mem_rman.rm_descr = "IXP425 PCI Memory";
if (rman_init(&sc->sc_mem_rman) != 0 ||
rman_manage_region(&sc->sc_mem_rman, IXP425_PCI_MEM_HWBASE,
IXP425_PCI_MEM_HWBASE + IXP425_PCI_MEM_SIZE) != 0) {
panic("ixppcib_probe: failed to set up memory rman");
}
/*
* PCI->AHB address translation
* begin at the physical memory start + OFFSET
*/
#define AHB_OFFSET 0x10000000UL
PCI_CSR_WRITE_4(sc, PCI_AHBMEMBASE,
(AHB_OFFSET & 0xFF000000) +
((AHB_OFFSET & 0xFF000000) >> 8) +
((AHB_OFFSET & 0xFF000000) >> 16) +
((AHB_OFFSET & 0xFF000000) >> 24) +
0x00010203);
#define IXPPCIB_WRITE_CONF(sc, reg, val) \
ixp425_pci_conf_reg_write(sc, reg, val)
/* Write Mapping registers PCI Configuration Registers */
/* Base Address 0 - 3 */
IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR0, AHB_OFFSET + 0x00000000);
IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR1, AHB_OFFSET + 0x01000000);
IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR2, AHB_OFFSET + 0x02000000);
IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR3, AHB_OFFSET + 0x03000000);
/* Base Address 4 */
IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR4, 0xffffffff);
/* Base Address 5 */
IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR5, 0x00000000);
/* Assert some PCI errors */
PCI_CSR_WRITE_4(sc, PCI_ISR, ISR_AHBE | ISR_PPE | ISR_PFE | ISR_PSE);
#ifdef __ARMEB__
/*
* Set up byte lane swapping between little-endian PCI
* and the big-endian AHB bus
*/
PCI_CSR_WRITE_4(sc, PCI_CSR, CSR_IC | CSR_ABE | CSR_PDS);
#else
PCI_CSR_WRITE_4(sc, PCI_CSR, CSR_IC | CSR_ABE);
#endif
/*
* Enable bus mastering and I/O,memory access
*/
IXPPCIB_WRITE_CONF(sc, PCIR_COMMAND,
PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
/*
* Wait some more to ensure PCI devices have stabilised.
*/
DELAY(50000);
device_add_child(dev, "pci", -1);
return (bus_generic_attach(dev));
}
static int
ixppcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct ixppcib_softc *sc;
sc = device_get_softc(dev);
switch (which) {
case PCIB_IVAR_BUS:
*result = sc->sc_bus;
return (0);
}
return (ENOENT);
}
static int
ixppcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
{
struct ixppcib_softc *sc;
sc = device_get_softc(dev);
switch (which) {
case PCIB_IVAR_BUS:
sc->sc_bus = value;
return (0);
}
return (ENOENT);
}
static int
ixppcib_setup_intr(device_t dev, device_t child, struct resource *ires,
int flags, driver_intr_t *intr, void *arg, void **cookiep)
{
return (BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
intr, arg, cookiep));
}
static int
ixppcib_teardown_intr(device_t dev, device_t child, struct resource *vec,
void *cookie)
{
return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, vec, cookie));
}
static struct resource *
ixppcib_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
bus_space_tag_t tag;
struct ixppcib_softc *sc = device_get_softc(bus);
struct rman *rmanp;
struct resource *rv;
tag = NULL; /* shut up stupid gcc */
rv = NULL;
switch (type) {
case SYS_RES_IRQ:
rmanp = &sc->sc_irq_rman;
break;
case SYS_RES_IOPORT:
rmanp = &sc->sc_io_rman;
tag = &sc->sc_pci_iot;
break;
case SYS_RES_MEMORY:
rmanp = &sc->sc_mem_rman;
tag = &sc->sc_pci_memt;
break;
default:
return (rv);
}
rv = rman_reserve_resource(rmanp, start, end, count, flags, child);
if (rv != NULL) {
rman_set_rid(rv, *rid);
if (type == SYS_RES_IOPORT) {
rman_set_bustag(rv, tag);
rman_set_bushandle(rv, rman_get_start(rv));
} else if (type == SYS_RES_MEMORY) {
rman_set_bustag(rv, tag);
rman_set_bushandle(rv, rman_get_bushandle(sc->sc_mem) +
(rman_get_start(rv) - IXP425_PCI_MEM_HWBASE));
}
}
return (rv);
}
static int
ixppcib_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
device_printf(bus, "%s called activate_resource\n", device_get_nameunit(child));
return (ENXIO);
}
static int
ixppcib_deactivate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
device_printf(bus, "%s called deactivate_resource\n", device_get_nameunit(child));
return (ENXIO);
}
static int
ixppcib_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
device_printf(bus, "%s called release_resource\n", device_get_nameunit(child));
return (ENXIO);
}
static void
ixppcib_conf_setup(struct ixppcib_softc *sc, int bus, int slot, int func,
int reg)
{
if (bus == 0) {
if (slot == 0 && func == 0) {
PCI_CSR_WRITE_4(sc, PCI_NP_AD, (reg & ~3));
} else {
bus &= 0xff;
slot &= 0x1f;
func &= 0x07;
/* configuration type 0 */
PCI_CSR_WRITE_4(sc, PCI_NP_AD, (1U << (32 - slot)) |
(func << 8) | (reg & ~3));
}
} else {
/* configuration type 1 */
PCI_CSR_WRITE_4(sc, PCI_NP_AD,
(bus << 16) | (slot << 11) |
(func << 8) | (reg & ~3) | 1);
}
}
static int
ixppcib_maxslots(device_t dev)
{
return (PCI_SLOTMAX);
}
static u_int32_t
ixppcib_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
int bytes)
{
struct ixppcib_softc *sc = device_get_softc(dev);
u_int32_t data, ret;
ixppcib_conf_setup(sc, bus, slot, func, reg & ~3);
PCI_CSR_WRITE_4(sc, PCI_NP_CBE, COMMAND_NP_CONF_READ);
ret = PCI_CSR_READ_4(sc, PCI_NP_RDATA);
ret >>= (reg & 3) * 8;
ret &= 0xffffffff >> ((4 - bytes) * 8);
#if 0
device_printf(dev, "read config: %u:%u:%u %#x(%d) = %#x\n", bus, slot, func, reg, bytes, ret);
#endif
/* check & clear PCI abort */
data = PCI_CSR_READ_4(sc, PCI_ISR);
if (data & ISR_PFE) {
PCI_CSR_WRITE_4(sc, PCI_ISR, ISR_PFE);
return (-1);
}
return (ret);
}
static const int byteenables[] = { 0, 0x10, 0x30, 0x70, 0xf0 };
static void
ixppcib_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
u_int32_t val, int bytes)
{
struct ixppcib_softc *sc = device_get_softc(dev);
u_int32_t data;
#if 0
device_printf(dev, "write config: %u:%u:%u %#x(%d) = %#x\n", bus, slot, func, reg, bytes, val);
#endif
ixppcib_conf_setup(sc, bus, slot, func, reg & ~3);
/* Byte enables are active low, so not them first */
PCI_CSR_WRITE_4(sc, PCI_NP_CBE, COMMAND_NP_CONF_WRITE |
(~(byteenables[bytes] << (reg & 3)) & 0xf0));
PCI_CSR_WRITE_4(sc, PCI_NP_WDATA, val << ((reg & 3) * 8));
/* check & clear PCI abort */
data = PCI_CSR_READ_4(sc, PCI_ISR);
if (data & ISR_PFE)
PCI_CSR_WRITE_4(sc, PCI_ISR, ISR_PFE);
}
static int
ixppcib_route_interrupt(device_t bridge, device_t device, int pin)
{
return (ixp425_md_route_interrupt(bridge, device, pin));
}
static device_method_t ixppcib_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ixppcib_probe),
DEVMETHOD(device_attach, ixppcib_attach),
/* Bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_read_ivar, ixppcib_read_ivar),
DEVMETHOD(bus_write_ivar, ixppcib_write_ivar),
DEVMETHOD(bus_setup_intr, ixppcib_setup_intr),
DEVMETHOD(bus_teardown_intr, ixppcib_teardown_intr),
DEVMETHOD(bus_alloc_resource, ixppcib_alloc_resource),
DEVMETHOD(bus_activate_resource, ixppcib_activate_resource),
DEVMETHOD(bus_deactivate_resource, ixppcib_deactivate_resource),
DEVMETHOD(bus_release_resource, ixppcib_release_resource),
/* DEVMETHOD(bus_get_dma_tag, ixppcib_get_dma_tag), */
/* pcib interface */
DEVMETHOD(pcib_maxslots, ixppcib_maxslots),
DEVMETHOD(pcib_read_config, ixppcib_read_config),
DEVMETHOD(pcib_write_config, ixppcib_write_config),
DEVMETHOD(pcib_route_interrupt, ixppcib_route_interrupt),
{0, 0},
};
static driver_t ixppcib_driver = {
"pcib",
ixppcib_methods,
sizeof(struct ixppcib_softc),
};
static devclass_t ixppcib_devclass;
DRIVER_MODULE(ixppcib, ixp, ixppcib_driver, ixppcib_devclass, 0, 0);

View File

@ -0,0 +1,102 @@
/* $NetBSD: ixp425_pci_asm.S,v 1.2 2005/12/11 12:16:51 christos Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* 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 for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* 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.
*
* $FreeBSD$
*
*/
#include <machine/asm.h>
/*
* Bus space functions for IXP425 PCI space access. We have to swizzle
* the address for 1 and 2 byte accesses when in big-endian mode.
*/
/*
* read single
*/
ENTRY(ixp425_pci_mem_bs_r_1)
#ifdef __ARMEB__
add r1, r1, r2
eor r1, r1, #0x3
ldrb r0, [r1]
#else
ldrb r0, [r1, r2]
#endif /* __ARMEB__ */
mov pc, lr
ENTRY(ixp425_pci_mem_bs_r_2)
#ifdef __ARMEB__
add r1, r1, r2
eor r1, r1, #0x2
ldrh r0, [r1]
#else
ldrh r0, [r1, r2]
#endif /* __ARMEB__ */
mov pc, lr
ENTRY(ixp425_pci_mem_bs_r_4)
ldr r0, [r1, r2]
mov pc, lr
/*
* write single
*/
ENTRY(ixp425_pci_mem_bs_w_1)
#ifdef __ARMEB__
add r1, r1, r2
eor r1, r1, #0x3
strb r3, [r1]
#else
strb r3, [r1, r2]
#endif /* __ARMEB__ */
mov pc, lr
ENTRY(ixp425_pci_mem_bs_w_2)
#ifdef __ARMEB__
add r1, r1, r2
eor r1, r1, #0x2
strh r3, [r1]
#else
strh r3, [r1, r2]
#endif /* __ARMEB__ */
mov pc, lr
ENTRY(ixp425_pci_mem_bs_w_4)
str r3, [r1, r2]
mov pc, lr

View File

@ -0,0 +1,496 @@
/* $NetBSD: ixp425_pci_space.c,v 1.6 2006/04/10 03:36:03 simonb Exp $ */
/*
* Copyright (c) 2003
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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 Ichiro FUKUHARA.
* 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 ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* bus_space PCI functions for ixp425
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/endian.h>
#include <machine/pcb.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/pmap.h>
#include <vm/vm_page.h>
#include <vm/vm_extern.h>
#include <machine/bus.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h>
/*
* Macros to read/write registers
*/
#define CSR_READ_4(x) *(volatile uint32_t *) \
(IXP425_PCI_CSR_BASE + (x))
#define CSR_WRITE_4(x, v) *(volatile uint32_t *) \
(IXP425_PCI_CSR_BASE + (x)) = (v)
/* Proto types for all the bus_space structure functions */
bs_protos(ixp425_pci);
bs_protos(ixp425_pci_io);
bs_protos(ixp425_pci_mem);
/* special I/O functions */
static u_int8_t _pci_io_bs_r_1(void *, bus_space_handle_t, bus_size_t);
static u_int16_t _pci_io_bs_r_2(void *, bus_space_handle_t, bus_size_t);
static u_int32_t _pci_io_bs_r_4(void *, bus_space_handle_t, bus_size_t);
static void _pci_io_bs_w_1(void *, bus_space_handle_t, bus_size_t, u_int8_t);
static void _pci_io_bs_w_2(void *, bus_space_handle_t, bus_size_t, u_int16_t);
static void _pci_io_bs_w_4(void *, bus_space_handle_t, bus_size_t, u_int32_t);
#ifdef __ARMEB__
static u_int8_t _pci_io_bs_r_1_s(void *, bus_space_handle_t, bus_size_t);
static u_int16_t _pci_io_bs_r_2_s(void *, bus_space_handle_t, bus_size_t);
static u_int32_t _pci_io_bs_r_4_s(void *, bus_space_handle_t, bus_size_t);
static void _pci_io_bs_w_1_s(void *, bus_space_handle_t, bus_size_t, u_int8_t);
static void _pci_io_bs_w_2_s(void *, bus_space_handle_t, bus_size_t, u_int16_t);
static void _pci_io_bs_w_4_s(void *, bus_space_handle_t, bus_size_t, u_int32_t);
static u_int8_t _pci_mem_bs_r_1(void *, bus_space_handle_t, bus_size_t);
static u_int16_t _pci_mem_bs_r_2(void *, bus_space_handle_t, bus_size_t);
static u_int32_t _pci_mem_bs_r_4(void *, bus_space_handle_t, bus_size_t);
static void _pci_mem_bs_w_1(void *, bus_space_handle_t, bus_size_t, u_int8_t);
static void _pci_mem_bs_w_2(void *, bus_space_handle_t, bus_size_t, u_int16_t);
static void _pci_mem_bs_w_4(void *, bus_space_handle_t, bus_size_t, u_int32_t);
#endif
struct bus_space ixp425_pci_io_bs_tag_template = {
/* mapping/unmapping */
.bs_map = ixp425_pci_io_bs_map,
.bs_unmap = ixp425_pci_io_bs_unmap,
.bs_subregion = ixp425_pci_bs_subregion,
.bs_alloc = ixp425_pci_io_bs_alloc,
.bs_free = ixp425_pci_io_bs_free,
/* barrier */
.bs_barrier = ixp425_pci_bs_barrier,
/*
* IXP425 processor does not have PCI I/O windows
*/
/* read (single) */
.bs_r_1 = _pci_io_bs_r_1,
.bs_r_2 = _pci_io_bs_r_2,
.bs_r_4 = _pci_io_bs_r_4,
/* write (single) */
.bs_w_1 = _pci_io_bs_w_1,
.bs_w_2 = _pci_io_bs_w_2,
.bs_w_4 = _pci_io_bs_w_4,
#ifdef __ARMEB__
.bs_r_1_s = _pci_io_bs_r_1_s,
.bs_r_2_s = _pci_io_bs_r_2_s,
.bs_r_4_s = _pci_io_bs_r_4_s,
.bs_w_1_s = _pci_io_bs_w_1_s,
.bs_w_2_s = _pci_io_bs_w_2_s,
.bs_w_4_s = _pci_io_bs_w_4_s,
#else
.bs_r_1_s = _pci_io_bs_r_1,
.bs_r_2_s = _pci_io_bs_r_2,
.bs_r_4_s = _pci_io_bs_r_4,
.bs_w_1_s = _pci_io_bs_w_1,
.bs_w_2_s = _pci_io_bs_w_2,
.bs_w_4_s = _pci_io_bs_w_4,
#endif
};
void
ixp425_io_bs_init(bus_space_tag_t bs, void *cookie)
{
*bs = ixp425_pci_io_bs_tag_template;
bs->bs_cookie = cookie;
}
struct bus_space ixp425_pci_mem_bs_tag_template = {
/* mapping/unmapping */
.bs_map = ixp425_pci_mem_bs_map,
.bs_unmap = ixp425_pci_mem_bs_unmap,
.bs_subregion = ixp425_pci_bs_subregion,
.bs_alloc = ixp425_pci_mem_bs_alloc,
.bs_free = ixp425_pci_mem_bs_free,
/* barrier */
.bs_barrier = ixp425_pci_bs_barrier,
#ifdef __ARMEB__
/* read (single) */
.bs_r_1_s = _pci_mem_bs_r_1,
.bs_r_2_s = _pci_mem_bs_r_2,
.bs_r_4_s = _pci_mem_bs_r_4,
.bs_r_1 = ixp425_pci_mem_bs_r_1,
.bs_r_2 = ixp425_pci_mem_bs_r_2,
.bs_r_4 = ixp425_pci_mem_bs_r_4,
/* write (single) */
.bs_w_1_s = _pci_mem_bs_w_1,
.bs_w_2_s = _pci_mem_bs_w_2,
.bs_w_4_s = _pci_mem_bs_w_4,
.bs_w_1 = ixp425_pci_mem_bs_w_1,
.bs_w_2 = ixp425_pci_mem_bs_w_2,
.bs_w_4 = ixp425_pci_mem_bs_w_4,
#else
/* read (single) */
.bs_r_1 = ixp425_pci_mem_bs_r_1,
.bs_r_2 = ixp425_pci_mem_bs_r_2,
.bs_r_4 = ixp425_pci_mem_bs_r_4,
.bs_r_1_s = ixp425_pci_mem_bs_r_1,
.bs_r_2_s = ixp425_pci_mem_bs_r_2,
.bs_r_4_s = ixp425_pci_mem_bs_r_4,
/* write (single) */
.bs_w_1 = ixp425_pci_mem_bs_w_1,
.bs_w_2 = ixp425_pci_mem_bs_w_2,
.bs_w_4 = ixp425_pci_mem_bs_w_4,
.bs_w_1_s = ixp425_pci_mem_bs_w_1,
.bs_w_2_s = ixp425_pci_mem_bs_w_2,
.bs_w_4_s = ixp425_pci_mem_bs_w_4,
#endif
};
void
ixp425_mem_bs_init(bus_space_tag_t bs, void *cookie)
{
*bs = ixp425_pci_mem_bs_tag_template;
bs->bs_cookie = cookie;
}
/* common routine */
int
ixp425_pci_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset,
bus_size_t size, bus_space_handle_t *nbshp)
{
*nbshp = bsh + offset;
return (0);
}
void
ixp425_pci_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset,
bus_size_t len, int flags)
{
/* NULL */
}
/* io bs */
int
ixp425_pci_io_bs_map(void *t, bus_addr_t bpa, bus_size_t size,
int cacheable, bus_space_handle_t *bshp)
{
*bshp = bpa;
return (0);
}
void
ixp425_pci_io_bs_unmap(void *t, bus_space_handle_t h, bus_size_t size)
{
/* Nothing to do. */
}
int
ixp425_pci_io_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
bus_size_t size, bus_size_t alignment, bus_size_t boundary, int cacheable,
bus_addr_t *bpap, bus_space_handle_t *bshp)
{
panic("ixp425_pci_io_bs_alloc(): not implemented\n");
}
void
ixp425_pci_io_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
{
panic("ixp425_pci_io_bs_free(): not implemented\n");
}
/* special I/O functions */
static __inline u_int32_t
_bs_r(void *v, bus_space_handle_t ioh, bus_size_t off, u_int32_t be)
{
u_int32_t data;
CSR_WRITE_4(PCI_NP_AD, (ioh + off) & ~3);
CSR_WRITE_4(PCI_NP_CBE, be | COMMAND_NP_IO_READ);
data = CSR_READ_4(PCI_NP_RDATA);
if (CSR_READ_4(PCI_ISR) & ISR_PFE)
CSR_WRITE_4(PCI_ISR, ISR_PFE);
return data;
}
static u_int8_t
_pci_io_bs_r_1(void *v, bus_space_handle_t ioh, bus_size_t off)
{
u_int32_t data, n, be;
n = (ioh + off) % 4;
be = (0xf & ~(1U << n)) << NP_CBE_SHIFT;
data = _bs_r(v, ioh, off, be);
return data >> (8 * n);
}
static u_int16_t
_pci_io_bs_r_2(void *v, bus_space_handle_t ioh, bus_size_t off)
{
u_int32_t data, n, be;
n = (ioh + off) % 4;
be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT;
data = _bs_r(v, ioh, off, be);
return data >> (8 * n);
}
static u_int32_t
_pci_io_bs_r_4(void *v, bus_space_handle_t ioh, bus_size_t off)
{
u_int32_t data;
data = _bs_r(v, ioh, off, 0);
return data;
}
#ifdef __ARMEB__
static u_int8_t
_pci_io_bs_r_1_s(void *v, bus_space_handle_t ioh, bus_size_t off)
{
u_int32_t data, n, be;
n = (ioh + off) % 4;
be = (0xf & ~(1U << n)) << NP_CBE_SHIFT;
data = _bs_r(v, ioh, off, be);
return data >> (8 * n);
}
static u_int16_t
_pci_io_bs_r_2_s(void *v, bus_space_handle_t ioh, bus_size_t off)
{
u_int32_t data, n, be;
n = (ioh + off) % 4;
be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT;
data = _bs_r(v, ioh, off, be);
return data >> (8 * n);
}
static u_int32_t
_pci_io_bs_r_4_s(void *v, bus_space_handle_t ioh, bus_size_t off)
{
u_int32_t data;
data = _bs_r(v, ioh, off, 0);
return le32toh(data);
}
#endif /* __ARMEB__ */
static __inline void
_bs_w(void *v, bus_space_handle_t ioh, bus_size_t off,
u_int32_t be, u_int32_t data)
{
CSR_WRITE_4(PCI_NP_AD, (ioh + off) & ~3);
CSR_WRITE_4(PCI_NP_CBE, be | COMMAND_NP_IO_WRITE);
CSR_WRITE_4(PCI_NP_WDATA, data);
if (CSR_READ_4(PCI_ISR) & ISR_PFE)
CSR_WRITE_4(PCI_ISR, ISR_PFE);
}
static void
_pci_io_bs_w_1(void *v, bus_space_handle_t ioh, bus_size_t off,
u_int8_t val)
{
u_int32_t data, n, be;
n = (ioh + off) % 4;
be = (0xf & ~(1U << n)) << NP_CBE_SHIFT;
data = val << (8 * n);
_bs_w(v, ioh, off, be, data);
}
static void
_pci_io_bs_w_2(void *v, bus_space_handle_t ioh, bus_size_t off,
u_int16_t val)
{
u_int32_t data, n, be;
n = (ioh + off) % 4;
be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT;
data = val << (8 * n);
_bs_w(v, ioh, off, be, data);
}
static void
_pci_io_bs_w_4(void *v, bus_space_handle_t ioh, bus_size_t off,
u_int32_t val)
{
_bs_w(v, ioh, off, 0, val);
}
#ifdef __ARMEB__
static void
_pci_io_bs_w_1_s(void *v, bus_space_handle_t ioh, bus_size_t off,
u_int8_t val)
{
u_int32_t data, n, be;
n = (ioh + off) % 4;
be = (0xf & ~(1U << n)) << NP_CBE_SHIFT;
data = val << (8 * n);
_bs_w(v, ioh, off, be, data);
}
static void
_pci_io_bs_w_2_s(void *v, bus_space_handle_t ioh, bus_size_t off,
u_int16_t val)
{
u_int32_t data, n, be;
n = (ioh + off) % 4;
be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT;
data = val << (8 * n);
_bs_w(v, ioh, off, be, data);
}
static void
_pci_io_bs_w_4_s(void *v, bus_space_handle_t ioh, bus_size_t off,
u_int32_t val)
{
_bs_w(v, ioh, off, 0, htole32(val));
}
#endif /* __ARMEB__ */
/* mem bs */
int
ixp425_pci_mem_bs_map(void *t, bus_addr_t bpa, bus_size_t size,
int cacheable, bus_space_handle_t *bshp)
{
vm_paddr_t pa, endpa;
pa = trunc_page(bpa);
endpa = round_page(bpa + size);
*bshp = (vm_offset_t)pmap_mapdev(pa, endpa - pa);
return (0);
}
void
ixp425_pci_mem_bs_unmap(void *t, bus_space_handle_t h, bus_size_t size)
{
vm_offset_t va, endva;
va = trunc_page((vm_offset_t)t);
endva = va + round_page(size);
/* Free the kernel virtual mapping. */
kmem_free(kernel_map, va, endva - va);
}
int
ixp425_pci_mem_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
bus_size_t size, bus_size_t alignment, bus_size_t boundary, int cacheable,
bus_addr_t *bpap, bus_space_handle_t *bshp)
{
panic("ixp425_mem_bs_alloc(): not implemented\n");
}
void
ixp425_pci_mem_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
{
panic("ixp425_mem_bs_free(): not implemented\n");
}
#ifdef __ARMEB__
static u_int8_t
_pci_mem_bs_r_1(void *v, bus_space_handle_t ioh, bus_size_t off)
{
return ixp425_pci_mem_bs_r_1(v, ioh, off);
}
static u_int16_t
_pci_mem_bs_r_2(void *v, bus_space_handle_t ioh, bus_size_t off)
{
return (ixp425_pci_mem_bs_r_2(v, ioh, off));
}
static u_int32_t
_pci_mem_bs_r_4(void *v, bus_space_handle_t ioh, bus_size_t off)
{
u_int32_t data;
data = ixp425_pci_mem_bs_r_4(v, ioh, off);
return (le32toh(data));
}
static void
_pci_mem_bs_w_1(void *v, bus_space_handle_t ioh, bus_size_t off,
u_int8_t val)
{
ixp425_pci_mem_bs_w_1(v, ioh, off, val);
}
static void
_pci_mem_bs_w_2(void *v, bus_space_handle_t ioh, bus_size_t off,
u_int16_t val)
{
ixp425_pci_mem_bs_w_2(v, ioh, off, val);
}
static void
_pci_mem_bs_w_4(void *v, bus_space_handle_t ioh, bus_size_t off,
u_int32_t val)
{
ixp425_pci_mem_bs_w_4(v, ioh, off, htole32(val));
}
#endif /* __ARMEB__ */
/* End of ixp425_pci_space.c */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,243 @@
/*-
* Copyright (c) 2006 Sam Leffler, Errno Consulting
* 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,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
*
* $FreeBSD$
*/
/*-
* Copyright (c) 2001-2005, Intel Corporation.
* 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 Intel Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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_XSCALE_IXP425_QMGR_H
#define ARM_XSCALE_IXP425_QMGR_H
#define IX_QMGR_MAX_NUM_QUEUES 64
#define IX_QMGR_MIN_QUEUPP_QID 32
#define IX_QMGR_MIN_ENTRY_SIZE_IN_WORDS 16
/* Total size of SRAM */
#define IX_QMGR_AQM_SRAM_SIZE_IN_BYTES 0x4000
#define IX_QMGR_Q_PRIORITY_0 0
#define IX_QMGR_Q_PRIORITY_1 1
#define IX_QMGR_Q_PRIORITY_2 2
#define IX_QMGR_NUM_PRIORITY_LEVELS 3 /* number of priority levels */
#define IX_QMGR_Q_STATUS_E_BIT_MASK 0x1 /* Empty */
#define IX_QMGR_Q_STATUS_NE_BIT_MASK 0x2 /* Nearly Empty */
#define IX_QMGR_Q_STATUS_NF_BIT_MASK 0x4 /* Nearly Full */
#define IX_QMGR_Q_STATUS_F_BIT_MASK 0x8 /* Full */
#define IX_QMGR_Q_STATUS_UF_BIT_MASK 0x10 /* Underflow */
#define IX_QMGR_Q_STATUS_OF_BIT_MASK 0x20 /* Overflow */
#define IX_QMGR_Q_SOURCE_ID_E 0 /* Q Empty after last read */
#define IX_QMGR_Q_SOURCE_ID_NE 1 /* Q Nearly Empty after last read */
#define IX_QMGR_Q_SOURCE_ID_NF 2 /* Q Nearly Full after last write */
#define IX_QMGR_Q_SOURCE_ID_F 3 /* Q Full after last write */
#define IX_QMGR_Q_SOURCE_ID_NOT_E 4 /* Q !Empty after last write */
#define IX_QMGR_Q_SOURCE_ID_NOT_NE 5 /* Q !Nearly Empty after last write */
#define IX_QMGR_Q_SOURCE_ID_NOT_NF 6 /* Q !Nearly Full after last read */
#define IX_QMGR_Q_SOURCE_ID_NOT_F 7 /* Q !Full after last read */
#define IX_QMGR_UNDERFLOW_BIT_OFFSET 0x0 /* underflow bit mask */
#define IX_QMGR_OVERFLOW_BIT_OFFSET 0x1 /* overflow bit mask */
#define IX_QMGR_QUEACC0_OFFSET 0x0000 /* q 0 access register */
#define IX_QMGR_QUEACC_SIZE 0x4/*words*/
#define IX_QMGR_QUELOWSTAT0_OFFSET 0x400 /* Q status, q's 0-7 */
#define IX_QMGR_QUELOWSTAT1_OFFSET 0x404 /* Q status, q's 8-15 */
#define IX_QMGR_QUELOWSTAT2_OFFSET 0x408 /* Q status, q's 16-23 */
#define IX_QMGR_QUELOWSTAT3_OFFSET 0x40c /* Q status, q's 24-31 */
/* Queue status register Q status bits mask */
#define IX_QMGR_QUELOWSTAT_QUE_STS_BITS_MASK 0xF
/* Size of queue 0-31 status register */
#define IX_QMGR_QUELOWSTAT_SIZE 0x4 /*words*/
#define IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD 8 /* # status/word */
#define IX_QMGR_QUEUOSTAT0_OFFSET 0x410 /* Q UF/OF status, q's 0-15 */
#define IX_QMGR_QUEUOSTAT1_OFFSET 0x414 /* Q UF/OF status, q's 16-31 */
#define IX_QMGR_QUEUOSTAT_NUM_QUE_PER_WORD 16 /* # UF/OF status/word */
#define IX_QMGR_QUEUPPSTAT0_OFFSET 0x418 /* NE status, q's 32-63 */
#define IX_QMGR_QUEUPPSTAT1_OFFSET 0x41c /* F status, q's 32-63 */
#define IX_QMGR_INT0SRCSELREG0_OFFSET 0x420 /* INT src select, q's 0-7 */
#define IX_QMGR_INT0SRCSELREG1_OFFSET 0x424 /* INT src select, q's 8-15 */
#define IX_QMGR_INT0SRCSELREG2_OFFSET 0x428 /* INT src select, q's 16-23 */
#define IX_QMGR_INT0SRCSELREG3_OFFSET 0x42c /* INT src select, q's 24-31 */
#define IX_QMGR_INTSRC_NUM_QUE_PER_WORD 8 /* # INT src select/word */
#define IX_QMGR_QUEIEREG0_OFFSET 0x430 /* INT enable, q's 0-31 */
#define IX_QMGR_QUEIEREG1_OFFSET 0x434 /* INT enable, q's 32-63 */
#define IX_QMGR_QINTREG0_OFFSET 0x438 /* INT status, q's 0-31 */
#define IX_QMGR_QINTREG1_OFFSET 0x43c /* INT status, q's 32-63 */
#define IX_QMGR_QUECONFIG_BASE_OFFSET 0x2000 /* Q config register, q 0 */
#define IX_QMGR_QUECONFIG_SIZE 0x100 /* total size of Q config regs*/
#define IX_QMGR_QUEBUFFER_SPACE_OFFSET 0x2100 /* start of SRAM */
/* Total bits in a word */
#define BITS_PER_WORD 32
/* Size of queue buffer space */
#define IX_QMGR_QUE_BUFFER_SPACE_SIZE 0x1F00
/*
* This macro will return the address of the access register for the
* queue specified by qId
*/
#define IX_QMGR_Q_ACCESS_ADDR_GET(qId)\
(((qId) * (IX_QMGR_QUEACC_SIZE * sizeof(uint32_t)))\
+ IX_QMGR_QUEACC0_OFFSET)
/*
* Bit location of bit-3 of INT0SRCSELREG0 register to enabled
* sticky interrupt register.
*/
#define IX_QMGR_INT0SRCSELREG0_BIT3 3
/*
* These defines are the bit offsets of the various fields of
* the queue configuration register.
*/
#if 0
#define IX_QMGR_Q_CONFIG_WRPTR_OFFSET 0x00
#define IX_QMGR_Q_CONFIG_RDPTR_OFFSET 0x07
#define IX_QMGR_Q_CONFIG_BADDR_OFFSET 0x0E
#define IX_QMGR_Q_CONFIG_ESIZE_OFFSET 0x16
#define IX_QMGR_Q_CONFIG_BSIZE_OFFSET 0x18
#define IX_QMGR_Q_CONFIG_NE_OFFSET 0x1A
#define IX_QMGR_Q_CONFIG_NF_OFFSET 0x1D
#define IX_QMGR_NE_NF_CLEAR_MASK 0x03FFFFFF
#define IX_QMGR_NE_MASK 0x7
#define IX_QMGR_NF_MASK 0x7
#define IX_QMGR_SIZE_MASK 0x3
#define IX_QMGR_ENTRY_SIZE_MASK 0x3
#define IX_QMGR_BADDR_MASK 0x003FC000
#define IX_QMGR_RDPTR_MASK 0x7F
#define IX_QMGR_WRPTR_MASK 0x7F
#define IX_QMGR_RDWRPTR_MASK 0x00003FFF
#else
#define IX_QMGR_Q_CONFIG_WRPTR_OFFSET 0
#define IX_QMGR_WRPTR_MASK 0x7F
#define IX_QMGR_Q_CONFIG_RDPTR_OFFSET 7
#define IX_QMGR_RDPTR_MASK 0x7F
#define IX_QMGR_Q_CONFIG_BADDR_OFFSET 14
#define IX_QMGR_BADDR_MASK 0x3FC000 /* XXX not used */
#define IX_QMGR_Q_CONFIG_ESIZE_OFFSET 22
#define IX_QMGR_ENTRY_SIZE_MASK 0x3
#define IX_QMGR_Q_CONFIG_BSIZE_OFFSET 24
#define IX_QMGR_SIZE_MASK 0x3
#define IX_QMGR_Q_CONFIG_NE_OFFSET 26
#define IX_QMGR_NE_MASK 0x7
#define IX_QMGR_Q_CONFIG_NF_OFFSET 29
#define IX_QMGR_NF_MASK 0x7
#define IX_QMGR_RDWRPTR_MASK 0x00003FFF
#define IX_QMGR_NE_NF_CLEAR_MASK 0x03FFFFFF
#endif
#define IX_QMGR_BASE_ADDR_16_WORD_ALIGN 64
#define IX_QMGR_BASE_ADDR_16_WORD_SHIFT 6
#define IX_QMGR_AQM_ADDRESS_SPACE_SIZE_IN_WORDS 0x1000
/* Base address of AQM SRAM */
#define IX_QMGR_AQM_SRAM_BASE_ADDRESS_OFFSET \
((IX_QMGR_QUECONFIG_BASE_OFFSET) + (IX_QMGR_QUECONFIG_SIZE))
/* Min buffer size used for generating buffer size in QUECONFIG */
#define IX_QMGR_MIN_BUFFER_SIZE 16
/* Reset values of QMgr hardware registers */
#define IX_QMGR_QUELOWSTAT_RESET_VALUE 0x33333333
#define IX_QMGR_QUEUOSTAT_RESET_VALUE 0x00000000
#define IX_QMGR_QUEUPPSTAT0_RESET_VALUE 0xFFFFFFFF
#define IX_QMGR_QUEUPPSTAT1_RESET_VALUE 0x00000000
#define IX_QMGR_INT0SRCSELREG_RESET_VALUE 0x00000000
#define IX_QMGR_QUEIEREG_RESET_VALUE 0x00000000
#define IX_QMGR_QINTREG_RESET_VALUE 0xFFFFFFFF
#define IX_QMGR_QUECONFIG_RESET_VALUE 0x00000000
#define IX_QMGR_QUELOWSTAT_BITS_PER_Q \
(BITS_PER_WORD/IX_QMGR_QUELOWSTAT_NUM_QUE_PER_WORD)
#define IX_QMGR_QUELOWSTAT_QID_MASK 0x7
#define IX_QMGR_Q_CONFIG_ADDR_GET(qId)\
(((qId) * sizeof(uint32_t)) + IX_QMGR_QUECONFIG_BASE_OFFSET)
#define IX_QMGR_ENTRY1_OFFSET 0
#define IX_QMGR_ENTRY2_OFFSET 1
#define IX_QMGR_ENTRY4_OFFSET 3
int ixpqmgr_qconfig(int qId, int qSizeInWords, int ne, int nf, int srcSel,
void (*cb)(int, void *), void *cbarg);
int ixpqmgr_qwrite(int qId, uint32_t entry);
int ixpqmgr_qread(int qId, uint32_t *entry);
int ixpqmgr_qreadm(int qId, uint32_t n, uint32_t *p);
uint32_t ixpqmgr_getqstatus(int qId);
uint32_t ixpqmgr_getqconfig(int qId);
void ixpqmgr_notify_enable(int qId, int srcSel);
void ixpqmgr_notify_disable(int qId);
void ixpqmgr_dump(void);
#endif /* ARM_XSCALE_IXP425_QMGR_H */

View File

@ -0,0 +1,215 @@
/* $NetBSD: ixp425_space.c,v 1.6 2006/04/10 03:36:03 simonb Exp $ */
/*
* Copyright (c) 2003
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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 Ichiro FUKUHARA.
* 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 ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* bus_space I/O functions for ixp425
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <machine/pcb.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/pmap.h>
#include <vm/vm_page.h>
#include <vm/vm_extern.h>
#include <machine/bus.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h>
/* Proto types for all the bus_space structure functions */
bs_protos(ixp425);
bs_protos(generic);
bs_protos(generic_armv4);
struct bus_space ixp425_bs_tag = {
/* cookie */
.bs_cookie = (void *) 0,
/* mapping/unmapping */
.bs_map = ixp425_bs_map,
.bs_unmap = ixp425_bs_unmap,
.bs_subregion = ixp425_bs_subregion,
/* allocation/deallocation */
.bs_alloc = ixp425_bs_alloc,
.bs_free = ixp425_bs_free,
/* barrier */
.bs_barrier = ixp425_bs_barrier,
/* read (single) */
.bs_r_1 = generic_bs_r_1,
.bs_r_2 = generic_armv4_bs_r_2,
.bs_r_4 = generic_bs_r_4,
.bs_r_8 = NULL,
/* read multiple */
.bs_rm_1 = generic_bs_rm_1,
.bs_rm_2 = generic_armv4_bs_rm_2,
.bs_rm_4 = generic_bs_rm_4,
.bs_rm_8 = NULL,
/* read region */
.bs_rr_1 = generic_bs_rr_1,
.bs_rr_2 = generic_armv4_bs_rr_2,
.bs_rr_4 = generic_bs_rr_4,
.bs_rr_8 = NULL,
/* write (single) */
.bs_w_1 = generic_bs_w_1,
.bs_w_2 = generic_armv4_bs_w_2,
.bs_w_4 = generic_bs_w_4,
.bs_w_8 = NULL,
/* write multiple */
.bs_wm_1 = generic_bs_wm_1,
.bs_wm_2 = generic_armv4_bs_wm_2,
.bs_wm_4 = generic_bs_wm_4,
.bs_wm_8 = NULL,
/* write region */
.bs_wr_1 = generic_bs_wr_1,
.bs_wr_2 = generic_armv4_bs_wr_2,
.bs_wr_4 = generic_bs_wr_4,
.bs_wr_8 = NULL,
/* set multiple */
/* XXX not implemented */
/* set region */
.bs_sr_1 = NULL,
.bs_sr_2 = generic_armv4_bs_sr_2,
.bs_sr_4 = generic_bs_sr_4,
.bs_sr_8 = NULL,
/* copy */
.bs_c_1 = NULL,
.bs_c_2 = generic_armv4_bs_c_2,
.bs_c_4 = NULL,
.bs_c_8 = NULL,
};
int
ixp425_bs_map(void *t, bus_addr_t bpa, bus_size_t size,
int cacheable, bus_space_handle_t *bshp)
{
const struct pmap_devmap *pd;
vm_paddr_t startpa, endpa, pa, offset;
vm_offset_t va;
pt_entry_t *pte;
if ((pd = pmap_devmap_find_pa(bpa, size)) != NULL) {
/* Device was statically mapped. */
*bshp = pd->pd_va + (bpa - pd->pd_pa);
return (0);
}
endpa = round_page(bpa + size);
offset = bpa & PAGE_MASK;
startpa = trunc_page(bpa);
va = kmem_alloc(kernel_map, endpa - startpa);
if (va == 0)
return (ENOMEM);
*bshp = va + offset;
for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
pmap_kenter(va, pa);
pte = vtopte(va);
*pte &= ~L2_S_CACHE_MASK;
PTE_SYNC(pte);
}
return (0);
}
void
ixp425_bs_unmap(void *t, bus_space_handle_t h, bus_size_t size)
{
vm_offset_t va, endva;
if (pmap_devmap_find_va((vm_offset_t)t, size) != NULL) {
/* Device was statically mapped; nothing to do. */
return;
}
endva = round_page((vm_offset_t)t + size);
va = trunc_page((vm_offset_t)t);
while (va < endva) {
pmap_kremove(va);
va += PAGE_SIZE;
}
kmem_free(kernel_map, va, endva - va);
}
int
ixp425_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
bus_size_t size, bus_size_t alignment, bus_size_t boundary, int cacheable,
bus_addr_t *bpap, bus_space_handle_t *bshp)
{
panic("ixp425_bs_alloc(): not implemented");
}
void
ixp425_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
{
panic("ixp425_bs_free(): not implemented");
}
int
ixp425_bs_subregion(void *t, bus_space_handle_t bsh, bus_size_t offset,
bus_size_t size, bus_space_handle_t *nbshp)
{
*nbshp = bsh + offset;
return (0);
}
void
ixp425_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset,
bus_size_t len, int flags)
{
/* Nothing to do. */
}

View File

@ -0,0 +1,267 @@
/* $NetBSD: ixp425_timer.c,v 1.11 2006/04/10 03:36:03 simonb Exp $ */
/*
* Copyright (c) 2003
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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 Ichiro FUKUHARA.
* 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 ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/time.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/timetc.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/frame.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h>
static uint32_t counts_per_hz;
/* callback functions for intr_functions */
void ixpclk_intr(void *);
struct ixpclk_softc {
device_t sc_dev;
bus_addr_t sc_baseaddr;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
};
static unsigned ixp425_timer_get_timecount(struct timecounter *tc);
#ifndef IXP425_CLOCK_FREQ
#define COUNTS_PER_SEC 66666600 /* 66MHz */
#else
#define COUNTS_PER_SEC IXP425_CLOCK_FREQ
#endif
#define COUNTS_PER_USEC ((COUNTS_PER_SEC / 1000000) + 1)
static struct ixpclk_softc *ixpclk_sc = NULL;
#define GET_TS_VALUE(sc) (*(volatile u_int32_t *) \
(IXP425_TIMER_VBASE + IXP425_OST_TS))
static struct timecounter ixp425_timer_timecounter = {
ixp425_timer_get_timecount, /* get_timecount */
NULL, /* no poll_pps */
~0u, /* counter_mask */
COUNTS_PER_SEC, /* frequency */
"IXP425 Timer", /* name */
1000, /* quality */
};
static int
ixpclk_probe(device_t dev)
{
device_set_desc(dev, "IXP425 Timer");
return (0);
}
static int
ixpclk_attach(device_t dev)
{
struct ixpclk_softc *sc = device_get_softc(dev);
struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
ixpclk_sc = sc;
sc->sc_dev = dev;
sc->sc_iot = sa->sc_iot;
sc->sc_baseaddr = IXP425_TIMER_HWBASE;
if (bus_space_map(sc->sc_iot, sc->sc_baseaddr, 8, 0,
&sc->sc_ioh))
panic("%s: Cannot map registers", device_get_name(dev));
return (0);
}
static device_method_t ixpclk_methods[] = {
DEVMETHOD(device_probe, ixpclk_probe),
DEVMETHOD(device_attach, ixpclk_attach),
{0, 0},
};
static driver_t ixpclk_driver = {
"ixpclk",
ixpclk_methods,
sizeof(struct ixpclk_softc),
};
static devclass_t ixpclk_devclass;
DRIVER_MODULE(ixpclk, ixp, ixpclk_driver, ixpclk_devclass, 0, 0);
static unsigned
ixp425_timer_get_timecount(struct timecounter *tc)
{
uint32_t ret;
ret = GET_TS_VALUE(sc);
return (ret);
}
/*
* cpu_initclocks:
*
* Initialize the clock and get them going.
*/
void
cpu_initclocks(void)
{
struct ixpclk_softc* sc = ixpclk_sc;
struct resource *irq;
device_t dev = sc->sc_dev;
u_int oldirqstate;
int rid = 0;
void *ihl;
if (hz < 50 || COUNTS_PER_SEC % hz) {
printf("Cannot get %d Hz clock; using 100 Hz\n", hz);
hz = 100;
}
tick = 1000000 / hz; /* number of microseconds between interrupts */
/*
* We only have one timer available; stathz and profhz are
* always left as 0 (the upper-layer clock code deals with
* this situation).
*/
if (stathz != 0)
printf("Cannot get %d Hz statclock\n", stathz);
stathz = 0;
if (profhz != 0)
printf("Cannot get %d Hz profclock\n", profhz);
profhz = 0;
/* Report the clock frequency. */
oldirqstate = disable_interrupts(I32_bit);
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, IXP425_INT_TMR0,
IXP425_INT_TMR0, 1, RF_ACTIVE);
if (!irq)
panic("Unable to setup the clock irq handler.\n");
else
bus_setup_intr(dev, irq, INTR_TYPE_CLK | INTR_FAST,
ixpclk_intr, NULL, &ihl);
/* Set up the new clock parameters. */
/* clear interrupt */
bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_OST_STATUS,
OST_WARM_RESET | OST_WDOG_INT | OST_TS_INT |
OST_TIM1_INT | OST_TIM0_INT);
counts_per_hz = COUNTS_PER_SEC / hz;
/* reload value & Timer enable */
bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_OST_TIM0_RELOAD,
(counts_per_hz & TIMERRELOAD_MASK) | OST_TIMER_EN);
tc_init(&ixp425_timer_timecounter);
restore_interrupts(oldirqstate);
rid = 0;
}
/*
* DELAY:
*
* Delay for at least N microseconds.
*/
void
DELAY(int n)
{
u_int32_t first, last;
int usecs;
if (n == 0)
return;
/*
* Clamp the timeout at a maximum value (about 32 seconds with
* a 66MHz clock). *Nobody* should be delay()ing for anywhere
* near that length of time and if they are, they should be hung
* out to dry.
*/
if (n >= (0x80000000U / COUNTS_PER_USEC))
usecs = (0x80000000U / COUNTS_PER_USEC) - 1;
else
usecs = n * COUNTS_PER_USEC;
/* Note: Timestamp timer counts *up*, unlike the other timers */
first = GET_TS_VALUE();
while (usecs > 0) {
last = GET_TS_VALUE();
usecs -= (int)(last - first);
first = last;
}
}
/*
* ixpclk_intr:
*
* Handle the hardclock interrupt.
*/
void
ixpclk_intr(void *arg)
{
struct ixpclk_softc* sc = ixpclk_sc;
struct trapframe *frame = arg;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_OST_STATUS,
OST_TIM0_INT);
hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
}
void
cpu_startprofclock(void)
{
}
void
cpu_stopprofclock(void)
{
}

View File

@ -0,0 +1,118 @@
/*-
* Copyright (c) 2006 Sam Leffler. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* IXP425 Watchdog Timer Support.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/time.h>
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <sys/watchdog.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/frame.h>
#include <machine/resource.h>
#include <machine/intr.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h>
struct ixpwdog_softc {
device_t sc_dev;
};
static __inline uint32_t
RD4(struct ixpwdog_softc *sc, bus_size_t off)
{
return bus_space_read_4(&ixp425_bs_tag, IXP425_TIMER_VBASE, off);
}
static __inline void
WR4(struct ixpwdog_softc *sc, bus_size_t off, uint32_t val)
{
bus_space_write_4(&ixp425_bs_tag, IXP425_TIMER_VBASE, off, val);
}
static void
ixp425_watchdog(void *arg, u_int cmd, int *error)
{
struct ixpwdog_softc *sc = arg;
u_int u = cmd & WD_INTERVAL;
WR4(sc, IXP425_OST_WDOG_KEY, OST_WDOG_KEY_MAJICK);
if (cmd && 4 <= u && u <= 35) {
WR4(sc, IXP425_OST_WDOG_ENAB, 0);
/* approximate 66.66MHz cycles */
WR4(sc, IXP425_OST_WDOG, 2<<(u - 4));
/* NB: reset on timer expiration */
WR4(sc, IXP425_OST_WDOG_ENAB,
OST_WDOG_ENAB_CNT_ENA | OST_WDOG_ENAB_RST_ENA);
*error = 0;
} else {
/* disable watchdog */
WR4(sc, IXP425_OST_WDOG_ENAB, 0);
}
WR4(sc, IXP425_OST_WDOG_KEY, 0);
}
static int
ixpwdog_probe(device_t dev)
{
device_set_desc(dev, "IXP425 Watchdog Timer");
return (0);
}
static int
ixpwdog_attach(device_t dev)
{
struct ixpwdog_softc *sc = device_get_softc(dev);
sc->sc_dev = dev;
EVENTHANDLER_REGISTER(watchdog_list, ixp425_watchdog, sc, 0);
return (0);
}
static device_method_t ixpwdog_methods[] = {
DEVMETHOD(device_probe, ixpwdog_probe),
DEVMETHOD(device_attach, ixpwdog_attach),
{0, 0},
};
static driver_t ixpwdog_driver = {
"ixpwdog",
ixpwdog_methods,
sizeof(struct ixpwdog_softc),
};
static devclass_t ixpwdog_devclass;
DRIVER_MODULE(ixpwdog, ixp, ixpwdog_driver, ixpwdog_devclass, 0, 0);

View File

@ -0,0 +1,582 @@
/* $NetBSD: ixp425reg.h,v 1.19 2005/12/11 12:16:51 christos Exp $ */
/*
* Copyright (c) 2003
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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 Ichiro FUKUHARA.
* 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 ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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.
*
* $FreeBSD$
*
*/
#ifndef _IXP425REG_H_
#define _IXP425REG_H_
/*
* Physical memory map for the Intel IXP425
*/
/*
* CC00 00FF ---------------------------
* SDRAM Configuration Registers
* CC00 0000 ---------------------------
*
* C800 BFFF ---------------------------
* System and Peripheral Registers
* C800 0000 ---------------------------
* Expansion Bus Configuration Registers
* C400 0000 ---------------------------
* PCI Configuration and Status Registers
* C000 0000 ---------------------------
*
* 6400 0000 ---------------------------
* Queue manager
* 6000 0000 ---------------------------
* Expansion Bus Data
* 5000 0000 ---------------------------
* PCI Data
* 4800 0000 ---------------------------
*
* 4000 0000 ---------------------------
* SDRAM
* 1000 0000 ---------------------------
*/
/*
* Virtual memory map for the Intel IXP425 integrated devices
*/
/*
* FFFF FFFF ---------------------------
*
* FC00 0000 ---------------------------
* PCI Data (memory space)
* F800 0000 ---------------------------
*
* F020 1000 ---------------------------
* SDRAM Controller
* F020 0000 ---------------------------
*
* F001 2000 ---------------------------
* PCI Configuration and Status Registers
* F001 1000 ---------------------------
* Expansion bus Configuration Registers
* F001 0000 ---------------------------
* System and Peripheral Registers
* VA F000 0000 = PA C800 0000 (SIZE 0x10000)
* F000 0000 ---------------------------
*
* 0000 0000 ---------------------------
*
*/
/* Physical/Virtual address for I/O space */
#define IXP425_IO_VBASE 0xf0000000UL
#define IXP425_IO_HWBASE 0xc8000000UL
#define IXP425_IO_SIZE 0x00010000UL
/* Offset */
#define IXP425_UART0_OFFSET 0x00000000UL
#define IXP425_UART1_OFFSET 0x00001000UL
#define IXP425_PMC_OFFSET 0x00002000UL
#define IXP425_INTR_OFFSET 0x00003000UL
#define IXP425_GPIO_OFFSET 0x00004000UL
#define IXP425_TIMER_OFFSET 0x00005000UL
#define IXP425_NPE_A_OFFSET 0x00006000UL /* Not User Programmable */
#define IXP425_NPE_B_OFFSET 0x00007000UL /* Not User Programmable */
#define IXP425_NPE_C_OFFSET 0x00008000UL /* Not User Programmable */
#define IXP425_MAC_A_OFFSET 0x00009000UL
#define IXP425_MAC_B_OFFSET 0x0000a000UL
#define IXP425_USB_OFFSET 0x0000b000UL
#define IXP425_REG_SIZE 0x1000
/*
* UART
* UART0 0xc8000000
* UART1 0xc8001000
*
*/
/* I/O space */
#define IXP425_UART0_HWBASE (IXP425_IO_HWBASE + IXP425_UART0_OFFSET)
#define IXP425_UART1_HWBASE (IXP425_IO_HWBASE + IXP425_UART1_OFFSET)
#define IXP425_UART0_VBASE (IXP425_IO_VBASE + IXP425_UART0_OFFSET)
/* 0xf0000000 */
#define IXP425_UART1_VBASE (IXP425_IO_VBASE + IXP425_UART1_OFFSET)
/* 0xf0001000 */
#define IXP425_UART_FREQ 14745600
#define IXP425_UART_IER 0x01 /* interrupt enable register */
#define IXP425_UART_IER_RTOIE 0x10 /* receiver timeout interrupt enable */
#define IXP425_UART_IER_UUE 0x40 /* UART Unit enable */
/*#define IXP4XX_COM_NPORTS 8*/
/*
* Timers
*
*/
#define IXP425_TIMER_HWBASE (IXP425_IO_HWBASE + IXP425_TIMER_OFFSET)
#define IXP425_TIMER_VBASE (IXP425_IO_VBASE + IXP425_TIMER_OFFSET)
#define IXP425_OST_TS 0x0000
#define IXP425_OST_TIM0 0x0004
#define IXP425_OST_TIM1 0x000C
#define IXP425_OST_TIM0_RELOAD 0x0008
#define IXP425_OST_TIM1_RELOAD 0x0010
#define TIMERRELOAD_MASK 0xFFFFFFFC
#define OST_ONESHOT_EN (1U << 1)
#define OST_TIMER_EN (1U << 0)
#define IXP425_OST_STATUS 0x0020
#define OST_WARM_RESET (1U << 4)
#define OST_WDOG_INT (1U << 3)
#define OST_TS_INT (1U << 2)
#define OST_TIM1_INT (1U << 1)
#define OST_TIM0_INT (1U << 0)
#define IXP425_OST_WDOG 0x0014
#define IXP425_OST_WDOG_ENAB 0x0018
#define IXP425_OST_WDOG_KEY 0x001c
#define OST_WDOG_KEY_MAJICK 0x482e
#define OST_WDOG_ENAB_RST_ENA (1u << 0)
#define OST_WDOG_ENAB_INT_ENA (1u << 1)
#define OST_WDOG_ENAB_CNT_ENA (1u << 2)
/*
* Interrupt Controller Unit.
* PA 0xc8003000
*/
#define IXP425_IRQ_HWBASE IXP425_IO_HWBASE + IXP425_INTR_OFFSET
#define IXP425_IRQ_VBASE IXP425_IO_VBASE + IXP425_INTR_OFFSET
/* 0xf0003000 */
#define IXP425_IRQ_SIZE 0x00000020UL
#define IXP425_INT_STATUS (IXP425_IRQ_VBASE + 0x00)
#define IXP425_INT_ENABLE (IXP425_IRQ_VBASE + 0x04)
#define IXP425_INT_SELECT (IXP425_IRQ_VBASE + 0x08)
#define IXP425_IRQ_STATUS (IXP425_IRQ_VBASE + 0x0C)
#define IXP425_FIQ_STATUS (IXP425_IRQ_VBASE + 0x10)
#define IXP425_INT_PRTY (IXP425_IRQ_VBASE + 0x14)
#define IXP425_IRQ_ENC (IXP425_IRQ_VBASE + 0x18)
#define IXP425_FIQ_ENC (IXP425_IRQ_VBASE + 0x1C)
#define IXP425_INT_SW1 31 /* SW Interrupt 1 */
#define IXP425_INT_SW0 30 /* SW Interrupt 0 */
#define IXP425_INT_GPIO_12 29 /* GPIO 12 */
#define IXP425_INT_GPIO_11 28 /* GPIO 11 */
#define IXP425_INT_GPIO_10 27 /* GPIO 11 */
#define IXP425_INT_GPIO_9 26 /* GPIO 9 */
#define IXP425_INT_GPIO_8 25 /* GPIO 8 */
#define IXP425_INT_GPIO_7 24 /* GPIO 7 */
#define IXP425_INT_GPIO_6 23 /* GPIO 6 */
#define IXP425_INT_GPIO_5 22 /* GPIO 5 */
#define IXP425_INT_GPIO_4 21 /* GPIO 4 */
#define IXP425_INT_GPIO_3 20 /* GPIO 3 */
#define IXP425_INT_GPIO_2 19 /* GPIO 2 */
#define IXP425_INT_XSCALE_PMU 18 /* XScale PMU */
#define IXP425_INT_AHB_PMU 17 /* AHB PMU */
#define IXP425_INT_WDOG 16 /* Watchdog Timer */
#define IXP425_INT_UART0 15 /* HighSpeed UART */
#define IXP425_INT_STAMP 14 /* Timestamp Timer */
#define IXP425_INT_UART1 13 /* Console UART */
#define IXP425_INT_USB 12 /* USB */
#define IXP425_INT_TMR1 11 /* General-Purpose Timer1 */
#define IXP425_INT_PCIDMA2 10 /* PCI DMA Channel 2 */
#define IXP425_INT_PCIDMA1 9 /* PCI DMA Channel 1 */
#define IXP425_INT_PCIINT 8 /* PCI Interrupt */
#define IXP425_INT_GPIO_1 7 /* GPIO 1 */
#define IXP425_INT_GPIO_0 6 /* GPIO 0 */
#define IXP425_INT_TMR0 5 /* General-Purpose Timer0 */
#define IXP425_INT_QUE33_64 4 /* Queue Manager 33-64 */
#define IXP425_INT_QUE1_32 3 /* Queue Manager 1-32 */
#define IXP425_INT_NPE_C 2 /* NPE C */
#define IXP425_INT_NPE_B 1 /* NPE B */
#define IXP425_INT_NPE_A 0 /* NPE A */
/*
* software interrupt
*/
#define IXP425_INT_bit31 31
#define IXP425_INT_bit30 30
#define IXP425_INT_bit14 14
#define IXP425_INT_bit11 11
#define IXP425_INT_HWMASK (0xffffffff & \
~((1 << IXP425_INT_bit31) | \
(1 << IXP425_INT_bit30) | \
(1 << IXP425_INT_bit14) | \
(1 << IXP425_INT_bit11)))
#define IXP425_INT_GPIOMASK (0x3ff800c0u)
/*
* GPIO
*/
#define IXP425_GPIO_HWBASE IXP425_IO_HWBASE + IXP425_GPIO_OFFSET
#define IXP425_GPIO_VBASE IXP425_IO_VBASE + IXP425_GPIO_OFFSET
/* 0xf0004000 */
#define IXP425_GPIO_SIZE 0x00000020UL
#define IXP425_GPIO_GPOUTR 0x00
#define IXP425_GPIO_GPOER 0x04
#define IXP425_GPIO_GPINR 0x08
#define IXP425_GPIO_GPISR 0x0c
#define IXP425_GPIO_GPIT1R 0x10
#define IXP425_GPIO_GPIT2R 0x14
#define IXP425_GPIO_GPCLKR 0x18
# define GPCLKR_MUX14 (1U << 8)
# define GPCLKR_CLK0TC_SHIFT 4
# define GPCLKR_CLK0DC_SHIFT 0
/* GPIO Output */
#define GPOUT_ON 0x1
#define GPOUT_OFF 0x0
/* GPIO direction */
#define GPOER_INPUT 0x1
#define GPOER_OUTPUT 0x0
/* GPIO Type bits */
#define GPIO_TYPE_ACT_HIGH 0x0
#define GPIO_TYPE_ACT_LOW 0x1
#define GPIO_TYPE_EDG_RISING 0x2
#define GPIO_TYPE_EDG_FALLING 0x3
#define GPIO_TYPE_TRANSITIONAL 0x4
#define GPIO_TYPE_MASK 0x7
#define GPIO_TYPE(b,v) ((v) << (((b) & 0x7) * 3))
#define GPIO_TYPE_REG(b) (((b)&8)?IXP425_GPIO_GPIT2R:IXP425_GPIO_GPIT1R)
/*
* Expansion Bus Configuration Space.
*/
#define IXP425_EXP_HWBASE 0xc4000000UL
#define IXP425_EXP_VBASE (IXP425_IO_VBASE + IXP425_IO_SIZE)
/* 0xf0010000 */
#define IXP425_EXP_SIZE IXP425_REG_SIZE /* 0x1000 */
/* offset */
#define EXP_TIMING_CS0_OFFSET 0x0000
#define EXP_TIMING_CS1_OFFSET 0x0004
#define EXP_TIMING_CS2_OFFSET 0x0008
#define EXP_TIMING_CS3_OFFSET 0x000c
#define EXP_TIMING_CS4_OFFSET 0x0010
#define EXP_TIMING_CS5_OFFSET 0x0014
#define EXP_TIMING_CS6_OFFSET 0x0018
#define EXP_TIMING_CS7_OFFSET 0x001c
#define EXP_CNFG0_OFFSET 0x0020
#define EXP_CNFG1_OFFSET 0x0024
#define EXP_FCTRL_OFFSET 0x0028
#define IXP425_EXP_RECOVERY_SHIFT 16
#define IXP425_EXP_HOLD_SHIFT 20
#define IXP425_EXP_STROBE_SHIFT 22
#define IXP425_EXP_SETUP_SHIFT 26
#define IXP425_EXP_ADDR_SHIFT 28
#define IXP425_EXP_CS_EN (1U << 31)
#define IXP425_EXP_RECOVERY_T(x) (((x) & 15) << IXP425_EXP_RECOVERY_SHIFT)
#define IXP425_EXP_HOLD_T(x) (((x) & 3) << IXP425_EXP_HOLD_SHIFT)
#define IXP425_EXP_STROBE_T(x) (((x) & 15) << IXP425_EXP_STROBE_SHIFT)
#define IXP425_EXP_SETUP_T(x) (((x) & 3) << IXP425_EXP_SETUP_SHIFT)
#define IXP425_EXP_ADDR_T(x) (((x) & 3) << IXP425_EXP_ADDR_SHIFT)
/* EXP_CSn bits */
#define EXP_BYTE_EN 0x00000001 /* bus uses only 8-bit data */
#define EXP_WR_EN 0x00000002 /* ena writes to CS region */
/* bit 2 is reserved */
#define EXP_SPLT_EN 0x00000008 /* ena AHB split transfers */
#define EXP_MUX_EN 0x00000010 /* multiplexed address/data */
#define EXP_HRDY_POL 0x00000020 /* HPI|HRDY polarity */
#define EXP_BYTE_RD16 0x00000040 /* byte rd access to word dev */
#define EXP_CNFG 0x00003c00 /* device config size */
#define EXP_SZ_512 (0 << 10)
#define EXP_SZ_1K (1 << 10)
#define EXP_SZ_2K (2 << 10)
#define EXP_SZ_4K (3 << 10)
#define EXP_SZ_8K (4 << 10)
#define EXP_SZ_16K (5 << 10)
#define EXP_SZ_32K (6 << 10)
#define EXP_SZ_64K (7 << 10)
#define EXP_SZ_128K (8 << 10)
#define EXP_SZ_256K (9 << 10)
#define EXP_SZ_512K (10 << 10)
#define EXP_SZ_1M (11 << 10)
#define EXP_SZ_2M (12 << 10)
#define EXP_SZ_4M (13 << 10)
#define EXP_SZ_8M (14 << 10)
#define EXP_SZ_16M (15 << 10)
#define EXP_CYC_TYPE 0x0000c000 /* bus cycle "type" */
#define EXP_CYC_INTEL (0 << 14)
#define EXP_CYC_MOTO (1 << 14)
#define EXP_CYC_HPI (2 << 14)
#define EXP_T5 0x000f0000 /* recovery timing */
#define EXP_T4 0x00300000 /* hold timing */
#define EXP_T3 0x03c00000 /* strobe timing */
#define EXP_T2 0x0c000000 /* setup/chip select timing */
#define EXP_T1 0x30000000 /* address timing */
/* bit 30 is reserved */
#define EXP_CS_EN 0x80000000 /* chip select enabled */
/* EXP_CNFG0 bits */
#define EXP_CNFG0_8BIT (1 << 0)
#define EXP_CNFG0_PCI_HOST (1 << 1)
#define EXP_CNFG0_PCI_ARB (1 << 2)
#define EXP_CNFG0_PCI_66MHZ (1 << 4)
#define EXP_CNFG0_MEM_MAP (1 << 31)
/* EXP_CNFG1 bits */
#define EXP_CNFG1_SW_INT0 (1 << 0)
#define EXP_CNFG1_SW_INT1 (1 << 1)
#define EXP_FCTRL_RCOMP (1<<0)
#define EXP_FCTRL_USB (1<<1)
#define EXP_FCTRL_HASH (1<<2)
#define EXP_FCTRL_AES (1<<3)
#define EXP_FCTRL_DES (1<<4)
#define EXP_FCTRL_HDLC (1<<5)
#define EXP_FCTRL_AAL (1<<6)
#define EXP_FCTRL_HSS (1<<7)
#define EXP_FCTRL_UTOPIA (1<<8)
#define EXP_FCTRL_ETH0 (1<<9)
#define EXP_FCTRL_ETH1 (1<<10)
#define EXP_FCTRL_NPEA (1<<11)
#define EXP_FCTRL_NPEB (1<<12)
#define EXP_FCTRL_NPEC (1<<13)
#define EXP_FCTRL_PCI (1<<14)
/* XXX more stuff we don't care about */
/*
* PCI
*/
#define IXP425_PCI_HWBASE 0xc0000000
#define IXP425_PCI_VBASE (IXP425_EXP_VBASE + IXP425_EXP_SIZE)
/* 0xf0011000 */
#define IXP425_PCI_SIZE IXP425_REG_SIZE /* 0x1000 */
/*
* Mapping registers of IXP425 PCI Configuration
*/
/* PCI_ID_REG 0x00 */
/* PCI_COMMAND_STATUS_REG 0x04 */
/* PCI_CLASS_REG 0x08 */
/* PCI_BHLC_REG 0x0c */
#define PCI_MAPREG_BAR0 0x10 /* Base Address 0 */
#define PCI_MAPREG_BAR1 0x14 /* Base Address 1 */
#define PCI_MAPREG_BAR2 0x18 /* Base Address 2 */
#define PCI_MAPREG_BAR3 0x1c /* Base Address 3 */
#define PCI_MAPREG_BAR4 0x20 /* Base Address 4 */
#define PCI_MAPREG_BAR5 0x24 /* Base Address 5 */
/* PCI_SUBSYS_ID_REG 0x2c */
/* PCI_INTERRUPT_REG 0x3c */
#define PCI_RTOTTO 0x40
/* PCI Controller CSR Base Address */
#define IXP425_PCI_CSR_BASE IXP425_PCI_VBASE
/* PCI Memory Space */
#define IXP425_PCI_MEM_HWBASE 0x48000000UL
#define IXP425_PCI_MEM_VBASE 0xf8000000UL
#define IXP425_PCI_MEM_SIZE 0x04000000UL /* 64MB */
/* PCI I/O Space */
#define IXP425_PCI_IO_HWBASE 0x00000000UL
#define IXP425_PCI_IO_SIZE 0x00100000UL /* 1Mbyte */
/* PCI Controller Configuration Offset */
#define PCI_NP_AD 0x00
#define PCI_NP_CBE 0x04
# define NP_CBE_SHIFT 4
#define PCI_NP_WDATA 0x08
#define PCI_NP_RDATA 0x0c
#define PCI_CRP_AD_CBE 0x10
#define PCI_CRP_AD_WDATA 0x14
#define PCI_CRP_AD_RDATA 0x18
#define PCI_CSR 0x1c
# define CSR_PRST (1U << 16)
# define CSR_IC (1U << 15)
# define CSR_ABE (1U << 4)
# define CSR_PDS (1U << 3)
# define CSR_ADS (1U << 2)
# define CSR_HOST (1U << 0)
#define PCI_ISR 0x20
# define ISR_AHBE (1U << 3)
# define ISR_PPE (1U << 2)
# define ISR_PFE (1U << 1)
# define ISR_PSE (1U << 0)
#define PCI_INTEN 0x24
#define PCI_DMACTRL 0x28
#define PCI_AHBMEMBASE 0x2c
#define PCI_AHBIOBASE 0x30
#define PCI_PCIMEMBASE 0x34
#define PCI_AHBDOORBELL 0x38
#define PCI_PCIDOORBELL 0x3c
#define PCI_ATPDMA0_AHBADDR 0x40
#define PCI_ATPDMA0_PCIADDR 0x44
#define PCI_ATPDMA0_LENGTH 0x48
#define PCI_ATPDMA1_AHBADDR 0x4c
#define PCI_ATPDMA1_PCIADDR 0x50
#define PCI_ATPDMA1_LENGTH 0x54
#define PCI_PTADMA0_AHBADDR 0x58
#define PCI_PTADMA0_PCIADDR 0x5c
#define PCI_PTADMA0_LENGTH 0x60
#define PCI_PTADMA1_AHBADDR 0x64
#define PCI_PTADMA1_PCIADDR 0x68
#define PCI_PTADMA1_LENGTH 0x6c
/* PCI target(T)/initiator(I) Interface Commands for PCI_NP_CBE register */
#define COMMAND_NP_IA 0x0 /* Interrupt Acknowledge (I)*/
#define COMMAND_NP_SC 0x1 /* Special Cycle (I)*/
#define COMMAND_NP_IO_READ 0x2 /* I/O Read (T)(I) */
#define COMMAND_NP_IO_WRITE 0x3 /* I/O Write (T)(I) */
#define COMMAND_NP_MEM_READ 0x6 /* Memory Read (T)(I) */
#define COMMAND_NP_MEM_WRITE 0x7 /* Memory Write (T)(I) */
#define COMMAND_NP_CONF_READ 0xa /* Configuration Read (T)(I) */
#define COMMAND_NP_CONF_WRITE 0xb /* Configuration Write (T)(I) */
/* PCI byte enables */
#define BE_8BIT(a) ((0x10u << ((a) & 0x03)) ^ 0xf0)
#define BE_16BIT(a) ((0x30u << ((a) & 0x02)) ^ 0xf0)
#define BE_32BIT(a) 0x00
/* PCI byte selects */
#define READ_8BIT(v,a) ((u_int8_t)((v) >> (((a) & 3) * 8)))
#define READ_16BIT(v,a) ((u_int16_t)((v) >> (((a) & 2) * 8)))
#define WRITE_8BIT(v,a) (((u_int32_t)(v)) << (((a) & 3) * 8))
#define WRITE_16BIT(v,a) (((u_int32_t)(v)) << (((a) & 2) * 8))
/* PCI Controller Configuration Commands for PCI_CRP_AD_CBE */
#define COMMAND_CRP_READ 0x00
#define COMMAND_CRP_WRITE (1U << 16)
/*
* SDRAM Configuration Register
*/
#define IXP425_MCU_HWBASE 0xcc000000UL
#define IXP425_MCU_VBASE 0xf0200000UL
#define IXP425_MCU_SIZE 0x1000 /* Actually only 256 bytes */
#define MCU_SDR_CONFIG 0x00
#define MCU_SDR_CONFIG_MCONF(x) ((x) & 0x7)
#define MCU_SDR_CONFIG_64MBIT (1u << 5)
#define MCU_SDR_REFRESH 0x04
#define MCU_SDR_IR 0x08
/*
* Performance Monitoring Unit (CP14)
*
* CP14.0.1 Performance Monitor Control Register(PMNC)
* CP14.1.1 Clock Counter(CCNT)
* CP14.4.1 Interrupt Enable Register(INTEN)
* CP14.5.1 Overflow Flag Register(FLAG)
* CP14.8.1 Event Selection Register(EVTSEL)
* CP14.0.2 Performance Counter Register 0(PMN0)
* CP14.1.2 Performance Counter Register 0(PMN1)
* CP14.2.2 Performance Counter Register 0(PMN2)
* CP14.3.2 Performance Counter Register 0(PMN3)
*/
#define PMNC_E 0x00000001 /* enable all counters */
#define PMNC_P 0x00000002 /* reset all PMNs to 0 */
#define PMNC_C 0x00000004 /* clock counter reset */
#define PMNC_D 0x00000008 /* clock counter / 64 */
#define INTEN_CC_IE 0x00000001 /* enable clock counter interrupt */
#define INTEN_PMN0_IE 0x00000002 /* enable PMN0 interrupt */
#define INTEN_PMN1_IE 0x00000004 /* enable PMN1 interrupt */
#define INTEN_PMN2_IE 0x00000008 /* enable PMN2 interrupt */
#define INTEN_PMN3_IE 0x00000010 /* enable PMN3 interrupt */
#define FLAG_CC_IF 0x00000001 /* clock counter overflow */
#define FLAG_PMN0_IF 0x00000002 /* PMN0 overflow */
#define FLAG_PMN1_IF 0x00000004 /* PMN1 overflow */
#define FLAG_PMN2_IF 0x00000008 /* PMN2 overflow */
#define FLAG_PMN3_IF 0x00000010 /* PMN3 overflow */
#define EVTSEL_EVCNT_MASK 0x0000000ff /* event to count for PMNs */
#define PMNC_EVCNT0_SHIFT 0
#define PMNC_EVCNT1_SHIFT 8
#define PMNC_EVCNT2_SHIFT 16
#define PMNC_EVCNT3_SHIFT 24
/*
* Queue Manager
*/
#define IXP425_QMGR_HWBASE 0x60000000UL
#define IXP425_QMGR_VBASE (IXP425_PCI_VBASE + IXP425_PCI_SIZE)
#define IXP425_QMGR_SIZE 0x4000
/*
* Network Processing Engines (NPE's) and associated Ethernet MAC's.
*/
#define IXP425_NPE_A_HWBASE (IXP425_IO_HWBASE + IXP425_NPE_A_OFFSET)
#define IXP425_NPE_A_VBASE (IXP425_IO_VBASE + IXP425_NPE_A_OFFSET)
#define IXP425_NPE_A_SIZE 0x1000 /* Actually only 256 bytes */
#define IXP425_NPE_B_HWBASE (IXP425_IO_HWBASE + IXP425_NPE_B_OFFSET)
#define IXP425_NPE_B_VBASE (IXP425_IO_VBASE + IXP425_NPE_B_OFFSET)
#define IXP425_NPE_B_SIZE 0x1000 /* Actually only 256 bytes */
#define IXP425_NPE_C_HWBASE (IXP425_IO_HWBASE + IXP425_NPE_C_OFFSET)
#define IXP425_NPE_C_VBASE (IXP425_IO_VBASE + IXP425_NPE_C_OFFSET)
#define IXP425_NPE_C_SIZE 0x1000 /* Actually only 256 bytes */
#define IXP425_MAC_A_HWBASE (IXP425_IO_HWBASE + IXP425_MAC_A_OFFSET)
#define IXP425_MAC_A_VBASE (IXP425_IO_VBASE + IXP425_MAC_A_OFFSET)
#define IXP425_MAC_A_SIZE 0x1000 /* Actually only 256 bytes */
#define IXP425_MAC_B_HWBASE (IXP425_IO_HWBASE + IXP425_MAC_B_OFFSET)
#define IXP425_MAC_B_VBASE (IXP425_IO_VBASE + IXP425_MAC_B_OFFSET)
#define IXP425_MAC_B_SIZE 0x1000 /* Actually only 256 bytes */
/*
* Expansion Bus Data Space.
*/
#define IXP425_EXP_BUS_HWBASE 0x50000000UL
#define IXP425_EXP_BUS_SIZE 0x01000000 /* max, typically smaller */
#define IXP425_EXP_BUS_CSx_HWBASE(i) \
(IXP425_EXP_BUS_HWBASE + (i)*IXP425_EXP_BUS_SIZE)
#define IXP425_EXP_BUS_CS1_HWBASE IXP425_EXP_BUS_CSx_HWBASE(1)
#define IXP425_EXP_BUS_CS1_VBASE (IXP425_MAC_B_VBASE + IXP425_MAC_B_SIZE)
#define IXP425_EXP_BUS_CS1_SIZE 0x1000
/* NB: not mapped (yet) */
#define IXP425_EXP_BUS_CS0_HWBASE IXP425_EXP_BUS_CSx_HWBASE(0)
#define IXP425_EXP_BUS_CS2_HWBASE IXP425_EXP_BUS_CSx_HWBASE(2)
#define IXP425_EXP_BUS_CS3_HWBASE IXP425_EXP_BUS_CSx_HWBASE(3)
#define IXP425_EXP_BUS_CS4_HWBASE IXP425_EXP_BUS_CSx_HWBASE(4)
#define IXP425_EXP_BUS_CS5_HWBASE IXP425_EXP_BUS_CSx_HWBASE(5)
#define IXP425_EXP_BUS_CS6_HWBASE IXP425_EXP_BUS_CSx_HWBASE(6)
#define IXP425_EXP_BUS_CS7_HWBASE IXP425_EXP_BUS_CSx_HWBASE(7)
#endif /* _IXP425REG_H_ */

View File

@ -0,0 +1,99 @@
/* $NetBSD: ixp425var.h,v 1.10 2006/04/10 03:36:03 simonb Exp $ */
/*
* Copyright (c) 2003
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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 Ichiro FUKUHARA.
* 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 ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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.
*
* $FreeBSD$
*
*/
#ifndef _IXP425VAR_H_
#define _IXP425VAR_H_
#include <sys/conf.h>
#include <sys/queue.h>
#include <machine/bus.h>
#include <dev/pci/pcivar.h>
#include <sys/rman.h>
struct ixp425_softc {
device_t sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_gpio_ioh;
bus_space_handle_t sc_exp_ioh;
u_int32_t sc_intrmask;
struct rman sc_irq_rman;
struct rman sc_mem_rman;
};
struct ixppcib_softc {
device_t sc_dev;
u_int sc_bus;
struct resource *sc_csr;
struct resource *sc_mem;
struct rman sc_io_rman;
struct rman sc_mem_rman;
struct rman sc_irq_rman;
struct bus_space sc_pci_memt;
struct bus_space sc_pci_iot;
};
#define EXP_BUS_WRITE_4(sc, reg, data) \
bus_space_write_4(sc->sc_iot, sc->sc_exp_ioh, reg, data)
#define EXP_BUS_READ_4(sc, reg) \
bus_space_read_4(sc->sc_iot, sc->sc_exp_ioh, reg)
#define GPIO_CONF_WRITE_4(sc, reg, data) \
bus_space_write_4(sc->sc_iot, sc->sc_gpio_ioh, reg, data)
#define GPIO_CONF_READ_4(sc, reg) \
bus_space_read_4(sc->sc_iot, sc->sc_gpio_ioh, reg)
extern struct bus_space ixp425_bs_tag;
extern struct bus_space ixp425_a4x_bs_tag;
void ixp425_io_bs_init(bus_space_tag_t, void *);
void ixp425_mem_bs_init(bus_space_tag_t, void *);
uint32_t ixp425_sdram_size(void);
int ixp425_md_route_interrupt(device_t, device_t, int);
void ixp425_md_attach(device_t);
#endif /* _IXP425VAR_H_ */

View File

@ -0,0 +1,6 @@
#GW2348-4 board configuration
#$FreeBSD$
include "../xscale/ixp425/std.ixp425"
files "../xscale/ixp425/files.avila"
makeoptions KERNPHYSADDR=0x10200000
makeoptions KERNVIRTADDR=0xc0200000

View File

@ -0,0 +1,6 @@
#XScale IXP425 generic configuration
#$FreeBSD$
files "../xscale/ixp425/files.ixp425"
include "../xscale/std.xscale"
cpu CPU_XSCALE_IXP425
makeoption ARM_BIG_ENDIAN

View File

@ -0,0 +1,91 @@
/*-
* Copyright (c) 2006 Kevin Lo. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <dev/pci/pcivar.h>
#include <dev/ic/ns16550.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h>
#include "uart_if.h"
static int uart_ixp425_probe(device_t dev);
static device_method_t uart_ixp425_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, uart_ixp425_probe),
DEVMETHOD(device_attach, uart_bus_attach),
DEVMETHOD(device_detach, uart_bus_detach),
{ 0, 0 }
};
static driver_t uart_ixp425_driver = {
uart_driver_name,
uart_ixp425_methods,
sizeof(struct uart_softc),
};
extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
static int
uart_ixp425_probe(device_t dev)
{
struct uart_softc *sc;
sc = device_get_softc(dev);
sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs);
sc->sc_class = &uart_ns8250_class;
bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
/*
* XXX set UART Unit Enable (0x40) AND
* receiver timeout int enable (0x10).
* The first turns on the UART. The second is necessary to get
* interrupts when the FIFO has data but is not full. Note that
* uart_ns8250 carefully avoids touching these bits so we can
* just set them here and proceed. But this is fragile...
*/
bus_space_write_4(&ixp425_a4x_bs_tag,
device_get_unit(dev) == 0 ? IXP425_UART0_VBASE : IXP425_UART1_VBASE,
IXP425_UART_IER, IXP425_UART_IER_UUE | IXP425_UART_IER_RTOIE);
return(uart_bus_probe(dev, 0, IXP425_UART_FREQ, 0, 0));
}
DRIVER_MODULE(uart, ixp, uart_ixp425_driver, uart_devclass, 0, 0);

View File

@ -0,0 +1,67 @@
/*-
* Copyright (c) 2003 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/cons.h>
#include <machine/bus.h>
#include <dev/uart/uart.h>
#include <dev/uart/uart_cpu.h>
#include <arm/xscale/ixp425/ixp425reg.h>
#include <arm/xscale/ixp425/ixp425var.h>
bus_space_tag_t uart_bus_space_io;
bus_space_tag_t uart_bus_space_mem;
int
uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
{
return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0);
}
int
uart_cpu_getdev(int devtype, struct uart_devinfo *di)
{
di->ops = uart_ns8250_ops;
di->bas.chan = 0;
di->bas.bst = &ixp425_a4x_bs_tag;
di->bas.regshft = 0;
di->bas.rclk = IXP425_UART_FREQ;
di->baudrate = 115200;
di->databits = 8;
di->stopbits = 1;
di->parity = UART_PARITY_NONE;
uart_bus_space_io = &ixp425_a4x_bs_tag;
uart_bus_space_mem = NULL;
di->bas.bsh = IXP425_UART0_VBASE;
return (0);
}