Re-write Decstation turbochannel autoconfiguration code to use the machine-

independent TC support in sys/dev/tc/tc.c and sys/dev/tc/tcvar.h:
  * Change the tc autoconfiguration tables to use a struct tc_attach_args
    instead of the ad-hoc structure.
  * Change all pmax device drivers to use a `struct confargs' that's
    assignment-compatible with  sys/dev/tc/tcvar.h `struct tcdev_attach_args'.
    Devices that can be present on a TC or as ioctl asic/mainbus builtins
    use  the same `struct confargs'.
  * Eliminate the `BUS_CVTADDR()' macros which the pmax port inherited from
    an old, now-obsolete sys/arch/alpha snapshot.

  * Update the comments and debugging code in interrupt handlers to
    be consistent with the machine-independent TC support.

Other commits that overlap the same source files include: re-enabling
clock-tick interrupts earlier, and counting hardclock ticks for vmstat -i.
This commit is contained in:
jonathan 1996-01-29 22:52:15 +00:00
parent 2efc4c5f38
commit 5ea2ec2357
27 changed files with 739 additions and 813 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.24 1995/12/28 16:22:41 jonathan Exp $ */
/* $NetBSD: trap.c,v 1.25 1996/01/29 22:52:35 jonathan Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -876,7 +876,6 @@ interrupt(statusReg, causeReg, pc)
clnlintr();
}
#endif
#include "ppp.h"
#if NPPP > 0
if (netisr & (1 << NETISR_PPP)) {
netisr &= ~(1 << NETISR_PPP);
@ -916,6 +915,7 @@ kn01_intr(mask, pc, statusReg, causeReg)
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[6]++;
/* keep clock interrupts enabled */
causeReg &= ~MACH_INT_MASK_3;
@ -930,6 +930,13 @@ kn01_intr(mask, pc, statusReg, causeReg)
#endif
#if NLE > 0
if (mask & MACH_INT_MASK_1) {
/*
* tty interrupts were disabled by the splx() call
* that re-enables clock interrupts. A slip or ppp driver
* manipulating if queues should have called splimp(),
* which would mask out MACH_INT_MASK_1.
*/
intrcnt[3]++;
leintr(lecd.cd_devs[0]);
}
@ -982,6 +989,7 @@ kn02_intr(mask, pc, statusReg, causeReg)
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[6]++;
/* keep clock interrupts enabled */
causeReg &= ~MACH_INT_MASK_1;
@ -1075,6 +1083,7 @@ kmin_intr(mask, pc, statusReg, causeReg)
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[6]++;
}
if ((intr & KMIN_INTR_SCC_0) &&
@ -1156,10 +1165,12 @@ xine_intr(mask, pc, statusReg, causeReg)
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[6]++;
causeReg &= ~MACH_INT_MASK_1;
/* reenable clock interrupts */
splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);
}
/* reenable clock interrupts */
splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);
if (mask & MACH_INT_MASK_3) {
intr = *intrp;
/* masked interrupts are still observable */
@ -1270,6 +1281,7 @@ kn03_intr(mask, pc, statusReg, causeReg)
struct clockframe cf;
int temp;
static int user_warned = 0;
register u_long old_buscycle = latched_cycle_cnt;
old_mask = *imaskp & kn03_tc3_imask;
*imaskp = kn03_tc3_imask;
@ -1282,13 +1294,33 @@ kn03_intr(mask, pc, statusReg, causeReg)
temp = c->regc; /* XXX clear interrupt bits */
cf.pc = pc;
cf.sr = statusReg;
intrcnt[6]++;
hardclock(&cf);
latched_cycle_cnt = *(u_long*)(ASIC_REG_CTR(asic_base));
hardclock(&cf);
intrcnt[6]++;
old_buscycle = latched_cycle_cnt - old_buscycle;
causeReg &= ~MACH_INT_MASK_1;
/* reenable clock interrupts */
splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);
}
/* reenable clock interrupts */
splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);
/*
* Check for late clock interrupts (allow 10% slop). Be careful
* to do so only after calling hardclock(), due to logging cost.
* Even then, logging dropped ticks just causes more clock
* ticks to be missed.
*/
#ifdef notdef
if ((mask & MACH_INT_MASK_1) && old_buscycle > (tick+49) * 25) {
extern int msgbufmapped;
if(msgbufmapped && 0)
addlog("kn03: clock intr %d usec late\n",
old_buscycle/25);
}
#endif
/*
* IOCTL asic DMA-related interrupts should be checked here,
* and DMA pointers serviced as soon as possible.
*/
if (mask & MACH_INT_MASK_0) {
intr = *intrp;
@ -1302,6 +1334,18 @@ kn03_intr(mask, pc, statusReg, causeReg)
#endif
}
/*
* XXX
* DMA and non-DMA interrupts from the IOCTl asic all use the
* single interrupt request line from the IOCTL asic.
* Disabling IOASIC interrupts while servicing network or
* disk-driver interrupts causes DMA overruns. NON-dma IOASIC
* interrupts should be disabled in the ioasic, and
* interrupts from the IOASIC itself should be re-enabled.
* DMA interrupts can then be serviced whilst still servicing
* non-DMA interrupts from ioctl devices or TC options.
*/
if (intr & (KN03_INTR_SCSI_OVRUN | KN03_INTR_SCSI_READ_E))
*intrp &= ~(KN03_INTR_SCSI_OVRUN | KN03_INTR_SCSI_READ_E);

View File

