add Alpha 4100 support
This commit is contained in:
parent
0ba76b38c8
commit
aed073a77f
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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>
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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();
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue