Support for ADI Engineering's Big Endian Companion Chip for the

Intel i80200 XScale processor.  Despite its name, the BECC can
run in both big- and little-endian modes.
This commit is contained in:
thorpej 2003-01-25 01:57:17 +00:00
parent 15b88bc43f
commit b1b164a859
11 changed files with 2361 additions and 1 deletions

297
sys/arch/arm/xscale/becc.c Normal file
View File

@ -0,0 +1,297 @@
/* $NetBSD: becc.c,v 1.1 2003/01/25 01:57:17 thorpej Exp $ */
/*
* Copyright (c) 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.
*/
/*
* Autoconfiguration support for the ADI Engineering Big Endian
* Companion Chip.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <arm/xscale/i80200reg.h>
#include <arm/xscale/beccreg.h>
#include <arm/xscale/beccvar.h>
/*
* Virtual address at which the BECC is mapped. This is filled in
* by machine-dependent code.
*/
vaddr_t becc_vaddr;
/*
* BECC revision number. This is initialized by early bootstrap code.
*/
int becc_rev;
const char *becc_revisions[] = {
"<= 7",
"8",
">= 9",
};
/*
* There can be only one BECC, so we keep a global pointer to
* the softc, so board-specific code can use features of the
* BECC without having to have a handle on the softc itself.
*/
struct becc_softc *becc_softc;
static int becc_pcibus_print(void *, const char *);
static void becc_pci_dma_init(struct becc_softc *);
/*
* becc_attach:
*
* Board-independent attach routine for the BECC.
*/
void
becc_attach(struct becc_softc *sc)
{
struct pcibus_attach_args pba;
uint32_t reg;
becc_softc = sc;
/*
* Set the AF bit in the BCUMOD since the BECC will honor it.
* This allows the BECC to return the requested 4-byte word
* first when filling a cache line.
*/
__asm __volatile("mrc p13, 0, %0, c1, c1, 0" : "=r" (reg) );
__asm __volatile("mcr p13, 0, %0, c1, c1, 0" : : "r" (reg | BCUMOD_AF));
/*
* Program the address windows of the PCI core. Note
* that PCI master and target cycles must be disabled
* while we configure the windows.
*/
reg = becc_pcicore_read(sc, PCI_COMMAND_STATUS_REG);
reg &= ~(PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_MASTER_ENABLE);
becc_pcicore_write(sc, PCI_COMMAND_STATUS_REG, reg);
/*
* Program the two inbound PCI memory windows.
*/
becc_pcicore_write(sc, PCI_MAPREG_START + 0,
sc->sc_iwin[0].iwin_base | PCI_MAPREG_MEM_TYPE_32BIT |
PCI_MAPREG_MEM_PREFETCHABLE_MASK);
reg = becc_pcicore_read(sc, PCI_MAPREG_START + 0);
BECC_CSR_WRITE(BECC_PSTR0, sc->sc_iwin[0].iwin_xlate & PSTRx_ADDRMASK);
becc_pcicore_write(sc, PCI_MAPREG_START + 4,
sc->sc_iwin[1].iwin_base | PCI_MAPREG_MEM_TYPE_32BIT |
PCI_MAPREG_MEM_PREFETCHABLE_MASK);
reg = becc_pcicore_read(sc, PCI_MAPREG_START + 4);
BECC_CSR_WRITE(BECC_PSTR1, sc->sc_iwin[1].iwin_xlate & PSTRx_ADDRMASK);
/*
* ...and the third on v8 and later.
*/
if (becc_rev >= BECC_REV_V8) {
becc_pcicore_write(sc, PCI_MAPREG_START + 8,
sc->sc_iwin[2].iwin_base | PCI_MAPREG_MEM_TYPE_32BIT |
PCI_MAPREG_MEM_PREFETCHABLE_MASK);
reg = becc_pcicore_read(sc, PCI_MAPREG_START + 8);
BECC_CSR_WRITE(BECC_PSTR1,
sc->sc_iwin[2].iwin_xlate & PSTR2_ADDRMASK);
}
/*
* Program the two outbound PCI memory windows. On a
* big-endian system, we byte-swap the first window.
* The second window is used for STREAM transfers.
*
* There's a third window on v9 and later, but we don't
* use it for anything; program it anyway, just to be
* safe.
*/
#ifdef __ARMEB__
BECC_CSR_WRITE(BECC_POMR1, sc->sc_owin_xlate[0] /* | POMRx_F32 */ |
POMRx_BEE);
#else
BECC_CSR_WRITE(BECC_POMR1, sc->sc_owin_xlate[0] /* | POMRx_F32 */);
#endif
BECC_CSR_WRITE(BECC_POMR2, sc->sc_owin_xlate[1] /* | POMRx_F32 */);
if (becc_rev >= BECC_REV_V9)
BECC_CSR_WRITE(BECC_POMR3,
sc->sc_owin_xlate[2] /* | POMRx_F32 */);
/*
* Program the PCI I/O window. On a big-endian system,
* we do byte-swapping.
*
* XXX What about STREAM transfers?
*/
#ifdef __ARMEB__
BECC_CSR_WRITE(BECC_POIR, sc->sc_ioout_xlate | POIR_BEE);
#else
BECC_CSR_WRITE(BECC_POIR, sc->sc_ioout_xlate);
#endif
/*
* Configure PCI configuration cycle access.
*/
BECC_CSR_WRITE(BECC_POCR, 0);
/*
* ...and now reenable PCI access.
*/
reg = becc_pcicore_read(sc, PCI_COMMAND_STATUS_REG);
reg |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE |
PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE;
becc_pcicore_write(sc, PCI_COMMAND_STATUS_REG, reg);
/* Initialize the bus space tags. */
becc_io_bs_init(&sc->sc_pci_iot, sc);
becc_mem_bs_init(&sc->sc_pci_memt, sc);
/* Initialize the PCI chipset tag. */
becc_pci_init(&sc->sc_pci_chipset, sc);
/* Initialize the DMA tags. */
becc_pci_dma_init(sc);
/*
* Attach the PCI bus.
*/
pba.pba_busname = "pci";
pba.pba_iot = &sc->sc_pci_iot;
pba.pba_memt = &sc->sc_pci_memt;
pba.pba_dmat = &sc->sc_pci_dmat;
pba.pba_pc = &sc->sc_pci_chipset;
pba.pba_bus = 0;
pba.pba_bridgetag = NULL;
pba.pba_intrswiz = 0;
pba.pba_intrtag = 0;
pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED |
PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;
(void) config_found(&sc->sc_dev, &pba, becc_pcibus_print);
}
/*
* becc_pcibus_print:
*
* Autoconfiguration cfprint routine when attaching
* to the "pcibus" attribute.
*/
static int
becc_pcibus_print(void *aux, const char *pnp)
{
struct pcibus_attach_args *pba = aux;
if (pnp)
printf("%s at %s", pba->pba_busname, pnp);
printf(" bus %d", pba->pba_bus);
return (UNCONF);
}
/*
* becc_pci_dma_init:
*
* Initialize the PCI DMA tag.
*/
static void
becc_pci_dma_init(struct becc_softc *sc)
{
bus_dma_tag_t dmat = &sc->sc_pci_dmat;
struct arm32_dma_range *dr = sc->sc_pci_dma_range;
int i = 0;
/*
* If we have the 128MB window, put it first, since it
* will always cover the entire memory range.
*/
if (becc_rev >= BECC_REV_V8) {
dr[i].dr_sysbase = sc->sc_iwin[2].iwin_xlate;
dr[i].dr_busbase = sc->sc_iwin[2].iwin_base;
dr[i].dr_len = (128U * 1024 * 1024);
i++;
}
dr[i].dr_sysbase = sc->sc_iwin[0].iwin_xlate;
dr[i].dr_busbase = sc->sc_iwin[0].iwin_base;
dr[i].dr_len = (32U * 1024 * 1024);
i++;
dr[i].dr_sysbase = sc->sc_iwin[1].iwin_xlate;
dr[i].dr_busbase = sc->sc_iwin[1].iwin_base;
dr[i].dr_len = (32U * 1024 * 1024);
i++;
dmat->_ranges = dr;
dmat->_nranges = i;
dmat->_dmamap_create = _bus_dmamap_create;
dmat->_dmamap_destroy = _bus_dmamap_destroy;
dmat->_dmamap_load = _bus_dmamap_load;
dmat->_dmamap_load_mbuf = _bus_dmamap_load_mbuf;
dmat->_dmamap_load_uio = _bus_dmamap_load_uio;
dmat->_dmamap_load_raw = _bus_dmamap_load_raw;
dmat->_dmamap_unload = _bus_dmamap_unload;
dmat->_dmamap_sync_pre = _bus_dmamap_sync;
dmat->_dmamap_sync_post = NULL;
dmat->_dmamem_alloc = _bus_dmamem_alloc;
dmat->_dmamem_free = _bus_dmamem_free;
dmat->_dmamem_map = _bus_dmamem_map;
dmat->_dmamem_unmap = _bus_dmamem_unmap;
dmat->_dmamem_mmap = _bus_dmamem_mmap;
}
uint32_t
becc_pcicore_read(struct becc_softc *sc, bus_addr_t reg)
{
vaddr_t va = sc->sc_pci_cfg_base | (1U << BECC_IDSEL_BIT) | reg;
return (*(__volatile uint32_t *) va);
}
void
becc_pcicore_write(struct becc_softc *sc, bus_addr_t reg, uint32_t val)
{
vaddr_t va = sc->sc_pci_cfg_base | (1U << BECC_IDSEL_BIT) | reg;
*(__volatile uint32_t *) va = val;
}