@ -1,4 +1,4 @@
/* $NetBSD: cfb.c,v 1.11 1995/09/12 22:36:09 jonathan Exp $ */
/* $NetBSD: cfb.c,v 1.12 1996/01/29 22:52:15 jonathan Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)sfb.c 8.1 (Berkeley) 6/10/93
* $Id: cfb.c,v 1.11 1995/09/12 22:36:09 jonathan Exp $
* $Id: cfb.c,v 1.12 1996/01/29 22:52:15 jonathan Exp $
*/
/*
@ -89,6 +89,7 @@
#include <sys/errno.h>
#include <sys/fcntl.h>
#include <sys/device.h>
#include <dev/tc/tcvar.h>
#include <machine/machConst.h>
#include <machine/pmioctl.h>
@ -121,6 +122,10 @@ extern struct cfdriver cfb;
#define CMAP_BITS (3 * 256) /* 256 entries, 3 bytes per. */
static u_char cmap_bits [NCFB * CMAP_BITS]; /* One colormap per cfb... */
/*
* Method table for standard framebuffer operations on a CFB.
* The CFB uses a Brooktree bt479 ramdac.
*/
struct fbdriver cfb_driver = {
bt459_video_on,
bt459_video_off,
@ -161,26 +166,6 @@ struct cfdriver cfbcd = {
NULL, "cfb", cfbmatch, cfbattach, DV_DULL, sizeof(struct fbinfo), 0
};
#if 0
/*
* Look for a cfb. Separated out from cfbmatch() so consinit() can call it.
*/
int
cfbprobe(cfbaddr)
caddr_t cfbaddr;
{
/* check for no frame buffer */
if (badaddr(cfbaddr, 4))
return (0);
/* make sure that we're looking for this type of device. */
if (!BUS_MATCHNAME(ca, "PMAG-BA "))
return (0);
return 1;
}
#endif
int
cfbmatch(parent, match, aux)
@ -191,7 +176,6 @@ cfbmatch(parent, match, aux)
struct cfdata *cf = match;
struct confargs *ca = aux;
static int ncfbs = 1;
caddr_t cfbaddr = BUS_CVTADDR(ca);
#ifdef FBDRIVER_DOES_ATTACH
/* leave configuration to the fb driver */
@ -199,8 +183,7 @@ cfbmatch(parent, match, aux)
#endif
/* make sure that we're looking for this type of device. */
/*if (!cfbprobe(cfbaddr)) return 0;*/
if (!BUS_MATCHNAME(ca, "PMAG-BA "))
if (!TC_BUS_MATCHNAME(ca, "PMAG-BA "))
return (0);
@ -214,7 +197,8 @@ cfbmatch(parent, match, aux)
/*
* Attach a device. Hand off all the work to cfbinit(),
* so console-config cod can attach cfbs early in boot.
* so console-config code can attach cfb devices very early in boot,
* to use as system console.
*/
void
cfbattach(parent, self, aux)
@ -223,14 +207,14 @@ cfbattach(parent, self, aux)
void *aux;
{
struct confargs *ca = aux;
caddr_t base = BUS_CVTADDR(ca);
caddr_t base = (caddr_t)(ca->ca_addr);
int unit = self->dv_unit;
struct fbinfo *fi = (struct fbinfo *) self;
#ifdef notyet
/* if this is the console, it's already configured. */
if (ca->ca_slotpri == cons_slot)
return; /* XXX patch up f softc pointer */
return; /* XXX patch up softc pointer */
#endif
if (!cfbinit(fi, base, unit, 0))
@ -238,21 +222,23 @@ cfbattach(parent, self, aux)
/*
* The only interrupt on the CFB proper is the vertical-blank
* interrupt, which cannot be disabled. The CFB always requests it.
* interrupt, which cannot be disabled. The CFB always requests
* an interrupt during every vertical-retrace period.
* We never enable interrupts from CFB cards, except on the
* 3MIN, where TC options interrupt at spl0 through spl2, and
* disabling those interrupts isn't currently honoured.
* disabling of TC option interrupts doesn't work.
*/
if (pmax_boardtype == DS_3MIN) {
BUS_INTR_ESTABLISH(ca, cfb_intr, self);
tc_intr_establish(parent, (void*)ca->ca_slotpri, TC_IPL_NONE,
cfb_intr, fi);
}
}
/*
* Initialization
* CFB initialization. This is divorced from cfbattch() so that
* a console framebuffer can be initialized early during boot.
*/
int
cfbinit(fi, cfbaddr, unit, silent)
@ -261,7 +247,12 @@ cfbinit(fi, cfbaddr, unit, silent)
int unit;
int silent;
{
/*
* If this device is being intialized as the console, malloc()
* is not yet up and we must use statically-allocated space.
*/
if (fi == NULL) fi = &cfbfi; /* XXX */
/* check for no frame buffer */
if (badaddr(cfbaddr, 4)) {
@ -300,6 +291,8 @@ cfbinit(fi, cfbaddr, unit, silent)
printf("cfb%d: vdac init failed.\n", unit);
return (0);
}
/*cfbInitColorMap();*/ /* done by bt459init() */
/*
* qvss/pm-style mmap()ed event queue compatibility glue
@ -333,8 +326,6 @@ cfbinit(fi, cfbaddr, unit, silent)
}
/*cfbInitColorMap();*/ /* done by bt459init() */
/*
* Connect to the raster-console pseudo-driver
*/
@ -352,8 +343,11 @@ cfbinit(fi, cfbaddr, unit, silent)
* The original TURBOChannel cfb interrupts on every vertical
* retrace, and we can't disable the board from requesting those
* interrupts. The 4.4BSD kernel never enabled those interrupts;
* but there's a kernel design bug on the 3MIN, where the cfb
* interrupts at spl0, spl1, or spl2.
* but there's a kernel design bug on the 3MIN, where disabling
* (or enabling) TC option interrupts has no effect the interrupts
* are mapped to R3000 interrupts and always seem to be taken.
* This function simply dismisses CFB interrupts, or the interrupt
* request from the card will still be active.
*/
int
cfb_intr(sc)

View File

@ -1,4 +1,4 @@
/* $NetBSD: dc.c,v 1.12 1995/09/11 21:29:23 jonathan Exp $ */
/* $NetBSD: dc.c,v 1.13 1996/01/29 22:52:16 jonathan Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -91,11 +91,16 @@
extern int pmax_boardtype;
struct dc_softc {
struct device sc_dv;
struct pdma dc_pdma[4];
};
/*
* Autoconfiguration data for config.new.
* Autoconfiguration data for config.
*
* Use the statically-allocated softc until old autoconfig code and
* config.old are completely gone.
*
*/
int dcmatch __P((struct device * parent, void *cfdata, void *aux));
void dcattach __P((struct device *parent, struct device *self, void *aux));
@ -105,7 +110,7 @@ int dcintr __P((void * xxxunit));
extern struct cfdriver dccd;
struct cfdriver dccd = {
NULL, "dc", dcmatch, dcattach, DV_DULL, sizeof(struct device), 0
NULL, "dc", dcmatch, dcattach, DV_TTY, sizeof(struct dc_softc), 0
};
@ -185,7 +190,9 @@ dcmatch(parent, match, aux)
static int nunits = 0;
if (!BUS_MATCHNAME(ca, "dc"))
if (strcmp(ca->ca_name, "dc") != 0 &&
strcmp(ca->ca_name, "mdc") != 0 &&
strcmp(ca->ca_name, "dc7085") != 0)
return (0);
/*
@ -207,13 +214,15 @@ dcattach(parent, self, aux)
void *aux;
{
register struct confargs *ca = aux;
caddr_t dcaddr;
(void) dc_doprobe((void*)MACH_PHYS_TO_UNCACHED(BUS_CVTADDR(ca)),
dcaddr = (caddr_t)ca->ca_addr;
(void) dc_doprobe((void*)MACH_PHYS_TO_UNCACHED(dcaddr),
self->dv_unit, self->dv_cfdata->cf_flags,
ca->ca_slot);
/* tie pseudo-slot to device */
BUS_INTR_ESTABLISH(ca, dcintr, (void *)self->dv_unit);
BUS_INTR_ESTABLISH(ca, dcintr, self);
printf("\n");
}
@ -230,6 +239,11 @@ raster_console()
}
/*
* DC7085 (dz-11) probe routine from old-style config.
* This is only here out of intertia.
*/
int
dc_doprobe(addr, unit, flags, priority)
void *addr;
int unit, flags, priority;
@ -546,10 +560,12 @@ int
dcintr(xxxunit)
void *xxxunit;
{
register int unit = (int)xxxunit;
register struct dc_softc *sc = xxxunit;
register dcregs *dcaddr;
register unsigned csr;
register int unit = sc->sc_dv.dv_unit;
unit <<= 2;
dcaddr = (dcregs *)dcpdma[unit].p_addr;
while ((csr = dcaddr->dc_csr) & (CSR_RDONE | CSR_TRDY)) {

View File

@ -1,11 +1,10 @@
/* $NetBSD: dcvar.h,v 1.1 1995/08/04 00:22:12 jonathan Exp $ */
/* $NetBSD: dcvar.h,v 1.2 1996/01/29 22:52:18 jonathan Exp $ */
/*
* external declarations from DECstation dc serial driver
* External declarations from DECstation dc serial driver.
*/
extern int dcGetc __P ((dev_t dev));
extern int dcparam __P((register struct tty *tp, register struct termios *t));
extern void dcPutc __P ((dev_t dev, int c));
extern void dcPutc __P((dev_t dev, int c));

View File

@ -1,4 +1,4 @@
/* $NetBSD: dtop.c,v 1.9 1995/09/25 21:12:33 jonathan Exp $ */
/* $NetBSD: dtop.c,v 1.10 1996/01/29 22:52:19 jonathan Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -224,7 +224,7 @@ dtopmatch(parent, match, aux)
static int nunits = 0;
if (!BUS_MATCHNAME(ca, "dtop"))
if (strcmp(ca->ca_name, "dtop") != 0)
return (0);
/*
@ -247,7 +247,7 @@ dtopattach(parent, self, aux)
{
register struct confargs *ca = aux;
(void) dtop_doprobe((void*)MACH_PHYS_TO_UNCACHED(BUS_CVTADDR(ca)),
(void) dtop_doprobe((void*)MACH_PHYS_TO_UNCACHED(ca->ca_addr),
self->dv_unit, ca->ca_slot);
/* tie pseudo-slot to device */

View File

@ -1,4 +1,4 @@
/* $NetBSD: mfb.c,v 1.8 1995/09/11 07:45:41 jonathan Exp $ */
/* $NetBSD: mfb.c,v 1.9 1996/01/29 22:52:20 jonathan Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -88,6 +88,8 @@
#include <sys/fcntl.h>
#include <sys/errno.h>
#include <sys/device.h>
#include <machine/autoconf.h>
#include <dev/tc/tcvar.h>
#include <machine/machConst.h>
#include <machine/pmioctl.h>
@ -173,8 +175,6 @@ struct fbdriver mfb_driver = {
#define MFB_OFFSET_ROM 0x0 /* Diagnostic ROM */
#define MFB_FB_SIZE 0x200000 /* frame buffer size */
#include <sys/device.h>
#include <machine/autoconf.h>
/*
* Autoconfiguration data for config.new.
@ -189,18 +189,6 @@ struct cfdriver mfbcd = {
NULL, "mfb", mfbmatch, mfbattach, DV_DULL, sizeof(struct device), 0
};
#if 0
int
mfbprobe(addr)
caddr_t addr;
{
/* make sure that we're looking for this type of device. */
if (!BUS_MATCHNAME(ca, "PMAG-AA "))
return (0);
}
#endif
int
mfbmatch(parent, match, aux)
struct device *parent;
@ -217,7 +205,7 @@ mfbmatch(parent, match, aux)
#endif
/* make sure that we're looking for this type of device. */
if (!BUS_MATCHNAME(ca, "PMAG-AA "))
if (!TC_BUS_MATCHNAME(ca, "PMAG-AA "))
return (0);
#ifdef notyet
@ -235,7 +223,7 @@ mfbattach(parent, self, aux)
void *aux;
{
struct confargs *ca = aux;
caddr_t base = BUS_CVTADDR(ca);
caddr_t mfbaddr = (caddr_t) ca->ca_addr;
int unit = self->dv_unit;
struct fbinfo *fi = &mfbfi;
@ -246,7 +234,7 @@ mfbattach(parent, self, aux)
#endif
if (!mfbinit(BUS_CVTADDR(ca), unit, 0))
if (!mfbinit(mfbaddr, unit, 0))
return;
/* no interrupts for MFB */

View File

@ -1,4 +1,4 @@
/* $NetBSD: pm.c,v 1.10 1995/11/25 10:39:57 mellon Exp $ */
/* $NetBSD: pm.c,v 1.11 1996/01/29 22:52:21 jonathan Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -113,10 +113,6 @@ extern void pmScreenInit __P((struct fbinfo *fi));
static void pmLoadCursor __P((struct fbinfo *fi, u_short *ptr));
void pmPosCursor __P((struct fbinfo *fi, int x, int y));
#ifdef notyet /* these should be removed */
static void pmRestoreCursorColor __P(());
#endif
void bt478CursorColor __P((struct fbinfo *fi, u_int *color));
void bt478InitColorMap __P((struct fbinfo *fi));
@ -189,11 +185,10 @@ pmmatch(parent, match, aux)
struct cfdata *cf = match;
struct confargs *ca = aux;
static int npms = 1;
caddr_t pmaddr = BUS_CVTADDR(ca);
caddr_t pmaddr = (caddr_t)ca->ca_addr;
/* make sure that we're looking for this type of device. */
if (!BUS_MATCHNAME(ca, "pm"))
if (strcmp(ca->ca_name, "pm") != 0)
return (0);
if (badaddr(pmaddr, 4))
@ -214,7 +209,7 @@ pmattach(parent, self, aux)
void *aux;
{
struct confargs *ca = aux;
caddr_t pmaddr = BUS_CVTADDR(ca);
caddr_t pmaddr = (caddr_t)ca->ca_addr;
if (!pminit(&pmfi, 0, 0))
return;
@ -226,8 +221,8 @@ pmattach(parent, self, aux)
/*
* Test to see if device is present.
* Return true if found and initialized ok.
* pmax FB initialization. This is abstracted out from pmbattch() so
* that a console framebuffer can be initialized early in boot.
*/
pminit(fi, unit, silent)
struct fbinfo *fi;

View File

@ -1,4 +1,4 @@
/* $NetBSD: promio.c,v 1.6 1996/01/03 20:39:19 jonathan Exp $ */
/* $NetBSD: promio.c,v 1.7 1996/01/29 22:52:31 jonathan Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -105,7 +105,7 @@ static void romputc __P ((dev_t, int));
static void rompollc __P((dev_t, int));
int pmax_boardtype; /* Mother board type */
extern int pmax_boardtype; /* Mother board type */
/*
* Major device numbers for possible console devices. XXX

View File

@ -1,4 +1,4 @@
/* $NetBSD: sii.c,v 1.8 1995/09/13 19:35:58 jonathan Exp $ */
/* $NetBSD: sii.c,v 1.9 1996/01/29 22:52:23 jonathan Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -230,11 +230,16 @@ siimatch(parent, match, aux)
struct cfdata *cf = match;
struct confargs *ca = aux;
if (!BUS_MATCHNAME(ca, "sii") && !BUS_MATCHNAME(ca, "PMAZ-AA "))
if (strcmp(ca->ca_name, "sii") != 0 &&
strncmp(ca->ca_name, "PMAZ-AA ", 8) != 0) /*XXX*/
return (0);
/* XXX check for bad address */
/* XXX kn01s have exactly one SII. Does any other machine use them? */
/*
* XXX kn01s have exactly one SII. the Decsystem 5100 apparently
* uses them also, but as yet we don't know at what address.
* XXX PVAXES apparently use the SII also.
*/
return (1);
}
@ -249,7 +254,7 @@ siiattach(parent, self, aux)
register void *siiaddr;
register int i;
siiaddr = (void*)MACH_PHYS_TO_UNCACHED(BUS_CVTADDR(ca));
siiaddr = (void*)MACH_PHYS_TO_UNCACHED(ca->ca_addr);
sc->sc_regs = (SIIRegs *)siiaddr;
sc->sc_flags = sc->sc_dev.dv_cfdata->cf_flags;

View File

@ -1,4 +1,4 @@
/* $NetBSD: xcfb.c,v 1.9 1995/10/09 01:45:26 jonathan Exp $ */
/* $NetBSD: xcfb.c,v 1.10 1996/01/29 22:52:24 jonathan Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -101,6 +101,7 @@ xcfb needs dtop device
#include <vm/vm.h>
#include <sys/device.h>
#include <dev/tc/tcvar.h>
#include <machine/autoconf.h>
#include <machine/machConst.h>
#include <machine/pmioctl.h>
@ -190,8 +191,9 @@ xcfbmatch(parent, match, aux)
struct confargs *ca = aux;
static int nxcfbs = 1;
/* make sure that we're looking for this type of device. */
if (!BUS_MATCHNAME(ca, "PMAG-DV ") && !BUS_MATCHNAME(ca, "xcfb"))
/* Make sure that it's an xcfb. */
if (!TC_BUS_MATCHNAME(ca, "PMAG-DV ") &&
strcmp(ca->ca_name, "xcfb") != 0)
return (0);
#ifdef notyet
@ -210,7 +212,7 @@ xcfbattach(parent, self, aux)
{
struct confargs *ca = aux;
if (!xcfbinit(NULL, BUS_CVTADDR(ca), self->dv_unit, 0));
if (!xcfbinit(NULL, ca->ca_addr, self->dv_unit, 0));
return;
/* no interrupts for XCFB */

View File

@ -1,4 +1,4 @@
/* $NetBSD: autoconf.h,v 1.3 1996/01/11 05:57:04 jonathan Exp $ */
/* $NetBSD: autoconf.h,v 1.4 1996/01/29 22:52:26 jonathan Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@ -31,6 +31,8 @@
* Machine-dependent structures of autoconfiguration
*/
#include <machine/tc_machdep.h>
struct confargs;
/* Handle device interrupt for given unit of a driver */
@ -38,43 +40,21 @@ struct confargs;
typedef void* intr_arg_t; /* pointer to some softc */
typedef int (*intr_handler_t) __P((intr_arg_t));
struct abus {
struct device *ab_dv; /* back-pointer to device */
int ab_type; /* bus type (see below) */
void (*ab_intr_establish) /* bus's set-handler function */
__P((struct confargs *, intr_handler_t, intr_arg_t));
void (*ab_intr_disestablish) /* bus's unset-handler function */
__P((struct confargs *));
caddr_t (*ab_cvtaddr) /* convert slot/offset to address */
__P((struct confargs *));
int (*ab_matchname) /* see if name matches driver */
__P((struct confargs *, char *));
};
#define BUS_MAIN 1 /* mainbus */
#define BUS_TC 2 /* TurboChannel */
#define BUS_ASIC 3 /* IOCTL ASIC; under TurboChannel */
#define BUS_TCDS 4 /* TCDS ASIC; under TurboChannel */
#define KN02_ASIC_NAME "KN02 " /* very special */
#define KN02_ASIC_NAME "KN02 " /* ROM name in 3max system slot */
#define BUS_INTR_ESTABLISH(ca, handler, val) \
(*(ca)->ca_bus->ab_intr_establish)((ca), (handler), (val))
#define BUS_INTR_DISESTABLISH(ca) \
(*(ca)->ca_bus->ab_intr_establish)(ca)
#define BUS_CVTADDR(ca) \
(*(ca)->ca_bus->ab_cvtaddr)(ca)
#define BUS_MATCHNAME(ca, name) \
(*(ca)->ca_bus->ab_matchname)((ca), (name))
generic_intr_establish((ca), (handler), (val))
struct confargs {
char *ca_name; /* Device name. */
char ca_name[8+1]; /* Device name. */
int ca_slot; /* Device slot (table entry). */
int ca_offset; /* Offset into slot. */
tc_addr_t ca_addr; /* Device address. */
int ca_slotpri; /* Device interrupt "priority" */
struct abus *ca_bus; /* bus device resides on. */
};
extern caddr_t baseboard_cvtaddr __P((struct confargs *)); /*XXX*/
#ifndef pmax
void set_clockintr __P((void (*)(struct clockframe *)));

View File

@ -1,4 +1,4 @@
/* $NetBSD: tc_machdep.h,v 1.1 1995/12/28 08:42:17 jonathan Exp $ */
/* $NetBSD: tc_machdep.h,v 1.2 1996/01/29 22:52:27 jonathan Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@ -81,4 +81,16 @@ typedef int32_t tc_offset_t;
#define TC_PHYS_TO_UNCACHED(addr) \
(addr)
#define tc_badaddr(tcaddr) \
badaddr((void *)(tcaddr), sizeof (u_int32_t))
/*
* Use the following macros to compare device names on a pmax, as
* the autoconfig structs are in a state of flux.
*/
struct confargs;
#define TC_BUS_MATCHNAME(ca, name) \
(strncmp( (ca)->ca_name, (name), TC_ROM_LLEN+1) == 0)
#endif /* __MACHINE_TC_MACHDEP_H__*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: clock.c,v 1.9 1996/01/07 15:38:44 jonathan Exp $ */
/* $NetBSD: clock.c,v 1.10 1996/01/29 22:52:28 jonathan Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -77,6 +77,32 @@ volatile struct chiptime *Mach_clock_addr;
#define RATE_2048_HZ 0x5 /* 488.281 usecs/interrupt */
#undef SELECTED_RATE
#if (HZ == 64)
# define SELECTED_RATE RATE_64_HZ /* 4.4bsd default on pmax */
# define SHIFT_HZ 6
# else /* !64 Hz */
#if (HZ == 128)
# define SELECTED_RATE RATE_128_HZ
# define SHIFT_HZ 7
#else /* !128 Hz */
#if (HZ == 256)
# define SELECTED_RATE RATE_256_HZ
# define SHIFT_HZ 8
#else /*!256Hz*/
#if (HZ == 512)
# define SELECTED_RATE RATE_512_HZ
# define SHIFT_HZ 9
#else /*!512hz*/
#if (HZ == 1024)
# define SELECTED_RATE RATE_1024_HZ
# define SHIFT_HZ 10
#else /* !1024hz*/
# error RTC interrupt rate HZ not recognised; must be a power of 2
#endif /*!64Hz*/
#endif /*!1024Hz*/
#endif /*!512 Hz*/
#endif /*!256 Hz*/
#endif /*!128Hz*/
/*
* RTC interrupt rate: pick one of 64, 128, 256, 512, 1024, 2048.
@ -93,39 +119,25 @@ volatile struct chiptime *Mach_clock_addr;
* give resolution in ns or tens of ns.
*/
#ifndef RTC_HZ
#ifndef HZ
#ifdef __mips__
#define RTC_HZ 64
/*#define HZ 64*/ /* conveniently divides 1 sec */
#define HZ 256 /* default on Ultrix */
#else
# error Kernel config parameter RTC_HZ not defined
# error Kernel config parameter HZ not defined
#endif
#endif
/* Compute value to program clock with, given config parameter RTC_HZ */
#if (RTC_HZ == 128)
# define SELECTED_RATE RATE_128_HZ
#else /* !128 Hz */
#if (RTC_HZ == 256)
# define SELECTED_RATE RATE_256_HZ
#else /*!256Hz*/
#if (RTC_HZ == 512)
# define SELECTED_RATE RATE_512_HZ
#else /*!512hz*/
#if (RTC_HZ == 1024)
# define SELECTED_RATE RATE_1024_HZ
#else /* !1024hz*/
# if (RTC_HZ == 64)
# define SELECTED_RATE RATE_64_HZ /* 4.4bsd default on pmax */
# else
# error RTC interrupt rate RTC_HZ not recognised; must be a power of 2
#endif /*!64Hz*/
#endif /*!1024Hz*/
#endif /*!512 Hz*/
#endif /*!256 Hz*/
#endif /*!128Hz*/
/* global autoconfiguration variables -- bus type*/
extern struct cfdriver mainbuscd;
extern struct cfdriver ioasiccd;
extern struct cfdriver tccd;
/* Definition of the driver for autoconfig. */
static int clockmatch __P((struct device *, void *, void *));
static void clockattach __P((struct device *, struct device *, void *));
@ -153,24 +165,17 @@ clockmatch(parent, cfdata, aux)
int vec, ipl;
int nclocks;
if (parent->dv_cfdata->cf_driver != &ioasiccd &&
parent->dv_cfdata->cf_driver != &tccd &&
parent->dv_cfdata->cf_driver != &mainbuscd)
return(0);
/* make sure that we're looking for this type of device. */
if (!BUS_MATCHNAME(ca, "dallas_rtc"))
if (strcmp(ca->ca_name, "mc146818") != 0)
return (0);
/* All known decstations have a Dallas RTC */
#ifdef pmax
nclocks = 1;
#else
/*See how many clocks this system has */
switch (hwrpb->rpb_type) {
case ST_DEC_3000_500:
case ST_DEC_3000_300:
nclocks = 1;
break;
default:
nclocks = 0;
}
#endif
/* if it can't have the one mentioned, reject it */
if (cf->cf_unit >= nclocks)
@ -189,7 +194,7 @@ clockattach(parent, self, aux)
struct confargs *ca = aux;
Mach_clock_addr = (struct chiptime *)
MACH_PHYS_TO_UNCACHED(BUS_CVTADDR(ca));
MACH_PHYS_TO_UNCACHED(ca->ca_addr);
#ifdef pmax
printf("\n");
@ -216,14 +221,15 @@ void
cpu_initclocks()
{
register volatile struct chiptime *c;
extern int tickadj;
extern int tickadj, fixtick;
register long tmp;
if (Mach_clock_addr == NULL)
panic("cpu_initclocks: no clock to initialize");
hz = RTC_HZ; /* Clock Hz is a configuration parameter */
hz = HZ; /* Clock Hz is a configuration parameter */
tick = 1000000 / hz; /* number of microseconds between interrupts */
tickfix = 1000000 - (hz * tick);
fixtick = tickfix = 1000000 - (hz * tick);
if (tickfix) {
int ftp;
@ -236,6 +242,15 @@ cpu_initclocks()
c->rega = REGA_TIME_BASE | SELECTED_RATE;
c->regb = REGB_PER_INT_ENA | REGB_DATA_MODE | REGB_HOURS_FORMAT;
MachEmptyWriteBuffer(); /* Alpha needs this */
/*
* Reset tickadj to ntp's idea of what it should be
* XXX this should be in conf/param.c
*/
tmp = (long) tick * 500L;
tickadj = (int)(tmp / 1000000L);
if (tmp % 1000000L > 0)
tickadj++;
}
/*

View File

@ -204,7 +204,7 @@ noattach(parent, self, aux)
ca->ca_name, self->dv_unit,
parent->dv_xname);
#else
panic("Can't do ew-attach of old device %s\n",
panic("Can't do new-config attach of old device %s\n",
ca->ca_name, self->dv_unit);
#endif
return;

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.c,v 1.1 1995/08/10 05:17:11 jonathan Exp $ */
/* $NetBSD: cpu.c,v 1.2 1996/01/29 22:52:30 jonathan Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@ -84,7 +84,6 @@ cpuattach(parent, dev, aux)
nca.ca_name = "kn01";
nca.ca_slot = 0;
nca.ca_offset = 0;
nca.ca_bus = NULL;
if (!config_found(dev, &nca, cpuprint))
panic("cpuattach: couldn't attach LCA bus interface");
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu_cons.c,v 1.6 1996/01/03 20:39:19 jonathan Exp $ */
/* $NetBSD: cpu_cons.c,v 1.7 1996/01/29 22:52:31 jonathan Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -105,7 +105,7 @@ static void romputc __P ((dev_t, int));
static void rompollc __P((dev_t, int));
int pmax_boardtype; /* Mother board type */
extern int pmax_boardtype; /* Mother board type */
/*
* Major device numbers for possible console devices. XXX

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.41 1996/01/04 22:22:40 jtc Exp $ */
/* $NetBSD: machdep.c,v 1.42 1996/01/29 22:52:32 jonathan Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -402,7 +402,7 @@ mach_init(argc, argv, code, cv)
Mach_splbio = Mach_spl0;
Mach_splnet = Mach_spl1;
Mach_spltty = Mach_spl2;
Mach_splimp = Mach_spl2;
Mach_splimp = splhigh; /*XXX Mach_spl1(), if not for malloc()*/
Mach_splclock = Mach_spl3;
Mach_splstatclock = Mach_spl3;
Mach_clock_addr = (volatile struct chiptime *)
@ -1175,6 +1175,84 @@ dumpsys()
}
}
/*
* Read a high-resolution clock, if one is available, and return
* the current microsecond offset from time-of-day.
*/
#ifndef DS5000_240
# define clkread() (0)
#else
/*
* IOASIC TC cycle counter, latched on every interrupt from RTC chip.
*/
u_long latched_cycle_cnt;
/*
* On a Decstation 5000/240, use the turbochannel bus-cycle counter
* to interpolate micro-seconds since the last RTC clock tick.
* The interpolation base is the copy of the bus cycle-counter taken
* by the RTC interrupt handler.
* XXX on XINE, use the microsecond free-running counter.
*
*/
static inline u_long
clkread()
{
register u_long usec, cycles; /* really 32 bits? */
/* only support 5k/240 TC bus counter */
if (pmax_boardtype != DS_3MAXPLUS) {
return (0);
}
cycles = *(u_long*)ASIC_REG_CTR(asic_base);
/* Compute difference in cycle count from last hardclock() to now */
#if 1
/* my code, using u_ints */
cycles = cycles - latched_cycle_cnt;
#else
/* Mills code, using (signed) ints */
if (cycles >= latched_cycle_cnt)
cycles = cycles - latched_cycle_cnt;
else
cycles = latched_cycle_cnt - cycles;
#endif
/*
* Scale from 40ns to microseconds.
* Avoid a kernel FP divide (by 25) using the approximation
* 1/25 = 40/1000 =~ 41/ 1024, which is good to 0.0975 %
*/
usec = cycles + (cycles << 3) + (cycles << 5);
usec = usec >> 10;
#ifdef CLOCK_DEBUG
if (usec > 3906 +4) {
addlog("clkread: usec %d, counter=%lx\n",
usec, latched_cycle_cnt);
stacktrace();
}
#endif /*CLOCK_DEBUG*/
return usec;
}
#if 0
void
microset()
{
latched_cycle_cnt = *(u_long*)(ASIC_REG_CTR(asic_base));
}
#endif
#endif /*DS5000_240*/
/*
* Return the best possible estimate of the time in the timeval
* to which tvp points. Unfortunately, we can't read the hardware registers.
@ -1191,42 +1269,11 @@ microtime(tvp)
*tvp = time;
#ifdef notdef
tvp->tv_usec += clkread();
while (tvp->tv_usec > 1000000) {
tvp->tv_sec++;
if (tvp->tv_usec >= 1000000) {
tvp->tv_usec -= 1000000;
tvp->tv_sec++;
}
#endif
/*
* if there's a turbochannel cycle counter, use that to
* interpolate micro-seconds since the last RTC clock tick,
* using the software copy of the bus cycle-counter taken by
* the RTC interrupt handler.
*/
#ifdef DS5000_240
if (pmax_boardtype == DS_3MAXPLUS) {
usec = *(u_int*)ASIC_REG_CTR(asic_base);
/* subtract cycle count a last tick */
if (usec >= latched_cycle_cnt)
usec = usec - latched_cycle_cnt;
else
usec = latched_cycle_cnt - usec;
/*
* scale from 40ns to microseconds.
* avoid a kernel FP divide (by 25) using
* an approximation 1/25 = 40/1000 =~ 41/ 1024.
*/
usec = usec + (usec << 3) + (usec << 5);
usec = usec >> 10;
tvp-> tv_usec += usec;
if (tvp->tv_usec >= 1000000) {
tvp->tv_usec -= 1000000;
tvp->tv_sec++;
}
}
#endif
if (tvp->tv_sec == lasttime.tv_sec &&
tvp->tv_usec <= lasttime.tv_usec &&
@ -1388,8 +1435,8 @@ kn02_enable_intr(slotno, handler, sc, on)
int s;
#if 0
printf("3MAX enable_intr: imask %x, %sabling slot %d, unit %d\n",
kn03_tc3_imask, (on? "en" : "dis"), slotno, unit);
printf("3MAX enable_intr: imask %x, %sabling slot %d, sc %p\n",
kn03_tc3_imask, (on? "en" : "dis"), slotno, sc);
#endif
if (slotno > TC_MAX_LOGICAL_SLOTS)

View File

@ -1,4 +1,4 @@
/* $NetBSD: mainbus.c,v 1.4 1995/12/28 06:45:01 jonathan Exp $ */
/* $NetBSD: mainbus.c,v 1.5 1996/01/29 22:52:34 jonathan Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@ -42,7 +42,6 @@
struct mainbus_softc {
struct device sc_dv;
struct abus sc_bus;
};
/* Definition of the mainbus driver. */
@ -56,15 +55,12 @@ void mb_intr_establish __P((struct confargs *ca,
int (*handler)(intr_arg_t),
intr_arg_t val ));
void mb_intr_disestablish __P((struct confargs *));
caddr_t mb_cvtaddr __P((struct confargs *));
int mb_matchname __P((struct confargs *, char *));
/* KN01 has devices directly on the system bus */
void kn01_intr_establish __P((struct confargs *ca,
int (*handler)(intr_arg_t),
intr_arg_t val ));
void kn01_intr_disestablish __P((struct confargs *));
caddr_t kn01_cvtaddr __P((struct confargs *));
static void kn01_attach __P((struct device *, struct device *, void *));
@ -104,13 +100,6 @@ mbattach(parent, self, aux)
printf("\n");
sc->sc_bus.ab_dv = (struct device *)sc;
sc->sc_bus.ab_type = BUS_MAIN;
sc->sc_bus.ab_intr_establish = mb_intr_establish;
sc->sc_bus.ab_intr_disestablish = mb_intr_disestablish;
sc->sc_bus.ab_cvtaddr = mb_cvtaddr;
sc->sc_bus.ab_matchname = mb_matchname;
/*
* Try to find and attach all of the CPUs in the machine.
*/
@ -128,7 +117,7 @@ mbattach(parent, self, aux)
nca.ca_name = "cpu";
nca.ca_slot = 0;
nca.ca_offset = 0;
nca.ca_bus = &sc->sc_bus;
nca.ca_addr = 0;
if (config_found(self, &nca, mbprint))
cpuattachcnt++;
}
@ -149,12 +138,17 @@ mbattach(parent, self, aux)
if (cputype == DS_3MIN || cputype == DS_MAXINE)
printf("UNTESTED autoconfiguration!!\n"); /*XXX*/
#if 0
/* we have a TurboChannel bus! */
nca.ca_name = "tc";
strcpy(nca.ca_name, "tc");
nca.ca_slot = 0;
nca.ca_offset = 0;
nca.ca_bus = &sc->sc_bus;
config_found(self, &nca, mbprint);
#else
config_tcbus(self, &nca, mbprint);
#endif
}
#endif /*Turbochannel*/
@ -166,11 +160,6 @@ mbattach(parent, self, aux)
#if defined(DS3100)
/* XXX mipsfair: just a guess */
if (cputype == DS_PMAX || cputype == DS_MIPSFAIR) {
/*XXX*/
sc->sc_bus.ab_intr_establish = kn01_intr_establish;
sc->sc_bus.ab_intr_disestablish = kn01_intr_disestablish;
sc->sc_bus.ab_cvtaddr = kn01_cvtaddr;
kn01_attach(parent, self, aux);
}
#endif /*DS3100*/
@ -180,12 +169,12 @@ mbattach(parent, self, aux)
#define KN01_MAXDEVS 5
struct confargs kn01_devs[KN01_MAXDEVS] = {
/* name index pri xxx */
{ "pm", 0, 3, (u_int)KV(KN01_PHYS_FBUF_START) },
{ "dc", 1, 2, (u_int)KV(KN01_SYS_DZ) },
{ "lance", 2, 1, (u_int)KV(KN01_SYS_LANCE) },
{ "sii", 3, 0, (u_int)KV(KN01_SYS_SII) },
{ "dallas_rtc", 4, 16, (u_int)KV(KN01_SYS_CLOCK) }
/* name slot offset addr intpri */
{ "pm", 0, 0, (u_int)KV(KN01_PHYS_FBUF_START), 3, },
{ "dc", 1, 0, (u_int)KV(KN01_SYS_DZ), 2, },
{ "lance", 2, 0, (u_int)KV(KN01_SYS_LANCE), 1, },
{ "sii", 3, 0, (u_int)KV(KN01_SYS_SII), 0, },
{ "mc146818", 4, 0, (u_int)KV(KN01_SYS_CLOCK), 16, }
};
/*
@ -209,7 +198,6 @@ kn01_attach(parent, self, aux)
printf("mbattach: bad config for slot %d\n", i);
break;
}
nca->ca_bus = &sc->sc_bus;
#if defined(DIAGNOSTIC) || defined(DEBUG)
if (nca->ca_slot > KN01_MAXDEVS)
@ -225,6 +213,16 @@ dev slot > number of slots for %s",
/* Tell the autoconfig machinery we've found the hardware. */
config_found(self, nca, mbprint);
}
/*
* The Decstation 5100 has an sii, clock, ethernet, and dc,
* like the 3100 and presumably at the same address. The
* 5100 also has a slot for PrestoServe NVRAM and for
* an additional `mbc' dc-like serial option.
* If we supported those devices, we would attempt to configure
* them now.
*/
}
static int
@ -256,23 +254,6 @@ mb_intr_disestablish(ca)
panic("can never mb_intr_disestablish");
}
caddr_t
mb_cvtaddr(ca)
struct confargs *ca;
{
return (NULL);
}
int
mb_matchname(ca, name)
struct confargs *ca;
char *name;
{
return (strcmp(name, ca->ca_name) == 0);
}
void
kn01_intr_establish(ca, handler, val)
struct confargs *ca;
@ -290,9 +271,33 @@ kn01_intr_disestablish(ca)
printf("(kn01: ignoring intr_disestablish) ");
}
caddr_t
kn01_cvtaddr(ca)
/*
* An interrupt-establish method. This should somehow be folded
* back into the autoconfiguration machinery. Until the TC machine
* portmasters agree on how to do that, it's a separate function
*/
void
generic_intr_establish(ca, handler, arg)
struct confargs *ca;
intr_handler_t handler;
intr_arg_t arg;
{
return ((void *)ca->ca_offset);
struct device *dev = arg;
extern struct cfdriver ioasiccd, tccd;
if (dev->dv_parent->dv_cfdata->cf_driver == &ioasiccd) {
/*XXX*/ printf("ioasic interrupt for %d\n", ca->ca_slotpri);
asic_intr_establish(ca, handler, arg);
} else
if (dev->dv_parent->dv_cfdata->cf_driver == &tccd) {
tc_intr_establish(dev->dv_parent, ca->ca_slotpri, 0, handler, arg);
} else
if (dev->dv_parent->dv_cfdata->cf_driver == &mainbuscd) {
kn01_intr_establish(ca, handler, arg);
}
else {
printf("intr_establish: unknown parent bustype for %s\n",
dev->dv_xname);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmax_trap.c,v 1.24 1995/12/28 16:22:41 jonathan Exp $ */
/* $NetBSD: pmax_trap.c,v 1.25 1996/01/29 22:52:35 jonathan Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -876,7 +876,6 @@ interrupt(statusReg, causeReg, pc)
clnlintr();
}
#endif
#include "ppp.h"
#if NPPP > 0
if (netisr & (1 << NETISR_PPP)) {
netisr &= ~(1 << NETISR_PPP);
@ -916,6 +915,7 @@ kn01_intr(mask, pc, statusReg, causeReg)
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[6]++;
/* keep clock interrupts enabled */
causeReg &= ~MACH_INT_MASK_3;
@ -930,6 +930,13 @@ kn01_intr(mask, pc, statusReg, causeReg)
#endif
#if NLE > 0
if (mask & MACH_INT_MASK_1) {
/*
* tty interrupts were disabled by the splx() call
* that re-enables clock interrupts. A slip or ppp driver
* manipulating if queues should have called splimp(),
* which would mask out MACH_INT_MASK_1.
*/
intrcnt[3]++;
leintr(lecd.cd_devs[0]);
}
@ -982,6 +989,7 @@ kn02_intr(mask, pc, statusReg, causeReg)
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[6]++;
/* keep clock interrupts enabled */
causeReg &= ~MACH_INT_MASK_1;
@ -1075,6 +1083,7 @@ kmin_intr(mask, pc, statusReg, causeReg)
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[6]++;
}
if ((intr & KMIN_INTR_SCC_0) &&
@ -1156,10 +1165,12 @@ xine_intr(mask, pc, statusReg, causeReg)
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[6]++;
causeReg &= ~MACH_INT_MASK_1;
/* reenable clock interrupts */
splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);
}
/* reenable clock interrupts */
splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);
if (mask & MACH_INT_MASK_3) {
intr = *intrp;
/* masked interrupts are still observable */
@ -1270,6 +1281,7 @@ kn03_intr(mask, pc, statusReg, causeReg)
struct clockframe cf;
int temp;
static int user_warned = 0;
register u_long old_buscycle = latched_cycle_cnt;
old_mask = *imaskp & kn03_tc3_imask;
*imaskp = kn03_tc3_imask;
@ -1282,13 +1294,33 @@ kn03_intr(mask, pc, statusReg, causeReg)
temp = c->regc; /* XXX clear interrupt bits */
cf.pc = pc;
cf.sr = statusReg;
intrcnt[6]++;
hardclock(&cf);
latched_cycle_cnt = *(u_long*)(ASIC_REG_CTR(asic_base));
hardclock(&cf);
intrcnt[6]++;
old_buscycle = latched_cycle_cnt - old_buscycle;
causeReg &= ~MACH_INT_MASK_1;
/* reenable clock interrupts */
splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);
}
/* reenable clock interrupts */
splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);
/*
* Check for late clock interrupts (allow 10% slop). Be careful
* to do so only after calling hardclock(), due to logging cost.
* Even then, logging dropped ticks just causes more clock
* ticks to be missed.
*/
#ifdef notdef
if ((mask & MACH_INT_MASK_1) && old_buscycle > (tick+49) * 25) {
extern int msgbufmapped;
if(msgbufmapped && 0)
addlog("kn03: clock intr %d usec late\n",
old_buscycle/25);
}
#endif
/*
* IOCTL asic DMA-related interrupts should be checked here,
* and DMA pointers serviced as soon as possible.
*/
if (mask & MACH_INT_MASK_0) {
intr = *intrp;
@ -1302,6 +1334,18 @@ kn03_intr(mask, pc, statusReg, causeReg)
#endif
}
/*
* XXX
* DMA and non-DMA interrupts from the IOCTl asic all use the
* single interrupt request line from the IOCTL asic.
* Disabling IOASIC interrupts while servicing network or
* disk-driver interrupts causes DMA overruns. NON-dma IOASIC
* interrupts should be disabled in the ioasic, and
* interrupts from the IOASIC itself should be re-enabled.
* DMA interrupts can then be serviced whilst still servicing
* non-DMA interrupts from ioctl devices or TC options.
*/
if (intr & (KN03_INTR_SCSI_OVRUN | KN03_INTR_SCSI_READ_E))
*intrp &= ~(KN03_INTR_SCSI_OVRUN | KN03_INTR_SCSI_READ_E);

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.24 1995/12/28 16:22:41 jonathan Exp $ */
/* $NetBSD: trap.c,v 1.25 1996/01/29 22:52:35 jonathan Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@ -876,7 +876,6 @@ interrupt(statusReg, causeReg, pc)
clnlintr();
}
#endif
#include "ppp.h"
#if NPPP > 0
if (netisr & (1 << NETISR_PPP)) {
netisr &= ~(1 << NETISR_PPP);
@ -916,6 +915,7 @@ kn01_intr(mask, pc, statusReg, causeReg)
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[6]++;
/* keep clock interrupts enabled */
causeReg &= ~MACH_INT_MASK_3;
@ -930,6 +930,13 @@ kn01_intr(mask, pc, statusReg, causeReg)
#endif
#if NLE > 0
if (mask & MACH_INT_MASK_1) {
/*
* tty interrupts were disabled by the splx() call
* that re-enables clock interrupts. A slip or ppp driver
* manipulating if queues should have called splimp(),
* which would mask out MACH_INT_MASK_1.
*/
intrcnt[3]++;
leintr(lecd.cd_devs[0]);
}
@ -982,6 +989,7 @@ kn02_intr(mask, pc, statusReg, causeReg)
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[6]++;
/* keep clock interrupts enabled */
causeReg &= ~MACH_INT_MASK_1;
@ -1075,6 +1083,7 @@ kmin_intr(mask, pc, statusReg, causeReg)
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[6]++;
}
if ((intr & KMIN_INTR_SCC_0) &&
@ -1156,10 +1165,12 @@ xine_intr(mask, pc, statusReg, causeReg)
cf.pc = pc;
cf.sr = statusReg;
hardclock(&cf);
intrcnt[6]++;
causeReg &= ~MACH_INT_MASK_1;
/* reenable clock interrupts */
splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);
}
/* reenable clock interrupts */
splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);
if (mask & MACH_INT_MASK_3) {
intr = *intrp;
/* masked interrupts are still observable */
@ -1270,6 +1281,7 @@ kn03_intr(mask, pc, statusReg, causeReg)
struct clockframe cf;
int temp;
static int user_warned = 0;
register u_long old_buscycle = latched_cycle_cnt;
old_mask = *imaskp & kn03_tc3_imask;
*imaskp = kn03_tc3_imask;
@ -1282,13 +1294,33 @@ kn03_intr(mask, pc, statusReg, causeReg)
temp = c->regc; /* XXX clear interrupt bits */
cf.pc = pc;
cf.sr = statusReg;
intrcnt[6]++;
hardclock(&cf);
latched_cycle_cnt = *(u_long*)(ASIC_REG_CTR(asic_base));
hardclock(&cf);
intrcnt[6]++;
old_buscycle = latched_cycle_cnt - old_buscycle;
causeReg &= ~MACH_INT_MASK_1;
/* reenable clock interrupts */
splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);
}
/* reenable clock interrupts */
splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);
/*
* Check for late clock interrupts (allow 10% slop). Be careful
* to do so only after calling hardclock(), due to logging cost.
* Even then, logging dropped ticks just causes more clock
* ticks to be missed.
*/
#ifdef notdef
if ((mask & MACH_INT_MASK_1) && old_buscycle > (tick+49) * 25) {
extern int msgbufmapped;
if(msgbufmapped && 0)
addlog("kn03: clock intr %d usec late\n",
old_buscycle/25);
}
#endif
/*
* IOCTL asic DMA-related interrupts should be checked here,
* and DMA pointers serviced as soon as possible.
*/
if (mask & MACH_INT_MASK_0) {
intr = *intrp;
@ -1302,6 +1334,18 @@ kn03_intr(mask, pc, statusReg, causeReg)
#endif
}
/*
* XXX
* DMA and non-DMA interrupts from the IOCTl asic all use the
* single interrupt request line from the IOCTL asic.
* Disabling IOASIC interrupts while servicing network or
* disk-driver interrupts causes DMA overruns. NON-dma IOASIC
* interrupts should be disabled in the ioasic, and
* interrupts from the IOASIC itself should be re-enabled.
* DMA interrupts can then be serviced whilst still servicing
* non-DMA interrupts from ioctl devices or TC options.
*/
if (intr & (KN03_INTR_SCSI_OVRUN | KN03_INTR_SCSI_READ_E))
*intrp &= ~(KN03_INTR_SCSI_OVRUN | KN03_INTR_SCSI_READ_E);

