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:
parent
15b88bc43f
commit
b1b164a859
|
@ -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;
|
||||
}
|
|
@ -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_ */
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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_ */
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue