update for new turbochannel configuration code.

This commit is contained in:
cgd 1995-12-20 00:43:20 +00:00
parent ec7644f74f
commit a5c7435308
9 changed files with 1084 additions and 253 deletions

376
sys/arch/alpha/tc/ioasic.c Normal file
View File

@ -0,0 +1,376 @@
/* $NetBSD: ioasic.c,v 1.1 1995/12/20 00:43:20 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Keith Bostic, Chris G. Demetriou
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <machine/autoconf.h>
#include <machine/pte.h>
#include <machine/rpb.h>
#include <dev/tc/tcvar.h>
#include <alpha/tc/ioasicreg.h>
#include <dev/tc/ioasicvar.h>
struct ioasic_softc {
struct device sc_dv;
tc_addr_t sc_base;
void *sc_cookie;
};
/* Definition of the driver for autoconfig. */
int ioasicmatch __P((struct device *, void *, void *));
void ioasicattach __P((struct device *, struct device *, void *));
int ioasicprint(void *, char *);
struct cfdriver ioasiccd =
{ NULL, "ioasic", ioasicmatch, ioasicattach, DV_DULL,
sizeof(struct ioasic_softc) };
int ioasic_intr __P((void *));
int ioasic_intrnull __P((void *));
#define C(x) ((void *)(x))
#define IOASIC_DEV_LANCE 0
#define IOASIC_DEV_SCC0 1
#define IOASIC_DEV_SCC1 2
#define IOASIC_DEV_ISDN 3
#define IOASIC_DEV_BOGUS -1
#define IOASIC_NCOOKIES 4
struct ioasic_dev {
char *iad_modname;
tc_offset_t iad_offset;
void *iad_cookie;
u_int32_t iad_intrbits;
} ioasic_devs[] = {
{ "lance ", 0x000c0000, C(IOASIC_DEV_LANCE), IOASIC_INTR_LANCE, },
{ "z8530 ", 0x00100000, C(IOASIC_DEV_SCC0), IOASIC_INTR_SCC_0, },
{ "z8530 ", 0x00180000, C(IOASIC_DEV_SCC1), IOASIC_INTR_SCC_1, },
{ "TOY_RTC ", 0x00200000, C(IOASIC_DEV_BOGUS), 0, },
{ "AMD79c30", 0x00240000, C(IOASIC_DEV_ISDN), IOASIC_INTR_ISDN, },
};
int ioasic_ndevs = sizeof(ioasic_devs) / sizeof(ioasic_devs[0]);
struct ioasicintr {
int (*iai_func) __P((void *));
void *iai_arg;
} ioasicintrs[IOASIC_NCOOKIES];
tc_addr_t ioasic_base; /* XXX XXX XXX */
/* There can be only one. */
int ioasicfound;
extern int cputype;
int
ioasicmatch(parent, cfdata, aux)
struct device *parent;
void *cfdata;
void *aux;
{
struct tcdev_attach_args *tcdev = aux;
/* Make sure that we're looking for this type of device. */
if (strncmp("FLAMG-IO", tcdev->tcda_modname, TC_ROM_LLEN))
return (0);
/* Check that it can actually exist. */
if ((cputype != ST_DEC_3000_500) && (cputype != ST_DEC_3000_300))
panic("ioasicmatch: how did we get here?");
if (ioasicfound)
return (0);
return (1);
}
void
ioasicattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
struct ioasic_softc *sc = (struct ioasic_softc *)self;
struct tcdev_attach_args *tcdev = aux;
struct ioasicdev_attach_args ioasicdev;
u_long i;
ioasicfound = 1;
sc->sc_base = tcdev->tcda_addr;
ioasic_base = sc->sc_base; /* XXX XXX XXX */
sc->sc_cookie = tcdev->tcda_cookie;
#ifdef DEC_3000_300
if (cputype == ST_DEC_3000_300) {
*(volatile u_int *)IOASIC_REG_CSR(sc->sc_base) |=
IOASIC_CSR_FASTMODE;
tc_mb();
printf(": slow mode\n");
} else
#endif
printf(": fast mode\n");
/*
* Turn off all device interrupt bits.
* (This does _not_ include 3000/300 TC option slot bits.
*/
for (i = 0; i < ioasic_ndevs; i++)
*(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) &=
~ioasic_devs[i].iad_intrbits;
tc_mb();
/*
* Set up interrupt handlers.
*/
for (i = 0; i < IOASIC_NCOOKIES; i++) {
ioasicintrs[i].iai_func = ioasic_intrnull;
ioasicintrs[i].iai_arg = (void *)i;
}
tc_intr_establish(parent, sc->sc_cookie, TC_IPL_NONE, ioasic_intr, sc);
/*
* Try to configure each device.
*/
for (i = 0; i < ioasic_ndevs; i++) {
strncpy(ioasicdev.iada_modname, ioasic_devs[i].iad_modname,
TC_ROM_LLEN);
ioasicdev.iada_modname[TC_ROM_LLEN] = '\0';
ioasicdev.iada_offset = ioasic_devs[i].iad_offset;
ioasicdev.iada_addr = sc->sc_base + ioasic_devs[i].iad_offset;
ioasicdev.iada_cookie = ioasic_devs[i].iad_cookie;
/* Tell the autoconfig machinery we've found the hardware. */
config_found(self, &ioasicdev, ioasicprint);
}
}
int
ioasicprint(aux, pnp)
void *aux;
char *pnp;
{
struct ioasicdev_attach_args *d = aux;
if (pnp)
printf("%s at %s", d->iada_modname, pnp);
printf(" offset 0x%lx", (long)d->iada_offset);
return (UNCONF);
}
int
ioasic_submatch(match, d)
struct cfdata *match;
struct ioasicdev_attach_args *d;
{
return ((match->ioasiccf_offset == d->iada_offset) ||
(match->ioasiccf_offset == IOASIC_OFFSET_UNKNOWN));
}
void
ioasic_intr_establish(ioa, cookie, level, func, arg)
struct device *ioa;
void *cookie, *arg;
tc_intrlevel_t level;
int (*func) __P((void *));
{
u_long dev, i;
dev = (u_long)cookie;
#ifdef DIAGNOSTIC
/* XXX check cookie. */
#endif
if (ioasicintrs[dev].iai_func != ioasic_intrnull)
panic("ioasic_intr_establish: cookie %d twice", dev);
ioasicintrs[dev].iai_func = func;
ioasicintrs[dev].iai_arg = arg;
/* Enable interrupts for the device. */
for (i = 0; i < ioasic_ndevs; i++)
if (ioasic_devs[i].iad_cookie == cookie)
break;
if (i == ioasic_ndevs)
panic("ioasic_intr_establish: invalid cookie.");
*(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) |=
ioasic_devs[i].iad_intrbits;
tc_mb();
}
void
ioasic_intr_disestablish(ioa, cookie)
struct device *ioa;
void *cookie;
{
u_long dev, i;
dev = (u_long)cookie;
#ifdef DIAGNOSTIC
/* XXX check cookie. */
#endif
if (ioasicintrs[dev].iai_func == ioasic_intrnull)
panic("ioasic_intr_disestablish: cookie %d missing intr", dev);
/* Enable interrupts for the device. */
for (i = 0; i < ioasic_ndevs; i++)
if (ioasic_devs[i].iad_cookie == cookie)
break;
if (i == ioasic_ndevs)
panic("ioasic_intr_disestablish: invalid cookie.");
*(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) &=
~ioasic_devs[i].iad_intrbits;
tc_mb();
ioasicintrs[dev].iai_func = ioasic_intrnull;
ioasicintrs[dev].iai_arg = (void *)dev;
}
int
ioasic_intrnull(val)
void *val;
{
panic("ioasic_intrnull: uncaught IOASIC intr for cookie %ld\n",
(u_long)val);
}
/*
* asic_intr --
* ASIC interrupt handler.
*/
int
ioasic_intr(val)
void *val;
{
register struct ioasic_softc *sc = val;
register int i, ifound;
int gifound;
u_int32_t sir, junk;
volatile u_int32_t *sirp, *junkp;
sirp = (volatile u_int32_t *)IOASIC_REG_INTR(sc->sc_base);
gifound = 0;
do {
ifound = 0;
tc_syncbus();
sir = *sirp;
/* XXX DUPLICATION OF INTERRUPT BIT INFORMATION... */
#define CHECKINTR(slot, bits) \
if (sir & bits) { \
ifound = 1; \
(*ioasicintrs[slot].iai_func) \
(ioasicintrs[slot].iai_arg); \
}
CHECKINTR(IOASIC_DEV_SCC0, IOASIC_INTR_SCC_0);
CHECKINTR(IOASIC_DEV_SCC1, IOASIC_INTR_SCC_1);
CHECKINTR(IOASIC_DEV_LANCE, IOASIC_INTR_LANCE);
CHECKINTR(IOASIC_DEV_ISDN, IOASIC_INTR_ISDN);
gifound |= ifound;
} while (ifound);
return (gifound);
}
/* XXX */
char *
ioasic_lance_ether_address()
{
return (u_char *)IOASIC_SYS_ETHER_ADDRESS(ioasic_base);
}
void
ioasic_lance_dma_setup(v)
void *v;
{
volatile u_int32_t *ldp;
tc_addr_t tca;
tca = (tc_addr_t)v;
ldp = (volatile u_int *)IOASIC_REG_LANCE_DMAPTR(ioasic_base);
*ldp = ((tca << 3) & ~(tc_addr_t)0x1f) | ((tca >> 29) & 0x1f);
tc_wmb();
*(volatile u_int32_t *)IOASIC_REG_CSR(ioasic_base) |=
IOASIC_CSR_DMAEN_LANCE;
tc_mb();
}
#ifdef DEC_3000_300
void
ioasic_intr_300_opt0_enable(enable)
int enable;
{
if (enable)
*(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) |=
IOASIC_INTR_300_OPT0;
else
*(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) &=
~IOASIC_INTR_300_OPT0;
}
void
ioasic_intr_300_opt1_enable(enable)
int enable;
{
if (enable)
*(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) |=
IOASIC_INTR_300_OPT1;
else
*(volatile u_int32_t *)IOASIC_REG_IMSK(ioasic_base) &=
~IOASIC_INTR_300_OPT1;
}
void
ioasic_300_opts_isintr(opt0, opt1)
int *opt0, *opt1;
{
u_int32_t sir;
sir = *(volatile u_int32_t *)IOASIC_REG_INTR(ioasic_base);
*opt0 = sir & IOASIC_INTR_300_OPT0;
*opt1 = sir & IOASIC_INTR_300_OPT1;
}
#endif