View File

@ -0,0 +1,55 @@
/* $NetBSD: becc_csrvar.h,v 1.1 2003/01/25 01:57:18 thorpej Exp $ */
/*
* Copyright (c) 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.
*/
#ifndef _BECC_CSRVAR_H_
#define _BECC_CSRVAR_H_
/*
* Machine-dependent code maps the BECC quite early, and plops the
* virtual address of the BECC in this variable.
*/
extern vaddr_t becc_vaddr;
/*
* Macros to read/write the BECC registers.
*/
#define BECC_CSR_READ(x) *(__volatile uint32_t *)(becc_vaddr + (x))
#define BECC_CSR_WRITE(x, v) *(__volatile uint32_t *)(becc_vaddr + (x)) = (v)
extern const char *becc_irqnames[];
#endif /* _BECC_CSRVAR_H_ */

View File

@ -0,0 +1,508 @@
/* $NetBSD: becc_icu.c,v 1.1 2003/01/25 01:57:18 thorpej Exp $ */
/*
* Copyright (c) 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.
*/
/*
* Interrupt support for the ADI Engineering Big Endian Companion Chip.
*/
#ifndef EVBARM_SPL_NOINLINE
#define EVBARM_SPL_NOINLINE
#endif
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <uvm/uvm_extern.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <arm/cpufunc.h>
#include <arm/xscale/beccreg.h>
#include <arm/xscale/beccvar.h>
#include <arm/xscale/i80200reg.h>
#include <arm/xscale/i80200var.h>
/* Interrupt handler queues. */
struct intrq intrq[NIRQ];
/* Interrupts to mask at each level. */
uint32_t becc_imask[NIPL];
/* Current interrupt priority level. */
__volatile uint32_t current_spl_level;
/* Interrupts pending. */
__volatile uint32_t becc_ipending;
__volatile uint32_t becc_sipending;
/* Software copy of the IRQs we have enabled. */
__volatile uint32_t intr_enabled;
/* Mask if interrupts steered to FIQs. */
uint32_t intr_steer;
/*
* Interrupt bit names.
* XXX Some of these are BRH-centric.
*/
const char *becc_irqnames[] = {
"soft",
"timer A",
"timer B",
"irq 3",
"irq 4",
"irq 5",
"irq 6",
"diagerr",
"DMA EOT",
"DMA PERR",
"DMA TABT",
"DMA MABT",
"irq 12",
"irq 13",
"irq 14",
"irq 15",
"PCI PERR",
"irq 17",
"irq 18",
"PCI SERR",
"PCI OAPE",
"PCI OATA",
"PCI OAMA",
"irq 23",
"irq 24",
"irq 25",
"irq 26", /* PCI INTA */
"irq 27", /* PCI INTB */
"irq 28", /* PCI INTC */
"irq 29", /* PCI INTD */
"pushbutton",
"irq 31",
};
void becc_intr_dispatch(struct clockframe *frame);
static __inline uint32_t
becc_icsr_read(void)
{
uint32_t icsr;
icsr = BECC_CSR_READ(BECC_ICSR);
/*
* The ICSR register shows bits that are active even if they are
* masked in ICMR, so we have to mask them off with the interrupts
* we consider enabled.
*/
return (icsr & intr_enabled);
}
static __inline void
becc_set_intrsteer(void)
{
BECC_CSR_WRITE(BECC_ICSTR, intr_steer & ICU_VALID_MASK);
(void) BECC_CSR_READ(BECC_ICSTR);
}
static __inline void
becc_enable_irq(int irq)
{
intr_enabled |= (1U << irq);
becc_set_intrmask();
}
static __inline void
becc_disable_irq(int irq)
{
intr_enabled &= ~(1U << irq);
becc_set_intrmask();
}
/*
* NOTE: This routine must be called with interrupts disabled in the CPSR.
*/
static void
becc_intr_calculate_masks(void)
{
struct intrq *iq;
struct intrhand *ih;
int irq, ipl;
/* First, figure out which IPLs each IRQ has. */
for (irq = 0; irq < NIRQ; irq++) {
int levels = 0;
iq = &intrq[irq];
becc_disable_irq(irq);
for (ih = TAILQ_FIRST(&iq->iq_list); ih != NULL;
ih = TAILQ_NEXT(ih, ih_list))
levels |= (1U << ih->ih_ipl);
iq->iq_levels = levels;
}
/* Next, figure out which IRQs are used by each IPL. */
for (ipl = 0; ipl < NIPL; ipl++) {
int irqs = 0;
for (irq = 0; irq < NIRQ; irq++) {
if (intrq[irq].iq_levels & (1U << ipl))
irqs |= (1U << irq);
}
becc_imask[ipl] = irqs;
}
becc_imask[IPL_NONE] = 0;
/*
* Initialize the soft interrupt masks to block themselves.
* Note they all come in at the same physical IRQ.
*/
becc_imask[IPL_SOFT] = (1U << ICU_SOFT);
becc_imask[IPL_SOFTCLOCK] = (1U << ICU_SOFT);
becc_imask[IPL_SOFTNET] = (1U << ICU_SOFT);
becc_imask[IPL_SOFTSERIAL] = (1U << ICU_SOFT);
/*
* splsoftclock() is the only interface that users of the
* generic software interrupt facility have to block their
* soft intrs, so splsoftclock() must also block IPL_SOFT.
*/
becc_imask[IPL_SOFTCLOCK] |= becc_imask[IPL_SOFT];
/*
* splsoftnet() must also block splsoftclock(), since we don't
* want timer-driven network events to occur while we're
* processing incoming packets.
*/
becc_imask[IPL_SOFTNET] |= becc_imask[IPL_SOFTCLOCK];
/*
* Enforce a heirarchy that gives "slow" device (or devices with
* limited input buffer space/"real-time" requirements) a better
* chance at not dropping data.
*/
becc_imask[IPL_BIO] |= becc_imask[IPL_SOFTNET];
becc_imask[IPL_NET] |= becc_imask[IPL_BIO];
becc_imask[IPL_SOFTSERIAL] |= becc_imask[IPL_NET];
becc_imask[IPL_TTY] |= becc_imask[IPL_SOFTSERIAL];
/*
* splvm() blocks all interrupts that use the kernel memory
* allocation facilities.
*/
becc_imask[IPL_IMP] |= becc_imask[IPL_TTY];
/*
* Audio devices are not allowed to perform memory allocation
* in their interrupt routines, and they have fairly "real-time"
* requirements, so give them a high interrupt priority.
*/
becc_imask[IPL_AUDIO] |= becc_imask[IPL_IMP];
/*
* splclock() must block anything that uses the scheduler.
*/
becc_imask[IPL_CLOCK] |= becc_imask[IPL_AUDIO];
/*
* No separate statclock on the IQ80310.
*/
becc_imask[IPL_STATCLOCK] |= becc_imask[IPL_CLOCK];
/*
* splhigh() must block "everything".
*/
becc_imask[IPL_HIGH] |= becc_imask[IPL_STATCLOCK];
/*
* XXX We need serial drivers to run at the absolute highest priority
* in order to avoid overruns, so serial > high.
*/
becc_imask[IPL_SERIAL] |= becc_imask[IPL_HIGH];
/*
* Now compute which IRQs must be blocked when servicing any
* given IRQ.
*/
for (irq = 0; irq < NIRQ; irq++) {
int irqs = (1U << irq);
iq = &intrq[irq];
if (TAILQ_FIRST(&iq->iq_list) != NULL)
becc_enable_irq(irq);
for (ih = TAILQ_FIRST(&iq->iq_list); ih != NULL;
ih = TAILQ_NEXT(ih, ih_list))
irqs |= becc_imask[ih->ih_ipl];
iq->iq_mask = irqs;
}
}
void
splx(int new)
{
becc_splx(new);
}
int
_spllower(int ipl)
{
return (becc_spllower(ipl));
}
int
_splraise(int ipl)
{
return (becc_splraise(ipl));
}
void
_setsoftintr(int si)
{
becc_setsoftintr(si);
}
static const int si_to_ipl[SI_NQUEUES] = {
IPL_SOFT, /* SI_SOFT */
IPL_SOFTCLOCK, /* SI_SOFTCLOCK */
IPL_SOFTNET, /* SI_SOFTNET */
IPL_SOFTSERIAL, /* SI_SOFTSERIAL */
};
int
becc_softint(void *arg)
{
static __cpu_simple_lock_t processing = __SIMPLELOCK_UNLOCKED;
uint32_t new, oldirqstate;
/* Clear interrupt */
BECC_CSR_WRITE(BECC_ICSR, 0);
if (__cpu_simple_lock_try(&processing) == 0)
return 0;
oldirqstate = disable_interrupts(I32_bit);
new = current_spl_level;
#define DO_SOFTINT(si) \
if (becc_sipending & (1 << (si))) { \
becc_sipending &= ~(1 << (si)); \
current_spl_level |= becc_imask[si_to_ipl[(si)]]; \
restore_interrupts(oldirqstate); \
softintr_dispatch(si); \
oldirqstate = disable_interrupts(I32_bit); \
current_spl_level = new; \
}
DO_SOFTINT(SI_SOFTSERIAL);
DO_SOFTINT(SI_SOFTNET);
DO_SOFTINT(SI_SOFTCLOCK);
DO_SOFTINT(SI_SOFT);
__cpu_simple_unlock(&processing);
restore_interrupts(oldirqstate);
return 1;
}
/*
* becc_icu_init:
*
* Initialize the BECC ICU. Called early in bootstrap
* to make sure the ICU is in a pristine state.
*/
void
becc_icu_init(void)
{
intr_enabled = 0; /* All interrupts disabled */
becc_set_intrmask();
intr_steer = 0; /* All interrupts steered to IRQ */
becc_set_intrsteer();
i80200_extirq_dispatch = becc_intr_dispatch;
i80200_intr_enable(INTCTL_IM);
}
/*
* becc_intr_init:
*
* Initialize the rest of the interrupt subsystem, making it
* ready to handle interrupts from devices.
*/
void
becc_intr_init(void)
{
struct intrq *iq;
int i;
intr_enabled = 0;
for (i = 0; i < NIRQ; i++) {
iq = &intrq[i];
TAILQ_INIT(&iq->iq_list);
evcnt_attach_dynamic(&iq->iq_ev, EVCNT_TYPE_INTR,
NULL, "becc", becc_irqnames[i]);
}
becc_intr_calculate_masks();
/* Enable IRQs (don't yet use FIQs). */
enable_interrupts(I32_bit);
}
void *
becc_intr_establish(int irq, int ipl, int (*func)(void *), void *arg)
{
struct intrq *iq;
struct intrhand *ih;
uint32_t oldirqstate;
if (irq < 0 || irq > NIRQ)
panic("becc_intr_establish: IRQ %d out of range", irq);
ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT);
if (ih == NULL)
return (NULL);
ih->ih_func = func;
ih->ih_arg = arg;
ih->ih_ipl = ipl;
ih->ih_irq = irq;
iq = &intrq[irq];
/* All BECC interrupts are level-triggered. */
iq->iq_ist = IST_LEVEL;
oldirqstate = disable_interrupts(I32_bit);
TAILQ_INSERT_TAIL(&iq->iq_list, ih, ih_list);
becc_intr_calculate_masks();
restore_interrupts(oldirqstate);
return (ih);
}
void
becc_intr_disestablish(void *cookie)
{
struct intrhand *ih = cookie;
struct intrq *iq = &intrq[ih->ih_irq];
uint32_t oldirqstate;
oldirqstate = disable_interrupts(I32_bit);
TAILQ_REMOVE(&iq->iq_list, ih, ih_list);
becc_intr_calculate_masks();
restore_interrupts(oldirqstate);
}
void
becc_intr_dispatch(struct clockframe *frame)
{
struct intrq *iq;
struct intrhand *ih;
uint32_t oldirqstate, pcpl, irq, ibit, hwpend;
pcpl = current_spl_level;
hwpend = becc_icsr_read();
/*
* Disable all the interrupts that are pending. We will
* reenable them once they are processed and not masked.
*/
intr_enabled &= ~hwpend;
becc_set_intrmask();
while (hwpend != 0) {
irq = ffs(hwpend) - 1;
ibit = (1U << irq);
hwpend &= ~ibit;
if (pcpl & ibit) {
/*
* IRQ is masked; mark it as pending and check
* the next one. Note: the IRQ is already disabled.
*/
becc_ipending |= ibit;
continue;
}
becc_ipending &= ~ibit;
iq = &intrq[irq];
iq->iq_ev.ev_count++;
uvmexp.intrs++;
current_spl_level |= iq->iq_mask;
oldirqstate = enable_interrupts(I32_bit);
for (ih = TAILQ_FIRST(&iq->iq_list); ih != NULL;
ih = TAILQ_NEXT(ih, ih_list)) {
(void) (*ih->ih_func)(ih->ih_arg ? ih->ih_arg : frame);
}
restore_interrupts(oldirqstate);
current_spl_level = pcpl;
/* Re-enable this interrupt now that's it's cleared. */
intr_enabled |= ibit;
becc_set_intrmask();
}
if (becc_ipending & ~pcpl) {
intr_enabled |= (becc_ipending & ~pcpl);
becc_set_intrmask();
}
}

