add Alpha 4100 support

This commit is contained in:
mjacob 1998-04-15 00:50:14 +00:00
parent 0ba76b38c8
commit aed073a77f
9 changed files with 1975 additions and 0 deletions

235
sys/arch/alpha/pci/mcpcia.c Normal file
View File

@ -0,0 +1,235 @@
/* $NetBSD: mcpcia.c,v 1.1 1998/04/15 00:50:14 mjacob Exp $ */
/*
* Copyright (c) 1998 by Matthew Jacob
* NASA AMES Research Center.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* MCPCIA mcbus to PCI bus adapter
* found on AlphaServer 4100 systems.
*/
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: mcpcia.c,v 1.1 1998/04/15 00:50:14 mjacob Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <machine/autoconf.h>
#include <machine/rpb.h>
#include <machine/pte.h>
#include <alpha/mcbus/mcbusreg.h>
#include <alpha/mcbus/mcbusvar.h>
#include <alpha/pci/mcpciareg.h>
#include <alpha/pci/mcpciavar.h>
#include <alpha/pci/pci_kn300.h>
struct mcpcia_softc *mcpcias = NULL;
static struct mcpcia_softc *mcpcia_lt = NULL;
#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
#define MCPCIA_SYSBASE(sc) \
((((unsigned long) (sc)->mcpcia_gid) << MCBUS_GID_SHIFT) | \
(((unsigned long) (sc)->mcpcia_mid) << MCBUS_MID_SHIFT) | \
(MCBUS_IOSPACE))
static int mcpciamatch __P((struct device *, struct cfdata *, void *));
static void mcpciaattach __P((struct device *, struct device *, void *));
struct cfattach mcpcia_ca = {
sizeof(struct mcpcia_softc), mcpciamatch, mcpciaattach
};
static int mcpciaprint __P((void *, const char *));
void mcpcia_intr_establish __P((struct confargs *, int (*)(void *), void *));
void mcpcia_intr_disestablish __P((struct confargs *));
caddr_t mcpcia_cvtaddr __P((struct confargs *));
int mcpcia_matchname __P((struct confargs *, char *));
static int
mcpciaprint(aux, pnp)
void *aux;
const char *pnp;
{
register struct pcibus_attach_args *pba = aux;
/* only PCIs can attach to MCPCIA for now */
if (pnp)
printf("%s at %s", pba->pba_busname, pnp);
printf(" bus %d", pba->pba_bus);
return (UNCONF);
}
static int
mcpciamatch(parent, cf, aux)
struct device *parent;
struct cfdata *cf;
void *aux;
{
struct mcbus_dev_attach_args *ma = aux;
if (ma->ma_type == MCBUS_TYPE_PCI)
return (1);
return (0);
}
static void
mcpciaattach(parent, self, aux)
struct device *parent;
struct device *self;
void *aux;
{
static int first = 1;
struct mcbus_dev_attach_args *ma = aux;
struct mcpcia_softc *mcp = (struct mcpcia_softc *)self;
struct pcibus_attach_args pba;
mcp->mcpcia_dev = *self;
mcp->mcpcia_mid = ma->ma_mid;
mcp->mcpcia_gid = ma->ma_gid;
printf("\n");
mcpcia_init(mcp);
mcp->mcpcia_next = NULL;
if (mcpcia_lt == NULL) {
mcpcias = mcp;
} else {
mcpcia_lt->mcpcia_next = mcp;
}
mcpcia_lt = mcp;
/*
* Set up interrupts
*/
pci_kn300_pickintr(&mcp->mcpcia_cc, first);
#ifdef EVCNT_COUNTERS
if (first == 1) {
evcnt_attach(self, "intr", kn300_intr_evcnt);
first = 0;
}
#else
first = 0;
#endif
/*
* Attach PCI bus
*/
pba.pba_busname = "pci";
pba.pba_iot = &mcp->mcpcia_cc.cc_iot;
pba.pba_memt = &mcp->mcpcia_cc.cc_memt;
pba.pba_dmat = /* start with direct, may change... */
alphabus_dma_get_tag(&mcp->mcpcia_cc.cc_dmat_direct, ALPHA_BUS_PCI);
pba.pba_pc = &mcp->mcpcia_cc.cc_pc;
pba.pba_bus = 0;
pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
config_found(self, &pba, mcpciaprint);
}
void
mcpcia_init(mcp)
struct mcpcia_softc *mcp;
{
u_int32_t ctl;
struct mcpcia_config *ccp = &mcp->mcpcia_cc;
if (ccp->cc_initted == 0) {
mcpcia_bus_io_init(&ccp->cc_iot, ccp);
mcpcia_bus_mem_init(&ccp->cc_memt, ccp);
}
mcpcia_pci_init(&ccp->cc_pc, ccp);
ccp->cc_sc = mcp;
/*
* Establish a precalculated base for convenience's sake.
*/
ccp->cc_sysbase = MCPCIA_SYSBASE(mcp);
ctl = REGVAL(MCPCIA_PCI_REV(mcp));
printf("%s: Horse Revision %d, %s Handed Saddle Revision %d,"
" CAP Revision %d\n", mcp->mcpcia_dev.dv_xname, HORSE_REV(ctl),
(SADDLE_TYPE(ctl) & 1)? "Right": "Left", SADDLE_REV(ctl),
CAP_REV(ctl));
/*
* Disable interrupts and clear errors prior to probing
*/
REGVAL(MCPCIA_INT_MASK0(mcp)) = 0;
REGVAL(MCPCIA_INT_MASK1(mcp)) = 0;
REGVAL(MCPCIA_CAP_ERR(mcp)) = 0xFFFFFFFF;
alpha_mb();
/*
* Set up DMA stuff for this MCPCIA.
*/
mcpcia_dma_init(ccp);
/*
* Clean up any post probe errors (W1TC).
*/
REGVAL(MCPCIA_CAP_ERR(mcp)) = 0xFFFFFFFF;
alpha_mb();
/*
* Use this opportunity to also find out the MID and CPU
* type of the currently running CPU (that's us, billybob....)
*/
ctl = REGVAL(MCPCIA_WHOAMI(mcp));
mcbus_primary.mcbus_cpu_mid = MCBUS_CPU_MID(ctl);
if ((ctl & CPU_Fill_Err) == 0 && mcbus_primary.mcbus_valid == 0) {
mcbus_primary.mcbus_bcache =
MCBUS_CPU_INFO(ctl) & CPU_BCacheMask;
mcbus_primary.mcbus_valid = 1;
}
alpha_mb();
ccp->cc_initted = 1;
}
void
mcpcia_config_cleanup()
{
volatile u_int32_t ctl;
struct mcpcia_softc *mcp;
/*
* Turn on Hard, Soft error interrupts. Maybe i2c too.
*/
for (mcp = mcpcias; mcp; mcp = mcp->mcpcia_next) {
ctl = REGVAL(MCPCIA_INT_MASK0(mcp));
ctl |= MCPCIA_GEN_IENABL;
REGVAL(MCPCIA_INT_MASK0(mcp)) = ctl;
alpha_mb();
/* force stall while write completes */
ctl = REGVAL(MCPCIA_INT_MASK0(mcp));
}
}

View File

@ -0,0 +1,74 @@
/* $NetBSD: mcpcia_bus_io.c,v 1.1 1998/04/15 00:50:14 mjacob Exp $ */
/*
* Copyright (c) 1998 by Matthew Jacob
* NASA AMES Research Center.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(1, "$NetBSD: mcpcia_bus_io.c,v 1.1 1998/04/15 00:50:14 mjacob Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
#include <sys/device.h>
#include <vm/vm.h>
#include <machine/bus.h>
#include <alpha/pci/mcpciareg.h>
#include <alpha/pci/mcpciavar.h>
#define CHIP mcpcia
#define CHIP_EX_MALLOC_SAFE(v) (1)
#define CHIP_IO_EXTENT(v) (((struct mcpcia_config *)(v))->cc_io_ex)
#define CHIP_IO_EX_STORE(v) (((struct mcpcia_config *)(v))->cc_io_exstorage)
#define CHIP_IO_EX_STORE_SIZE(v) \
(sizeof (((struct mcpcia_config *)(v))->cc_io_exstorage))
/* IO Region 1 */
#define CHIP_IO_W1_BUS_START(v) 0x00000000UL
#define CHIP_IO_W1_BUS_END(v) 0x0000ffffUL
#define CHIP_IO_W1_SYS_START(v) \
(((struct mcpcia_config *)(v))->cc_sysbase | MCPCIA_PCI_IOSPACE)
#define CHIP_IO_W1_SYS_END(v) \
(CHIP_IO_W1_SYS_START(v) + ((CHIP_IO_W1_BUS_END(v) + 1) << 5) - 1)
/* IO Region 2 */
#define CHIP_IO_W2_BUS_START(v) 0x00010000UL
#define CHIP_IO_W2_BUS_END(v) 0x01ffffffUL
#define CHIP_IO_W2_SYS_START(v) \
(((struct mcpcia_config *)(v))->cc_sysbase + MCPCIA_PCI_IOSPACE + \
(0x00010000 << 5))
#define CHIP_IO_W2_SYS_END(v) \
((CHIP_IO_W1_SYS_START(v) + ((CHIP_IO_W2_BUS_END(v) + 1) << 5) - 1))
#include <alpha/pci/pci_swiz_bus_io_chipdep.c>