View File

@ -0,0 +1,226 @@
/* $NetBSD: ioasicreg.h,v 1.1 1995/12/20 00:43:22 cgd Exp $ */
/*
* Copyright (c) 1991,1990,1989,1994,1995 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* The Mach Operating System project at Carnegie-Mellon University,
* Ralph Campbell and Rick Macklem.
*
* 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 University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*
* @(#)asic.h 8.1 (Berkeley) 6/10/93
*/
/*
* Slot definitions
*/
#define IOASIC_SLOT_0_START 0x000000
#define IOASIC_SLOT_1_START 0x040000
#define IOASIC_SLOT_2_START 0x080000
#define IOASIC_SLOT_3_START 0x0c0000
#define IOASIC_SLOT_4_START 0x100000
#define IOASIC_SLOT_5_START 0x140000
#define IOASIC_SLOT_6_START 0x180000
#define IOASIC_SLOT_7_START 0x1c0000
#define IOASIC_SLOT_8_START 0x200000
#define IOASIC_SLOT_9_START 0x240000
#define IOASIC_SLOT_10_START 0x280000
#define IOASIC_SLOT_11_START 0x2c0000
#define IOASIC_SLOT_12_START 0x300000
#define IOASIC_SLOT_13_START 0x340000
#define IOASIC_SLOT_14_START 0x380000
#define IOASIC_SLOT_15_START 0x3c0000
#define IOASIC_SLOTS_END 0x3fffff
/*
* Register offsets (slot 1)
*/
#define IOASIC_SCSI_DMAPTR IOASIC_SLOT_1_START+0x000
#define IOASIC_SCSI_NEXTPTR IOASIC_SLOT_1_START+0x010
#define IOASIC_LANCE_DMAPTR IOASIC_SLOT_1_START+0x020
#define IOASIC_SCC_T1_DMAPTR IOASIC_SLOT_1_START+0x030
#define IOASIC_SCC_R1_DMAPTR IOASIC_SLOT_1_START+0x040
#define IOASIC_SCC_T2_DMAPTR IOASIC_SLOT_1_START+0x050
#define IOASIC_SCC_R2_DMAPTR IOASIC_SLOT_1_START+0x060
#define IOASIC_FLOPPY_DMAPTR IOASIC_SLOT_1_START+0x070
#define IOASIC_ISDN_X_DMAPTR IOASIC_SLOT_1_START+0x080
#define IOASIC_ISDN_X_NEXTPTR IOASIC_SLOT_1_START+0x090
#define IOASIC_ISDN_R_DMAPTR IOASIC_SLOT_1_START+0x0a0
#define IOASIC_ISDN_R_NEXTPTR IOASIC_SLOT_1_START+0x0b0
#define IOASIC_BUFF0 IOASIC_SLOT_1_START+0x0c0
#define IOASIC_BUFF1 IOASIC_SLOT_1_START+0x0d0
#define IOASIC_BUFF2 IOASIC_SLOT_1_START+0x0e0
#define IOASIC_BUFF3 IOASIC_SLOT_1_START+0x0f0
#define IOASIC_CSR IOASIC_SLOT_1_START+0x100
#define IOASIC_INTR IOASIC_SLOT_1_START+0x110
#define IOASIC_IMSK IOASIC_SLOT_1_START+0x120
#define IOASIC_CURADDR IOASIC_SLOT_1_START+0x130
#define IOASIC_ISDN_X_DATA IOASIC_SLOT_1_START+0x140
#define IOASIC_ISDN_R_DATA IOASIC_SLOT_1_START+0x150
#define IOASIC_LANCE_DECODE IOASIC_SLOT_1_START+0x160
#define IOASIC_SCSI_DECODE IOASIC_SLOT_1_START+0x170
#define IOASIC_SCC0_DECODE IOASIC_SLOT_1_START+0x180
#define IOASIC_SCC1_DECODE IOASIC_SLOT_1_START+0x190
#define IOASIC_FLOPPY_DECODE IOASIC_SLOT_1_START+0x1a0
#define IOASIC_SCSI_SCR IOASIC_SLOT_1_START+0x1b0
#define IOASIC_SCSI_SDR0 IOASIC_SLOT_1_START+0x1c0
#define IOASIC_SCSI_SDR1 IOASIC_SLOT_1_START+0x1d0
/* System Status and control Register (SSR). */
#define IOASIC_CSR_DMAEN_T1 0x80000000 /* rw */
#define IOASIC_CSR_DMAEN_R1 0x40000000 /* rw */
#define IOASIC_CSR_DMAEN_T2 0x20000000 /* rw */
#define IOASIC_CSR_DMAEN_R2 0x10000000 /* rw */
#define IOASIC_CSR_FASTMODE 0x08000000 /* rw */
#define IOASIC_CSR_xxx 0x07800000 /* unused/reserved */
#define IOASIC_CSR_FLOPPY_DIR 0x00400000 /* rw */
#define IOASIC_CSR_DMAEN_FLOPPY 0x00200000 /* rw */
#define IOASIC_CSR_DMAEN_ISDN_T 0x00100000 /* rw */
#define IOASIC_CSR_DMAEN_ISDN_R 0x00080000 /* rw */
#define IOASIC_CSR_SCSI_DIR 0x00040000 /* rw */
#define IOASIC_CSR_DMAEN_SCSI 0x00020000 /* rw */
#define IOASIC_CSR_DMAEN_LANCE 0x00010000 /* rw */
/* low 16 bits are rw gp outputs */
/* System Interrupt Register (and Interrupt Mask Register). */
#define IOASIC_INTR_T1_PAGE_END 0x80000000 /* rz */
#define IOASIC_INTR_T1_READ_E 0x40000000 /* rz */
#define IOASIC_INTR_R1_HALF_PAGE 0x20000000 /* rz */
#define IOASIC_INTR_R1_DMA_OVRUN 0x10000000 /* rz */
#define IOASIC_INTR_T2_PAGE_END 0x08000000 /* rz */
#define IOASIC_INTR_T2_READ_E 0x04000000 /* rz */
#define IOASIC_INTR_R2_HALF_PAGE 0x02000000 /* rz */
#define IOASIC_INTR_R2_DMA_OVRUN 0x01000000 /* rz */
#define IOASIC_INTR_FLOPPY_DMA_E 0x00800000 /* rz */
#define IOASIC_INTR_ISDN_PTR_LOAD 0x00400000 /* rz */
#define IOASIC_INTR_ISDN_OVRUN 0x00200000 /* rz */
#define IOASIC_INTR_ISDN_READ_E 0x00100000 /* rz */
#define IOASIC_INTR_SCSI_PTR_LOAD 0x00080000 /* rz */
#define IOASIC_INTR_SCSI_OVRUN 0x00040000 /* rz */
#define IOASIC_INTR_SCSI_READ_E 0x00020000 /* rz */
#define IOASIC_INTR_LANCE_READ_E 0x00010000 /* rz */
#define IOASIC_INTR_ISDN 0x00002000 /* ro */
#define IOASIC_INTR_SEC_CON 0x00000200 /* ro */
#define IOASIC_INTR_LANCE 0x00000100 /* ro */
#define IOASIC_INTR_SCC_1 0x00000080 /* ro */
#define IOASIC_INTR_SCC_0 0x00000040 /* ro */
#define IOASIC_INTR_ALT_CON 0x00000008 /* ro - 3000/500 */
#define IOASIC_INTR_300_OPT1 IOASIC_INTR_ALT_CON /* ro - 3000/300 */
#define IOASIC_INTR_300_OPT0 0x00000004 /* ro - 3000/300 */
/* DMA pointer registers (SCSI, Comm, ...) */
#define IOASIC_DMAPTR_MASK 0xffffffe0
#define IOASIC_DMAPTR_SHIFT 5
#define IOASIC_DMAPTR_SET(reg,val) \
(reg) = (((val)<<IOASIC_DMAPTR_SHIFT)&IOASIC_DMAPTR_MASK)
#define IOASIC_DMAPTR_GET(reg,val) \
(val) = (((reg)&IOASIC_DMAPTR_MASK)>>IOASIC_DMAPTR_SHIFT)
#define IOASIC_DMA_ADDR(p) (((unsigned)p) << (5-2))
/* For the LANCE DMA pointer register initialization the above suffices */
/* More SCSI DMA registers */
#define IOASIC_SCR_STATUS 0x00000004
#define IOASIC_SCR_WORD 0x00000003
/* Various Decode registers */
#define IOASIC_DECODE_HW_ADDRESS 0x000003f0
#define IOASIC_DECODE_CHIP_SELECT 0x0000000f
/*
* Asic register addresses at offset from base.
*/
#define IOASIC_REG_SCSI_DMAPTR(base) ((base) + IOASIC_SCSI_DMAPTR)
#define IOASIC_REG_SCSI_DMANPTR(base) ((base) + IOASIC_SCSI_NEXTPTR)
#define IOASIC_REG_LANCE_DMAPTR(base) ((base) + IOASIC_LANCE_DMAPTR)
#define IOASIC_REG_SCC_T1_DMAPTR(base) ((base) + IOASIC_SCC_T1_DMAPTR)
#define IOASIC_REG_SCC_R1_DMAPTR(base) ((base) + IOASIC_SCC_R1_DMAPTR)
#define IOASIC_REG_SCC_T2_DMAPTR(base) ((base) + IOASIC_SCC_T2_DMAPTR)
#define IOASIC_REG_SCC_R2_DMAPTR(base) ((base) + IOASIC_SCC_R2_DMAPTR)
#define IOASIC_REG_FLOPPY_DMAPTR(base) ((base) + IOASIC_FLOPPY_DMAPTR)
#define IOASIC_REG_ISDN_X_DMAPTR(base) ((base) + IOASIC_ISDN_X_DMAPTR)
#define IOASIC_REG_ISDN_X_NEXTPTR(base) ((base) + IOASIC_ISDN_X_NEXTPTR)
#define IOASIC_REG_ISDN_R_DMAPTR(base) ((base) + IOASIC_ISDN_R_DMAPTR)
#define IOASIC_REG_ISDN_R_NEXTPTR(base) ((base) + IOASIC_ISDN_R_NEXTPTR)
#define IOASIC_REG_BUFF0(base) ((base) + IOASIC_BUFF0)
#define IOASIC_REG_BUFF1(base) ((base) + IOASIC_BUFF1)
#define IOASIC_REG_BUFF2(base) ((base) + IOASIC_BUFF2)
#define IOASIC_REG_BUFF3(base) ((base) + IOASIC_BUFF3)
#define IOASIC_REG_CSR(base) ((base) + IOASIC_CSR)
#define IOASIC_REG_INTR(base) ((base) + IOASIC_INTR)
#define IOASIC_REG_IMSK(base) ((base) + IOASIC_IMSK)
#define IOASIC_REG_CURADDR(base) ((base) + IOASIC_CURADDR)
#define IOASIC_REG_ISDN_X_DATA(base) ((base) + IOASIC_ISDN_X_DATA)
#define IOASIC_REG_ISDN_R_DATA(base) ((base) + IOASIC_ISDN_R_DATA)
#define IOASIC_REG_LANCE_DECODE(base) ((base) + IOASIC_LANCE_DECODE)
#define IOASIC_REG_SCSI_DECODE(base) ((base) + IOASIC_SCSI_DECODE)
#define IOASIC_REG_SCC0_DECODE(base) ((base) + IOASIC_SCC0_DECODE)
#define IOASIC_REG_SCC1_DECODE(base) ((base) + IOASIC_SCC1_DECODE)
#define IOASIC_REG_FLOPPY_DECODE(base) ((base) + IOASIC_FLOPPY_DECODE)
#define IOASIC_REG_SCSI_SCR(base) ((base) + IOASIC_SCSI_SCR)
#define IOASIC_REG_SCSI_SDR0(base) ((base) + IOASIC_SCSI_SDR0)
#define IOASIC_REG_SCSI_SDR1(base) ((base) + IOASIC_SCSI_SDR1)
/*
* And slot assignments.
*/
#define IOASIC_SYS_ETHER_ADDRESS(base) ((base) + IOASIC_SLOT_2_START)
#define IOASIC_SYS_LANCE(base) ((base) + IOASIC_SLOT_3_START)