View File

@ -0,0 +1,136 @@
/* $NetBSD: becc_intr.h,v 1.1 2003/01/25 01:57:18 thorpej Exp $ */
/*
* Copyright (c) 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.
*/
#ifndef _BECC_INTR_H_
#define _BECC_INTR_H_
#include <arm/armreg.h>
#include <arm/cpufunc.h>
#include <arm/xscale/beccreg.h>
#include <arm/xscale/becc_csrvar.h>
static __inline void __attribute__((__unused__))
becc_set_intrmask(void)
{
extern __volatile uint32_t intr_enabled;
/*
* The bits in the ICMR indicate which interrupts are masked
* (disabled), so we must invert our intr_enabled mask.
*/
BECC_CSR_WRITE(BECC_ICMR, ~intr_enabled & ICU_VALID_MASK);
(void) BECC_CSR_READ(BECC_ICMR);
}
static __inline int __attribute__((__unused__))
becc_splraise(int ipl)
{
extern __volatile uint32_t current_spl_level;
extern uint32_t becc_imask[];
uint32_t old;
old = current_spl_level;
current_spl_level |= becc_imask[ipl];
return (old);
}
static __inline void __attribute__((__unused__))
becc_splx(int new)
{
extern __volatile uint32_t intr_enabled, becc_ipending;
extern __volatile uint32_t current_spl_level;
uint32_t oldirqstate, hwpend;
current_spl_level = new;
/*
* If there are pending HW interrupts which are being
* unmasked, then enable them in the ICMR register.
* This will cause them to come flooding in. This
* includes soft interrupts.
*/
hwpend = becc_ipending & ~new;
if (hwpend != 0) {
oldirqstate = disable_interrupts(I32_bit);
intr_enabled |= hwpend;
becc_set_intrmask();
restore_interrupts(oldirqstate);
}
}
static __inline int __attribute__((__unused__))
becc_spllower(int ipl)
{
extern __volatile uint32_t current_spl_level;
extern uint32_t becc_imask[];
uint32_t old = current_spl_level;
becc_splx(becc_imask[ipl]);
return (old);
}
static __inline void __attribute__((__unused__))
becc_setsoftintr(int si)
{
extern __volatile uint32_t becc_sipending;
becc_sipending |= (1 << si);
BECC_CSR_WRITE(BECC_ICSR, (1U << ICU_SOFT));
}
int becc_softint(void *arg);
#if !defined(EVBARM_SPL_NOINLINE)
#define _splraise(ipl) becc_splraise(ipl)
#define splx(new) becc_splx(new)
#define _spllower(ipl) becc_spllower(ipl)
#define _setsoftintr(si) becc_setsoftintr(si)
#else
int _splraise(int);
void splx(int);
int _spllower(int);
void _setsoftintr(int);
#endif /* ! EVBARM_SPL_NOINLINE */
#endif /* _BECC_INTR_H_ */