View File

@ -0,0 +1,88 @@
/* $NetBSD: mcpcia_bus_mem.c,v 1.1 1998/04/15 00:50:14 mjacob Exp $ */
/*
* Copyright (c) 1998 by Matthew Jacob
* NASA AMES Research Center.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(1, "$NetBSD: mcpcia_bus_mem.c,v 1.1 1998/04/15 00:50:14 mjacob Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
#include <sys/device.h>
#include <vm/vm.h>
#include <machine/bus.h>
#include <alpha/pci/mcpciareg.h>
#include <alpha/pci/mcpciavar.h>
#define CHIP mcpcia
#define CHIP_EX_MALLOC_SAFE(v) (1)
#define CHIP_D_MEM_EXTENT(v) (((struct mcpcia_config *)(v))->cc_d_mem_ex)
#define CHIP_D_MEM_EX_STORE(v) \
(((struct mcpcia_config *)(v))->cc_dmem_exstorage)
#define CHIP_D_MEM_EX_STORE_SIZE(v) \
(sizeof (((struct mcpcia_config *)(v))->cc_dmem_exstorage))
#define CHIP_S_MEM_EXTENT(v) (((struct mcpcia_config *)(v))->cc_s_mem_ex)
#define CHIP_S_MEM_EX_STORE(v) \
(((struct mcpcia_config *)(v))->cc_smem_exstorage)
#define CHIP_S_MEM_EX_STORE_SIZE(v) \
(sizeof (((struct mcpcia_config *)(v))->cc_smem_exstorage))
/* Dense region 1 */
#define CHIP_D_MEM_W1_BUS_START(v) 0x00000000UL
#define CHIP_D_MEM_W1_BUS_END(v) 0x7fffffffUL
#define CHIP_D_MEM_W1_SYS_START(v) \
(((struct mcpcia_config *)(v))->cc_sysbase | MCPCIA_PCI_DENSE)
#define CHIP_D_MEM_W1_SYS_END(v) \
(CHIP_D_MEM_W1_SYS_START(v) + 0x7fffffffUL)
/* Sparse region 1 */
#define CHIP_S_MEM_W1_BUS_START(v) 0x00000000UL
#define CHIP_S_MEM_W1_BUS_END(v) 0x00ffffffUL
#define CHIP_S_MEM_W1_SYS_START(v) \
(((struct mcpcia_config *)(v))->cc_sysbase | MCPCIA_PCI_SPARSE)
#define CHIP_S_MEM_W1_SYS_END(v) \
(CHIP_S_MEM_W1_SYS_START(v) + ((CHIP_S_MEM_W1_BUS_END(v) + 1) << 5) - 1)
/* Sparse region 2 */
#define CHIP_S_MEM_W2_BUS_START(v) 0x01000000UL
#define CHIP_S_MEM_W2_BUS_END(v) 0x07FFFFFFUL
#define CHIP_S_MEM_W2_SYS_START(v) \
((((struct mcpcia_config *)(v))->cc_sysbase|MCPCIA_PCI_SPARSE) + \
(0x01000000UL<<5))
#define CHIP_S_MEM_W2_SYS_END(v) \
(CHIP_S_MEM_W1_SYS_START(v) + ((CHIP_S_MEM_W2_BUS_END(v) + 1) << 5) - 1)
#include <alpha/pci/pci_swiz_bus_mem_chipdep.c>

View File