View File

@ -1,4 +1,4 @@
/* $NetBSD: asic.c,v 1.6 1995/09/25 20:33:28 jonathan Exp $ */
/* $NetBSD: asic.c,v 1.7 1996/01/29 22:52:37 jonathan Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@ -31,6 +31,7 @@
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <dev/tc/tcvar.h>
#include <machine/autoconf.h>
#include <machine/pte.h>
@ -61,7 +62,6 @@ extern int cputype;
struct asic_softc {
struct device sc_dv;
struct abus sc_bus;
caddr_t sc_base;
};
@ -75,8 +75,7 @@ struct cfdriver ioasiccd =
void asic_intr_establish __P((struct confargs *, intr_handler_t,
intr_arg_t));
void asic_intr_disestablish __P((struct confargs *));
caddr_t asic_cvtaddr __P((struct confargs *));
int asic_matchname __P((struct confargs *, char *));
caddr_t ioasic_cvtaddr __P((struct confargs *));
#ifndef pmax
int asic_intr __P((void *));
@ -92,11 +91,11 @@ struct asic_slot {
};
#ifdef pmax
#define ASIC_DEBUG
struct asic_slot *asic_slots;
#include "ds-asic-conf.c"
#endif
#endif /*pmax*/
#ifdef alpha
struct asic_slot asic_slots[ASIC_MAX_NSLOTS] =
@ -115,6 +114,12 @@ struct asic_slot asic_slots[ASIC_MAX_NSLOTS] =
};
#endif /*alpha*/
#ifdef ASIC_DEBUG
#define ASIC_DPRINTF(x) printf x
#else
#define ASIC_DPRINTF(x) (void) x
#endif
caddr_t asic_base; /* XXX XXX XXX */
int
@ -126,18 +131,23 @@ asicmatch(parent, cfdata, aux)
struct cfdata *cf = cfdata;
struct confargs *ca = aux;
/* It can only occur on the turbochannel, anyway. */
if (ca->ca_bus->ab_type != BUS_TC)
ASIC_DPRINTF(("asicmatch: %s slot %d offset 0x%x pri %d\n",
ca->ca_name, ca->ca_slot, ca->ca_offset, ca->ca_slotpri));
/* An IOCTL asic can only occur on the turbochannel, anyway. */
#ifdef notyet
if (parent != &tccd)
return (0);
#endif
/* The 3MAX (kn02) is special. */
if (BUS_MATCHNAME(ca, KN02_ASIC_NAME)) {
if (TC_BUS_MATCHNAME(ca, KN02_ASIC_NAME)) {
printf("(configuring KN02 system slot as asic)\n");
goto gotasic;
}
/* Make sure that we're looking for this type of device. */
if (!BUS_MATCHNAME(ca, "IOCTL "))
if (!TC_BUS_MATCHNAME(ca, "IOCTL "))
return (0);
gotasic:
@ -185,15 +195,11 @@ asicattach(parent, self, aux)
if (asic_slots == NULL)
panic("asicattach: no asic_slot map\n");
sc->sc_base = BUS_CVTADDR(ca);
asic_base = sc->sc_base; /* XXX XXX XXX */
ASIC_DPRINTF(("asicattach: %s\n", sc->sc_dv.dv_xname));
sc->sc_bus.ab_dv = (struct device *)sc;
sc->sc_bus.ab_type = BUS_ASIC;
sc->sc_bus.ab_intr_establish = asic_intr_establish;
sc->sc_bus.ab_intr_disestablish = asic_intr_disestablish;
sc->sc_bus.ab_cvtaddr = asic_cvtaddr;
sc->sc_bus.ab_matchname = asic_matchname;
sc->sc_base = (caddr_t)ca->ca_addr;
asic_base = sc->sc_base; /* XXX XXX XXX */
#ifdef pmax
printf("\n");
@ -220,25 +226,23 @@ asicattach(parent, self, aux)
/* Try to configure each CPU-internal device */
for (i = 0; i < ASIC_MAX_NSLOTS; i++) {
#ifdef DEBUG_ASIC
printf("asicattach: entry %d\n", i); /*XXX*/
#endif
ASIC_DPRINTF(("asicattach: entry %d, base addr %x\n",
i, sc->sc_base));
nca = &asic_slots[i].as_ca;
if (nca == NULL) panic ("bad asic table\n");
if (nca->ca_name == NULL && nca->ca_bus == NULL)
if (nca->ca_name == NULL || nca->ca_name[0] == 0)
break;
nca->ca_bus = &sc->sc_bus;
nca->ca_addr = ((u_int)sc->sc_base) + nca->ca_offset;
#ifdef DEBUG_ASIC
printf(" adding %s subslot %d offset %x\n", /*XXX*/
nca->ca_name, nca->ca_slot, nca->ca_offset);
#endif
ASIC_DPRINTF((" adding %s subslot %d offset %x addr %x\n",
nca->ca_name, nca->ca_slot, nca->ca_offset,
nca->ca_addr));
/* Tell the autoconfig machinery we've found the hardware. */
config_found(self, nca, asicprint);
}
ASIC_DPRINTF(("asicattach: done\n"));
}
int
@ -257,7 +261,7 @@ asicprint(aux, pnp)
/*
* Save interrupt slotname and enable mask (??)
* On decstaitons this isn't useful, as the turbochannel
* On decstations this isn't useful, as the turbochannel
* decstations all have incompatible ways of mapping interrupts
* to IO ASIC or r3000 interrupt bits.
* Instead of writing "as_bits" directly into an IOASIC interrupt-enable
@ -273,12 +277,10 @@ asic_intr_establish(ca, handler, val)
intr_arg_t val;
{
#ifdef DIAGNOSTIC
#ifdef alpha /*XXX*/
#if defined(DIAGNOSTIC) && defined(alpha)
if (ca->ca_slot == ASIC_SLOT_RTC)
panic("setting clock interrupt incorrectly");
#endif /*alpha*/
#endif /*DIAGNOSTIC*/
#endif /*defined(DIAGNOSTIC) && defined(alpha)*/
/* XXX SHOULD NOT BE THIS LITERAL */
if (asic_slots[ca->ca_slot].as_handler != asic_intrnull)
@ -288,14 +290,15 @@ asic_intr_establish(ca, handler, val)
* XXX We need to invent a better interface to machine-dependent
* interrupt-enable code, or redo the Decstation configuration
* tables with unused entries, so that slot is always equal
* to "priority" (software pseudo-slot number).
* to "priority" (software pseudo-slot number). FIXME.
*/
#ifdef pmax
#ifdef DEBUG_ASIC
printf("asic:%s%d: intr for entry %d(%d) slot %d\n",
ca->ca_name, val, ca->ca_slot, ca->ca_slotpri,
#if defined(ASIC_DEBUG) && 0
printf("asic: %s: intr for entry %d slot %d pri %d\n",
ca->ca_name, ca->ca_slot, ca->ca_slotpri,
asic_slots[ca->ca_slot].as_val);
#endif /*DEBUG*/
#endif /*ASIC_DEBUG*/
#ifdef pmax
tc_enable_interrupt(ca->ca_slotpri, handler, val, 1);
#else /* Alpha AXP */
@ -327,25 +330,7 @@ asic_intr_disestablish(ca)
#endif
}
caddr_t
asic_cvtaddr(ca)
struct confargs *ca;
{
return
(((struct asic_softc *)ca->ca_bus->ab_dv)->sc_base + ca->ca_offset);
}
int
asic_matchname(ca, name)
struct confargs *ca;
char *name;
{
return (strcmp(name, ca->ca_name) == 0);
}
#ifndef pmax
#ifdef alpha
/*
* asic_intr --
* ASIC interrupt handler.

View File

@ -1,4 +1,4 @@
/* $NetBSD: ds-asic-conf.c,v 1.4 1996/01/03 20:39:14 jonathan Exp $ */
/* $NetBSD: ds-asic-conf.c,v 1.5 1996/01/29 22:52:38 jonathan Exp $ */
/*
* Copyright (c) 1995 Jonathan Stone
@ -20,20 +20,20 @@ struct asic_slot {
struct asic_slot kn03_asic_slots[] =
{
/* name slot offset intpri */
{ { "lance", 0, (u_int) (3 * 0x40000), KN03_LANCE_SLOT, },
/* name slot offset addr intpri */
{ { "lance", 0, (u_int) (3 * 0x40000), 0,KN03_LANCE_SLOT },
KN03_INTR_LANCE, asic_intrnull, (void*) KN03_LANCE_SLOT, },
{ { "scc", 1, (u_int) (4 * 0x40000), KN03_SCC0_SLOT, },
{ { "scc", 1, (u_int) (4 * 0x40000), 0, KN03_SCC0_SLOT },
KN03_INTR_SCC_0, asic_intrnull, (void *)KN03_SCC0_SLOT, },
{ { "scc", 2, (u_int) (6 * 0x40000), KN03_SCC1_SLOT, },
{ { "scc", 2, (u_int) (6 * 0x40000), 0, KN03_SCC1_SLOT },
KN03_INTR_SCC_1, asic_intrnull, (void *)KN03_SCC1_SLOT, },
{ { "dallas_rtc", 3, (u_int) (8* 0x40000), 0 /*XXX*/, },
{ { "mc146818", 3, (u_int) (8* 0x40000), 0 /*XXX*/, 0 /*XXX*/},
0, asic_intrnull, (void *)(long) 16 /*XXX*/, },
{ { "asc", 4, (u_int) (12* 0x40000), KN03_SCSI_SLOT, },
{ { "asc", 4, (u_int) (12* 0x40000), 0, KN03_SCSI_SLOT, },
0, asic_intrnull, (void *)KN03_SCSI_SLOT, },
{ { NULL, 0, 0, 0 }, 0, NULL, NULL }
@ -42,28 +42,28 @@ struct asic_slot kn03_asic_slots[] =
struct asic_slot xine_asic_slots[] =
{
{ { "lance", 0, (u_int) (3 * 0x40000), KN03_LANCE_SLOT, },
{ { "lance", 0, (u_int) (3 * 0x40000), 0, KN03_LANCE_SLOT },
KN03_INTR_LANCE, asic_intrnull, (void*) KN03_LANCE_SLOT, },
{ { "scc", 1, (u_int) (4 * 0x40000), KN03_SCC0_SLOT, },
{ { "scc", 1, (u_int) (4 * 0x40000), 0, KN03_SCC0_SLOT },
KN03_INTR_SCC_0, asic_intrnull, (void *)KN03_SCC0_SLOT, },
{ { "dallas_rtc", 2, 0, (u_int) (8* 0x40000), },
{ { "mc146818", 2, 0, (u_int) (8* 0x40000), },
0, asic_intrnull, (void *)(long) 16 /*XXX*/, },
{ { "isdn", 3, (u_int) (9 * 0x40000), XINE_ISDN_SLOT, },
{ { "isdn", 3, (u_int) (9 * 0x40000), 0, XINE_ISDN_SLOT },
0, asic_intrnull, (void *)(long) XINE_ISDN_SLOT, },
{ { "dtop", 4, (u_int) (10* 0x40000), XINE_DTOP_SLOT, },
{ { "dtop", 4, (u_int) (10* 0x40000), 0, XINE_DTOP_SLOT },
0, asic_intrnull, (void *)(long) XINE_DTOP_SLOT, },
{ { "fdc", 5, (u_int) (11* 0x40000), XINE_FLOPPY_SLOT, },
{ { "fdc", 5, (u_int) (11* 0x40000), 0, XINE_FLOPPY_SLOT },
0, asic_intrnull, (void *) (long)XINE_FLOPPY_SLOT, },
{ { "asc", 6, (u_int) (12* 0x40000), XINE_SCSI_SLOT, },
{ { "asc", 6, (u_int) (12* 0x40000), 0, XINE_SCSI_SLOT },
0 /*XINE_INTR_SCSI*/, asic_intrnull, (void*)XINE_SCSI_SLOT, },
#if 0
{ { "frc", 3, (u_int) (15* 0x40000), XINE_SLOT_FRC, },
{ { "frc", 3, (u_int) (15* 0x40000), 0, XINE_SLOT_FRC },
0, asic_intrnull, (void *)(long) XINE_SLOT_FRC, },
#endif
{ { NULL, 0, 0, }, 0, NULL, NULL }
@ -80,10 +80,11 @@ struct asic_slot xine_asic_slots[] =
*/
struct asic_slot kn02_asic_slots[] = {
{ { "dc", 0, (u_int) (4 * 0x80000), 7 },
/* name slot offset addr intpri */
{ { "dc", 0, (u_int) (4 * 0x80000), 0, 7 },
KN03_INTR_SCC_0, asic_intrnull, (void *) 7, },
{ { "dallas_rtc", 0, (u_int) (5 * 0x80000), 0, },
{ { "mc146818", 0, (u_int) (5 * 0x80000), 0, 0 },
0, asic_intrnull, (void *) 16 /*XXX*/, },
{ { NULL, 0, 0 }, 0, NULL, NULL }

View File

@ -1,4 +1,4 @@
/* $NetBSD: ds-tc-conf.c,v 1.6 1996/01/11 05:59:23 jonathan Exp $ */
/* $NetBSD: ds-tc-conf.c,v 1.7 1996/01/29 22:52:39 jonathan Exp $ */
/*
* Copyright (c) 1995 Jonathan Stone
@ -17,28 +17,15 @@
*/
#define C(x) ((void *)(u_long)x)
#if 0
#define TC_SCSI "PMAZ-AA "
#define TC_ETHER "PMAD-AA "
#else
#define TC_SCSI NULL
#define TC_ETHER NULL
#endif
struct confargs tc3_devs[4] = {
/* name slot offset intpri */
{ "IOCTL ", 3, 0x0, -1, }, /* IOCTL asic, builtin */
{ NULL, 2, 0x0, 2, }, /* option slot 2 */
{ NULL, 1, 0x0, 1, }, /* option slot 1 */
{ NULL, 0, 0x0, 0, } /* option slot 0 */
};
/*
* The only builtin Turbonchannel device on the kn03 and kmin
* is the IOCTL asic, which is mapped into TC slot 3.
*/
struct tc_builtin tc_kn03_builtins[] = {
const struct tc_builtin tc_kn03_builtins[] = {
{ "IOCTL ", 3, 0x0, C(3), /*C(3)*/ }
};
@ -54,14 +41,12 @@ int tc_kn03_nslots =
/* 3MAXPLUS turbochannel autoconfiguration table */
struct tc_cpu_desc kn03_tc_desc =
struct tc_attach_args kn03_tc_desc =
{
tc_kn03_slots, KN03_TC_NSLOTS,
tc3_devs, KN03_TC_NSLOTS, /*XXX*/
tc_ds_ioasic_intr_setup,
KN03_TC_NSLOTS, tc_kn03_slots,
1, tc_kn03_builtins,
tc_ds_ioasic_intr_establish,
tc_ds_ioasic_intr_disestablish,
(void*)-1
tc_ds_ioasic_intr_disestablish
};
/************************************************************************/
@ -78,67 +63,50 @@ int tc_kmin_nslots =
sizeof(tc_kmin_slots) / sizeof(tc_kmin_slots[0]);
/* 3MIN turbochannel autoconfiguration table */
struct tc_cpu_desc kmin_tc_desc =
struct tc_attach_args kmin_tc_desc =
{
tc_kmin_slots, KMIN_TC_NSLOTS,
tc3_devs, KMIN_TC_NSLOTS, /*XXX*/
tc_ds_ioasic_intr_setup,
KMIN_TC_NSLOTS, tc_kmin_slots,
1, tc_kn03_builtins, /*XXX*/
tc_ds_ioasic_intr_establish,
tc_ds_ioasic_intr_disestablish,
/*kmin_intr*/ (void*) -1
tc_ds_ioasic_intr_disestablish
};
/************************************************************************/
/* MAXINE turbochannel slots */
struct confargs xine_devs[4] = {
/* name slot offset intpri */
{ "PMAG-DV ", 3, 0x0, 3, }, /* xcfb */
{ "IOCTL ", 2, 0x0, -1, },
{ NULL, 1, 0x0, 1, },
{ NULL, 0, 0x0, 0, }
/*
* The builtin Turbonchannel devices on the MAXINE
* is the IOCTL asic, which is mapped into TC slot 3, and the PMAG-DV
* xcfb framebuffer, which is built into the baseboard.
*/
const struct tc_builtin tc_xine_builtins[] = {
{ "IOCTL ", 3, 0x0, C(3), /*C(3)*/ },
{ "PMAG-DV ", 4, 0x0, C(4), /*C(4)*/ }
};
/* MAXINE slot addreseses */
static struct tc_slotdesc tc_xine_slots [4] = {
{ KV(XINE_PHYS_TC_0_START), C(0) }, /* slot 0 - tc option slot 0 */
{ KV(XINE_PHYS_TC_1_START), C(1) }, /* slot 1 - tc option slot 1 */
/* physical space for ``slot 2'' is reserved */
{ KV(XINE_PHYS_TC_3_START), C(8) }, /* slot 2 - IO asic on b'board */
{ KV(XINE_PHYS_CFB_START), C(-1) } /* slot 3 - fb on b'board */
/*{ KV(-1), C(-1) },*/ /* physical space for ``slot 2'' is reserved */
{ KV(XINE_PHYS_TC_3_START), C(2) }, /* slot 2 - IO asic on b'board */
{ KV(XINE_PHYS_CFB_START), C(3) } /* slot 3 - fb on b'board */
};
int tc_xine_nslots =
sizeof(tc_xine_slots) / sizeof(tc_xine_slots[0]);
struct tc_cpu_desc xine_tc_desc =
struct tc_attach_args xine_tc_desc =
{
tc_xine_slots, XINE_TC_NSLOTS,
xine_devs, 4, /*XXX*/
tc_ds_ioasic_intr_setup,
XINE_TC_NSLOTS, tc_xine_slots,
2, tc_xine_builtins,
tc_ds_ioasic_intr_establish,
tc_ds_ioasic_intr_disestablish,
/*xine_intr*/ (void *) -1
tc_ds_ioasic_intr_disestablish
};
/************************************************************************/
/* 3MAX (kn02) turbochannel slots */
struct confargs kn02_devs[8] = {
/* The 3max supposedly has "KN02 " at 0xbffc0410 */
/* name slot offset intpri */
{ KN02_ASIC_NAME, 7, 0x0, -1, }, /* System CSR and subslots */
{ TC_ETHER, 6, 0x0, 6, }, /* slot 6: Ether on cpu board*/
{ TC_SCSI, 5, 0x0, 5, }, /* slot 5: SCSI on cpu board */
/*XXX*/ { NULL, 4, -1, 0, }, /* slot 4 reserved */
/*XXX*/ { NULL, 3, -1, 0, }, /* slot 3 reserved */
{ NULL, 2, 0x0, 2, }, /* slot 2 - TC option slot 2 */
{ NULL, 1, 0x0, 1, }, /* slot 1 - TC option slot 1 */
{ NULL, 0, 0x0, 0, } /* slot 0 - TC option slot 0 */
};
/* slot addreseses */
static struct tc_slotdesc tc_kn02_slots [8] = {
{ KV(KN02_PHYS_TC_0_START), C(0)}, /* slot 0 - tc option slot 0 */
@ -148,8 +116,7 @@ static struct tc_slotdesc tc_kn02_slots [8] = {
{ KV(KN02_PHYS_TC_4_START), C(4), }, /* slot 4 - reserved */
{ KV(KN02_PHYS_TC_5_START), C(5), }, /* slot 5 - SCSI on b`board */
{ KV(KN02_PHYS_TC_6_START), C(6), }, /* slot 6 - b'board Ether */
{ KV(KN02_PHYS_TC_7_START), C(7), } /* slot 7 - system devices */
{ KV(KN02_PHYS_TC_7_START), C(7), } /* slot 7 - system CSR, etc. */
};
int tc_kn02_nslots =
@ -161,19 +128,17 @@ int tc_kn02_nslots =
#define TC_KN02_DEV_ETHER 6
#define TC_KN02_DEV_SCSI 5
struct tc_builtin tc_kn02_builtins[] = {
const struct tc_builtin tc_kn02_builtins[] = {
{ KN02_ROM_NAME,7, 0x0, C(TC_KN02_DEV_IOASIC) /* C(7)*/ },
{ TC_ETHER, 6, 0x0, C(TC_KN02_DEV_ETHER) /* C(6)*/ },
{ TC_SCSI, 5, 0x0, C(TC_KN02_DEV_SCSI) /* C(5)*/ },
{ TC_SCSI, 5, 0x0, C(TC_KN02_DEV_SCSI) /* C(5)*/ }
};
struct tc_cpu_desc kn02_tc_desc =
struct tc_attach_args kn02_tc_desc =
{
tc_kn02_slots, KN02_TC_NSLOTS,
kn02_devs, 8, /*XXX*/
tc_ds_ioasic_intr_setup,
8, tc_kn02_slots,
3, tc_kn02_builtins, /*XXX*/
tc_ds_ioasic_intr_establish,
tc_ds_ioasic_intr_disestablish,
/*kn02_intr*/ (void*) -1
tc_ds_ioasic_intr_disestablish
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_le.c,v 1.7 1995/12/28 08:42:15 jonathan Exp $ */
/* $NetBSD: if_le.c,v 1.8 1996/01/29 22:52:40 jonathan Exp $ */
/*-
* Copyright (c) 1995 Charles M. Hannum. All rights reserved.
@ -149,9 +149,9 @@ lematch(parent, match, aux)
/* XXX CHECK BUS */
/* make sure that we're looking for this type of device. */
if (!BUS_MATCHNAME(ca, "PMAD-BA ") && /* untested alpha TC option */
!BUS_MATCHNAME(ca, "PMAD-AA ") && /* KN02 baseboard, old option */
!BUS_MATCHNAME(ca, "lance")) /* NetBSD name for b'board */
if (!TC_BUS_MATCHNAME(ca, "PMAD-BA ") && /* untested alpha TC option */
!TC_BUS_MATCHNAME(ca, "PMAD-AA ") && /* KN02 b'board, old option */
!TC_BUS_MATCHNAME(ca, "lance")) /* NetBSD name for b'board */
return (0);
#ifdef notdef /* XXX */
@ -184,7 +184,7 @@ leattach(parent, self, aux)
tc_addr_t dma_mask;
sc->sc_r1 = (struct lereg1 *)
MACH_PHYS_TO_UNCACHED(BUS_CVTADDR(ca));
MACH_PHYS_TO_UNCACHED(ca->ca_addr);
#ifdef alpha
sc->sc_r1 = TC_DENSE_TO_SPARSE(sc->sc_r1);
#endif
@ -212,11 +212,26 @@ leattach(parent, self, aux)
ASIC_CSR_DMAEN_LANCE;
wbflush();
}
else
if (parent->dv_cfdata->cf_driver == &tccd) {
/* It's on the turbochannel proper, or on KN02 baseboard. */
sc->sc_r1 = (struct lereg1 *)
(ca->ca_addr + LE_OFFSET_LANCE);
sc->sc_mem = (void *)
(ca->ca_addr + LE_OFFSET_RAM);
cp = (u_char *)(ca->ca_addr + LE_OFFSET_ROM + 2);
sc->sc_copytodesc = copytobuf_contig;
sc->sc_copyfromdesc = copyfrombuf_contig;
sc->sc_copytobuf = copytobuf_contig;
sc->sc_copyfrombuf = copyfrombuf_contig;
sc->sc_zerobuf = zerobuf_contig;
}
#ifdef pmax
else if (parent->dv_cfdata->cf_driver == &mainbuscd) {
/* It's on the baseboard, attached directly to mainbus. */
sc->sc_r1 = (struct lereg1 *)BUS_CVTADDR(ca);
sc->sc_r1 = (struct lereg1 *)(ca->ca_addr);
/*XXX*/ sc->sc_mem = (void *)MACH_PHYS_TO_UNCACHED(0x19000000);
/*XXX*/ cp = (u_char *)(MACH_PHYS_TO_UNCACHED(KN01_SYS_CLOCK) + 1);
@ -227,21 +242,6 @@ leattach(parent, self, aux)
sc->sc_zerobuf = zerobuf_gap2;
}
#endif
else
if (parent->dv_cfdata->cf_driver == &tccd) {
/* It's on the turbochannel proper, or on KN02 baseboard. */
sc->sc_r1 = (struct lereg1 *)
(BUS_CVTADDR(ca) + LE_OFFSET_LANCE);
sc->sc_mem = (void *)
(BUS_CVTADDR(ca) + LE_OFFSET_RAM);
cp = (u_char *)(BUS_CVTADDR(ca) + LE_OFFSET_ROM + 2);
sc->sc_copytodesc = copytobuf_contig;
sc->sc_copyfromdesc = copyfrombuf_contig;
sc->sc_copytobuf = copytobuf_contig;
sc->sc_copyfrombuf = copyfrombuf_contig;
sc->sc_zerobuf = zerobuf_contig;
}
sc->sc_conf3 = 0;
sc->sc_addr = 0;

View File

@ -0,0 +1,9 @@
/*
* Copyright 1995, 1996 Jonathan Stone
* All rights reserved
*/
#ifndef __IOASICVAR_H__
#define __IOASICVAR_H__
extern struct cfdriver ioasiccd; /* FIXME: in header file */
extern caddr_t ioasic_cvtaddr __P((struct confargs *ca));
#endif /*__IOASICVAR_H__*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: scc.c,v 1.5 1995/09/29 21:55:19 jonathan Exp $ */
/* $NetBSD: scc.c,v 1.6 1996/01/29 22:52:42 jonathan Exp $ */
/*
* Copyright (c) 1991,1990,1989,1994,1995 Carnegie Mellon University
@ -65,12 +65,6 @@
* from: @(#)scc.c 8.2 (Berkeley) 11/30/93
*/
/*
* Old, non-rcons Pmax console-redirection won't compile on Alphas.
*/
#ifdef pmax
#define TK_NOTYET
#endif
#include <scc.h>
#if NSCC > 0
@ -106,8 +100,6 @@
#include <dev/ic/z8530reg.h>
#include <pmax/dev/lk201.h>
#include <machine/autoconf.h>
#ifdef pmax
#include <machine/machConst.h>
#include <pmax/pmax/cons.h>
@ -118,15 +110,17 @@
#include <pmax/dev/sccvar.h> /* XXX */
#endif
#ifdef alpha
#include <alpha/tc/sccreg.h>
#include <alpha/tc/sccvar.h>
#include <machine/rpb.h>
#include <alpha/tc/asic.h>
#include <alpha/tc/tc.h>
#include <alpha/tc/ioasicreg.h>
#endif
#include <machine/autoconf.h>
#include <dev/tc/tcvar.h>
#include <dev/tc/ioasicvar.h>
extern void ttrstrt __P((void *));
#ifdef alpha
@ -135,11 +129,12 @@ extern void ttrstrt __P((void *));
#endif
/*
* Support old-style pmax console redirection, with
* macros that also work on Alphas with serial consoles.
* (Should be replaced with rcons?)
* rcons glass-tty console (as used on pmax and sparc) won't compile on Alphas.
*/
#ifdef pmax
#define HAVE_RCONS
#include <machine/ioasic_machdep.h>
#endif
/*
* True iff the console unit is diverted throught this SCC device.
@ -296,12 +291,9 @@ sccmatch(parent, match, aux)
struct confargs *ca = aux;
void *sccaddr;
extern struct cfdriver ioasiccd;
if (parent->dv_cfdata->cf_driver == &ioasiccd) {
/* Make sure that we're looking for this type of device. */
if (!BUS_MATCHNAME(ca, "scc"))
if (!TC_BUS_MATCHNAME(ca, "scc"))
return (0);
}
else {
@ -317,7 +309,7 @@ sccmatch(parent, match, aux)
return (0);
/* Get the address, and check it for validity. */
sccaddr = BUS_CVTADDR(ca);
sccaddr = (caddr_t)ca->ca_addr;
#ifdef alpha
sccaddr = TC_DENSE_TO_SPARSE(sccaddr);
#endif /*alpha*/
@ -334,20 +326,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();
@ -377,19 +369,39 @@ sccattach(parent, self, aux)
unit = sc->sc_dv.dv_unit;
flags = sc->sc_dv.dv_cfdata->cf_flags;
sccaddr = (void*)MACH_PHYS_TO_UNCACHED(BUS_CVTADDR(ca));
/* serial console debugging */
#if defined(DEBUG) && defined(HAVE_RCONS) && 0
if (CONSOLE_ON_UNIT(unit) && (cn_tab->cn_pri == CN_REMOTE))
printf("\nattaching scc%d, currently PROM console\n", unit);
#endif /* defined(DEBUG) && defined(HAVE_RCONS)*/
sccaddr = (void*)MACH_PHYS_TO_UNCACHED(ca->ca_addr);
#ifdef alpha
sccaddr = TC_DENSE_TO_SPARSE(sccaddr);
#endif /*alpha*/
/* Register the interrupt handler. */
BUS_INTR_ESTABLISH(ca, sccintr, (void *)sc);
#ifdef notyet /*FIXME*/
ioasic_intr_establish(parent, ca->ca_cookie, TC_IPL_TTY,
sccintr, (void *)sc);
#endif /*FIXME*/
BUS_INTR_ESTABLISH(ca, sccintr, sc);
/* serial console debugging */
#if defined(DEBUG) && defined(HAVE_RCONS) && 0 /*XXX*/
if (CONSOLE_ON_UNIT(unit) && (cn_tab->cn_pri == CN_REMOTE)) {
DELAY(10000);
printf("(attached interrupt, delaying)\n");
}
#endif /* defined(DEBUG) && defined(HAVE_RCONS)*/
/*
* For a remote console, wait a while for previous output to
* complete.
*/
#ifdef TK_NOTYET
#ifdef HAVE_RCONS
if (CONSOLE_ON_UNIT(unit) && (cn_tab->cn_pri == CN_REMOTE))
DELAY(10000);
#else
@ -418,7 +430,7 @@ sccattach(parent, self, aux)
/*
* Special handling for consoles.
*/
#ifdef TK_NOTYET
#ifdef HAVE_RCONS
if ((cn_tab->cn_getc == LKgetc)) {
/* XXX test below may be too inclusive ? */
if (1 /*CONSOLE_ON_UNIT(unit)*/ ) {
@ -430,7 +442,7 @@ sccattach(parent, self, aux)
#ifdef pmax
/* XXX -- why on pmax, not on Alpha? */
cterm.c_cflag |= CLOCAL;
#endif
#endif /* pmax */
cterm.c_ospeed = cterm.c_ispeed = 4800;
(void) sccparam(&ctty, &cterm);
DELAY(10000);
@ -441,7 +453,7 @@ sccattach(parent, self, aux)
* works ok without it.
*/
KBDReset(ctty.t_dev, sccPutc);
#endif
#endif /* notyet */
DELAY(10000);
splx(s);
} else if (unit == 0) {
@ -450,7 +462,7 @@ sccattach(parent, self, aux)
cterm.c_cflag = CS8 | PARENB | PARODD;
cterm.c_ospeed = cterm.c_ispeed = 4800;
(void) sccparam(&ctty, &cterm);
#ifdef TK_NOTYET
#ifdef HAVE_RCONS
DELAY(10000);
MouseInit(ctty.t_dev, sccPutc, sccGetc);
DELAY(10000);
@ -459,7 +471,7 @@ sccattach(parent, self, aux)
}
}
} else
#endif /* TK_NOTYET */
#endif /* HAVE_RCONS */
if (SCCUNIT(cn_tab->cn_dev) == unit)
{
s = spltty();
@ -478,7 +490,7 @@ sccattach(parent, self, aux)
cterm.c_ospeed = cterm.c_ispeed = 9600;
(void) sccparam(&ctty, &cterm);
DELAY(1000);
#ifdef TK_NOTYET
#ifdef HAVE_RCONS
/*cn_tab.cn_disabled = 0;*/ /* FIXME */
#endif
splx(s);
@ -652,7 +664,7 @@ sccclose(dev, flag, mode, p)
{
register struct scc_softc *sc = scccd.cd_devs[SCCUNIT(dev)];
register struct tty *tp;
register int bit, line;
register int line;
tp = scc_tty[minor(dev)];
line = SCCLINE(dev);
@ -791,7 +803,7 @@ sccparam(tp, t)
/*
* Handle console specially.
*/
#ifdef TK_NOTYET
#ifdef HAVE_RCONS
if (cn_tab->cn_getc == LKgetc) {
if (minor(tp->t_dev) == SCCKBD_PORT) {
cflag = CS8;
@ -801,7 +813,7 @@ sccparam(tp, t)
ospeed = ttspeedtab(4800, sccspeedtab);
}
} else if (tp->t_dev == cn_tab->cn_dev)
#endif /*TK_NOTYET*/
#endif /*HAVE_RCONS*/
{
cflag = CS8;
ospeed = ttspeedtab(9600, sccspeedtab);
@ -1028,7 +1040,7 @@ sccintr(xxxsc)
(*sccDivertXInput)(cc);
continue;
}
#ifdef TK_NOTYET
#ifdef HAVE_RCONS
if ((cc = kbdMapChar(cc)) < 0)
continue;
#endif

View File

@ -1,10 +1,10 @@
/* $NetBSD: tc.c,v 1.7 1996/01/03 20:39:10 jonathan Exp $ */
/* $NetBSD: tc.c,v 1.8 1996/01/29 22:52:44 jonathan Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
* All rights reserved.
*
* Author: Chris G. Demetriou
* Author: Jonathan Stone
*
* Permission to use, copy, modify and distribute this software and
* its documentation is hereby granted, provided that both the copyright
@ -27,15 +27,14 @@
* rights to redistribute these changes.
*/
#define TC_DEBUG /* until decstatn autoconfig works with dev/tc/tc.c*/
#include <sys/param.h>
#include <sys/device.h>
#include <dev/cons.h>
#include <dev/tc/tcvar.h>
#include <machine/autoconf.h>
#ifdef alpha
#include <machine/rpb.h>
#endif
/* Which TC framebuffers have drivers, for configuring a console device. */
#include <cfb.h>
@ -45,52 +44,36 @@
extern int pmax_boardtype;
struct tc_softc {
struct device sc_dv;
int sc_nslots;
struct tc_slotdesc *sc_slots;
void (*sc_intr_establish) __P((struct device *, void *,
tc_intrlevel_t, int (*)(void *), void *));
void (*sc_intr_disestablish) __P((struct device *, void *));
#ifndef goneverysoon
struct abus sc_bus;
struct tc_cpu_desc *sc_desc;
#endif /* goneverysoon */
};
/*
* Old-style model-specific autoconfiguration description.
*/
struct tc_cpu_desc {
struct tc_slotdesc *tcd_slots;
long tcd_nslots;
struct confargs *tcd_devs;
long tcd_ndevs;
void (*tc_intr_setup) __P((void));
void (*tc_intr_establish) __P((struct device *dev, void *cookie,
int level, intr_handler_t handler, void *arg));
void (*tc_intr_disestablish) __P((struct device *, void *));
int (*tc_iointr) __P((u_int mask, u_int pc,
u_int statusReg, u_int causeReg));
struct tcbus_attach_args {
u_int tca_nslots;
struct tc_slotdesc *tca_slots;
u_int tca_nbuiltins;
const struct tc_builtin *tca_builtins;
void (*tca_intr_establish) __P((struct device *dev, void *cookie,
tc_intrlevel_t level,
intr_handler_t handler,
void *arg));
void (*tca_intr_disestablish) __P((struct device *, void *));
};
/* Return the appropriate tc_cpu_desc for a given cputype */
extern struct tc_cpu_desc * cpu_tcdesc __P ((int cputype));
/* Return the appropriate tc_attach_args for a given cputype */
extern struct tc_attach_args * cpu_tcdesc __P ((int cputype));
/* Definition of the driver for autoconfig. */
int tcmatch(struct device *, void *, void *);
void tcattach(struct device *, struct device *, void *);
int tcprint(void *, char *);
struct cfdriver tccd =
{ NULL, "tc", tcmatch, tcattach, DV_DULL, sizeof (struct tc_softc) };
void tc_intr_establish __P((struct device *, void *, tc_intrlevel_t,
void tc_ds_intr_establish __P((struct device *, void *, tc_intrlevel_t,
intr_handler_t handler, intr_arg_t arg));
void tc_intr_disestablish __P((struct device *dev, void *cookie));
caddr_t tc_cvtaddr __P((struct confargs *));
int tc_matchname __P((struct confargs *, char *));
extern int cputype;
extern int tc_findconsole __P((int prom_slot));
@ -99,12 +82,8 @@ extern int tc_findconsole __P((int prom_slot));
int consprobeslot __P((int slot));
/*XXX*/ /* should be in separate source file */
/*
* tc config structures for DECstations.
* Since there will never be new decstations, we just
* bash it in here, for now.
* TurboChannel autoconfiguration declarations and tables for DECstations.
*/
#include <machine/machConst.h>
@ -125,7 +104,9 @@ int consprobeslot __P((int slot));
void tc_ds_ioasic_intr_setup __P((void));
void tc_ds_ioasic_intr_establish __P((struct device *dev, void *cookie,
int level, intr_handler_t handler, void *arg));
tc_intrlevel_t level,
intr_handler_t handler,
void *arg));
void tc_ds_ioasic_intr_disestablish __P((struct device *, void *));
void tc_ds_ioasic_iointr __P((void *, int));
int tc_ds_ioasic_getdev __P((struct confargs *));
@ -157,11 +138,11 @@ extern void xine_enable_intr __P ((u_int slot, tc_handler_t,
/*
* Function to map from a CPU code to a tc_cpu_desc.
* This hould really be in machine-dependent code, where
* Function to map from a CPU code to a tcbus tc_attach_args struct.
* This should really be in machine-dependent code, where
* it could even be a macro.
*/
struct tc_cpu_desc *
struct tc_attach_args *
cpu_tcdesc(cpu)
int cpu;
{
@ -175,9 +156,6 @@ cpu_tcdesc(cpu)
tc_enable_interrupt = kmin_enable_intr;
return &kmin_tc_desc;
} else if (cpu == DS_MAXINE) {
#ifdef DEBUG
printf("MAXINE turbochannel\n");
#endif
tc_enable_interrupt = xine_enable_intr;
return &xine_tc_desc;
} else if (cpu == DS_PMAX) {
@ -189,267 +167,38 @@ cpu_tcdesc(cpu)
printf("tcattach: Mipsfair (5100), no turbochannel\n");
return NULL;
} else {
panic("tcattach: Unrecognized bus type 0x%x\n", cpu);
panic("cpu_tc: Unrecognized bus type 0x%x\n", cpu);
}
}
/*
* Temporary glue:
* present the old-style signatures as used by BUS_INTR_ESTABLISH(),
* but using the new NetBSD machine-independent TC infrastructure.
*/
void
confglue_tc_intr_establish(ca, handler, arg)
struct confargs *ca;
intr_handler_t handler;
intr_arg_t arg;
{
struct tc_softc *sc = tccd.cd_devs[0]; /* XXX */
/* XXX guess at level */
(*sc->sc_desc->tc_intr_establish)
((struct device*)sc, (void*)ca->ca_slotpri, 0, handler, arg);
}
void
confglue_tc_intr_disestablish(ca)
struct confargs *ca;
{
struct tc_softc *sc = tccd.cd_devs[0]; /* XXX */
(*sc->sc_desc->tc_intr_disestablish)(
(struct device*)sc, (void*)ca->ca_slotpri);
}
/*
* End of temporary glue.
*/
int
tcmatch(parent, cfdata, aux)
struct device *parent;
void *cfdata;
void *aux;
{
struct cfdata *cf = cfdata;
struct confargs *ca = aux;
/* Make sure that we're looking for a TC. */
if (strcmp(ca->ca_name, tccd.cd_name) != 0)
return (0);
/* Make sure that unit exists. */
if (cf->cf_unit != 0 ||
#ifdef pmax
0
#else
cputype > ntc_cpu_devs || tc_cpu_devs[cputype] == NULL
#endif
)
return (0);
return (1);
}
/*
* Attach a turbochannel bus. Once the turbochannel is attached,
* search recursively for a system slot (which contains registers
* for baseboard devices in "subslots"), and for "real" on-board or
* option turbochannel slots (that have their own turbochannel ROM
* signature.
* We have a TurboChannel bus. Configure it.
*/
void
tcattach(parent, self, aux)
struct device *parent;
struct device *self;
void *aux;
config_tcbus(parent, cputype, printfn)
struct device *parent;
int cputype;
int printfn __P((void *, char *));
{
struct tc_softc *sc = (struct tc_softc *)self;
struct confargs *nca;
char namebuf[TC_ROM_LLEN+1];
int i;
struct tc_attach_args tc;
printf("\n");
struct tc_attach_args * tcbus = cpu_tcdesc(pmax_boardtype);
/* keep our CPU description handy */
sc->sc_desc = cpu_tcdesc(cputype);
/*
* Set up important CPU/chipset information.
*/
tc.tca_nslots = tcbus->tca_nslots;
tc.tca_slots = tcbus->tca_slots;
#ifndef pmax /*XXX*/
/* set up interrupt handlers */
(*sc->sc_desc->tc_intr_setup)();
set_iointr(sc->sc_desc->tc_iointr);
#endif /*!PMAX*/
tc.tca_nbuiltins = tcbus->tca_nbuiltins;
tc.tca_builtins = tcbus->tca_builtins;
tc.tca_intr_establish = tc_ds_intr_establish; /*XXX*/
tc.tca_intr_disestablish = tc_ds_ioasic_intr_disestablish; /*XXX*/
sc->sc_bus.ab_dv = (struct device *)sc;
sc->sc_bus.ab_type = BUS_TC;
sc->sc_bus.ab_intr_establish = confglue_tc_intr_establish;
sc->sc_bus.ab_intr_disestablish = confglue_tc_intr_disestablish;
sc->sc_bus.ab_cvtaddr = tc_cvtaddr;
sc->sc_bus.ab_matchname = tc_matchname;
if (sc->sc_desc == NULL)
return;
/* Try to configure each turbochannel (or CPU-internal) device */
for (i = 0; i < sc->sc_desc->tcd_ndevs; i++) {
nca = &sc->sc_desc->tcd_devs[i];
if (nca == NULL) {
printf("tcattach: bad config for slot %d\n", i);
break;
}
nca->ca_bus = &sc->sc_bus;
#if defined(DIAGNOSTIC) || defined(DEBUG)
if (nca->ca_slot > sc->sc_desc->tcd_nslots)
panic("tcattach: dev slot > number of slots for %s",
nca->ca_name);
#endif
if (tc_checkdevmem(BUS_CVTADDR(nca)) == 0)
continue;
/* If no name, we have to see what might be there. */
if (nca->ca_name == NULL) {
if (tc_checkslot(BUS_CVTADDR(nca), namebuf) == 0)
continue;
nca->ca_name = namebuf;
}
/* Tell the autoconfig machinery we've found the hardware. */
config_found(self, nca, tcprint);
}
config_found(parent, (struct confargs*)&tc, printfn);
}
int
tcprint(aux, pnp)
void *aux;
char *pnp;
{
struct confargs *ca = aux;
if (pnp)
printf("%s at %s", ca->ca_name, pnp);
printf(" slot %ld offset 0x%lx", ca->ca_slot, ca->ca_offset);
return (UNCONF);
}
caddr_t
tc_cvtaddr(ca)
struct confargs *ca;
{
struct tc_softc *sc = tccd.cd_devs[0];
return ((caddr_t)sc->sc_desc->tcd_slots[ca->ca_slot].tcs_addr +
ca->ca_offset);
}
void
tc_intr_establish(dev, cookie, level, handler, arg)
/*struct confargs *ca;*/
struct device *dev;
void *cookie;
tc_intrlevel_t level;
intr_handler_t handler;
intr_arg_t arg;
{
struct tc_softc *sc = (struct tc_softc *)dev;
#ifdef DEBUG
printf("tc_intr_establish: %s parent intrcode %d\n",
dev->dv_xname, dev->dv_parent->dv_xname, (int) cookie);
#endif
/* XXX pmax interrupt-enable interface */
(*sc->sc_desc->tc_intr_establish)(sc->sc_dv.dv_parent, cookie,
level, handler, arg);
}
void
tc_intr_disestablish(dev, cookie)
struct device *dev;
void *cookie;
{
struct tc_softc *sc = (struct tc_softc *)dev;
(*sc->sc_intr_disestablish)(sc->sc_dv.dv_parent, cookie);
}
int
tc_matchname(ca, name)
struct confargs *ca;
char *name;
{
return (bcmp(name, ca->ca_name, TC_ROM_LLEN) == 0);
}
int
tc_checkdevmem(addr)
caddr_t addr;
{
u_int32_t *datap = (u_int32_t *) addr;
/* Return non-zero if memory was there (i.e. address wasn't bad). */
return (!badaddr(datap, sizeof (u_int32_t)));
}
u_int tc_slot_romoffs[] = { TC_SLOT_ROM, TC_SLOT_PROTOROM };
int ntc_slot_romoffs = sizeof tc_slot_romoffs / sizeof tc_slot_romoffs[0];
int
tc_checkslot(addr, namep)
caddr_t addr;
char *namep;
{
struct tc_rommap *romp;
int i, j;
for (i = 0; i < ntc_slot_romoffs; i++) {
romp = (struct tc_rommap *)
(addr + tc_slot_romoffs[i]);
switch (romp->tcr_width.v) {
case 1:
case 2:
case 4:
break;
default:
continue;
}
if (romp->tcr_stride.v != 4)
continue;
for (j = 0; j < 4; j++)
if (romp->tcr_test[j+0*romp->tcr_stride.v] != 0x55 ||
romp->tcr_test[j+1*romp->tcr_stride.v] != 0x00 ||
romp->tcr_test[j+2*romp->tcr_stride.v] != 0xaa ||
romp->tcr_test[j+3*romp->tcr_stride.v] != 0xff)
continue;
for (j = 0; j < TC_ROM_LLEN; j++)
namep[j] = romp->tcr_modname[j].v;
namep[TC_ROM_LLEN] = '\0';
return (1);
}
return (0);
}
int
tc_intrnull(val)
void *val;
{
panic("uncaught TC intr for slot %ld\n", (long)val);
}
/*
* Probe the turbochannel for a framebuffer option card, starting
* at the preferred slot and then scanning all slots. Configure the first
@ -463,7 +212,7 @@ tc_findconsole(preferred_slot)
{
int slot;
struct tc_cpu_desc * sc_desc;
struct tc_attach_args * sc_desc;
/* First, try the slot configured as console in NVRAM. */
/* if (consprobeslot(preferred_slot)) return (1); */
@ -475,7 +224,7 @@ tc_findconsole(preferred_slot)
*/
if ((sc_desc = cpu_tcdesc(pmax_boardtype)) == NULL)
return 0;
for (slot = 0; slot < sc_desc->tcd_ndevs; slot++) {
for (slot = 0; slot < sc_desc->tca_nslots; slot++) {
if (tc_consprobeslot(slot))
return (1);
@ -495,13 +244,13 @@ tc_consprobeslot(slot)
{
void *slotaddr;
char name[20];
struct tc_cpu_desc * sc_desc;
struct tc_attach_args * sc_desc;
if (slot < 0 || ((sc_desc = cpu_tcdesc(pmax_boardtype)) == NULL))
return 0;
slotaddr = (void *)(sc_desc->tcd_slots[slot].tcs_addr);
slotaddr = (void *)(sc_desc->tca_slots[slot].tcs_addr);
if (tc_checkdevmem(slotaddr) == 0)
if (tc_badaddr(slotaddr))
return (0);
if (tc_checkslot(slotaddr, name) == 0)
@ -541,41 +290,18 @@ tc_consprobeslot(slot)
return (0);
}
/* hack for kn03 ioasic */
void
tc_ds_ioasic_intr_setup ()
{
printf("not setting up TC intrs\n");
}
/*
* Estabish an interrupt handler, but on what bus -- TC or ioctl asic?
*/
void
tc_ds_ioasic_intr_establish(dev, cookie, level, handler, val)
tc_ds_intr_establish(dev, cookie, level, handler, val)
struct device *dev;
void *cookie;
int level;
tc_intrlevel_t level;
intr_handler_t handler;
void *val;
{
#ifdef notanymore
if (BUS_MATCHNAME(ca, "IOCTL ")) {
printf("(no interrupt for asic");
return;
}
/* The kn02 doesn't really have an ASIC */
if (BUS_MATCHNAME(ca, KN02_ASIC_NAME)) {
printf("(no interrupt for proto-asic)\n");
return;
}
#endif
/* Never tested on these processors */
if (cputype == DS_3MIN || cputype == DS_MAXINE)
printf("tc_enable %s sc %x slot %d\n",
@ -586,17 +312,53 @@ tc_ds_ioasic_intr_establish(dev, cookie, level, handler, val)
panic("tc_intr_establish: tc_enable not set\n");
#endif
/* Enable interrupt number "cookie" on this CPU */
#ifdef DEBUG
printf("tc_intr_establish: slot %d level %d handler %p sc %p on\n",
(int) cookie, (int) level, handler, val);
#endif
/*
* Enable the interrupt from tc (or ioctl asic) slot with NetBSD/pmax
* sw-convention name ``cookie'' on this CPU.
* XXX store the level somewhere for selective enabling of
* interrupts from TC option slots.
*/
(*tc_enable_interrupt) ((int)cookie, handler, val, 1);
}
/* hack for kn03 ioasic */
void
tc_ds_ioasic_intr_setup ()
{
printf("not setting up TC intrs\n");
}
/*
* establish an interrupt handler for an ioasic device.
* On NetBSD/pmax, there is currently a single, merged interrupt handler for
* both TC and ioasic. Just use the tc interrupt-establish function.
*/
void
tc_ds_ioasic_intr_establish(dev, cookie, level, handler, val)
struct device *dev;
void *cookie;
tc_intrlevel_t level;
intr_handler_t handler;
void *val;
{
tc_intr_establish(dev, cookie, level, handler, val);
}
void
tc_ds_ioasic_intr_disestablish(dev, arg)
struct device *dev;
void *arg;
{
/*(*tc_enable_interrupt) (ca->ca_slot, handler, 0);*/
printf("cannot dis-establish TC intrs\n");
printf("cannot dis-establish IOASIC interrupts\n");
}
void
@ -606,3 +368,6 @@ tc_ds_ioasic_iointr (framep, vec)
{
printf("bogus interrupt handler fp %x vec %d\n", framep, vec);
}
/* XXX */
#include <dev/tc/tc.c>