View File

@ -0,0 +1,383 @@
/* $NetBSD: becc_pci.c,v 1.1 2003/01/25 01:57:19 thorpej 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.
*/
/*
* PCI configuration support for the ADI Engineering Big Endian Companion
* Chip.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/extent.h>
#include <sys/malloc.h>
#include <uvm/uvm_extern.h>
#include <machine/bus.h>
#include <arm/xscale/beccreg.h>
#include <arm/xscale/beccvar.h>
#include <dev/pci/ppbreg.h>
#include <dev/pci/pciconf.h>
#include "opt_pci.h"
#include "pci.h"
void becc_pci_attach_hook(struct device *, struct device *,
struct pcibus_attach_args *);
int becc_pci_bus_maxdevs(void *, int);
pcitag_t becc_pci_make_tag(void *, int, int, int);
void becc_pci_decompose_tag(void *, pcitag_t, int *, int *,
int *);
pcireg_t becc_pci_conf_read(void *, pcitag_t, int);
void becc_pci_conf_write(void *, pcitag_t, int, pcireg_t);
int becc_pci_intr_map(struct pci_attach_args *,
pci_intr_handle_t *);
const char *becc_pci_intr_string(void *, pci_intr_handle_t);
const struct evcnt *becc_pci_intr_evcnt(void *, pci_intr_handle_t);
void *becc_pci_intr_establish(void *, pci_intr_handle_t,
int, int (*)(void *), void *);
void becc_pci_intr_disestablish(void *, void *);
#define PCI_CONF_LOCK(s) (s) = disable_interrupts(I32_bit)
#define PCI_CONF_UNLOCK(s) restore_interrupts((s))
#if 0
#define DPRINTF(x) printf(x)
#else
#define DPRINTF(x)
#endif
void
becc_pci_init(pci_chipset_tag_t pc, void *cookie)
{
#if NPCI > 0 && defined(PCI_NETBSD_CONFIGURE)
struct becc_softc *sc = cookie;
struct extent *ioext, *memext;
#endif
pc->pc_conf_v = cookie;
pc->pc_attach_hook = becc_pci_attach_hook;
pc->pc_bus_maxdevs = becc_pci_bus_maxdevs;
pc->pc_make_tag = becc_pci_make_tag;
pc->pc_decompose_tag = becc_pci_decompose_tag;
pc->pc_conf_read = becc_pci_conf_read;
pc->pc_conf_write = becc_pci_conf_write;
pc->pc_intr_v = cookie;
pc->pc_intr_map = becc_pci_intr_map;
pc->pc_intr_string = becc_pci_intr_string;
pc->pc_intr_evcnt = becc_pci_intr_evcnt;
pc->pc_intr_establish = becc_pci_intr_establish;
pc->pc_intr_disestablish = becc_pci_intr_disestablish;
#if NPCI > 0 && defined(PCI_NETBSD_CONFIGURE)
/*
* Configure the PCI bus.
*
* XXX We need to revisit this. We only configure the Secondary
* bus (and its children). The bus configure code needs changes
* to support how the busses are arranged on this chip. We also
* need to only configure devices in the private device space on
* the Secondary bus.
*/
/* Reserve the bottom 32K of the PCI address space. */
ioext = extent_create("pciio", sc->sc_ioout_xlate + (32 * 1024),
sc->sc_ioout_xlate + (64 * 1024) - 1,
M_DEVBUF, NULL, 0, EX_NOWAIT);
memext = extent_create("pcimem", sc->sc_owin_xlate[0],
sc->sc_owin_xlate[0] + BECC_PCI_MEM1_SIZE - 1,
M_DEVBUF, NULL, 0, EX_NOWAIT);
printf("%s: configuring PCI bus\n", sc->sc_dev.dv_xname);
pci_configure_bus(pc, ioext, memext, NULL, 0, arm_dcache_align);
extent_destroy(ioext);
extent_destroy(memext);
#endif
}
void
pci_conf_interrupt(pci_chipset_tag_t pc, int a, int b, int c, int d, int *p)
{
}
void
becc_pci_attach_hook(struct device *parent, struct device *self,
struct pcibus_attach_args *pba)
{
/* Nothing to do. */
}
int
becc_pci_bus_maxdevs(void *v, int busno)
{
return (32);
}
pcitag_t
becc_pci_make_tag(void *v, int b, int d, int f)
{
return ((b << 16) | (d << 11) | (f << 8));
}
void
becc_pci_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
{
if (bp != NULL)
*bp = (tag >> 16) & 0xff;
if (dp != NULL)
*dp = (tag >> 11) & 0x1f;
if (fp != NULL)
*fp = (tag >> 8) & 0x7;
}
struct pciconf_state {
uint32_t ps_offset;
int ps_b, ps_d, ps_f;
int ps_type;
};
static int
becc_pci_conf_setup(struct becc_softc *sc, pcitag_t tag, int offset,
struct pciconf_state *ps)
{
becc_pci_decompose_tag(sc, tag, &ps->ps_b, &ps->ps_d, &ps->ps_f);
/*
* If the bus # is the same as our own, then use Type 0 cycles,
* else use Type 1.
*/
if (ps->ps_b == 0) {
/* XXX This is a platform-specific parameter. */
if (ps->ps_d > (14 - BECC_IDSEL_BIT))
return (1);
ps->ps_offset = (1U << (ps->ps_d + BECC_IDSEL_BIT)) |
(ps->ps_f << 8) | offset;
ps->ps_type = 0;
} else {
/* The tag is already in the correct format. */
ps->ps_offset = tag | offset | 1;
ps->ps_type = 1;
}
return (0);
}
static int becc_pci_conf_cleanup(struct becc_softc *sc);
static int
becc_pci_conf_cleanup(struct becc_softc *sc)
{
uint32_t reg;
int err=0;
BECC_CSR_WRITE(BECC_POCR, 0);
reg = becc_pcicore_read(sc, PCI_COMMAND_STATUS_REG);
if (reg & 0xf9000000) {
DPRINTF((" ** pci status error: %08x (%08x) **\n",
reg, reg & 0xf9000000));
err = 1;
becc_pcicore_write(sc, PCI_COMMAND_STATUS_REG,
reg & 0xf900ffff);
reg = becc_pcicore_read(sc, PCI_COMMAND_STATUS_REG);
DPRINTF((" ** pci status after clearing: %08x (%08x) **\n",
reg, reg & 0xf9000000));
}
reg = BECC_CSR_READ(BECC_PMISR);
if (reg & 0x000f000d) {
DPRINTF((" ** pci master isr: %08x (%08x) **\n",
reg, reg & 0x000f000d));
err = 1;
BECC_CSR_WRITE(BECC_PMISR, reg & 0x000f000d);
reg = BECC_CSR_READ(BECC_PMISR);
DPRINTF((" ** pci master isr after clearing: %08x (%08x) **\n",
reg, reg & 0x000f000d));
}
reg = BECC_CSR_READ(BECC_PSISR);
if (reg & 0x000f0210) {
DPRINTF((" ** pci slave isr: %08x (%08x) **\n",
reg, reg & 0x000f0210));
err = 1;
BECC_CSR_WRITE(BECC_PSISR, reg & 0x000f0210);
reg = BECC_CSR_READ(BECC_PSISR);
DPRINTF((" ** pci slave isr after clearing: %08x (%08x) **\n",
reg, reg & 0x000f0210));
}
return err;
}
pcireg_t
becc_pci_conf_read(void *v, pcitag_t tag, int offset)
{
struct becc_softc *sc = v;
struct pciconf_state ps;
vaddr_t va;
pcireg_t rv;
u_int s;
if (becc_pci_conf_setup(sc, tag, offset, &ps))
return ((pcireg_t) -1);
/*
* Skip device 0 (the BECC itself). We don't want it
* to appear as part of the PCI device space.
*/
if (ps.ps_b == 0 && ps.ps_d == 0)
return ((pcireg_t) -1);
PCI_CONF_LOCK(s);
va = sc->sc_pci_cfg_base + ps.ps_offset;
BECC_CSR_WRITE(BECC_POCR, ps.ps_type);
if (badaddr_read((void *) va, sizeof(rv), &rv)) {
/* XXX Check master/target abort? */
#if 0
printf("conf_read: %d/%d/%d bad address\n",
ps.ps_b, ps.ps_d, ps.ps_f);
#endif
rv = (pcireg_t) -1;
}
if (becc_pci_conf_cleanup(sc))
rv = (pcireg_t) -1;
PCI_CONF_UNLOCK(s);
return (rv);
}
void
becc_pci_conf_write(void *v, pcitag_t tag, int offset, pcireg_t val)
{
struct becc_softc *sc = v;
struct pciconf_state ps;
vaddr_t va;
u_int s;
if (becc_pci_conf_setup(sc, tag, offset, &ps))
return;
PCI_CONF_LOCK(s);
BECC_CSR_WRITE(BECC_POCR, ps.ps_type);
va = sc->sc_pci_cfg_base + ps.ps_offset;
*(__volatile pcireg_t *)va = val;
becc_pci_conf_cleanup(sc);
PCI_CONF_UNLOCK(s);
}
int
becc_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
{
int irq;
if (pa->pa_bus == 0) {
switch (pa->pa_device) {
case 1: irq = ICU_PCI_INTB; break; /* Ethernet #0 */
case 2: irq = ICU_PCI_INTC; break; /* Ethernet #1 */
case 3: irq = ICU_PCI_INTA; break; /* Card slot? */
default:
break;
}
} else {
switch (pa->pa_intrpin) {
case 1: irq = ICU_PCI_INTA; break;
case 2: irq = ICU_PCI_INTB; break;
case 3: irq = ICU_PCI_INTC; break;
case 4: irq = ICU_PCI_INTD; break;
default:
printf("becc_pci_intr_map: bogus pin: %d\n",
pa->pa_intrpin);
return (1);
}
}
*ihp = irq;
return (0);
}
const char *
becc_pci_intr_string(void *v, pci_intr_handle_t ih)
{
return (becc_irqnames[ih]);
}
const struct evcnt *
becc_pci_intr_evcnt(void *v, pci_intr_handle_t ih)
{
/* XXX For now. */
return (NULL);
}
void *
becc_pci_intr_establish(void *v, pci_intr_handle_t ih, int ipl,
int (*func)(void *), void *arg)
{
return (becc_intr_establish(ih, ipl, func, arg));
}
void
becc_pci_intr_disestablish(void *v, void *cookie)
{
becc_intr_disestablish(cookie);
}