@ -0,0 +1,465 @@
/* $NetBSD: mcpcia_dma.c,v 1.1 1998/04/15 00:50:14 mjacob Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center. This code happens to have been written
* by Matthew Jacob for NASA/Ames.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPEMCPCIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: mcpcia_dma.c,v 1.1 1998/04/15 00:50:14 mjacob Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <vm/vm.h>
#define _ALPHA_BUS_DMA_PRIVATE
#include <machine/bus.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <alpha/pci/mcpciareg.h>
#include <alpha/pci/mcpciavar.h>
#include <alpha/pci/pci_kn300.h>
bus_dma_tag_t mcpcia_dma_get_tag __P((bus_dma_tag_t, alpha_bus_t));
int mcpcia_bus_dmamap_create_sgmap __P((bus_dma_tag_t, bus_size_t, int,
bus_size_t, bus_size_t, int, bus_dmamap_t *));
void mcpcia_bus_dmamap_destroy_sgmap __P((bus_dma_tag_t, bus_dmamap_t));
int mcpcia_bus_dmamap_load_direct __P((bus_dma_tag_t, bus_dmamap_t, void *,
bus_size_t, struct proc *, int));
int mcpcia_bus_dmamap_load_sgmap __P((bus_dma_tag_t, bus_dmamap_t, void *,
bus_size_t, struct proc *, int));
int mcpcia_bus_dmamap_load_mbuf_direct __P((bus_dma_tag_t, bus_dmamap_t,
struct mbuf *, int));
int mcpcia_bus_dmamap_load_mbuf_sgmap __P((bus_dma_tag_t, bus_dmamap_t,
struct mbuf *, int));
int mcpcia_bus_dmamap_load_uio_direct __P((bus_dma_tag_t, bus_dmamap_t,
struct uio *, int));
int mcpcia_bus_dmamap_load_uio_sgmap __P((bus_dma_tag_t, bus_dmamap_t,
struct uio *, int));
int mcpcia_bus_dmamap_load_raw_direct __P((bus_dma_tag_t, bus_dmamap_t,
bus_dma_segment_t *, int, bus_size_t, int));
int mcpcia_bus_dmamap_load_raw_sgmap __P((bus_dma_tag_t, bus_dmamap_t,
bus_dma_segment_t *, int, bus_size_t, int));
void mcpcia_bus_dmamap_unload_sgmap __P((bus_dma_tag_t, bus_dmamap_t));
#define MCPCIA_DIRECT_MAPPED_BASE 0x80000000
#define MCPCIA_SG_MAPPED_BASE (8 << 20)
#define MCPCIA_SGTLB_INVALIDATE(mcp) \
alpha_mb(), \
REGVAL(MCPCIA_SG_TBIA(mcp)) = 0xdeadbeef, \
alpha_mb()
void
mcpcia_dma_init(ccp)
struct mcpcia_config *ccp;
{
bus_dma_tag_t t;
/*
* Initialize the DMA tag used for direct-mapped DMA.
*/
t = &ccp->cc_dmat_direct;
t->_cookie = ccp;
t->_get_tag = mcpcia_dma_get_tag;
t->_dmamap_create = _bus_dmamap_create;
t->_dmamap_destroy = _bus_dmamap_destroy;
t->_dmamap_load = mcpcia_bus_dmamap_load_direct;
t->_dmamap_load_mbuf = mcpcia_bus_dmamap_load_mbuf_direct;
t->_dmamap_load_uio = mcpcia_bus_dmamap_load_uio_direct;
t->_dmamap_load_raw = mcpcia_bus_dmamap_load_raw_direct;
t->_dmamap_unload = _bus_dmamap_unload;
t->_dmamap_sync = _bus_dmamap_sync;
t->_dmamem_alloc = _bus_dmamem_alloc;
t->_dmamem_free = _bus_dmamem_free;
t->_dmamem_map = _bus_dmamem_map;
t->_dmamem_unmap = _bus_dmamem_unmap;
t->_dmamem_mmap = _bus_dmamem_mmap;
/*
* Initialize the DMA tag used for sgmap-mapped DMA.
*/
t = &ccp->cc_dmat_sgmap;
t->_cookie = ccp;
t->_get_tag = mcpcia_dma_get_tag;
t->_dmamap_create = mcpcia_bus_dmamap_create_sgmap;
t->_dmamap_destroy = mcpcia_bus_dmamap_destroy_sgmap;
t->_dmamap_load = mcpcia_bus_dmamap_load_sgmap;
t->_dmamap_load_mbuf = mcpcia_bus_dmamap_load_mbuf_sgmap;
t->_dmamap_load_uio = mcpcia_bus_dmamap_load_uio_sgmap;
t->_dmamap_load_raw = mcpcia_bus_dmamap_load_raw_sgmap;
t->_dmamap_unload = mcpcia_bus_dmamap_unload_sgmap;
t->_dmamap_sync = _bus_dmamap_sync;
t->_dmamem_alloc = _bus_dmamem_alloc;
t->_dmamem_free = _bus_dmamem_free;
t->_dmamem_map = _bus_dmamem_map;
t->_dmamem_unmap = _bus_dmamem_unmap;
t->_dmamem_mmap = _bus_dmamem_mmap;
/*
* The SRM console is supposed to set up an 8MB direct mapped window
* at 8MB (window 0) and a 1MB direct mapped window at 1MB. Useless.
*
* The DU && OpenVMS convention is to have an 8MB S/G window
* at 8MB for window 0, a 1GB direct mapped window at 2GB
* for window 1, a 1 GB S/G window at window 2 and a 512 MB
* S/G window at window 3. This seems overkill.
*
* We'll just go with the 8MB S/G window and one 1GB direct window.
*/
/*
* Initialize the SGMAP.
*
* Must align page table to its size.
*/
alpha_sgmap_init(t, &ccp->cc_sgmap, "mcpcia_sgmap",
MCPCIA_SG_MAPPED_BASE, 0, (8 << 20),
sizeof(u_int64_t), NULL, 8 << 10);
if (ccp->cc_sgmap.aps_ptpa & (1024-1)) {
panic("mcpcia_dma_init: bad page table address %x",
ccp->cc_sgmap.aps_ptpa);
}
/*
* Disable windows first.
*/
REGVAL(MCPCIA_W0_BASE(ccp->cc_sc)) = 0;
REGVAL(MCPCIA_W1_BASE(ccp->cc_sc)) = 0;
REGVAL(MCPCIA_W2_BASE(ccp->cc_sc)) = 0;
REGVAL(MCPCIA_W3_BASE(ccp->cc_sc)) = 0;
REGVAL(MCPCIA_T0_BASE(ccp->cc_sc)) = 0;
REGVAL(MCPCIA_T1_BASE(ccp->cc_sc)) = 0;
REGVAL(MCPCIA_T2_BASE(ccp->cc_sc)) = 0;
REGVAL(MCPCIA_T3_BASE(ccp->cc_sc)) = 0;
alpha_mb();
/*
* Set up window 0 as an 8MB SGMAP-mapped window starting at 8MB.
*/
REGVAL(MCPCIA_W0_MASK(ccp->cc_sc)) = MCPCIA_WMASK_8M;
REGVAL(MCPCIA_T0_BASE(ccp->cc_sc)) =
ccp->cc_sgmap.aps_ptpa >> MCPCIA_TBASEX_SHIFT;
REGVAL(MCPCIA_W0_BASE(ccp->cc_sc)) =
MCPCIA_WBASE_EN | MCPCIA_WBASE_SG | MCPCIA_SG_MAPPED_BASE;
alpha_mb();
MCPCIA_SGTLB_INVALIDATE(ccp->cc_sc);
/*
* Set up window 1 as a 1 GB Direct-mapped window starting at 2GB.
*/
REGVAL(MCPCIA_W0_MASK(ccp->cc_sc)) = MCPCIA_WMASK_1G;
REGVAL(MCPCIA_T0_BASE(ccp->cc_sc)) = 0;
REGVAL(MCPCIA_W0_BASE(ccp->cc_sc)) =
MCPCIA_DIRECT_MAPPED_BASE | MCPCIA_WBASE_EN;
alpha_mb();
/* XXX XXX BEGIN XXX XXX */
{ /* XXX */
extern vm_offset_t alpha_XXX_dmamap_or; /* XXX */
alpha_XXX_dmamap_or = MCPCIA_DIRECT_MAPPED_BASE;/* XXX */
} /* XXX */
/* XXX XXX END XXX XXX */
}
/*
* Return the bus dma tag to be used for the specified bus type.
* INTERNAL USE ONLY!
*/
bus_dma_tag_t
mcpcia_dma_get_tag(t, bustype)
bus_dma_tag_t t;
alpha_bus_t bustype;
{
struct mcpcia_config *ccp = t->_cookie;
extern int physmem;
switch (bustype) {
case ALPHA_BUS_PCI:
case ALPHA_BUS_EISA:
/*
* As best as I can tell from the DU source, you can't
* do DIRECT MAPPED and S/G at the same time.
*/
return (&ccp->cc_dmat_direct);
case ALPHA_BUS_ISA:
/*
* ISA doesn't have enough address bits to use
* the direct-mapped DMA window, so we must use
* SGMAPs.
*/
return (&ccp->cc_dmat_sgmap);
default:
panic("mcpcia_dma_get_tag: shouldn't be here, really...");
}
}
/*
* Create a MCPCIA SGMAP-mapped DMA map.
*/
int
mcpcia_bus_dmamap_create_sgmap(t, size, nsegments, maxsegsz, boundary,
flags, dmamp)
bus_dma_tag_t t;
bus_size_t size;
int nsegments;
bus_size_t maxsegsz;
bus_size_t boundary;
int flags;
bus_dmamap_t *dmamp;
{
struct mcpcia_config *ccp = t->_cookie;
bus_dmamap_t map;
int error;
error = _bus_dmamap_create(t, size, nsegments, maxsegsz,
boundary, flags, dmamp);
if (error)
return (error);
map = *dmamp;
if (flags & BUS_DMA_ALLOCNOW) {
error = alpha_sgmap_alloc(map, round_page(size),
&ccp->cc_sgmap, flags);
if (error)
mcpcia_bus_dmamap_destroy_sgmap(t, map);
}
return (error);
}
/*
* Destroy a MCPCIA SGMAP-mapped DMA map.
*/
void
mcpcia_bus_dmamap_destroy_sgmap(t, map)
bus_dma_tag_t t;
bus_dmamap_t map;
{
struct mcpcia_config *ccp = t->_cookie;
if (map->_dm_flags & DMAMAP_HAS_SGMAP)
alpha_sgmap_free(map, &ccp->cc_sgmap);
_bus_dmamap_destroy(t, map);
}
/*
* Load a MCPCIA direct-mapped DMA map with a linear buffer.
*/
int
mcpcia_bus_dmamap_load_direct(t, map, buf, buflen, p, flags)
bus_dma_tag_t t;
bus_dmamap_t map;
void *buf;
bus_size_t buflen;
struct proc *p;
int flags;
{
return (_bus_dmamap_load_direct_common(t, map, buf, buflen, p,
flags, MCPCIA_DIRECT_MAPPED_BASE));
}
/*
* Load a MCPCIA SGMAP-mapped DMA map with a linear buffer.
*/
int
mcpcia_bus_dmamap_load_sgmap(t, map, buf, buflen, p, flags)
bus_dma_tag_t t;
bus_dmamap_t map;
void *buf;
bus_size_t buflen;
struct proc *p;
int flags;
{
int error;
struct mcpcia_config *ccp = t->_cookie;
error = pci_sgmap_pte64_load(t, map, buf, buflen, p,
flags, &ccp->cc_sgmap);
if (error == 0)
MCPCIA_SGTLB_INVALIDATE(ccp->cc_sc);
return (error);
}
/*
* Load a MCPCIA direct-mapped DMA map with an mbuf chain.
*/
int
mcpcia_bus_dmamap_load_mbuf_direct(t, map, m, flags)
bus_dma_tag_t t;
bus_dmamap_t map;
struct mbuf *m;
int flags;
{
return (_bus_dmamap_load_mbuf_direct_common(t, map, m,
flags, MCPCIA_DIRECT_MAPPED_BASE));
}
/*
* Load a MCPCIA SGMAP-mapped DMA map with an mbuf chain.
*/
int
mcpcia_bus_dmamap_load_mbuf_sgmap(t, map, m, flags)
bus_dma_tag_t t;
bus_dmamap_t map;
struct mbuf *m;
int flags;
{
int error;
struct mcpcia_config *ccp = t->_cookie;
error = pci_sgmap_pte64_load_mbuf(t, map, m, flags, &ccp->cc_sgmap);
if (error == 0)
MCPCIA_SGTLB_INVALIDATE(ccp->cc_sc);
return (error);
}
/*
* Load a MCPCIA direct-mapped DMA map with a uio.
*/
int
mcpcia_bus_dmamap_load_uio_direct(t, map, uio, flags)
bus_dma_tag_t t;
bus_dmamap_t map;
struct uio *uio;
int flags;
{
return (_bus_dmamap_load_uio_direct_common(t, map, uio,
flags, MCPCIA_DIRECT_MAPPED_BASE));
}
/*
* Load a MCPCIA SGMAP-mapped DMA map with a uio.
*/
int
mcpcia_bus_dmamap_load_uio_sgmap(t, map, uio, flags)
bus_dma_tag_t t;
bus_dmamap_t map;
struct uio *uio;
int flags;
{
int error;
struct mcpcia_config *ccp = t->_cookie;
error = pci_sgmap_pte64_load_uio(t, map, uio, flags, &ccp->cc_sgmap);
if (error == 0)
MCPCIA_SGTLB_INVALIDATE(ccp->cc_sc);
return (error);
}
/*
* Load a MCPCIA direct-mapped DMA map with raw memory.
*/
int
mcpcia_bus_dmamap_load_raw_direct(t, map, segs, nsegs, size, flags)
bus_dma_tag_t t;
bus_dmamap_t map;
bus_dma_segment_t *segs;
int nsegs;
bus_size_t size;
int flags;
{
return (_bus_dmamap_load_raw_direct_common(t, map, segs, nsegs,
size, flags, MCPCIA_DIRECT_MAPPED_BASE));
}
/*
* Load a MCPCIA SGMAP-mapped DMA map with raw memory.
*/
int
mcpcia_bus_dmamap_load_raw_sgmap(t, map, segs, nsegs, size, flags)
bus_dma_tag_t t;
bus_dmamap_t map;
bus_dma_segment_t *segs;
int nsegs;
bus_size_t size;
int flags;
{
int error;
struct mcpcia_config *ccp = t->_cookie;
error = pci_sgmap_pte64_load_raw(t, map, segs, nsegs,
size, flags, &ccp->cc_sgmap);
if (error == 0)
MCPCIA_SGTLB_INVALIDATE(ccp->cc_sc);
return (error);
}
/*
* Unload a MCPCIA DMA map.
*/
void
mcpcia_bus_dmamap_unload_sgmap(t, map)
bus_dma_tag_t t;
bus_dmamap_t map;
{
struct mcpcia_config *ccp = t->_cookie;
/*
* Invalidate any SGMAP page table entries used by this mapping.
*/
pci_sgmap_pte64_unload(t, map, &ccp->cc_sgmap);
MCPCIA_SGTLB_INVALIDATE(ccp->cc_sc);
/*
* Do the generic bits of the unload.
*/
_bus_dmamap_unload(t, map);
}