View File

@ -1,4 +1,4 @@
/* $NetBSD: scc.c,v 1.10 1995/11/23 02:41:29 cgd Exp $ */
/* $NetBSD: scc.c,v 1.11 1995/12/20 00:43:24 cgd Exp $ */
/*
* Copyright (c) 1991,1990,1989,1994,1995 Carnegie Mellon University
@ -100,11 +100,11 @@
#include <pmax/dev/fbreg.h>
#endif
#include <machine/autoconf.h>
#include <machine/rpb.h>
#include <alpha/tc/asic.h>
#include <alpha/tc/tc.h>
#include <dev/tc/tcvar.h>
#include <alpha/tc/ioasicreg.h>
#include <dev/tc/ioasicvar.h>
extern void ttrstrt __P((void *));
@ -205,13 +205,13 @@ sccmatch(parent, cfdata, aux)
void *aux;
{
struct cfdata *cf = cfdata;
struct confargs *ca = aux;
struct ioasicdev_attach_args *d = aux;
void *sccaddr;
/* XXX BUS TYPE? */
/* Make sure that we're looking for this type of device. */
if (!BUS_MATCHNAME(ca, "scc"))
if (strncmp(d->iada_modname, "z8530 ", TC_ROM_LLEN))
return (0);
/* XXX MATCH CFLOC */
@ -219,9 +219,9 @@ sccmatch(parent, cfdata, aux)
return (0);
/* Get the address, and check it for validity. */
sccaddr = BUS_CVTADDR(ca);
sccaddr = (void *)d->iada_addr;
#ifdef SPARSE
sccaddr = TC_DENSE_TO_SPARSE(sccaddr);
sccaddr = (void *)TC_DENSE_TO_SPARSE((tc_addr_t)sccaddr);
#endif
if (badaddr(sccaddr, 2))
return (0);
@ -234,20 +234,20 @@ scc_alphaintr(onoff)
int onoff;
{
if (onoff) {
*(volatile u_int *)ASIC_REG_IMSK(asic_base) |=
ASIC_INTR_SCC_1 | ASIC_INTR_SCC_0;
*(volatile u_int *)IOASIC_REG_IMSK(ioasic_base) |=
IOASIC_INTR_SCC_1 | IOASIC_INTR_SCC_0;
#if !defined(DEC_3000_300) && defined(SCC_DMA)
*(volatile u_int *)ASIC_REG_CSR(asic_base) |=
ASIC_CSR_DMAEN_T1 | ASIC_CSR_DMAEN_R1 |
ASIC_CSR_DMAEN_T2 | ASIC_CSR_DMAEN_R2;
*(volatile u_int *)IOASIC_REG_CSR(ioasic_base) |=
IOASIC_CSR_DMAEN_T1 | IOASIC_CSR_DMAEN_R1 |
IOASIC_CSR_DMAEN_T2 | IOASIC_CSR_DMAEN_R2;
#endif
} else {
*(volatile u_int *)ASIC_REG_IMSK(asic_base) &=
~(ASIC_INTR_SCC_1 | ASIC_INTR_SCC_0);
*(volatile u_int *)IOASIC_REG_IMSK(ioasic_base) &=
~(IOASIC_INTR_SCC_1 | IOASIC_INTR_SCC_0);
#if !defined(DEC_3000_300) && defined(SCC_DMA)
*(volatile u_int *)ASIC_REG_CSR(asic_base) &=
~(ASIC_CSR_DMAEN_T1 | ASIC_CSR_DMAEN_R1 |
ASIC_CSR_DMAEN_T2 | ASIC_CSR_DMAEN_R2);
*(volatile u_int *)IOASIC_REG_CSR(ioasic_base) &=
~(IOASIC_CSR_DMAEN_T1 | IOASIC_CSR_DMAEN_R1 |
IOASIC_CSR_DMAEN_T2 | IOASIC_CSR_DMAEN_R2);
#endif
}
wbflush();
@ -260,7 +260,7 @@ sccattach(parent, self, aux)
void *aux;
{
struct scc_softc *sc = (struct scc_softc *)self;
struct confargs *ca = aux;
struct ioasicdev_attach_args *d = aux;
struct pdma *pdp;
struct tty *tp;
void *sccaddr;
@ -271,13 +271,14 @@ sccattach(parent, self, aux)
extern int cputype;
/* Get the address, and check it for validity. */
sccaddr = BUS_CVTADDR(ca);
sccaddr = (void *)d->iada_addr;
#ifdef SPARSE
sccaddr = TC_DENSE_TO_SPARSE(sccaddr);
sccaddr = (void *)TC_DENSE_TO_SPARSE((tc_addr_t)sccaddr);
#endif
/* Register the interrupt handler. */
BUS_INTR_ESTABLISH(ca, sccintr, (void *)(long)sc->sc_dv.dv_unit);
ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_TTY,
sccintr, (void *)(long)sc->sc_dv.dv_unit);
/*
* For a remote console, wait a while for previous output to
@ -765,7 +766,7 @@ sccparam(tp, t)
SCC_WRITE_REG(regs, line, SCC_WR9, value);
SCC_WRITE_REG(regs, line, SCC_WR1, sc->scc_wreg[line].wr1);
scc_alphaintr(1);
scc_alphaintr(1); /* XXX XXX XXX */
return (0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: tc_3000_300.c,v 1.3 1995/08/03 00:52:29 cgd Exp $ */
/* $NetBSD: tc_3000_300.c,v 1.4 1995/12/20 00:43:27 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@ -33,109 +33,139 @@
#include <machine/autoconf.h>
#include <machine/pte.h>
#include <alpha/tc/tc.h>
#include <dev/tc/tcvar.h>
#include <alpha/tc/tc_conf.h>
#include <alpha/tc/tc_3000_300.h>
/* XXX ESTABLISH, DISESTABLISH */
void tc_3000_300_intr_setup __P((void));
void tc_3000_300_intr_establish
__P((struct confargs *, intr_handler_t, void *));
void tc_3000_300_intr_disestablish __P((struct confargs *));
void tc_3000_300_intr_establish __P((struct device *, void *,
tc_intrlevel_t, int (*)(void *), void *));
void tc_3000_300_intr_disestablish __P((struct device *, void *));
void tc_3000_300_iointr __P((void *, int));
int tc_3000_300_getdev __P((struct confargs *));
#define KV(x) ((caddr_t)phystok0seg(x))
#define TC_3000_300_NSLOTS 5
#define TC_3000_300_MAXDEVS 5
int tc_3000_300_intrnull __P((void *));
static struct tc_slot_desc dec_3000_300_slots[TC_3000_300_NSLOTS] = {
{ KV(0x100000000), }, /* slot 0 - TC option slot 0 */
{ KV(0x120000000), }, /* slot 1 - TC option slot 1 */
{ KV(0x180000000), }, /* slot 2 - TCDS ASIC on cpu board */
{ KV(0x1a0000000), }, /* slot 3 - IOCTL ASIC on cpu board */
{ KV(0x1c0000000), }, /* slot 4 - CXTurbo on cpu board */
#define C(x) ((void *)(u_long)x)
#define KV(x) (phystok0seg(x))
struct tc_slotdesc tc_3000_300_slots[] = {
{ KV(0x100000000), C(TC_3000_300_DEV_OPT0), }, /* 0 - opt slot 0 */
{ KV(0x120000000), C(TC_3000_300_DEV_OPT1), }, /* 1 - opt slot 1 */
{ KV(0x180000000), C(TC_3000_300_DEV_BOGUS), }, /* 2 - TCDS ASIC */
{ KV(0x1a0000000), C(TC_3000_300_DEV_BOGUS), }, /* 3 - IOCTL ASIC */
{ KV(0x1c0000000), C(TC_3000_300_DEV_CXTURBO), }, /* 4 - CXTurbo */
};
int tc_3000_300_nslots =
sizeof(tc_3000_300_slots) / sizeof(tc_3000_300_slots[0]);
static struct confargs dec_3000_300_devs[TC_3000_300_MAXDEVS] = {
{ "PMAGB-BA", 4, 0x02000000, },
{ "IOCTL ", 3, 0x00000000, },
{ "PMAZ-DS ", 2, 0x00000000, },
{ NULL, 1, 0x0, },
{ NULL, 0, 0x0, },
struct tc_builtin tc_3000_300_builtins[] = {
{ "PMAGB-BA", 4, 0x02000000, C(TC_3000_300_DEV_CXTURBO), },
{ "FLAMG-IO", 3, 0x00000000, C(TC_3000_300_DEV_IOASIC), },
{ "PMAZ-DS ", 2, 0x00000000, C(TC_3000_300_DEV_TCDS), },
};
int tc_3000_300_nbuiltins =
sizeof(tc_3000_300_builtins) / sizeof(tc_3000_300_builtins[0]);
/* Indices into the struct confargs array. */
#define TC_3000_300_DEV_CXTURBO 0
#define TC_3000_300_DEV_IOCTL 1
#define TC_3000_300_DEV_TCDS 2
#define TC_3000_300_DEV_OPT1 3
#define TC_3000_300_DEV_OPT0 4
struct tcintr {
int (*tci_func) __P((void *));
void *tci_arg;
} tc_3000_300_intr[TC_3000_300_NCOOKIES];
struct tc_cpu_desc dec_3000_300_cpu = {
dec_3000_300_slots, TC_3000_300_NSLOTS,
dec_3000_300_devs, TC_3000_300_MAXDEVS,
tc_3000_300_intr_setup,
tc_3000_300_intr_establish,
tc_3000_300_intr_disestablish,
tc_3000_300_iointr,
};
intr_handler_t tc_3000_300_intrhand[TC_3000_300_MAXDEVS];
void *tc_3000_300_intrval[TC_3000_300_MAXDEVS];
/* XXX */
void ioasic_intr_300_opt0_enable __P((int));
void ioasic_intr_300_opt1_enable __P((int));
void ioasic_300_opts_isintr __P((int *, int *));
void
tc_3000_300_intr_setup()
{
int i;
u_long i;
/* Set up interrupt handlers. */
for (i = 0; i < TC_3000_300_MAXDEVS; i++) {
tc_3000_300_intrhand[i] = tc_intrnull;
tc_3000_300_intrval[i] = (void *)(long)i;
/*
* Sisable all interrupts that we can (can't disable builtins).
*/
ioasic_intr_300_opt0_enable(0);
ioasic_intr_300_opt1_enable(0);
/*
* Set up interrupt handlers.
*/
for (i = 0; i < TC_3000_300_NCOOKIES; i++) {
tc_3000_300_intr[i].tci_func = tc_3000_300_intrnull;
tc_3000_300_intr[i].tci_arg = (void *)i;
}
}
void
tc_3000_300_intr_establish(ca, handler, val)
struct confargs *ca;
int (*handler) __P((void *));
void *val;
tc_3000_300_intr_establish(tcadev, cookie, level, func, arg)
struct device *tcadev;
void *cookie, *arg;
tc_intrlevel_t level;
int (*func) __P((void *));
{
int dev = tc_3000_300_getdev(ca);
u_long dev = (u_long)cookie;
#ifdef DIAGNOSTIC
if (dev == -1)
panic("tc_3000_300_intr_establish: dev == -1");
/* XXX bounds-check cookie. */
#endif
if (tc_3000_300_intrhand[dev] != tc_intrnull)
panic("tc_3000_300_intr_establish: dev %d twice", dev);
if (tc_3000_300_intr[dev].tci_func != tc_3000_300_intrnull)
panic("tc_3000_300_intr_establish: cookie %d twice", dev);
tc_3000_300_intrhand[dev] = handler;
tc_3000_300_intrval[dev] = val;
tc_3000_300_intr[dev].tci_func = func;
tc_3000_300_intr[dev].tci_arg = arg;
/* XXX ENABLE INTERRUPT MASK FOR DEV */
switch (dev) {
case TC_3000_300_DEV_OPT0:
ioasic_intr_300_opt0_enable(1);
break;
case TC_3000_300_DEV_OPT1:
ioasic_intr_300_opt1_enable(1);
break;
default:
/* interrupts for builtins always enabled */
break;
}
}
void
tc_3000_300_intr_disestablish(ca)
struct confargs *ca;
tc_3000_300_intr_disestablish(tcadev, cookie)
struct device *tcadev;
void *cookie;
{
int dev = tc_3000_300_getdev(ca);
u_long dev = (u_long)cookie;
#ifdef DIAGNOSTIC
if (dev == -1)
panic("tc_3000_300_intr_disestablish: somebody goofed");
/* XXX bounds-check cookie. */
#endif
if (tc_3000_300_intrhand[dev] == tc_intrnull)
panic("tc_3000_300_intr_disestablish: dev %d missing intr",
if (tc_3000_300_intr[dev].tci_func == tc_3000_300_intrnull)
panic("tc_3000_300_intr_disestablish: cookie %d bad intr",
dev);
tc_3000_300_intrhand[dev] = tc_intrnull;
tc_3000_300_intrval[dev] = (void *)(long)dev;
switch (dev) {
case TC_3000_300_DEV_OPT0:
ioasic_intr_300_opt0_enable(0);
break;
case TC_3000_300_DEV_OPT1:
ioasic_intr_300_opt1_enable(0);
break;
default:
/* interrupts for builtins always enabled */
break;
}
/* XXX DISABLE INTERRUPT MASK FOR DEV */
tc_3000_300_intr[dev].tci_func = tc_3000_300_intrnull;
tc_3000_300_intr[dev].tci_arg = (void *)dev;
}
int
tc_3000_300_intrnull(val)
void *val;
{
panic("tc_3000_300_intrnull: uncaught TC intr for cookie %ld\n",
(u_long)val);
}
void
@ -144,7 +174,7 @@ tc_3000_300_iointr(framep, vec)
int vec;
{
u_int32_t ir;
int ifound;
int opt0intr, opt1intr, ifound;
#ifdef DIAGNOSTIC
int s;
@ -157,38 +187,33 @@ tc_3000_300_iointr(framep, vec)
#endif
do {
MAGIC_READ;
wbflush();
tc_syncbus();
/* find out what interrupts/errors occurred */
ir = *(volatile u_int32_t *)TC_3000_300_IR;
wbflush();
ioasic_300_opts_isintr(&opt0intr, &opt1intr);
tc_mb();
/* clear the interrupts/errors we found. */
*(volatile u_int32_t *)TC_3000_300_IR = ir;
wbflush();
/* XXX can't clear TC option slot interrupts here? */
tc_wmb();
ifound = 0;
#define CHECKINTR(slot, bits) \
if (ir & bits) { \
#define CHECKINTR(slot, flag) \
if (flag) { \
ifound = 1; \
(*tc_3000_300_intrhand[slot]) \
(tc_3000_300_intrval[slot]); \
(*tc_3000_300_intr[slot].tci_func) \
(tc_3000_300_intr[slot].tci_arg); \
}
/* Do them in order of priority; highest slot # first. */
CHECKINTR(TC_3000_300_DEV_CXTURBO, TC_3000_300_IR_CXTURBO);
CHECKINTR(TC_3000_300_DEV_IOCTL, TC_3000_300_IR_IOCTL);
CHECKINTR(TC_3000_300_DEV_TCDS, TC_3000_300_IR_TCDS);
#if 0
CHECKINTR(TC_3000_300_DEV_OPT1, TC_3000_300_IR_OPT1);
CHECKINTR(TC_3000_300_DEV_OPT0, TC_3000_300_IR_OPT0);
#else
/* XXX XXX XXX CHECK OPTION SLOT INTERRUPTS!!! */
/* XXX XXX XXX THEIR BITS LIVE IN ANOTHER REG. */
#endif
CHECKINTR(TC_3000_300_DEV_CXTURBO, ir & TC_3000_300_IR_CXTURBO);
CHECKINTR(TC_3000_300_DEV_IOASIC, ir & TC_3000_300_IR_IOASIC);
CHECKINTR(TC_3000_300_DEV_TCDS, ir & TC_3000_300_IR_TCDS);
CHECKINTR(TC_3000_300_DEV_OPT1, opt1intr);
CHECKINTR(TC_3000_300_DEV_OPT0, opt0intr);
#undef CHECKINTR
#ifdef DIAGNOSTIC
#define PRINTINTR(msg, bits) \
if (ir & bits) \
@ -204,18 +229,3 @@ tc_3000_300_iointr(framep, vec)
#endif
} while (ifound);
}
int
tc_3000_300_getdev(ca)
struct confargs *ca;
{
int i;
for (i = 0; i < TC_3000_300_MAXDEVS; i++)
if (ca->ca_slot == dec_3000_300_devs[i].ca_slot &&
ca->ca_offset == dec_3000_300_devs[i].ca_offset &&
!strncmp(ca->ca_name, dec_3000_300_devs[i].ca_name))
return (i);
return (-1);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: tc_3000_300.h,v 1.1 1995/03/08 00:39:07 cgd Exp $ */
/* $NetBSD: tc_3000_300.h,v 1.2 1995/12/20 00:43:28 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@ -42,9 +42,20 @@
/* Interrupt bits. */
#define TC_3000_300_IR_CXTURBO 0x00000004 /* TC CXTURBO */
#define TC_3000_300_IR_TCDS 0x00000008 /* TC Dual SCSI */
#define TC_3000_300_IR_IOCTL 0x00000010 /* TC IOCTL */
#define TC_3000_300_IR_IOASIC 0x00000010 /* TC IOASIC */
#define TC_3000_300_IR_BCTAGPARITY 0x08000000 /* BC tag par. err. */
#define TC_3000_300_IR_TCOVERRUN 0x10000000 /* TC overrun */
#define TC_3000_300_IR_TCTIMEOUT 0x20000000 /* TC timeout on I/O */
#define TC_3000_300_IR_BCACHEPARITY 0x40000000 /* Bcache par. err. */
#define TC_3000_300_IR_MEMPARITY 0x80000000 /* Memory par. err. */
/* Device number "cookies." */
#define TC_3000_300_DEV_OPT0 0
#define TC_3000_300_DEV_OPT1 1
#define TC_3000_300_DEV_TCDS 2
#define TC_3000_300_DEV_IOASIC 3
#define TC_3000_300_DEV_CXTURBO 4
#define TC_3000_300_DEV_BOGUS -1
#define TC_3000_300_NCOOKIES 5

View File

@ -1,4 +1,4 @@
/* $NetBSD: tc_3000_500.c,v 1.2 1995/08/03 00:52:36 cgd Exp $ */
/* $NetBSD: tc_3000_500.c,v 1.3 1995/12/20 00:43:30 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@ -33,133 +33,141 @@
#include <machine/autoconf.h>
#include <machine/pte.h>
#include <alpha/tc/tc.h>
#include <dev/tc/tcvar.h>
#include <alpha/tc/tc_conf.h>
#include <alpha/tc/tc_3000_500.h>
/* XXX ESTABLISH, DISESTABLISH */
void tc_3000_500_intr_setup __P((void));
void tc_3000_500_intr_establish
__P((struct confargs *, intr_handler_t, void *));
void tc_3000_500_intr_disestablish __P((struct confargs *));
void tc_3000_500_intr_establish __P((struct device *, void *,
tc_intrlevel_t, int (*)(void *), void *));
void tc_3000_500_intr_disestablish __P((struct device *, void *));
void tc_3000_500_iointr __P((void *, int));
int tc_3000_500_getdev __P((struct confargs *));
#define KV(x) ((caddr_t)phystok0seg(x))
#define TC_3000_500_NSLOTS 8
#define TC_3000_500_MAXDEVS 9
int tc_3000_500_intrnull __P((void *));
static struct tc_slot_desc dec_3000_500_slots[TC_3000_500_NSLOTS] = {
{ KV(0x100000000), }, /* slot 0 - TC option slot 0 */
{ KV(0x120000000), }, /* slot 1 - TC option slot 1 */
{ KV(0x140000000), }, /* slot 2 - TC option slot 2 */
{ KV(0x160000000), }, /* slot 3 - TC option slot 3 */
{ KV(0x180000000), }, /* slot 4 - TC option slot 4 */
{ KV(0x1a0000000), }, /* slot 5 - TC option slot 5 */
{ KV(0x1c0000000), }, /* slot 6 - TCDS ASIC on cpu board */
{ KV(0x1e0000000), }, /* slot 7 - IOCTL ASIC on cpu board */
#define C(x) ((void *)(u_long)x)
#define KV(x) (phystok0seg(x))
struct tc_slotdesc tc_3000_500_slots[] = {
{ KV(0x100000000), C(TC_3000_500_DEV_OPT0), }, /* 0 - opt slot 0 */
{ KV(0x120000000), C(TC_3000_500_DEV_OPT1), }, /* 1 - opt slot 1 */
{ KV(0x140000000), C(TC_3000_500_DEV_OPT2), }, /* 2 - opt slot 2 */
{ KV(0x160000000), C(TC_3000_500_DEV_OPT3), }, /* 3 - opt slot 3 */
{ KV(0x180000000), C(TC_3000_500_DEV_OPT4), }, /* 4 - opt slot 4 */
{ KV(0x1a0000000), C(TC_3000_500_DEV_OPT5), }, /* 5 - opt slot 5 */
{ KV(0x1c0000000), C(TC_3000_500_DEV_BOGUS), }, /* 6 - TCDS ASIC */
{ KV(0x1e0000000), C(TC_3000_500_DEV_BOGUS), }, /* 7 - IOCTL ASIC */
};
int tc_3000_500_nslots =
sizeof(tc_3000_500_slots) / sizeof(tc_3000_500_slots[0]);
struct tc_builtin tc_3000_500_builtins[] = {
{ "FLAMG-IO", 7, 0x00000000, C(TC_3000_500_DEV_IOASIC), },
{ "PMAGB-BA", 7, 0x02000000, C(TC_3000_500_DEV_CXTURBO), },
{ "PMAZ-DS ", 6, 0x00000000, C(TC_3000_500_DEV_TCDS), },
};
int tc_3000_500_nbuiltins =
sizeof(tc_3000_500_builtins) / sizeof(tc_3000_500_builtins[0]);
u_int32_t tc_3000_500_intrbits[TC_3000_500_NCOOKIES] = {
TC_3000_500_IR_OPT0,
TC_3000_500_IR_OPT1,
TC_3000_500_IR_OPT2,
TC_3000_500_IR_OPT3,
TC_3000_500_IR_OPT4,
TC_3000_500_IR_OPT5,
TC_3000_500_IR_TCDS,
TC_3000_500_IR_IOASIC,
TC_3000_500_IR_CXTURBO,
};
static struct confargs dec_3000_500_devs[TC_3000_500_MAXDEVS] = {
{ "IOCTL ", 7, 0x00000000, },
{ "PMAGB-BA", 7, 0x02000000, },
{ "PMAZ-DS ", 6, 0x00000000, },
{ NULL, 5, 0x0, },
{ NULL, 4, 0x0, },
{ NULL, 3, 0x0, },
{ NULL, 2, 0x0, },
{ NULL, 1, 0x0, },
{ NULL, 0, 0x0, },
};
/* Indices into the struct confargs array. */
#define TC_3000_500_DEV_IOCTL 0
#define TC_3000_500_DEV_CXTURBO 1
#define TC_3000_500_DEV_TCDS 2
#define TC_3000_500_DEV_OPT5 3
#define TC_3000_500_DEV_OPT4 4
#define TC_3000_500_DEV_OPT3 5
#define TC_3000_500_DEV_OPT2 6
#define TC_3000_500_DEV_OPT1 7
#define TC_3000_500_DEV_OPT0 8
struct tc_cpu_desc dec_3000_500_cpu = {
dec_3000_500_slots, TC_3000_500_NSLOTS,
dec_3000_500_devs, TC_3000_500_MAXDEVS,
tc_3000_500_intr_setup,
tc_3000_500_intr_establish,
tc_3000_500_intr_disestablish,
tc_3000_500_iointr,
};
intr_handler_t tc_3000_500_intrhand[TC_3000_500_MAXDEVS];
void *tc_3000_500_intrval[TC_3000_500_MAXDEVS];
struct tcintr {
int (*tci_func) __P((void *));
void *tci_arg;
} tc_3000_500_intr[TC_3000_500_NCOOKIES];
void
tc_3000_500_intr_setup()
{
int i;
/* Set up interrupt handlers. */
for (i = 0; i < TC_3000_500_MAXDEVS; i++) {
tc_3000_500_intrhand[i] = tc_intrnull;
tc_3000_500_intrval[i] = (void *)(long)i;
}
u_long i;
u_int32_t imr;
/*
* XXX
* The System Programmer's Manual (3-15) says IMR entries for option
* slots are initialized to 0. I think this is wrong, and that they
* are initialized to 1, i.e. the option slots are disabled. Enable
* them.
*
* XXX
* The MACH code appears to enable them by setting them to 1. !?!?!
* Disable all slot interrupts.
*/
*(volatile u_int32_t *)TC_3000_500_IMR_WRITE = 0;
wbflush();
imr = *(volatile u_int32_t *)TC_3000_500_IMR_READ;
for (i = 0; i < TC_3000_500_NCOOKIES; i++)
imr |= tc_3000_500_intrbits[i];
*(volatile u_int32_t *)TC_3000_500_IMR_WRITE = imr;
tc_mb();
/*
* Set up interrupt handlers.
*/
for (i = 0; i < TC_3000_500_NCOOKIES; i++) {
tc_3000_500_intr[i].tci_func = tc_3000_500_intrnull;
tc_3000_500_intr[i].tci_arg = (void *)i;
}
}
void
tc_3000_500_intr_establish(ca, handler, val)
struct confargs *ca;
int (*handler) __P((void *));
void *val;
tc_3000_500_intr_establish(tcadev, cookie, level, func, arg)
struct device *tcadev;
void *cookie, *arg;
tc_intrlevel_t level;
int (*func) __P((void *));
{
int dev = tc_3000_500_getdev(ca);
u_long dev = (u_long)cookie;
u_int32_t imr;
#ifdef DIAGNOSTIC
if (dev == -1)
panic("tc_3000_500_intr_establish: dev == -1");
/* XXX bounds-check cookie. */
#endif
if (tc_3000_500_intrhand[dev] != tc_intrnull)
panic("tc_3000_500_intr_establish: dev %d twice", dev);
if (tc_3000_500_intr[dev].tci_func != tc_3000_500_intrnull)
panic("tc_3000_500_intr_establish: cookie %d twice", dev);
tc_3000_500_intrhand[dev] = handler;
tc_3000_500_intrval[dev] = val;
tc_3000_500_intr[dev].tci_func = func;
tc_3000_500_intr[dev].tci_arg = arg;
/* XXX ENABLE INTERRUPT MASK FOR DEV */
imr = *(volatile u_int32_t *)TC_3000_500_IMR_READ;
imr &= ~tc_3000_500_intrbits[dev];
*(volatile u_int32_t *)TC_3000_500_IMR_WRITE = imr;
tc_mb();
}
void
tc_3000_500_intr_disestablish(ca)
struct confargs *ca;
tc_3000_500_intr_disestablish(tcadev, cookie)
struct device *tcadev;
void *cookie;
{
int dev = tc_3000_500_getdev(ca);
u_long dev = (u_long)cookie;
u_int32_t imr;
#ifdef DIAGNOSTIC
if (dev == -1)
panic("tc_3000_500_intr_disestablish: somebody goofed");
/* XXX bounds-check cookie. */
#endif
if (tc_3000_500_intrhand[dev] == tc_intrnull)
panic("tc_3000_500_intr_disestablish: dev %d missing intr",
if (tc_3000_500_intr[dev].tci_func == tc_3000_500_intrnull)
panic("tc_3000_500_intr_disestablish: cookie %d bad intr",
dev);
tc_3000_500_intrhand[dev] = tc_intrnull;
tc_3000_500_intrval[dev] = (void *)(long)dev;
imr = *(volatile u_int32_t *)TC_3000_500_IMR_READ;
imr |= tc_3000_500_intrbits[dev];
*(volatile u_int32_t *)TC_3000_500_IMR_WRITE = imr;
tc_mb();
/* XXX DISABLE INTERRUPT MASK FOR DEV */
tc_3000_500_intr[dev].tci_func = tc_3000_500_intrnull;
tc_3000_500_intr[dev].tci_arg = (void *)dev;
}
int
tc_3000_500_intrnull(val)
void *val;
{
panic("tc_3000_500_intrnull: uncaught TC intr for cookie %ld\n",
(u_long)val);
}
void
@ -181,28 +189,26 @@ tc_3000_500_iointr(framep, vec)
#endif
do {
MAGIC_READ;
wbflush();
tc_syncbus();
ir = *(volatile u_int32_t *)TC_3000_500_IR_CLEAR;
wbflush();
ifound = 0;
#define CHECKINTR(slot, bits) \
if (ir & bits) { \
#define CHECKINTR(slot) \
if (ir & tc_3000_500_intrbits[slot]) { \
ifound = 1; \
(*tc_3000_500_intrhand[slot]) \
(tc_3000_500_intrval[slot]); \
(*tc_3000_500_intr[slot].tci_func) \
(tc_3000_500_intr[slot].tci_arg); \
}
/* Do them in order of priority; highest slot # first. */
CHECKINTR(TC_3000_500_DEV_CXTURBO, TC_3000_500_IR_CXTURBO);
CHECKINTR(TC_3000_500_DEV_IOCTL, TC_3000_500_IR_IOCTL);
CHECKINTR(TC_3000_500_DEV_TCDS, TC_3000_500_IR_TCDS);
CHECKINTR(TC_3000_500_DEV_OPT5, TC_3000_500_IR_OPT5);
CHECKINTR(TC_3000_500_DEV_OPT4, TC_3000_500_IR_OPT4);
CHECKINTR(TC_3000_500_DEV_OPT3, TC_3000_500_IR_OPT3);
CHECKINTR(TC_3000_500_DEV_OPT2, TC_3000_500_IR_OPT2);
CHECKINTR(TC_3000_500_DEV_OPT1, TC_3000_500_IR_OPT1);
CHECKINTR(TC_3000_500_DEV_OPT0, TC_3000_500_IR_OPT0);
CHECKINTR(TC_3000_500_DEV_CXTURBO);
CHECKINTR(TC_3000_500_DEV_IOASIC);
CHECKINTR(TC_3000_500_DEV_TCDS);
CHECKINTR(TC_3000_500_DEV_OPT5);
CHECKINTR(TC_3000_500_DEV_OPT4);
CHECKINTR(TC_3000_500_DEV_OPT3);
CHECKINTR(TC_3000_500_DEV_OPT2);
CHECKINTR(TC_3000_500_DEV_OPT1);
CHECKINTR(TC_3000_500_DEV_OPT0);
#undef CHECKINTR
#ifdef DIAGNOSTIC
@ -228,21 +234,6 @@ tc_3000_500_iointr(framep, vec)
} while (ifound);
}
int
tc_3000_500_getdev(ca)
struct confargs *ca;
{
int i;
for (i = 0; i < TC_3000_500_MAXDEVS; i++)
if (ca->ca_slot == dec_3000_500_devs[i].ca_slot &&
ca->ca_offset == dec_3000_500_devs[i].ca_offset &&
!strncmp(ca->ca_name, dec_3000_500_devs[i].ca_name))
return (i);
return (-1);
}
/*
* tc_3000_500_ioslot --
* Set the PBS bits for devices on the TC.
@ -265,6 +256,6 @@ tc_3000_500_ioslot(slot, flags, set)
ios &= ~flags;
s = splhigh();
*iosp = ios;
wbflush();
tc_mb();
splx(s);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: tc_3000_500.h,v 1.1 1995/02/13 23:09:09 cgd Exp $ */
/* $NetBSD: tc_3000_500.h,v 1.2 1995/12/20 00:43:31 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@ -57,7 +57,7 @@
#define TC_3000_500_IR_OPT4 0x00000010 /* TC Option 4 */
#define TC_3000_500_IR_OPT5 0x00000020 /* TC Option 5 */
#define TC_3000_500_IR_TCDS 0x00000040 /* TC Dual SCSI */
#define TC_3000_500_IR_IOCTL 0x00000080 /* TC IOCTL */
#define TC_3000_500_IR_IOASIC 0x00000080 /* TC IOASIC */
#define TC_3000_500_IR_CXTURBO 0x00000100 /* TC CXTURBO */
#define TC_3000_500_IR_ERR2 0x00080000 /* Second error */
#define TC_3000_500_IR_DMABE 0x00100000 /* DMA buffer error */
@ -86,5 +86,20 @@
#define TC_IOSLOT_OPT4 4 /* Option 4 PBS offset. */
#define TC_IOSLOT_OPT5 5 /* Option 5 PBS offset. */
#define TC_IOSLOT_SCSI 6 /* Option SCSI PBS offset. */
#define TC_IOSLOT_IOCTL 7 /* Option IOCTL PBS offset. */
#define TC_IOSLOT_IOASIC 7 /* Option IOASIC PBS offset. */
#define TC_IOSLOT_CXTURBO 8 /* Option CXTURBO PBS offset. */
/* Device number "cookies." */
#define TC_3000_500_DEV_OPT0 0
#define TC_3000_500_DEV_OPT1 1
#define TC_3000_500_DEV_OPT2 2
#define TC_3000_500_DEV_OPT3 3
#define TC_3000_500_DEV_OPT4 4
#define TC_3000_500_DEV_OPT5 5
#define TC_3000_500_DEV_TCDS 6
#define TC_3000_500_DEV_IOASIC 7
#define TC_3000_500_DEV_CXTURBO 8
#define TC_3000_500_DEV_BOGUS -1
#define TC_3000_500_NCOOKIES 9

View File

@ -0,0 +1,60 @@
/* $NetBSD: tc_conf.h,v 1.1 1995/12/20 00:43:32 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Chris G. Demetriou
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
/*
* Machine-specific TurboChannel configuration definitions.
*/
#ifdef DEC_3000_500
extern void tc_3000_500_intr_setup __P((void));
extern void tc_3000_500_iointr __P((void *, int));
extern void tc_3000_500_intr_establish __P((struct device *, void *,
tc_intrlevel_t, int (*)(void *), void *));
extern void tc_3000_500_intr_disestablish __P((struct device *, void *));
extern int tc_3000_500_nslots;
extern struct tc_slotdesc tc_3000_500_slots[];
extern int tc_3000_500_nbuiltins;
extern struct tc_builtin tc_3000_500_builtins[];
#endif /* DEC_3000_500 */
#ifdef DEC_3000_300
extern void tc_3000_300_intr_setup __P((void));
extern void tc_3000_300_iointr __P((void *, int));
extern void tc_3000_300_intr_establish __P((struct device *, void *,
tc_intrlevel_t, int (*)(void *), void *));
extern void tc_3000_300_intr_disestablish __P((struct device *, void *));
extern int tc_3000_300_nslots;
extern struct tc_slotdesc tc_3000_300_slots[];
extern int tc_3000_300_nbuiltins;
extern struct tc_builtin tc_3000_300_builtins[];
#endif /* DEC_3000_300 */

141
sys/arch/alpha/tc/tcasic.c Normal file
View File

@ -0,0 +1,141 @@
/* $NetBSD: tcasic.c,v 1.1 1995/12/20 00:43:34 cgd Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Chris G. Demetriou
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*/
#include <sys/param.h>
#include <sys/device.h>
#include <machine/autoconf.h>
#include <machine/rpb.h>
#include <dev/tc/tcvar.h>
#include <alpha/tc/tc_conf.h>
/* Definition of the driver for autoconfig. */
int tcasicmatch(struct device *, void *, void *);
void tcasicattach(struct device *, struct device *, void *);
struct cfdriver tcasiccd =
{ NULL, "tcasic", tcasicmatch, tcasicattach, DV_DULL,
sizeof (struct device) };
int tcasicprint __P((void *, char *));
extern int cputype;
/* There can be only one. */
int tcasicfound;
int
tcasicmatch(parent, cfdata, aux)
struct device *parent;
void *cfdata;
void *aux;
{
struct confargs *ca = aux;
/* Make sure that we're looking for a TurboChannel ASIC. */
if (strcmp(ca->ca_name, tcasiccd.cd_name))
return (0);
/* Make sure that the system supports a TurboChannel ASIC. */
if ((cputype != ST_DEC_3000_500) && (cputype != ST_DEC_3000_300))
return (0);
if (tcasicfound)
return (0);
return (1);
}
void
tcasicattach(parent, self, aux)
struct device *parent;
struct device *self;
void *aux;
{
struct tc_attach_args tc;
void (*intr_setup) __P((void));
void (*iointr) __P((void *, int));
tcasicfound = 1;
switch (cputype) {
#ifdef DEC_3000_500
case ST_DEC_3000_500:
printf(": 25MHz\n");
intr_setup = tc_3000_500_intr_setup;
iointr = tc_3000_500_iointr;
tc.tca_nslots = tc_3000_500_nslots;
tc.tca_slots = tc_3000_500_slots;
tc.tca_nbuiltins = tc_3000_500_nbuiltins;
tc.tca_builtins = tc_3000_500_builtins;
tc.tca_intr_establish = tc_3000_500_intr_establish;
tc.tca_intr_disestablish = tc_3000_500_intr_disestablish;
break;
#endif /* DEC_3000_500 */
#ifdef DEC_3000_300
case ST_DEC_3000_300:
printf(": 12.5MHz\n");
intr_setup = tc_3000_300_intr_setup;
iointr = tc_3000_300_iointr;
tc.tca_nslots = tc_3000_300_nslots;
tc.tca_slots = tc_3000_300_slots;
tc.tca_nbuiltins = tc_3000_300_nbuiltins;
tc.tca_builtins = tc_3000_300_builtins;
tc.tca_intr_establish = tc_3000_300_intr_establish;
tc.tca_intr_disestablish = tc_3000_300_intr_disestablish;
break;
#endif /* DEC_3000_300 */
default:
printf("\n");
panic("tcasicattach: bad cputype");
}
(*intr_setup)();
set_iointr(iointr);
config_found(self, &tc, tcasicprint);
}
int
tcasicprint(aux, pnp)
void *aux;
char *pnp;
{
/* only TCs can attach to tcasics; easy. */
if (pnp)
printf("tc at %s", pnp);
return (UNCONF);
}