View File

@ -0,0 +1,332 @@
/* $NetBSD: becc_space.c,v 1.1 2003/01/25 01:57:19 thorpej 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.
*/
/*
* bus_space functions for the ADI Engineering Big Endian Companion Chip.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <uvm/uvm_extern.h>
#include <machine/bus.h>
#include <arm/xscale/beccreg.h>
#include <arm/xscale/beccvar.h>
/* Prototypes for all the bus_space structure functions */
bs_protos(becc);
bs_protos(becc_io);
bs_protos(becc_mem);
bs_protos(generic);
bs_protos(generic_armv4);
bs_protos(bs_notimpl);
/*
* Template bus_space -- copied, and the bits that are NULL are
* filled in.
*/
const struct bus_space becc_bs_tag_template = {
/* cookie */
(void *) 0,
/* mapping/unmapping */
NULL,
NULL,
becc_bs_subregion,
/* allocation/deallocation */
NULL,
NULL,
/* get kernel virtual address */
becc_bs_vaddr,
/* mmap */
becc_bs_mmap,
/* barrier */
becc_bs_barrier,
/* read (single) */
generic_bs_r_1,
generic_armv4_bs_r_2,
generic_bs_r_4,
bs_notimpl_bs_r_8,
/* read multiple */
generic_bs_rm_1,
generic_armv4_bs_rm_2,
generic_bs_rm_4,
bs_notimpl_bs_rm_8,
/* read region */
bs_notimpl_bs_rr_1,
generic_armv4_bs_rr_2,
generic_bs_rr_4,
bs_notimpl_bs_rr_8,
/* write (single) */
generic_bs_w_1,
generic_armv4_bs_w_2,
generic_bs_w_4,
bs_notimpl_bs_w_8,
/* write multiple */
generic_bs_wm_1,
generic_armv4_bs_wm_2,
generic_bs_wm_4,
bs_notimpl_bs_wm_8,
/* write region */
bs_notimpl_bs_wr_1,
generic_armv4_bs_wr_2,
generic_bs_wr_4,
bs_notimpl_bs_wr_8,
/* set multiple */
bs_notimpl_bs_sm_1,
bs_notimpl_bs_sm_2,
bs_notimpl_bs_sm_4,
bs_notimpl_bs_sm_8,
/* set region */
bs_notimpl_bs_sr_1,
generic_armv4_bs_sr_2,
bs_notimpl_bs_sr_4,
bs_notimpl_bs_sr_8,
/* copy */
bs_notimpl_bs_c_1,
generic_armv4_bs_c_2,
bs_notimpl_bs_c_4,
bs_notimpl_bs_c_8,
};
void
becc_io_bs_init(bus_space_tag_t bs, void *cookie)
{
*bs = becc_bs_tag_template;
bs->bs_cookie = cookie;
bs->bs_map = becc_io_bs_map;
bs->bs_unmap = becc_io_bs_unmap;
bs->bs_alloc = becc_io_bs_alloc;
bs->bs_free = becc_io_bs_free;
bs->bs_vaddr = becc_io_bs_vaddr;
}
void
becc_mem_bs_init(bus_space_tag_t bs, void *cookie)
{
*bs = becc_bs_tag_template;
bs->bs_cookie = cookie;
bs->bs_map = becc_mem_bs_map;
bs->bs_unmap = becc_mem_bs_unmap;
bs->bs_alloc = becc_mem_bs_alloc;
bs->bs_free = becc_mem_bs_free;
bs->bs_mmap = becc_mem_bs_mmap;
}
/* *** Routines shared by becc, PCI IO, and PCI MEM. *** */
int
becc_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
becc_bs_barrier(void *t, bus_space_handle_t bsh, bus_size_t offset,
bus_size_t len, int flags)
{
/* Nothing to do. */
}
void *
becc_bs_vaddr(void *t, bus_space_handle_t bsh)
{
return ((void *)bsh);
}
paddr_t
becc_bs_mmap(void *t, bus_addr_t addr, off_t off, int prot, int flags)
{
/* Not supported. */
return (-1);
}
/* *** Routines for PCI IO. *** */
int
becc_io_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
bus_space_handle_t *bshp)
{
struct becc_softc *sc = t;
vaddr_t winvaddr;
uint32_t busbase;
if (bpa >= sc->sc_ioout_xlate &&
bpa < (sc->sc_ioout_xlate + (64 * 1024))) {
busbase = sc->sc_ioout_xlate;
winvaddr = sc->sc_pci_io_base;
} else
return (EINVAL);
if ((bpa + size) >= (busbase + (64 * 1024)))
return (EINVAL);
/*
* Found the window -- PCI I/O space is mapped at a fixed
* virtual address by board-specific code. Translate the
* bus address to the virtual address.
*/
*bshp = winvaddr + (bpa - busbase);
return (0);
}
void
becc_io_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size)
{
/* Nothing to do. */
}
int
becc_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 flags,
bus_addr_t *bpap, bus_space_handle_t *bshp)
{
panic("becc_io_bs_alloc(): not implemented\n");
}
void
becc_io_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
{
panic("becc_io_bs_free(): not implemented\n");
}
void *
becc_io_bs_vaddr(void *t, bus_space_handle_t bsh)
{
/* Not supported. */
return (NULL);
}
/* *** Routines for PCI MEM. *** */
int
becc_mem_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
bus_space_handle_t *bshp)
{
struct becc_softc *sc = t;
vaddr_t winvaddr;
uint32_t busbase;
/*
* The two memory windows have been configured to the same
* PCI base by board-specific code, so we only need to look
* at the first one.
*/
if (bpa >= sc->sc_owin_xlate[0] &&
bpa < (sc->sc_owin_xlate[0] + BECC_PCI_MEM1_SIZE)) {
busbase = sc->sc_owin_xlate[0];
winvaddr = sc->sc_pci_mem_base[0];
} else
return (EINVAL);
if ((bpa + size) >= (busbase + BECC_PCI_MEM1_SIZE))
return (EINVAL);
/*
* Found the window -- PCI MEM space is mapped at a fixed
* virtual address by board-specific code. Translate the
* bus address to the virtual address.
*/
*bshp = winvaddr + (bpa - busbase);
return (0);
}
void
becc_mem_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size)
{
/* Nothing to do. */
}
int
becc_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 flags,
bus_addr_t *bpap, bus_space_handle_t *bshp)
{
panic("becc_mem_bs_alloc(): not implemented\n");
}
void
becc_mem_bs_free(void *t, bus_space_handle_t bsh, bus_size_t size)
{
panic("becc_mem_bs_free(): not implemented\n");
}
paddr_t
becc_mem_bs_mmap(void *t, bus_addr_t addr, off_t off, int prot, int flags)
{
/* XXX */
return (-1);
}

View File

@ -0,0 +1,306 @@
/* $NetBSD: becc_timer.c,v 1.1 2003/01/25 01:57:20 thorpej 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.
*/
/*
* Timer/clock support for the ADI Engineering Big Endian Companion Chip.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/time.h>
#include <machine/bus.h>
#include <arm/cpufunc.h>
#include <arm/xscale/beccreg.h>
#include <arm/xscale/beccvar.h>
void (*becc_hardclock_hook)(void);
/*
* Note, since COUNTS_PER_USEC doesn't divide evenly, we round up.
*/
#define COUNTS_PER_SEC BECC_PERIPH_CLOCK
#define COUNTS_PER_USEC ((COUNTS_PER_SEC / 1000000) + 1)
static void *clock_ih;
/*
* Since the timer interrupts when the counter underflows, we need to
* subtract 1 from counts_per_hz when loading the preload register.
*/
static uint32_t counts_per_hz;
int clockhandler(void *);
/*
* becc_calibrate_delay:
*
* Calibrate the delay loop.
*/
void
becc_calibrate_delay(void)
{
/*
* Just use hz=100 for now -- we'll adjust it, if necessary,
* in cpu_initclocks().
*/
counts_per_hz = COUNTS_PER_SEC / 100;
/* Stop both timers, clear interrupts. */
BECC_CSR_WRITE(BECC_TSCRA, TSCRx_TIF);
BECC_CSR_WRITE(BECC_TSCRB, TSCRx_TIF);
/* Set the timer preload value. */
BECC_CSR_WRITE(BECC_TPRA, counts_per_hz - 1);
/* Start the timer. */
BECC_CSR_WRITE(BECC_TSCRA, TSCRx_TE | TSCRx_CM);
}
/*
* cpu_initclocks:
*
* Initialize the clock and get them going.
*/
void
cpu_initclocks(void)
{
u_int oldirqstate;
#if 0
if (hz < 50 || COUNTS_PER_SEC % hz) {
printf("Cannot get %d Hz clock; using 100 Hz\n", hz);
hz = 100;
}
#endif
tick = 1000000 / hz; /* number of microseconds between interrupts */
tickfix = 1000000 - (hz * tick);
if (tickfix) {
int ftp;
ftp = min(ffs(tickfix), ffs(hz));
tickfix >>= (ftp - 1);
tickfixinterval = hz >> (ftp - 1);
}
/*
* 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. */
printf("clock: hz=%d stathz=%d profhz=%d\n", hz, stathz, profhz);
oldirqstate = disable_interrupts(I32_bit);
/* Hook up the clock interrupt handler. */
clock_ih = becc_intr_establish(ICU_TIMERA, IPL_CLOCK,
clockhandler, NULL);
if (clock_ih == NULL)
panic("cpu_initclocks: unable to register timer interrupt");
/* Set up the new clock parameters. */
/* Stop timer, clear interrupt */
BECC_CSR_WRITE(BECC_TSCRA, TSCRx_TIF);
counts_per_hz = COUNTS_PER_SEC / hz;
/* Set the timer preload value. */
BECC_CSR_WRITE(BECC_TPRA, counts_per_hz - 1);
/* ...and start it in motion. */
BECC_CSR_WRITE(BECC_TSCRA, TSCRx_TE | TSCRx_CM);
/* register soft interrupt handler as well */
becc_intr_establish(ICU_SOFT, IPL_SOFT, becc_softint, NULL);
restore_interrupts(oldirqstate);
}
/*
* setstatclockrate:
*
* Set the rate of the statistics clock.
*
* We assume that hz is either stathz or profhz, and that neither
* will change after being set by cpu_initclocks(). We could
* recalculate the intervals here, but that would be a pain.
*/
void
setstatclockrate(int hz)
{
/*
* XXX Use TMR1?
*/
}
/*
* microtime:
*
* Fill in the specified timeval struct with the current time
* accurate to the microsecond.
*/
void
microtime(struct timeval *tvp)
{
static struct timeval lasttv;
u_int oldirqstate;
uint32_t counts;
oldirqstate = disable_interrupts(I32_bit);
/*
* XXX How do we compensate for the -1 behavior of the preload value?
*/
counts = counts_per_hz - BECC_CSR_READ(BECC_TCVRA);
/* Fill in the timeval struct. */
*tvp = time;
tvp->tv_usec += (counts / COUNTS_PER_USEC);
/* Make sure microseconds doesn't overflow. */
while (tvp->tv_usec >= 1000000) {
tvp->tv_usec -= 1000000;
tvp->tv_sec++;
}
/* Make sure the time has advanced. */
if (tvp->tv_sec == lasttv.tv_sec &&
tvp->tv_usec <= lasttv.tv_usec) {
tvp->tv_usec = lasttv.tv_usec + 1;
if (tvp->tv_usec >= 1000000) {
tvp->tv_usec -= 1000000;
tvp->tv_sec++;
}
}
lasttv = *tvp;
restore_interrupts(oldirqstate);
}
/*
* delay:
*
* Delay for at least N microseconds.
*/
void
delay(u_int n)
{
uint32_t cur, last, delta, usecs;
/*
* This works by polling the timer and counting the
* number of microseconds that go by.
*/
last = BECC_CSR_READ(BECC_TCVRA);
delta = usecs = 0;
while (n > usecs) {
cur = BECC_CSR_READ(BECC_TCVRA);
/* Check to see if the timer has wrapped around. */
if (last < cur)
delta += (last + (counts_per_hz - cur));
else
delta += (last - cur);
last = cur;
if (delta >= COUNTS_PER_USEC) {
usecs += delta / COUNTS_PER_USEC;
delta %= COUNTS_PER_USEC;
}
}
}
/*
* inittodr:
*
* Initialize time from the time-of-day register.
*/
void
inittodr(time_t base)
{
time.tv_sec = base;
time.tv_usec = 0;
}
/*
* resettodr:
*
* Reset the time-of-day register with the current time.
*/
void
resettodr(void)
{
}
/*
* clockhandler:
*
* Handle the hardclock interrupt.
*/
int
clockhandler(void *arg)
{
struct clockframe *frame = arg;
/* ACK the interrupt. */
BECC_CSR_WRITE(BECC_TSCRA, TSCRx_TE | TSCRx_CM | TSCRx_TIF);
hardclock(frame);
if (becc_hardclock_hook != NULL)
(*becc_hardclock_hook)();
return (1);
}