View File

@ -0,0 +1,186 @@
/* $NetBSD: mcpcia_pci.c,v 1.1 1998/04/15 00:50:14 mjacob Exp $ */
/*
* Copyright (c) 1998 by Matthew Jacob
* NASA AMES Research Center.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: mcpcia_pci.c,v 1.1 1998/04/15 00:50:14 mjacob Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <vm/vm.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <alpha/tlsb/tlsbreg.h>
#include <alpha/pci/mcpciareg.h>
#include <alpha/pci/mcpciavar.h>
#define KV(_addr) ((caddr_t)ALPHA_PHYS_TO_K0SEG((_addr)))
void mcpcia_attach_hook __P((struct device *, struct device *,
struct pcibus_attach_args *));
int mcpcia_bus_maxdevs __P((void *, int));
pcitag_t mcpcia_make_tag __P((void *, int, int, int));
void mcpcia_decompose_tag __P((void *, pcitag_t, int *, int *,
int *));
pcireg_t mcpcia_conf_read __P((void *, pcitag_t, int));
void mcpcia_conf_write __P((void *, pcitag_t, int, pcireg_t));
void
mcpcia_pci_init(pc, v)
pci_chipset_tag_t pc;
void *v;
{
pc->pc_conf_v = v;
pc->pc_attach_hook = mcpcia_attach_hook;
pc->pc_bus_maxdevs = mcpcia_bus_maxdevs;
pc->pc_make_tag = mcpcia_make_tag;
pc->pc_decompose_tag = mcpcia_decompose_tag;
pc->pc_conf_read = mcpcia_conf_read;
pc->pc_conf_write = mcpcia_conf_write;
}
void
mcpcia_attach_hook(parent, self, pba)
struct device *parent, *self;
struct pcibus_attach_args *pba;
{
#if 0
struct mcpcia_config *ccp = pba->pba_pc->pc_conf_v;
printf("mcpcia_attach_hook for %s\n", ccp->cc_sc->mcpcia_dev.dv_xname);
#endif
}
int
mcpcia_bus_maxdevs(cpv, busno)
void *cpv;
int busno;
{
return (MCPCIA_MAXDEV);
}
pcitag_t
mcpcia_make_tag(cpv, b, d, f)
void *cpv;
int b, d, f;
{
pcitag_t tag;
tag = (b << 21) | (d << 16) | (f << 13);
return (tag);
}
void
mcpcia_decompose_tag(cpv, tag, bp, dp, fp)
void *cpv;
pcitag_t tag;
int *bp, *dp, *fp;
{
if (bp != NULL)
*bp = (tag >> 21) & 0xff;
if (dp != NULL)
*dp = (tag >> 16) & 0x1f;
if (fp != NULL)
*fp = (tag >> 13) & 0x7;
}
pcireg_t
mcpcia_conf_read(cpv, tag, offset)
void *cpv;
pcitag_t tag;
int offset;
{
struct mcpcia_config *ccp = cpv;
pcireg_t *dp, data = (pcireg_t) -1;
unsigned long paddr;
/*
* There's nothing in slot 0 on a primary bus- don't even try.
*/
if ((tag >> 21) == 0 && ((u_int32_t) tag & 0x1f0000) == 0)
return (data);
if (ccp == NULL) {
panic("NULL ccp in mcpcia_conf_read");
}
paddr = (unsigned long) tag;
paddr |= (3LL << 3); /* 32 Bit PCI byte enables */
paddr |= ((unsigned long) ((offset >> 2) << 7));
paddr |= MCPCIA_PCI_CONF;
paddr |= ccp->cc_sysbase;
#if 0
printf("mcpcia_conf_read: read paddr %lx\n", paddr);
#endif
dp = (pcireg_t *)KV(paddr);
if (badaddr(dp, sizeof (*dp)) == 0) {
data = *dp;
}
return (data);
}
void
mcpcia_conf_write(cpv, tag, offset, data)
void *cpv;
pcitag_t tag;
int offset;
pcireg_t data;
{
struct mcpcia_config *ccp = cpv;
pcireg_t *dp;
unsigned long paddr;
/*
* There's nothing in slot 0 on a primary bus- don't even try.
*/
if ((tag >> 21) == 0 && ((u_int32_t) tag & 0x1f0000) == 0)
return;
if (ccp == NULL) {
panic("NULL ccp in mcpcia_conf_write");
}
paddr = (unsigned long) tag;
paddr |= (3LL << 3); /* 32 Bit PCI byte enables */
paddr |= ((unsigned long) ((offset >> 2) << 7));
paddr |= MCPCIA_PCI_CONF;
paddr |= ccp->cc_sysbase;
#if 0
printf("mcpcia_conf_write: write paddr %lx\n", paddr);
#endif
dp = (pcireg_t *)KV(paddr);
*dp = data;
alpha_mb();
}

View File