View File

@ -0,0 +1,196 @@
/* $NetBSD: beccreg.h,v 1.1 2003/01/25 01:57:20 thorpej Exp $ */
/*
* Copyright (c) 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.
*/
#ifndef _BECCREG_H_
#define _BECCREG_H_
/*
* Register definitions for the ADI Engineering Big Endian Companion
* Chip for the Intel i80200.
*/
/* Revision codes */
#define BECC_REV_V7 0x00 /* rev <= 7 */
#define BECC_REV_V8 0x01 /* rev 8 */
#define BECC_REV_V9 0x02 /* rev >= 9 */
/* Memory Map */
#define BECC_REG_BASE 0x04000000
#define BECC_REG_SIZE 0x01000000 /* 16M */
#define BECC_PCI_CONF_BASE 0x08000000
#define BECC_PCI_CONF_SIZE 0x02000000 /* 32M */
#define BECC_PCI_IO_BASE 0x0a000000
#define BECC_PCI_IO_SIZE 0x02000000 /* 32M */
#define BECC_PCI_MEM1_BASE 0x0c000000
#define BECC_PCI_MEM1_SIZE 0x02000000 /* 32M */
#define BECC_PCI_MEM2_BASE 0x0e000000
#define BECC_PCI_MEM2_SIZE 0x02000000 /* 32M */
#define BECC_SDRAM_BASE 0xc0000000
/* Peripheral clock is 33.3MHz */
#define BECC_PERIPH_CLOCK 33300000
/* BECC registers; offsets from BECC_REG_BASE */
#define BECC_PSISR 0x0000 /* PCI slave interrupt status */
#define PSISR_SERR (1U << 4) /* system error */
#define PSISR_PERR (1U << 9) /* parity error */
#define PSISR_IFU (1U << 16) /* inbound FIFO uflow */
#define PSISR_IFO (1U << 17) /* inbound FIFO oflow */
#define PSISR_OFU (1U << 18) /* outbound FIFO uflow */
#define PSISR_OFO (1U << 19) /* outbound FIFO oflow */
#define BECC_PSTR0 0x0010 /* PCI slave translation window #0 */
#define BECC_PSTR1 0x0018 /* PCI slave translation window #1 */
#define PSTRx_ADDRMASK (3U << 25) /* address mask */
#define PSTRx_BEE (1U << 0) /* big-endian enable */
#define BECC_PSTR2 0x0020 /* PCI slave translation window #2 */
#define PSTR2_ADDRMASK (0U) /* address mask (all SDRAM) */
#define BECC_PMISR 0x0100 /* PCI master interrupt status */
#define PMISR_PE (1U << 0) /* parity error */
#define PMISR_TA (1U << 2) /* target abort */
#define PMISR_MA (1U << 3) /* master abort */
#define PMISR_IFU (1U << 16) /* inbound FIFO uflow */
#define PMISR_IFO (1U << 17) /* inbound FIFO oflow */
#define PMISR_OFU (1U << 18) /* outbound FIFO uflow */
#define PMISR_OFO (1U << 19) /* outbound FIFO oflow */
#define BECC_IDSEL_BIT 11 /* first device on PCI bus */
#define BECC_POMR1 0x0110 /* PCI outbound memory window #1 */
#define BECC_POMR2 0x0114 /* PCI outbound memory window #2 */
#define POMRx_ADDRMASK 0xfe000000 /* address mask */
#define POMRx_BEE (1U << 2) /* big-endian enable */
#define POMRx_F32 (1U << 3) /* force 32-bit transfer */
#define POMRx_BO(x) (x) /* busrt order (MBZ) */
#define BECC_POMR3 0x0130 /* PCI outbound memory window #3 */
#define POMR3_ADDRMASK 0xc0000000 /* address mask */
#define BECC_POIR 0x0118 /* PCI outbound I/O window */
#define POIR_ADDRMASK 0xfe000000 /* address mask */
#define POIR_BEE (1U << 2) /* big-endian enable */
#define BECC_POCR 0x0120 /* PCI outbound config window */
#define POCR_BEE (1U << 2) /* big-endian enable */
#define POCR_TYPE (1U << 0) /* for type 1 cycles */
#define BECC_DMACR 0x0200 /* DMA control register */
#define DMACR_CE (1U << 0) /* channel enable */
#define BECC_DMASR 0x0204 /* DMA status register */
#define DMASR_PEF (1U << 0) /* PCI parity error */
#define DMASR_PTA (1U << 2) /* PCI target abort */
#define DMASR_PMA (1U << 3) /* PCI master abort */
#define DMASR_EOTI (1U << 8) /* end of transfer interrupt */
#define DMASR_CA (1U << 9) /* channel active */
#define DMASR_IFU (1U << 16) /* inbound FIFO uflow */
#define DMASR_IFO (1U << 17) /* inbound FIFO oflow */
#define DMASR_OFU (1U << 18) /* outbound FIFO uflow */
#define DMASR_OFO (1U << 19) /* outbound FIFO oflow */
#define BECC_DMAPCIAR 0x0210 /* DMA PCI address */
#define BECC_DMALAR 0x021c /* DMA local address */
#define BECC_DMABCR 0x0220 /* DMA byte count */
#define BECC_DMADCR 0x0224 /* DMA descriptor control */
#define DMADCR_F32 (1U << 6) /* force 32-bit */
#define DMADCR_BEE (1U << 5) /* big-endian enable */
#define DMADCR_PCICMD(x) (x) /* PCI command */
#define PCICMD_MR 0x6 /* memory read */
#define PCICMD_MRL 0xe /* memory read line */
#define PCICMD_MRM 0xc /* memory read multiple */
#define PCICMD_MW 0x7 /* memory write */
#define BECC_TSCRA 0x0300 /* Timer status/control A */
#define BECC_TSCRB 0x0320 /* Timer status/control B */
#define TSCRx_TE (1U << 0) /* timer enable */
#define TSCRx_CM (1U << 1) /* continuous mode */
#define TSCRx_TIF (1U << 9) /* timer interrupt flag */
#define BECC_TPRA 0x0304 /* Timer preload A */
#define BECC_TPRB 0x0324 /* Timer preload B */
#define BECC_TCVRA 0x0308 /* Timer current value A */
#define BECC_TCVRB 0x0328 /* Timer current value B */
#define BECC_ICSR 0x0400 /* Interrupt control/status */
#define BECC_ICMR 0x0404 /* Interrupt mask */
#define BECC_ICSTR 0x0408 /* Interrupt steer */
#define ICU_SOFT 0 /* software interrupt */
#define ICU_TIMERA 1 /* timer A */
#define ICU_TIMERB 2 /* timer B */
#define ICU_DIAGERR 7 /* diagnostic error */
#define ICU_DMA_EOT 8 /* DMA end-of-transfer */
#define ICU_DMA_PEF 9 /* DMA parity error */
#define ICU_DMA_TA 10 /* DMA target abort */
#define ICU_DMA_MA 11 /* DMA master abort */
#define ICU_PCI_PERR 16 /* PCI parity error */
#define ICU_PCI_SERR 19 /* PCI system error */
#define ICU_PCI_POAPEI 20 /* PCI outbound ATU parity error */
#define ICU_PCI_POATAI 21 /* PCI outbound ATU target abort */
#define ICU_PCI_POAMAI 22 /* PCI outbound ATU master abort */
#define ICU_UARTA 24 /* UART A */
#define ICU_UARTB 25 /* UART B */
#define ICU_PCI_INTA 26 /* PCI INTA# */
#define ICU_PCI_INTB 27 /* PCI INTB# */
#define ICU_PCI_INTC 28 /* PCI INTC# */
#define ICU_PCI_INTD 29 /* PCI INTD# */
#define ICU_PUSHBUTTON 30 /* push button pulse */
#define ICU_RESERVED_MASK ((1U << 3) | (1U << 4) | (1U << 5) | \
(1U << 6) | (1U << 12) | (1U << 13) | \
(1U << 14) | (1U << 15) | (1U << 17) | \
(1U << 18) | (1U << 23) | (1U << 31))
#define ICU_VALID_MASK (~ICU_RESERVED_MASK)
#define BECC_RSSR 0x0500 /* rotary switch status */
#define RSSR_POS 0x0000000f /* switch position */
#define RSSR_BE (1U << 6) /* big-endian jumper */
#endif /* _BECCREG_H_ */

View File

@ -0,0 +1,127 @@
/* $NetBSD: beccvar.h,v 1.1 2003/01/25 01:57:20 thorpej Exp $ */
/*
* Copyright (c) 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.
*/
#ifndef _BECCVAR_H_
#define _BECCVAR_H_
#include <sys/queue.h>
#include <dev/pci/pcivar.h>
/*
* There are roughly 32 interrupt sources.
*/
#define NIRQ 32
struct intrhand {
TAILQ_ENTRY(intrhand) ih_list; /* link on intrq list */
int (*ih_func)(void *); /* handler */
void *ih_arg; /* arg for handler */
int ih_ipl; /* IPL_* */
int ih_irq; /* IRQ number */
};
struct intrq {
TAILQ_HEAD(, intrhand) iq_list; /* handler list */
struct evcnt iq_ev; /* event counter */
int iq_mask; /* IRQs to mask while handling */
int iq_levels; /* IPL_*'s this IRQ has */
int iq_ist; /* share type */
};
struct becc_softc {
struct device sc_dev; /* generic device glue */
/*
* We expect the board-specific front-end to have already mapped
* the PCI I/O, memory, and configuration spaces.
*/
vaddr_t sc_pci_io_base; /* I/O window vaddr */
vaddr_t sc_pci_mem_base[2]; /* MEM window vaddr */
vaddr_t sc_pci_cfg_base; /* CFG window vaddr */
/*
* These define the 2 32M PCI Inbound windows and 1 128M (rev8 & up).
*/
struct {
uint32_t iwin_base; /* PCI address */
uint32_t iwin_xlate; /* local address */
} sc_iwin[3];
/*
* Variables that define the 2 32M PCI Outbound windows and
* 1 1G (rev8 & up).
*/
uint32_t sc_owin_xlate[3]; /* PCI address */
/*
* This is the PCI address that the Outbound I/O
* window maps to.
*/
uint32_t sc_ioout_xlate;
/* Bus space, DMA, and PCI tags for the PCI bus. */
struct bus_space sc_pci_iot;
struct bus_space sc_pci_memt;
struct arm32_bus_dma_tag sc_pci_dmat;
struct arm32_pci_chipset sc_pci_chipset;
/* DMA window info for PCI DMA. */
struct arm32_dma_range sc_pci_dma_range[3];
};
extern int becc_rev; /* Set by early bootstrap code */
extern const char *becc_revisions[];
extern void (*becc_hardclock_hook)(void);
void becc_calibrate_delay(void);
void becc_icu_init(void);
void becc_intr_init(void);
void *becc_intr_establish(int, int, int (*)(void *), void *);
void becc_intr_disestablish(void *);
void becc_io_bs_init(bus_space_tag_t, void *);
void becc_mem_bs_init(bus_space_tag_t, void *);
void becc_pci_init(pci_chipset_tag_t, void *);
void becc_attach(struct becc_softc *);
uint32_t becc_pcicore_read(struct becc_softc *, bus_addr_t);
void becc_pcicore_write(struct becc_softc *, bus_addr_t, uint32_t);
#endif /* _BECCVAR_H_ */

View File

@ -0,0 +1,14 @@
# $NetBSD: files.becc,v 1.1 2003/01/25 01:57:17 thorpej Exp $
#
# Configuration info for the ADI Engineering Big Endian Companion Chip
# for the Intel i80200 processor
#
file arch/arm/xscale/becc_icu.c
file arch/arm/xscale/becc_timer.c
device becc {}: pcibus, bus_space_generic
# Board-specific front-end provides attachment.
file arch/arm/xscale/becc.c becc
file arch/arm/xscale/becc_pci.c becc
file arch/arm/xscale/becc_space.c becc

View File

@ -1,4 +1,4 @@
# $NetBSD: files.i80321,v 1.9 2003/01/03 00:41:19 thorpej Exp $
# $NetBSD: files.i80321,v 1.10 2003/01/25 01:57:17 thorpej Exp $
#
# Configuration info for Intel i80321 XScale I/O Processor support
#
@ -22,6 +22,12 @@ attach iopaau at iopxs
file arch/arm/xscale/i80321_aau.c iopaau
file arch/arm/xscale/iopaau.c iopaau
# DMA controller unit
device iopdma: dmover_service
attach iopdma at iopxs
file arch/arm/xscale/i80321_dma.c iopdma
file arch/arm/xscale/iopdma.c iopdma
# Watchdog timer
device iopwdog: sysmon_wdog
attach iopwdog at iopxs