@ -0,0 +1,386 @@
/* $NetBSD: mcpciareg.h,v 1.1 1998/04/15 00:50:14 mjacob Exp $ */
/*
* Copyright (c) 1998 by Matthew Jacob
* NASA AMES Research Center.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Taken from:
*
* ``RAWHIDE Systems Programmer's Manual, Revision 1.4''
*/
#define REGVAL(r) (*(volatile int32_t *)ALPHA_PHYS_TO_K0SEG(r))
/*
* There are 4 possible PCI busses per MCBUS.
*
* (from mcpcia.h, Digital Unix 4.0E):
*
* I/O Space Per PCI Node (8GBytes per)
* ------------------------------------
* (8+x)8 0000 0000 - (8+x)9 FFFF FFFF - I/O Space for PCI0
* (8+x)A 0000 0000 - (8+x)B FFFF FFFF - I/O Space for PCI1
* (8+x)C 0000 0000 - (8+x)D FFFF FFFF - I/O Space for PCI2
* (8+x)E 0000 0000 - (8+x)F FFFF FFFF - I/O Space for PCI3
*
* CPU to PCI Address Mapping:
* ---------------------------
*
* +---+-------+-------+--+--+--+--+--+--+---------------+----------+-----+
* | 1 | GID | MID | | | | | | | Byte Aligned | Byte Len | Zero|
* | | | | | | | | | | I/O Address | Field | |
* +---+-------+-------+--+--+--+--+--+--+---------------+----------+-----+
* 39 38 36 35 33 32 31 30 29 28 27 26 5 4 3 2 0
*
* <39> - I/O Select (Always 1 for direct I/O access)
*
* <38-36> - Global Bus slot # (MCBUS #)
* GID slot #0->7 (MCBUS #0->7)
*
* <35-33> - MCBUS Slot #
* MCBUS slot 0->7
*
* <32-27> - PCI Address Space
* 0.xxxxx = Sparse Memory Space ( 4GB on MCBUS; 128MB on PCI)
* 1.0xxxx = Dense Memory Space ( 2GB on MCBUS; 2GB on PCI)
* 1.10xxx = Sparse IO Space ( 1GB on MCBUS; 32MB on PCI)
* 1.110xx = Sparse Config Space (512MB on MCBUS; 16MB on PCI)
* 1.1110x = PCI Bridge CSR Space (256MB on MCBUS) -- Sparse-mapped!
* 1.11110 = Interrupt Acknowledge (128MB on MCBUS)
* 1.11111 = Unused (128MB on MCBUS)
*
* ------------------------------------------------------------
* Cpu to PCI Address Mapping for MCBUS-PCIy Bridge on MCBUS x:
* ------------------------------------------------------------
*
* CPU Address Range PCI Address Range PCI Address Space
* ------------------------ --------------------- ------------------------
* (8+x)(8+y*2).0000.0000 0000.0000 - 00FF.FFFF PCIy Sparse Memory Space
* - (8+x)(8+y*2).1FFF.FFFF (fixed, lower 16MB)
*
* (8+x)(8+y*2).2000.0000 0100.0000 - 07FF.FFFF PCIy Sparse Memory Space
* - (8+x)(8+y*2).FFFF.FFFF (variable, offset = 0)
*
* (8+x)(9+y*2).0000.0000 0000.0000 - 7FFF.FFFF PCIy Dense Memory Space
* - (8+x)(9+y*2).7FFF.FFFF or 8000.0000 - FFFF.FFFF if HAE_DENSE_MEM = 1
*
* (8+x)(9+y*2).8000.0000 0000.0000 - 0000.FFFF PCIy Sparse IO Space
* - (8+x)(9+y*2).801F.FFFF (fixed, lower 64K)
*
* (8+x)(9+y*2).8020.0000 0001.0000 - 01FF.FFFF PCIy Sparse IO Space
* - (8+x)(9+y*2).BFFF.FFFF (variable, offset = 0)
*
* (8+x)(9+y*2).C000.0000 0000.0000 - 0FFF.FFFF PCIy Config Space (16MB)
* - (8+x)(9+y*2).DFFF.FFFF
*
* (8+x)(9+y*2).E000.0000 N/A PCIy-Bridge CSR Space
* (8MB)
* - (8+x)(9+y*2).EFFF.FFFF
*
* (8+x)(9+y*2).F000.0000 N/A Unused
* - (8+x)(9+y*2).F000.3EFF
*
* (8+x)(9+y*2).F000.3F00, N/A PCIy Interrupt ACK0
* (8+x)(9+y*2).F000.3F40 PCIy INteruppt ACK1
*
* (8+x)(9+y*2).F000.3F80 N/A Unused
* - (8+x)(9+y*2).FFFF.FFFF
*
*/
/*
* MC-PCI Bus Bridge CSRs
*
* Address Map Overview:
*
* Offset Selected Space
* ---------------- -------------------------------------------------
* 0x00000000 General config, control, diag, error logging regs.
* 0x00001000 PCI Error Status
* 0x00001300 PCI Scatter/Gather Regs.
* 0x00001800 Scatter/Gather TLB Regs.
* 0x00004000 MDPA Error Status & Diagnostic Control
* 0x00008000 MDPB Error Status & Diagnostic Control
* 0x000E0000 - Flash Rom Space --
* 0x000FFFFF offset address into PCI Dense Mem Space
* 0x10003F00 Interrupt Acknowledge
*
*/
/*
* Address Space Cookies
*/
#define MCPCIA_PCI_SPARSE 0x000000000LL
#define MCPCIA_PCI_DENSE 0x100000000LL
#define MCPCIA_PCI_IOSPACE 0x180000000LL
#define MCPCIA_PCI_CONF 0x1C0000000LL
#define MCPCIA_PCI_BRIDGE 0x1E0000000LL
#define MCPCIA_PCI_IACK 0x1F0000000LL
/*
* MCPCIA Bus Bridge Registers
*
* These are offsets that don't include GBUS, MID, or address space offsets.
*/
#define _MCPCIA_PCI_REV 0x000000000 /* PCI Revision Register (R) */
#define _MCPCIA_WHOAMI 0x000000040 /* PCI Who Am I (R) */
#define _MCPCIA_PCI_LAT 0x000000080 /* PCI Latency Timer (RW) */
#define _MCPCIA_CAP_CTRL 0x000000100 /* PCI Bridge Control (RW) */
#define _MCPCIA_HAE_MEM 0x000000400 /* PCI HAE Sparse Memory (RW) */
#define _MCPCIA_HAE_IO 0x000000440 /* PCI HAE Sparse I/O (RW) */
#define _MCPCIA_IACK_SC 0x000000480 /* PCI Special Cycle Ack */
#define _MCPCIA_HAE_DENSE 0x0000004C0 /* PCI HAE Dense Memory (RW) */
#define _MCPCIA_INT_CTL 0x000000500 /* PCI Interrupt Control */
#define _MCPCIA_INT_REQ 0x000000540 /* PCI Interrupt Request */
#define _MCPCIA_INT_TARG 0x000000580 /* PCI Int Tgt Devices */
#define _MCPCIA_INT_ADR 0x0000005C0 /* PCI Int Tgt Address */
#define _MCPCIA_INT_ADR_EXT 0x000000600 /* PCI Int Tgt Addr Ext */
#define _MCPCIA_INT_MASK0 0x000000640 /* PCI Int Mask 0 */
#define _MCPCIA_INT_MASK1 0x000000680 /* PCI Int Mask 1 */
#define _MCPCIA_INT_ACK0 0x100003F00 /* PCI Int Ack 0 */
#define _MCPCIA_INT_ACK1 0x100003F40 /* PCI Int Ack 1 */
#define _MCPCIA_PERF_MON 0x000000300 /* PCI Perf Monitor */
#define _MCPCIA_PERF_CONT 0x000000340 /* PCI Perf Monitor Control */
#define _MCPCIA_CAP_DIAG 0x000000700 /* MC-PCI Diagnostic Control */
#define _MCPCIA_SCRATCH0 0x000000740 /* Diag General */
#define _MCPCIA_SCRATCH1 0x000000780 /* Diag General */
#define _MCPCIA_TOM 0x0000007C0 /* Top Of Memory */
#define _MCPCIA_MC_ERR0 0x000000800 /* MC Err Info 0 */
#define _MCPCIA_MC_ERR1 0x000000840 /* MC Err Info 1 */
#define _MCPCIA_CAP_ERR 0x000000880 /* CAP Error Register */
#define _MCPCIA_PCI_ERR1 0x000001040 /* PCI Error Status */
#define _MCPCIA_MDPA_STAT 0x000004000 /* MDPA Status */
#define _MCPCIA_MDPA_SYN 0x000004040 /* MDPA Syndrome */
#define _MCPCIA_MDPA_DIAG 0x000004080 /* Diag Check MDPA */
#define _MCPCIA_MDPB_STAT 0x000008000 /* MDPB Status */
#define _MCPCIA_MDPB_SYN 0x000008040 /* MDPB Syndrome */
#define _MCPCIA_MDPB_DIAG 0x000008080 /* Diag Check MDPB */
#define _MCPCIA_SG_TBIA 0x000001300 /* Scatter/Gather TBIA */
#define _MCPCIA_HBASE 0x000001340 /* PC "Hole" Compatibility */
#define _MCPCIA_W0_BASE 0x000001400 /* Window Base 0 */
#define _MCPCIA_W0_MASK 0x000001440 /* Window Mask 0 */
#define _MCPCIA_T0_BASE 0x000001480 /* Translated Base 0 */
#define _MCPCIA_W1_BASE 0x000001500 /* Window Base 1 */
#define _MCPCIA_W1_MASK 0x000001540 /* Window Mask 1 */
#define _MCPCIA_T1_BASE 0x000001580 /* Translated Base 1 */
#define _MCPCIA_W2_BASE 0x000001600 /* Window Base 2 */
#define _MCPCIA_W2_MASK 0x000001640 /* Window Mask 2 */
#define _MCPCIA_T2_BASE 0x000001680 /* Translated Base 2 */
#define _MCPCIA_W3_BASE 0x000001700 /* Window Base 3 */
#define _MCPCIA_W3_MASK 0x000001740 /* Window Mask 3 */
#define _MCPCIA_T3_BASE 0x000001780 /* Translated Base 3 */
#define _MCPCIA_W_DAC 0x0000017C0 /* Window DAC Base */
/*
* Handier defines- uses precalculated offset in softc.
*/
#define _SYBRIDGE(sc) ((sc)->mcpcia_cc.cc_sysbase | MCPCIA_PCI_BRIDGE)
#define MCPCIA_PCI_REV(sc) (_SYBRIDGE(sc) | _MCPCIA_PCI_REV)
#define MCPCIA_WHOAMI(sc) (_SYBRIDGE(sc) | _MCPCIA_WHOAMI)
#define MCPCIA_PCI_LAT(sc) (_SYBRIDGE(sc) | _MCPCIA_PCI_LAT)
#define MCPCIA_CAP_CTRL(sc) (_SYBRIDGE(sc) | _MCPCIA_CAP_CTRL)
#define MCPCIA_HAE_MEM(sc) (_SYBRIDGE(sc) | _MCPCIA_HAE_MEM)
#define MCPCIA_HAE_IO(sc) (_SYBRIDGE(sc) | _MCPCIA_HAE_IO)
#define MCPCIA_IACK_SC(sc) (_SYBRIDGE(sc) | _MCPCIA_IACK_SC)
#define MCPCIA_HAE_DENSE(sc) (_SYBRIDGE(sc) | _MCPCIA_HAE_DENSE)
#define MCPCIA_INT_CTL(sc) (_SYBRIDGE(sc) | _MCPCIA_INT_CTL)
#define MCPCIA_INT_REQ(sc) (_SYBRIDGE(sc) | _MCPCIA_INT_REQ)
#define MCPCIA_INT_TARG(sc) (_SYBRIDGE(sc) | _MCPCIA_INT_TARG)
#define MCPCIA_INT_ADR(sc) (_SYBRIDGE(sc) | _MCPCIA_INT_ADR)
#define MCPCIA_INT_ADR_EXT(sc) (_SYBRIDGE(sc) | _MCPCIA_INT_ADR_EXT)
#define MCPCIA_INT_MASK0(sc) (_SYBRIDGE(sc) | _MCPCIA_INT_MASK0)
#define MCPCIA_INT_MASK1(sc) (_SYBRIDGE(sc) | _MCPCIA_INT_MASK1)
#define MCPCIA_INT_ACK0(sc) (_SYBRIDGE(sc) | _MCPCIA_INT_ACK0)
#define MCPCIA_INT_ACK1(sc) (_SYBRIDGE(sc) | _MCPCIA_INT_ACK1)
#define MCPCIA_PERF_MON(sc) (_SYBRIDGE(sc) | _MCPCIA_PERF_MON)
#define MCPCIA_PERF_CONT(sc) (_SYBRIDGE(sc) | _MCPCIA_PERF_CONT)
#define MCPCIA_CAP_DIAG(sc) (_SYBRIDGE(sc) | _MCPCIA_CAP_DIAG)
#define MCPCIA_SCRATCH0(sc) (_SYBRIDGE(sc) | _MCPCIA_SCRATCH0)
#define MCPCIA_SCRATCH1(sc) (_SYBRIDGE(sc) | _MCPCIA_SCRATCH1)
#define MCPCIA_TOM(sc) (_SYBRIDGE(sc) | _MCPCIA_TOM)
#define MCPCIA_MC_ERR0(sc) (_SYBRIDGE(sc) | _MCPCIA_MC_ERR0)
#define MCPCIA_MC_ERR1(sc) (_SYBRIDGE(sc) | _MCPCIA_MC_ERR1)
#define MCPCIA_CAP_ERR(sc) (_SYBRIDGE(sc) | _MCPCIA_CAP_ERR)
#define MCPCIA_PCI_ERR1(sc) (_SYBRIDGE(sc) | _MCPCIA_PCI_ERR1)
#define MCPCIA_MDPA_STAT(sc) (_SYBRIDGE(sc) | _MCPCIA_MDPA_STAT)
#define MCPCIA_MDPA_SYN(sc) (_SYBRIDGE(sc) | _MCPCIA_MDPA_SYN)
#define MCPCIA_MDPA_DIAG(sc) (_SYBRIDGE(sc) | _MCPCIA_MDPA_DIAG)
#define MCPCIA_MDPB_STAT(sc) (_SYBRIDGE(sc) | _MCPCIA_MDPB_STAT)
#define MCPCIA_MDPB_SYN(sc) (_SYBRIDGE(sc) | _MCPCIA_MDPB_SYN)
#define MCPCIA_MDPB_DIAG(sc) (_SYBRIDGE(sc) | _MCPCIA_MDPB_DIAG)
#define MCPCIA_SG_TBIA(sc) (_SYBRIDGE(sc) | _MCPCIA_SG_TBIA)
#define MCPCIA_HBASE(sc) (_SYBRIDGE(sc) | _MCPCIA_HBASE)
#define MCPCIA_W0_BASE(sc) (_SYBRIDGE(sc) | _MCPCIA_W0_BASE)
#define MCPCIA_W0_MASK(sc) (_SYBRIDGE(sc) | _MCPCIA_W0_MASK)
#define MCPCIA_T0_BASE(sc) (_SYBRIDGE(sc) | _MCPCIA_T0_BASE)
#define MCPCIA_W1_BASE(sc) (_SYBRIDGE(sc) | _MCPCIA_W1_BASE)
#define MCPCIA_W1_MASK(sc) (_SYBRIDGE(sc) | _MCPCIA_W1_MASK)
#define MCPCIA_T1_BASE(sc) (_SYBRIDGE(sc) | _MCPCIA_T1_BASE)
#define MCPCIA_W2_BASE(sc) (_SYBRIDGE(sc) | _MCPCIA_W2_BASE)
#define MCPCIA_W2_MASK(sc) (_SYBRIDGE(sc) | _MCPCIA_W2_MASK)
#define MCPCIA_T2_BASE(sc) (_SYBRIDGE(sc) | _MCPCIA_T2_BASE)
#define MCPCIA_W3_BASE(sc) (_SYBRIDGE(sc) | _MCPCIA_W3_BASE)
#define MCPCIA_W3_MASK(sc) (_SYBRIDGE(sc) | _MCPCIA_W3_MASK)
#define MCPCIA_T3_BASE(sc) (_SYBRIDGE(sc) | _MCPCIA_T3_BASE)
#define MCPCIA_W_DAC(sc) (_SYBRIDGE(sc) | _MCPCIA_W_DAC)
/*
* PCI_REV Register definitions
*/
#define CAP_REV(reg) ((reg) & 0xf)
#define HORSE_REV(reg) (((reg) >> 4) & 0xf)
#define SADDLE_REV(reg) (((reg) >> 8) & 0xf)
#define SADDLE_TYPE(reg) (((reg) >> 12) & 0x3)
#define EISA_PRESENT(reg) ((reg) & (1 << 15))
/*
* WHOAMI Register definitions
*
* The Device ID is an echo of the MID of the CPU reading this register-
* cheezy way to figure out who you are (ask someone else!).
*/
#define MCBUS_CPU_MID(x) ((x) & 0x7)
#define MCBUS_CPU_INFO(x) (((x) >> 6) & 0xff)
#define CPU_Fill_Err 0x80
#define CPU_DTAG_Perr 0x40
#define CPU_RevMask 0x38
#define CPU_RevShift 3
#define CPU_BCacheMask 0x3
#define CPU_BCache_0MB 0
#define CPU_BCache_1MB 1
#define CPU_BCache_2MB 2
#define CPU_BCache_4MB 3
/*
* PCI Latency Register Definitions
*/
#define PCI_LAT_SHIFT 8 /* it's in the 2nd byte. */
/*
* CAP Control Register Defintions
*/
#define CAP_LED_ON 0x00000001 /* Selftest LED passed */
#define CAP_EV56_BW_EN 0x00000002 /* BW Enables (EV56, EV6 only) */
#define CAP_DLY_RD_EN 0x00000010 /* PCI Delayed Reads Enabled */
#define CAP_MEM_EN 0x00000020 /* Respond to PCI transactions */
#define CAP_REQ64_EN 0x00000040 /* Request 64 bit data transactions */
#define CAP_ACK64_EN 0x00000080 /* Respond to 64 bit data "" */
#define CAP_ADR_PAR_EN 0x00000100 /* Check PCI address Parity */
#define CAP_MC_CA_PAR 0x00000200 /* Check MC bus CMD/Address Parity */
#define CAP_MC_NXM_EN 0x00000400 /* Check for MC NXM */
#define CAP_BUS_MON 0x00000800 /* Check for PCI errs (as bystander) */
/* bits 19:16 control number of pending write transactions */
#define SHORT 0
#define MED 1
#define LONG 2
#define CAP_MEMRD_PREFETCH_SHIFT 20
#define CAP_MEMRDLN_PREFETCH_SHIFT 22
#define CAP_MEMRDMULT_PREFETCH_SHIFT 24
#define CAP_PARTIAL_WRITE (1 << 26)
#define CAP_ARB_BPRI 0x00000000 /* Bridge Priority Arb */
#define CAP_ARB_RROBIN 0x40000000 /* "" Round Robin */
#define CAP_ARB_RROBIN1 0x80000000 /* "" Round Robin #1 */
/*
* Interrupt Specific bits...
*
* Mostly we don't have to mess with any of the interrupt specific registers
* as the SRM has set most of this pretty complex stuff up for us.
*
* However, to enable specific interrupts, we need to set some bits
* in imask0 if we want to have them vectored to PALcode for appropriate
* dispatch.
*/
/*
* bits 0-15 correspond to 4 slots (time 4 buspins) for each PCI bus.
* bit 16 is the NCR810 onboard SCSI interrupt.
* bits 19-20 are reserved.
*/
#define MCPCIA_I2C_CTRL_INTR (1<<17)
#define MCPCIA_I2C_CTRL_BUS_ERR (1<<18)
#define MCPCIA_8259_NMI_INTR (1<<21)
#define MCPCIA_SOFT_ERR_INTR (1<<22)
#define MCPCIA_HARD_ERR_INTR (1<<23)
#ifdef YET
#define MCPCIA_GEN_IENABL \
(MCPCIA_I2C_CTRL_BUS_ERR|MCPCIA_SOFT_ERR_INTR|MCPCIA_HARD_ERR_INTR)
#else
#define MCPCIA_GEN_IENABL \
(MCPCIA_SOFT_ERR_INTR|MCPCIA_HARD_ERR_INTR)
#endif
/*
* DMA Address Specific bits...
*/
#define MCPCIA_WBASE_EN 0x1
#define MCPCIA_WBASE_SG 0x2
#define MCPCIA_WBASE_DAC 0x8
#define MCPCIA_WBASE_BSHIFT 20
#define MCPCIA_WMASK_1M 0x00000000
#define MCPCIA_WMASK_2M 0x00100000
#define MCPCIA_WMASK_4M 0x00300000
#define MCPCIA_WMASK_8M 0x00700000
#define MCPCIA_WMASK_16M 0x00f00000
#define MCPCIA_WMASK_32M 0x01f00000
#define MCPCIA_WMASK_64M 0x03f00000
#define MCPCIA_WMASK_128M 0x07f00000
#define MCPCIA_WMASK_256M 0x0ff00000
#define MCPCIA_WMASK_512M 0x1ff00000
#define MCPCIA_WMASK_1G 0x3ff00000
#define MCPCIA_WMASK_2G 0x7ff00000
#define MCPCIA_WMASK_4G 0xfff00000
/*
* The WBASEX register contains bits 39:10 of a physical address
* shifted to bits 31:2 of this 32 bit register. Namely, shifted
* right by 8 bits.
*/
#define MCPCIA_TBASEX_SHIFT 8

View File

@ -0,0 +1,108 @@
/* $NetBSD: mcpciavar.h,v 1.1 1998/04/15 00:50:14 mjacob Exp $ */
/*
* Copyright (c) 1998 by Matthew Jacob
* NASA AMES Research Center.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <dev/pci/pcivar.h>
#include <sys/extent.h>
#include <alpha/pci/pci_sgmap_pte64.h>
#define _FSTORE (EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long))
/*
* DWLPX configuration.
*/
struct mcpcia_config {
int cc_initted;
struct alpha_bus_space cc_iot;
struct alpha_bus_space cc_memt;
struct extent * cc_io_ex;
struct extent * cc_d_mem_ex;
struct extent * cc_s_mem_ex;
struct alpha_pci_chipset cc_pc;
struct mcpcia_softc * cc_sc; /* back pointer */
long cc_io_exstorage[_FSTORE];
long cc_dmem_exstorage[_FSTORE];
long cc_smem_exstorage[_FSTORE];
unsigned long cc_sysbase; /* shorthand */
struct alpha_bus_dma_tag cc_dmat_direct;
struct alpha_bus_dma_tag cc_dmat_sgmap;
struct alpha_sgmap cc_sgmap;
};
struct mcpcia_softc {
struct device mcpcia_dev;
struct mcpcia_softc * mcpcia_next; /* next in a list */
struct mcpcia_config mcpcia_cc; /* config info */
u_int8_t mcpcia_gid; /* GID of this MCbus */
u_int8_t mcpcia_mid; /* MCbus Module ID */
};
void mcpcia_config_cleanup __P((void));
extern struct mcpcia_config *mcpcia_eisaccp;
void mcpcia_init __P((struct mcpcia_softc *));
void mcpcia_pci_init __P((pci_chipset_tag_t, void *));
void mcpcia_dma_init __P((struct mcpcia_config *));
void mcpcia_bus_io_init __P((bus_space_tag_t, void *));
void mcpcia_bus_mem_init __P((bus_space_tag_t, void *));
/*
* IO Interrupt handler.
*/
void mcpcia_iointr __P((void *, unsigned long));
/*
* There are four PCI slots per MCPCIA PCI bus here, but some are 'hidden'-
* none seems to be higher than 6 though.
*/
#define MCPCIA_MAXDEV 6
#define MCPCIA_MAXSLOT 8
/*
* Interrupt Stuff for MCPCIA systems.
*
* EISA interrupts (at vector 0x800) have to be shared interrupts-
* and that can be easily managed. All the PCI interrupts are deterministic
* in that they start at vector 0x900, 0x40 per PCI slot, 0x200 per
* MCPCIA, 4 MCPCIAs per GCBUS....
*/
#define MCPCIA_EISA_KEYB_IRQ 1
#define MCPCIA_EISA_MOUSE_IRQ 12
#define MCPCIA_VEC_EISA 0x800
#define MCPCIA_VEC_PCI 0x900
/*
* Special Vectors
*/
#define MCPCIA_I2C_CVEC 0xA90
#define MCPCIA_I2C_BVEC 0xAA0

View File

@ -0,0 +1,396 @@
/* $NetBSD: pci_kn300.c,v 1.1 1998/04/15 00:50:14 mjacob Exp $ */
/*
* Copyright (c) 1998 by Matthew Jacob
* NASA AMES Research Center.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: pci_kn300.c,v 1.1 1998/04/15 00:50:14 mjacob Exp $");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#include <sys/device.h>
#include <sys/syslog.h>
#include <vm/vm.h>
#include <machine/autoconf.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <alpha/mcbus/mcbusvar.h>
#include <alpha/mcbus/mcbusreg.h>
#include <alpha/pci/mcpciareg.h>
#include <alpha/pci/mcpciavar.h>
#include <alpha/pci/pci_kn300.h>
#ifndef EVCNT_COUNTERS
#include <machine/intrcnt.h>
#endif
#include "sio.h"
#if NSIO
#include <alpha/pci/siovar.h>
#endif
int
dec_kn300_intr_map __P((void *, pcitag_t, int, int, pci_intr_handle_t *));
const char *dec_kn300_intr_string __P((void *, pci_intr_handle_t));
void * dec_kn300_intr_establish __P((void *, pci_intr_handle_t,
int, int (*func)(void *), void *));
void dec_kn300_intr_disestablish __P((void *, void *));
#define KN300_PCEB_IRQ 16
#define NPIN 4
static struct vectab {
int (*func) __P((void *));
void *arg;
int irq;
} vectab[MAX_MC_BUS][MCPCIA_PER_MCBUS][MCPCIA_MAXSLOT][NPIN];
struct mcpcia_config *mcpcia_eisaccp = NULL;
#ifdef EVCNT_COUNTERS
struct evcnt kn300_intr_evcnt;
#endif
int kn300_spurious __P((void *));
void kn300_iointr __P((void *, unsigned long));
void kn300_enable_intr __P((struct mcpcia_config *, int));
void kn300_disable_intr __P((struct mcpcia_config *, int));
void
pci_kn300_pickintr(ccp, first)
struct mcpcia_config *ccp;
int first;
{
pci_chipset_tag_t pc = &ccp->cc_pc;
if (first) {
int g;
for (g = 0; g < MAX_MC_BUS; g++) {
int m;
for (m = 0; m < MCPCIA_PER_MCBUS; m++) {
int s;
for (s = 0; s < MCPCIA_MAXSLOT; s++) {
int p;
for (p = 0; p < NPIN; p++) {
struct vectab *vp;
vp = &vectab[g][m][s][p];
vp->func = kn300_spurious;
vp->arg = (void *) ((long)
(g << 0) |
(m << 3) |
(s << 6) |
(p << 9));
vp->irq = -1;
}
}
}
}
set_iointr(kn300_iointr);
}
pc->pc_intr_v = ccp;
pc->pc_intr_map = dec_kn300_intr_map;
pc->pc_intr_string = dec_kn300_intr_string;
pc->pc_intr_establish = dec_kn300_intr_establish;
pc->pc_intr_disestablish = dec_kn300_intr_disestablish;
#if NSIO
if (EISA_PRESENT(REGVAL(MCPCIA_PCI_REV(ccp->cc_sc)))) {
extern void dec_kn300_cons_init __P((void));
bus_space_tag_t iot = &ccp->cc_iot;
if (mcpcia_eisaccp) {
printf("Huh? There's only supposed to be one eisa!\n");
}
sio_intr_setup(iot);
kn300_enable_intr(ccp, KN300_PCEB_IRQ);
mcpcia_eisaccp = ccp;
dec_kn300_cons_init(); /* XXXXXXXXXXXXXXXXXXX */
}
#endif
}
int
dec_kn300_intr_map(ccv, bustag, buspin, line, ihp)
void *ccv;
pcitag_t bustag;
int buspin, line;
pci_intr_handle_t *ihp;
{
struct mcpcia_config *ccp = ccv;
pci_chipset_tag_t pc = &ccp->cc_pc;
int device;
int kn300_irq;
if (buspin == 0) {
/* No IRQ used. */
return 1;
}
if (buspin > 4 || buspin < 0) {
printf("dec_kn300_intr_map: bad interrupt pin %d\n", buspin);
return 1;
}
alpha_pci_decompose_tag(pc, bustag, NULL, &device, NULL);
if (device == 1) {
/*
* This can only be the NCR810 SCSI.
* XXX: Do we need to check this more closely?
*/
if (EISA_PRESENT(REGVAL(MCPCIA_PCI_REV(ccp->cc_sc)))) {
printf("XXXXX: How can you have an EISA in the spot "
"as an NCR 810?\n");
}
kn300_irq = 16;
} else if (device >= 2 && device <= 5) {
kn300_irq = (device - 2) * 4;
} else {
printf("dec_kn300_intr_map: weird device number %d\n", device);
return(1);
}
/*
* handle layout:
*
* bits 0..2 7-GID
* bits 3..5 MID-4
* bits 6..8 PCI Slot (0..7- yes, some don't exist)
* bits 9..10 buspin-1
* bits 11-15 IRQ
*/
*ihp = (pci_intr_handle_t)
(7 - ccp->cc_sc->mcpcia_gid) |
((ccp->cc_sc->mcpcia_mid - 4) << 3) |
(device << 6) |
((buspin-1) << 9) |
(kn300_irq << 11);
return (0);
}
const char *
dec_kn300_intr_string(ccv, ih)
void *ccv;
pci_intr_handle_t ih;
{
static char irqstr[64];
sprintf(irqstr, "kn300 irq %d PCI Interrupt Pin %c",
(ih >> 11) & 0x1f, ((ih >> 9) & 0x3) + 'A');
return (irqstr);
}
void *
dec_kn300_intr_establish(ccv, ih, level, func, arg)
void *ccv;
pci_intr_handle_t ih;
int level;
int (*func) __P((void *));
void *arg;
{
struct vectab *vp;
int gidx, midx, slot, pidx, s;
void *cookie = NULL;
gidx = ih & 0x7;
midx = (ih >> 3) & 0x7;
slot = (ih >> 6) & 0x7;
pidx = (ih >> 9) & 0x3;
/*
* XXX: FIXME - for PCI bridges, the framework here is such that
* XXX: we're mapping the mapping for the bridge, not the
* XXX: device behind the bridge, so we're not cognizant of the
* XXX: pin swizzling that could go on. We really ought to fix
* XXX: this, but for a first cut, assuming all pins map to the
* XXX: same device and filling in all pin vectors is probably
* XXX: okay.
*/
for (pidx = 0; pidx < 4; pidx++) {
vp = &vectab[gidx][midx][slot][pidx];
if (vp->func != kn300_spurious) {
printf("dec_kn300_intr_establish: vector cookie 0x%x "
"already used\n", ih);
return (cookie);
}
s = splhigh();
vp->func = func;
vp->arg = arg;
vp->irq = (ih >> 11) & 0x1f;
(void) splx(s);
}
kn300_enable_intr(ccv, (int)((ih >> 11) & 0x1f));
cookie = (void *) ih;
return (cookie);
}
void
dec_kn300_intr_disestablish(ccv, cookie)
void *ccv, *cookie;
{
pci_intr_handle_t ih = (pci_intr_handle_t) cookie;
int gidx, midx, slot, pidx, s;
struct vectab *vp;
gidx = ih & 0x7;
midx = (ih >> 3) & 0x7;
slot = (ih >> 6) & 0x7;
pidx = (ih >> 9) & 0x3;
vp = &vectab[gidx][midx][slot][pidx];
s = splhigh();
vp->func = kn300_spurious;
vp->arg = cookie;
vp->irq = -1;
(void) splx(s);
kn300_disable_intr(ccv, (int)((ih >> 11) & 0x1f));
}
int
kn300_spurious(arg)
void *arg;
{
pci_intr_handle_t ih = (pci_intr_handle_t) arg;
int gidx, midx, slot, pidx;
gidx = ih & 0x7;
midx = (ih >> 3) & 0x7;
slot = (ih >> 6) & 0x7;
pidx = (ih >> 9) & 0x3;
printf("Spurious Interrupt from mcbus%d MID %d Slot %d "
"PCI Interrupt Pin %c\n", gidx, midx + 4, slot, pidx + 'A');
/*
* XXX: We *could*, if we have recorded all the mcpcia softcs
* XXX: that we've configured, and this spurious interrupt
* XXX: falls within this range, disable this interrupt.
*
* XXX: Later.
*/
return (-1);
}
void
kn300_iointr(framep, vec)
void *framep;
unsigned long vec;
{
int base, gidx, midx, slot, pidx;
struct vectab *vp;
if (vec >= MCPCIA_VEC_EISA && vec < MCPCIA_VEC_PCI) {
#if NSIO
sio_iointr(framep, vec);
return;
#else
printf("kn300_iointr: (E)ISA interrupt support not configured"
" for vector 0x%x", vec);
kn300_disable_intr(mcpcia_eisaccp, KN300_PCEB_IRQ);
#endif
}
base = (int) vec - MCPCIA_VEC_PCI;
midx = base / 0x200;
gidx = midx / 4;
midx = midx % 4;
slot = (base % 0x200) / 0x10;
pidx = ((slot / 4) & 0x3);
slot = slot / 4;
if (gidx >= MAX_MC_BUS || midx >= MCPCIA_PER_MCBUS ||
slot >= MCPCIA_MAXSLOT || pidx >= NPIN) {
panic("kn300_iointr: vec 0x%x (mcbus%d mid%d slot %d pin%d)",
vec, gidx, midx+4, slot, pidx);
}
#ifdef EVCNT_COUNTERS
kn300_intr_evcnt.ev_count++;
#endif
/*
* Check for i2c bus interrupts XXXXXXXXX
*/
if (gidx == 0 && midx == 0 && vec == MCPCIA_I2C_CVEC) {
#ifndef EVCNT_COUNTERS
intrcnt[INTRCNT_KN300_I2C_CTRL]++;
#endif
printf("i2c: controller interrupt\n");
return;
}
if (gidx == 0 && midx == 0 && vec == MCPCIA_I2C_BVEC) {
#ifndef EVCNT_COUNTERS
intrcnt[INTRCNT_KN300_I2C_BUS]++;
#endif
printf("i2c: bus interrupt\n");
return;
}
/*
* Now, for the main stuff...
*/
vp = &vectab[gidx][midx][slot][pidx];
#ifndef EVCNT_COUNTERS
if (vp->irq >= 0 && vp->irq <= INTRCNT_KN300_NCR810) {
intrcnt[INTRCNT_KN300_IRQ + vp->irq]++;
}
#endif
if ((*vp->func)(vp->arg) == 0) {
#if 0
printf("Unclaimed interrupt from mcbus%d MID %d Slot %d "
"PCI Interrupt Pin %c\n", gidx, midx + 4, slot, pidx + 'A');
#endif
}
}
void
kn300_enable_intr(ccp, irq)
struct mcpcia_config *ccp;
int irq;
{
alpha_mb();
REGVAL(MCPCIA_INT_MASK0(ccp->cc_sc)) |= (1 << irq);
alpha_mb();
}
void
kn300_disable_intr(ccp, irq)
struct mcpcia_config *ccp;
int irq;
{
alpha_mb();
REGVAL(MCPCIA_INT_MASK0(ccp->cc_sc)) &= ~(1 << irq);
alpha_mb();
}

View File

@ -0,0 +1,37 @@
/* $NetBSD: pci_kn300.h,v 1.1 1998/04/15 00:50:15 mjacob Exp $ */
/*
* Copyright (c) 1998 by Matthew Jacob
* NASA AMES Research Center.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
void pci_kn300_pickintr __P((struct mcpcia_config *, int));
#ifdef EVCNT_COUNTERS
extern struct evcnt kn300_intr_evcnt;
#endif