New-style config (config.new) autoconfiguration code for Decstation
turhsturbochannel machines. Lifted wholesale from cgd's Alpha turbochannel code, with changes that reflect the slightly different bus topology and `slot' numbering on Decstations.
This commit is contained in:
parent
8e77047f2c
commit
19e02269b2
|
@ -0,0 +1,385 @@
|
|||
/* $NetBSD: asic.c,v 1.1 1995/08/07 07:07:43 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Keith Bostic, Chris G. Demetriou, Jonathan Stone
|
||||
*
|
||||
* 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>
|
||||
|
||||
#if 0
|
||||
#include <machine/rpb.h>
|
||||
#include <alpha/tc/tc.h>
|
||||
#include <alpha/tc/asic.h>
|
||||
#endif
|
||||
|
||||
#ifdef pmax
|
||||
#include <pmax/pmax/pmaxtype.h>
|
||||
#include <pmax/pmax/asic.h>
|
||||
#include <pmax/pmax/kn01.h>
|
||||
#include <pmax/pmax/kn02.h>
|
||||
#include <pmax/pmax/kmin.h>
|
||||
#include <pmax/pmax/maxine.h>
|
||||
#include <pmax/pmax/kn03.h>
|
||||
#include <pmax/pmax/turbochannel.h> /* interrupt enable declaration */
|
||||
|
||||
#include <pmax/pmax/kn03.h>
|
||||
#include <pmax/pmax/kmin.h>
|
||||
#include <machine/machConst.h>
|
||||
#include <pmax/pmax/nameglue.h>
|
||||
|
||||
extern int cputype;
|
||||
#endif
|
||||
|
||||
struct asic_softc {
|
||||
struct device sc_dv;
|
||||
struct abus sc_bus;
|
||||
caddr_t sc_base;
|
||||
};
|
||||
|
||||
/* Definition of the driver for autoconfig. */
|
||||
int asicmatch __P((struct device *, void *, void *));
|
||||
void asicattach __P((struct device *, struct device *, void *));
|
||||
int asicprint(void *, char *);
|
||||
struct cfdriver asiccd =
|
||||
{ NULL, "asic", asicmatch, asicattach, DV_DULL, sizeof(struct asic_softc) };
|
||||
|
||||
void asic_intr_establish __P((struct confargs *, intr_handler_t,
|
||||
handler_arg_t));
|
||||
void asic_intr_disestablish __P((struct confargs *));
|
||||
caddr_t asic_cvtaddr __P((struct confargs *));
|
||||
int asic_matchname __P((struct confargs *, char *));
|
||||
|
||||
#ifndef pmax
|
||||
int asic_intr __P((void *));
|
||||
#endif
|
||||
|
||||
int asic_intrnull __P((handler_arg_t));
|
||||
|
||||
struct asic_slot {
|
||||
struct confargs as_ca;
|
||||
u_int as_bits;
|
||||
intr_handler_t as_handler;
|
||||
void *as_val;
|
||||
};
|
||||
|
||||
#ifdef pmax
|
||||
struct asic_slot *asic_slots;
|
||||
|
||||
#include "ds-asic-conf.c"
|
||||
|
||||
#else /*!pmax*/
|
||||
struct asic_slot asic_slots[ASIC_MAX_NSLOTS] =
|
||||
|
||||
{
|
||||
{ { "lance", /* XXX */ 0, 0x000c0000, },
|
||||
ASIC_INTR_LANCE, asic_intrnull, (void *)(long)ASIC_SLOT_LANCE, },
|
||||
{ { "scc", /* XXX */ 1, 0x00100000, },
|
||||
ASIC_INTR_SCC_0, asic_intrnull, (void *)(long)ASIC_SLOT_SCC0, },
|
||||
{ { "scc", /* XXX */ 2, 0x00180000, },
|
||||
ASIC_INTR_SCC_1, asic_intrnull, (void *)(long)ASIC_SLOT_SCC1, },
|
||||
{ { "dallas_rtc", /* XXX */ 3, 0x00200000, },
|
||||
0, asic_intrnull, (void *)(long)ASIC_SLOT_RTC, },
|
||||
{ { "AMD79c30", /* XXX */ 4, 0x00240000, },
|
||||
0 /* XXX */, asic_intrnull, (void *)(long)ASIC_SLOT_ISDN, },
|
||||
};
|
||||
#endif /*!pmax*/
|
||||
|
||||
caddr_t asic_base; /* XXX XXX XXX */
|
||||
|
||||
int
|
||||
asicmatch(parent, cfdata, aux)
|
||||
struct device *parent;
|
||||
void *cfdata;
|
||||
void *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)
|
||||
return (0);
|
||||
|
||||
/* The 3MAX (kn02) is special. */
|
||||
if (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 "))
|
||||
return (0);
|
||||
gotasic:
|
||||
|
||||
/* See if the unit number is valid. */
|
||||
switch (cputype) {
|
||||
case DS_3MIN:
|
||||
if (cf->cf_unit > 0)
|
||||
return (0);
|
||||
asic_slots = NULL;
|
||||
break;
|
||||
case DS_MAXINE:
|
||||
if (cf->cf_unit > 0)
|
||||
return (0);
|
||||
asic_slots = NULL;
|
||||
break;
|
||||
case DS_3MAX:
|
||||
if (cf->cf_unit > 0)
|
||||
return (0);
|
||||
asic_slots = kn02_asic_slots;
|
||||
break;
|
||||
case DS_3MAXPLUS:
|
||||
if (cf->cf_unit > 0)
|
||||
return (0);
|
||||
asic_slots = kn03_asic_slots;
|
||||
break;
|
||||
default:
|
||||
printf("no ASIC config table for this machine\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
asicattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
struct asic_softc *sc = (struct asic_softc *)self;
|
||||
struct confargs *ca = aux;
|
||||
struct confargs *nca;
|
||||
int i;
|
||||
extern int cputype;
|
||||
|
||||
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 */
|
||||
|
||||
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;
|
||||
|
||||
#ifndef pmax /* Alpha AXP: select ASIC speed */
|
||||
#ifdef DEC_3000_300
|
||||
if (cputype == ST_DEC_3000_300) {
|
||||
*(volatile u_int *)ASIC_REG_CSR(sc->sc_base) |=
|
||||
ASIC_CSR_FASTMODE;
|
||||
MB();
|
||||
printf(": slow mode\n");
|
||||
} else
|
||||
#endif
|
||||
printf(": fast mode\n");
|
||||
|
||||
/* Decstations use hand-craft code to enable asic interrupts */
|
||||
BUS_INTR_ESTABLISH(ca, asic_intr, sc);
|
||||
|
||||
#endif /*!pmax*/
|
||||
|
||||
|
||||
/* The MAXINE has seven pseudo-slots in its system slot */
|
||||
#define ASIC_MAX_NSLOTS 7 /*XXX*/
|
||||
|
||||
/* Try to configure each CPU-internal device */
|
||||
for (i = 0; i < ASIC_MAX_NSLOTS; i++) {
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("asicattach: entry %d\n", i); /*XXX*/
|
||||
#endif
|
||||
|
||||
nca = &asic_slots[i].as_ca;
|
||||
if (nca == NULL) panic ("bad asic table\n");
|
||||
if (nca->ca_name == NULL && nca->ca_bus == NULL)
|
||||
break;
|
||||
nca->ca_bus = &sc->sc_bus;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf(" adding %s subslot %d offset %x\n", /*XXX*/
|
||||
nca->ca_name, nca->ca_slot, nca->ca_offset);
|
||||
#endif
|
||||
|
||||
/* Tell the autoconfig machinery we've found the hardware. */
|
||||
config_found(self, nca, asicprint);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
asicprint(aux, pnp)
|
||||
void *aux;
|
||||
char *pnp;
|
||||
{
|
||||
struct confargs *ca = aux;
|
||||
|
||||
if (pnp)
|
||||
printf("%s at %s", ca->ca_name, pnp);
|
||||
printf(" offset 0x%lx", ca->ca_offset);
|
||||
return (UNCONF);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save interrupt slotname and enable mask (??)
|
||||
* On decstaitons 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
|
||||
* register, Decstations use a machine-dependent function that
|
||||
* interpret (pseudo-) slot numbers and do ``the right thing'' to enable
|
||||
* or disable interrupts for a specific slot (or pseudo-slot), by
|
||||
* slot number, on that given CPU.
|
||||
*/
|
||||
void
|
||||
asic_intr_establish(ca, handler, val)
|
||||
struct confargs *ca;
|
||||
intr_handler_t handler;
|
||||
handler_arg_t val;
|
||||
{
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (ca->ca_slot == ASIC_SLOT_RTC)
|
||||
panic("setting clock interrupt incorrectly");
|
||||
#endif /*DIAGNOSTIC*/
|
||||
|
||||
/* XXX SHOULD NOT BE THIS LITERAL */
|
||||
if (asic_slots[ca->ca_slot].as_handler != asic_intrnull)
|
||||
/*panic*/ printf("asic_intr_establish: slot %d twice", ca->ca_slot);
|
||||
|
||||
/*
|
||||
* 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).
|
||||
*/
|
||||
#ifdef pmax
|
||||
#ifdef DEBUG
|
||||
printf("asic:%s%d: intr for entry %d(%d) slot %d\n",
|
||||
ca->ca_name, val, ca->ca_slot, ca->ca_slotpri,
|
||||
asic_slots[ca->ca_slot].as_val);
|
||||
tc_enable_interrupt(ca->ca_slotpri, handler, (int)val, 1);
|
||||
#endif /*DEBUG*/
|
||||
|
||||
#else /* Alpha AXP */
|
||||
|
||||
/* Save handler info so it can be enabled later (??) */
|
||||
asic_slots[ca->ca_slot].as_handler = handler;
|
||||
asic_slots[ca->ca_slot].as_val = val;
|
||||
#endif /* Alpha AXP */
|
||||
}
|
||||
|
||||
void
|
||||
asic_intr_disestablish(ca)
|
||||
struct confargs *ca;
|
||||
{
|
||||
|
||||
#ifdef pmax
|
||||
panic("asic_intr_disestablish: shouldn't ever be called\n");
|
||||
#else
|
||||
if (ca->ca_slot == ASIC_SLOT_RTC)
|
||||
panic("asic_intr_disestablish: can't do clock interrupt");
|
||||
|
||||
/* XXX SHOULD NOT BE THIS LITERAL */
|
||||
if (asic_slots[ca->ca_slot].as_handler == asic_intrnull)
|
||||
panic("asic_intr_disestablish: slot %d missing intr",
|
||||
ca->ca_slot);
|
||||
|
||||
asic_slots[ca->ca_slot].as_handler = dsasic_intrnull;
|
||||
asic_slots[ca->ca_slot].as_val = (void *)(long)ca->ca_slot;
|
||||
#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
|
||||
/*
|
||||
* asic_intr --
|
||||
* ASIC interrupt handler.
|
||||
*/
|
||||
int
|
||||
asic_intr(val)
|
||||
void *val;
|
||||
{
|
||||
register struct asic_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 *)ASIC_REG_INTR(sc->sc_base);
|
||||
|
||||
gifound = 0;
|
||||
do {
|
||||
ifound = 0;
|
||||
MB();
|
||||
MAGIC_READ;
|
||||
MB();
|
||||
|
||||
sir = *sirp;
|
||||
for (i = 0; i < ASIC_MAX_NSLOTS; i++)
|
||||
if (sir & asic_slots[i].as_bits) {
|
||||
(void)(*asic_slots[i].as_handler)
|
||||
(asic_slots[i].as_val);
|
||||
ifound = 1;
|
||||
}
|
||||
gifound |= ifound;
|
||||
} while (ifound);
|
||||
|
||||
return (gifound);
|
||||
}
|
||||
#endif /*!pmax*/
|
||||
|
||||
int
|
||||
asic_intrnull(val)
|
||||
handler_arg_t val;
|
||||
{
|
||||
|
||||
panic("uncaught IOCTL ASIC intr for slot %ld\n", (long)val);
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/* $NetBSD: ds-asic-conf.c,v 1.1 1995/08/07 07:07:45 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Jonathan Stone
|
||||
* All rights reserved.
|
||||
*
|
||||
* DECstation IO ASIC subslot configuration
|
||||
*/
|
||||
|
||||
#if 0
|
||||
struct asic_slot {
|
||||
struct confargs as_ca;
|
||||
u_int as_bits;
|
||||
intr_handler_t as_handler;
|
||||
void *as_val;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Initial handler must be asic_intrnull or the ASIC newconf code panics */
|
||||
|
||||
struct asic_slot kn03_asic_slots[] =
|
||||
{
|
||||
{ { "lance", 0, KN03_LANCE_SLOT, (u_int) (3 * 0x40000), },
|
||||
KN03_INTR_LANCE, asic_intrnull, (void*) KN03_LANCE_SLOT, },
|
||||
|
||||
{ { "scc", 1, KN03_SCC0_SLOT, (u_int) (4 * 0x40000), },
|
||||
KN03_INTR_SCC_0, asic_intrnull, (void *)KN03_SCC0_SLOT, },
|
||||
|
||||
{ { "scc", 2, KN03_SCC1_SLOT, (u_int) (6 * 0x40000), },
|
||||
KN03_INTR_SCC_1, asic_intrnull, (void*)KN03_SCC1_SLOT, },
|
||||
|
||||
{ { "dallas_rtc", 3, 0 /*XXX*/, (u_int) (8* 0x40000), },
|
||||
0, asic_intrnull, (void *)(long) 16 /*XXX*/, },
|
||||
|
||||
{ { "asc", 4, KN03_SCSI_SLOT, (u_int) (12 * 0x40000), },
|
||||
0, asic_intrnull, (void*)KN03_SCSI_SLOT, },
|
||||
|
||||
{ { NULL, 0, 0, 0 }, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
/* UNTESTED*/
|
||||
struct asic_slot xine_asic_slots[] =
|
||||
{
|
||||
{ { "lance", 0, KN03_LANCE_SLOT, (u_int) (3 * 0x40000), },
|
||||
KN03_INTR_LANCE, asic_intrnull, (void*) KN03_LANCE_SLOT, },
|
||||
|
||||
{ { "scc", 1, KN03_SCC0_SLOT, (u_int) (4 * 0x40000), },
|
||||
KN03_INTR_SCC_0, asic_intrnull, (void *)KN03_SCC0_SLOT, },
|
||||
|
||||
{ { "dallas_rtc", 2, 0, (u_int) (8* 0x40000), },
|
||||
0, asic_intrnull, (void *)(long) 16 /*XXX*/, },
|
||||
|
||||
{ { "isdn", 3, XINE_ISDN_SLOT, (u_int) (9* 0x40000), },
|
||||
0, asic_intrnull, (void *)(long) XINE_ISDN_SLOT, },
|
||||
|
||||
{ { "dtop", 4, XINE_DTOP_SLOT, (u_int) (10* 0x40000), },
|
||||
0, asic_intrnull, (void *)(long) XINE_DTOP_SLOT, },
|
||||
|
||||
{ { "fdc", 5, XINE_FLOPPY_SLOT, (u_int) (11* 0x40000), },
|
||||
0, asic_intrnull, (void *)(long) XINE_FLOPPY_SLOT, },
|
||||
|
||||
{ { "asc", 6, XINE_SCSI_SLOT, (u_int) (12 * 0x40000), },
|
||||
XINE_INTR_SCSI, asic_intrnull, (void*)XINE_SCSI_SLOT, },
|
||||
#if 0
|
||||
{ { "frc", 3, (u_int) XINE_SLOT_FRC, (15* 0x40000), },
|
||||
0, asic_intrnull, (void *)(long) XINE_SLOT_FRC, },
|
||||
#endif
|
||||
{ { NULL, 0, 0, }, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
* The 3MAX (KN02) doesn't even have an asic but for now,
|
||||
* configure its system slot as if it did.
|
||||
* Instead there's a 4 Mbyte "system" slot with eight 512 Kbyte subslots
|
||||
* for system devices:
|
||||
* 0=ROM, 1=(reserved), 2=CHKSYN, 3=ERRADDR, 4=DZ, 5=CLOCK, 6=CSR, 7=ROM1
|
||||
* These are mapped onto slot numbers as
|
||||
* tc0=1, tc1=1, tc2=2, unsed=3, unused=4, scsi=5, ether=6, dc=7
|
||||
*/
|
||||
|
||||
struct asic_slot kn02_asic_slots[] = {
|
||||
{ { "dc", 0, 7, (u_int) (4 * 0x80000), },
|
||||
KN03_INTR_SCC_0, asic_intrnull, (void *) 7, },
|
||||
|
||||
{ { "dallas_rtc", 0, (u_int) (5 * 0x80000), },
|
||||
0, asic_intrnull, (void *) 16 /*XXX*/, },
|
||||
|
||||
{ { NULL, 0, 0 }, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/* $NetBSD: ds-tc-conf.c,v 1.1 1995/08/07 07:07:47 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Jonathan Stone
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 3MIN and 3MAXPLUS turbochannel slots.
|
||||
* The kmin (3MIN) and kn03 (3MAXPLUS) have the same number of slots.
|
||||
* We can share one configuration-struct table and use two slot-address
|
||||
* tables to handle the fact that the turbochannel slot size and base
|
||||
* addresses are different on the two machines.
|
||||
* (thankfully the IOASIC subslots are all the same size.)
|
||||
*/
|
||||
struct confargs tc3_devs[4] = {
|
||||
/* name entry pri xxx */
|
||||
{ "IOCTL ", 3, -1, /*0x040000*/ 0x0, },
|
||||
{ NULL, 2, 2, 0x0, },
|
||||
{ NULL, 1, 1, 0x0, },
|
||||
{ NULL, 0, 0, 0x0, }
|
||||
|
||||
};
|
||||
|
||||
/* 3MAXPLUS slot addreseses */
|
||||
static struct tc_slot_desc kn03_slot_addrs [4] = {
|
||||
{ KV(KN03_PHYS_TC_0_START), }, /* slot 0 - tc option slot 0 */
|
||||
{ KV(KN03_PHYS_TC_1_START), }, /* slot 1 - tc option slot 1 */
|
||||
{ KV(KN03_PHYS_TC_2_START), }, /* slot 2 - tc option slot 2 */
|
||||
{ KV(KN03_PHYS_TC_3_START), } /* slot 3 - IOCTL asic on CPU board */
|
||||
};
|
||||
|
||||
/* 3MAXPLUS turbochannel autoconfiguration table */
|
||||
struct tc_cpu_desc kn03_tc_desc =
|
||||
{
|
||||
kn03_slot_addrs, KN03_TC_NSLOTS,
|
||||
tc3_devs, KN03_TC_NSLOTS, /*XXX*/
|
||||
tc_ds_ioasic_intr_setup,
|
||||
tc_ds_ioasic_intr_establish,
|
||||
tc_ds_ioasic_intr_disestablish,
|
||||
(void*)-1
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/* 3MIN slot addreseses */
|
||||
static struct tc_slot_desc kmin_slot_addrs [4] = {
|
||||
{ KV(KMIN_PHYS_TC_0_START), }, /* slot 0 - tc option slot 0 */
|
||||
{ KV(KMIN_PHYS_TC_1_START), }, /* slot 1 - tc option slot 1 */
|
||||
{ KV(KMIN_PHYS_TC_2_START), }, /* slot 2 - tc option slot 2 */
|
||||
{ KV(KMIN_PHYS_TC_3_START), } /* slot 3 - IOCTL asic on CPU board */
|
||||
};
|
||||
|
||||
/* 3MIN turbochannel autoconfiguratin table */
|
||||
struct tc_cpu_desc kmin_tc_desc =
|
||||
{
|
||||
kmin_slot_addrs, KMIN_TC_NSLOTS,
|
||||
tc3_devs, 7, /*XXX*/
|
||||
tc_ds_ioasic_intr_setup,
|
||||
tc_ds_ioasic_intr_establish,
|
||||
tc_ds_ioasic_intr_disestablish,
|
||||
kmin_intr
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/* MAXINE turbochannel slots */
|
||||
struct confargs xine_devs[3] = {
|
||||
{ "IOCTL ", 2, -1, 0x0, },
|
||||
/*{ "PMAG-DV ", ?, ?, 0x0, },*/ /* xcfb ? */
|
||||
{ NULL, 1, 1, 0x0, },
|
||||
{ NULL, 0, 0, 0x0, }
|
||||
};
|
||||
|
||||
/* MAXINE slot addreseses */
|
||||
static struct tc_slot_desc xine_slot_addrs [4] = {
|
||||
{ KV(XINE_PHYS_TC_0_START), }, /* slot 0 - tc option slot 0 */
|
||||
{ KV(XINE_PHYS_TC_1_START), }, /* slot 1 - tc option slot 1 */
|
||||
{ KV(XINE_PHYS_TC_3_START), } /* slot 2 - IOCTL asic on CPU board */
|
||||
};
|
||||
|
||||
struct tc_cpu_desc xine_tc_desc =
|
||||
{
|
||||
xine_slot_addrs, XINE_TC_NSLOTS,
|
||||
xine_devs, 11, /*XXX*/
|
||||
tc_ds_ioasic_intr_setup,
|
||||
tc_ds_ioasic_intr_establish,
|
||||
tc_ds_ioasic_intr_disestablish,
|
||||
xine_intr
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#if 0
|
||||
#define TC_SCSI "PMAZ-AA "
|
||||
#define TC_ETHER "PMAD-AA "
|
||||
#else
|
||||
#define TC_SCSI NULL
|
||||
#define TC_ETHER NULL
|
||||
#endif
|
||||
|
||||
/* 3MAX (kn02) turbochannel slots */
|
||||
struct confargs kn02_devs[8] = {
|
||||
/* The 3max supposedly has "KN02 " at 0xbffc0410 */
|
||||
|
||||
/* name entry pri xxx */
|
||||
{ KN02_ASIC_NAME, 7, -1, 0x0, }, /* System CSR and subslots */
|
||||
{ TC_ETHER, 6, 6, 0x0, }, /* slot 6: Ether on cpu board*/
|
||||
{ TC_SCSI, 5, 5, 0x0, }, /* slot 5: SCSI on cpu board */
|
||||
/*XXX*/ { NULL, 4, 0, -1, }, /* slot 3 reserved */
|
||||
/*XXX*/ { NULL, 3, 0, -1, }, /* slot 3 reserved */
|
||||
{ NULL, 2, 2, 0x0, }, /* slot 2 - TC option slot 2 */
|
||||
{ NULL, 1, 1, 0x0, }, /* slot 1 - TC option slot 1 */
|
||||
{ NULL, 0, 0, 0x0, } /* slot 0 - TC option slot 0 */
|
||||
};
|
||||
|
||||
/* slot addreseses */
|
||||
static struct tc_slot_desc kn02_slot_addrs [8] = {
|
||||
{ KV(KN02_PHYS_TC_0_START), }, /* slot 0 - tc option slot 0 */
|
||||
{ KV(KN02_PHYS_TC_1_START), }, /* slot 1 - tc option slot 1 */
|
||||
{ KV(KN02_PHYS_TC_2_START), }, /* slot 2 - tc option slot 2 */
|
||||
{ KV(KN02_PHYS_TC_3_START), }, /* slot 3 - reserved */
|
||||
{ KV(KN02_PHYS_TC_4_START), }, /* slot 4 - reserved */
|
||||
{ KV(KN02_PHYS_TC_5_START), }, /* slot 5 - SCSI on cpu board */
|
||||
{ KV(KN02_PHYS_TC_6_START), }, /* slot 6 - Ether on cpu board */
|
||||
{ KV(KN02_PHYS_TC_7_START), } /* slot 7 - system devices */
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct tc_cpu_desc kn02_tc_desc =
|
||||
{
|
||||
kn02_slot_addrs, KN02_TC_NSLOTS,
|
||||
kn02_devs, 8, /*XXX*/
|
||||
tc_ds_ioasic_intr_setup,
|
||||
tc_ds_ioasic_intr_establish,
|
||||
tc_ds_ioasic_intr_disestablish,
|
||||
/*kn02_intr*/ (void*) -1
|
||||
};
|
|
@ -0,0 +1,444 @@
|
|||
/* $NetBSD: tc.c,v 1.1 1995/08/07 07:07:49 jonathan 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 <alpha/tc/tc.h>*/
|
||||
#include <pmax/tc/tc.h>
|
||||
|
||||
struct tc_softc {
|
||||
struct device sc_dv;
|
||||
struct abus sc_bus;
|
||||
struct tc_cpu_desc *sc_desc;
|
||||
};
|
||||
|
||||
/* 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 confargs *, intr_handler_t handler,
|
||||
handler_arg_t));
|
||||
void tc_intr_disestablish __P((struct confargs *));
|
||||
caddr_t tc_cvtaddr __P((struct confargs *));
|
||||
int tc_matchname __P((struct confargs *, char *));
|
||||
|
||||
extern int cputype;
|
||||
|
||||
|
||||
/*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.
|
||||
*/
|
||||
|
||||
#include <machine/machConst.h>
|
||||
#include <pmax/pmax/pmaxtype.h>
|
||||
#include <pmax/pmax/trap.h>
|
||||
#include <pmax/pmax/asic.h>
|
||||
#include <pmax/pmax/kn03.h>
|
||||
#include <pmax/pmax/kn02.h>
|
||||
#include <pmax/pmax/kmin.h>
|
||||
#include <pmax/pmax/maxine.h>
|
||||
#include <pmax/pmax/turbochannel.h>
|
||||
|
||||
#include <pmax/pmax/nameglue.h>
|
||||
|
||||
|
||||
void tc_ds_ioasic_intr_setup __P((void));
|
||||
void tc_ds_ioasic_intr_establish
|
||||
__P((struct confargs *, intr_handler_t, void *));
|
||||
void tc_ds_ioasic_intr_disestablish __P((struct confargs *));
|
||||
void tc_ds_ioasic_iointr __P((void *, int));
|
||||
int tc_ds_ioasic_getdev __P((struct confargs *));
|
||||
|
||||
|
||||
/* XXX*/
|
||||
/* should be handled elsewhere? */
|
||||
typedef void (*tc_enable_t) __P ((u_int slotno, intr_handler_t,
|
||||
int unit, int on));
|
||||
typedef void (*tc_handler_t) __P((int unit));
|
||||
|
||||
extern void (*tc_enable_interrupt) __P ((u_int slotno, tc_handler_t,
|
||||
int unit, int on));
|
||||
extern void kn03_enable_intr __P((u_int slot, tc_handler_t,
|
||||
int unit, int on));
|
||||
extern void kn02_enable_intr __P ((u_int slot, tc_handler_t,
|
||||
int unit, int on));
|
||||
extern void kmin_enable_intr __P ((u_int slot, tc_handler_t,
|
||||
int unit, int on));
|
||||
extern void xine_enable_intr __P ((u_int slot, tc_handler_t,
|
||||
int unit, int on));
|
||||
|
||||
/*
|
||||
* configuration tables for the four models of
|
||||
* Decstation that have turbochannels.
|
||||
* None of the four are the same.
|
||||
*/
|
||||
#include "ds-tc-conf.c"
|
||||
|
||||
|
||||
/*
|
||||
* Mapping from CPU type to a tc_cpu_desc for that CPU type.
|
||||
* (Alpha-specific.)
|
||||
*/
|
||||
struct tc_cpu_desc *tc_cpu_devs[] = {
|
||||
NULL, /* Unused */
|
||||
NULL, /* ST_ADU */
|
||||
NULL, /* ST_DEC_4000 */
|
||||
NULL, /* ST_DEC_7000 */
|
||||
#ifdef DEC_3000_500
|
||||
&dec_3000_500_cpu, /* ST_DEC_3000_500 */
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
NULL, /* Unused */
|
||||
NULL, /* ST_DEC_2000_300 */
|
||||
#ifdef DEC_3000_300
|
||||
&dec_3000_300_cpu, /* ST_DEC_3000_300 */
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
};
|
||||
int ntc_cpu_devs = sizeof tc_cpu_devs / sizeof tc_cpu_devs[0];
|
||||
|
||||
/*
|
||||
* Function to map from a CPU code to a tc_cpu_desc.
|
||||
* This hould really be in machine-dependent code, where
|
||||
* it could even be a macro.
|
||||
*/
|
||||
struct tc_cpu_desc *
|
||||
cpu_tcdesc(cpu)
|
||||
int cpu;
|
||||
{
|
||||
/*XXX*/
|
||||
#ifdef pmax
|
||||
if (cputype == DS_3MAXPLUS) {
|
||||
DPRINTF(("tcattach: 3MAXPLUS turbochannel\n"));
|
||||
tc_enable_interrupt = kn03_enable_intr;
|
||||
return &kn03_tc_desc;
|
||||
} else if (cputype == DS_3MAX) {
|
||||
DPRINTF(("tcattach: 3MAX turbochannel\n"));
|
||||
tc_enable_interrupt = kn02_enable_intr;
|
||||
return &kn02_tc_desc;
|
||||
} else if (cputype == DS_3MIN) {
|
||||
DPRINTF(("tcattach: 3MIN Turbochannel\n"));
|
||||
tc_enable_interrupt = kmin_enable_intr;
|
||||
return &kmin_tc_desc;
|
||||
} else if (cputype == DS_MAXINE) {
|
||||
DPRINTF(("MAXINE turbochannel\n"));
|
||||
tc_enable_interrupt = xine_enable_intr;
|
||||
return &xine_tc_desc;
|
||||
} else if (cputype == DS_PMAX) {
|
||||
DPRINTF(("tcattach: PMAX (no tc, but configured as one)\n"));
|
||||
return NULL;
|
||||
} else {
|
||||
panic("tcattach: Unrecognized bus type 0x%x\n", cputype);
|
||||
}
|
||||
|
||||
#else /* alpha?*/
|
||||
return tc_cpu_devs[cputype];
|
||||
#endif /* alpha?*/
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
void
|
||||
tcattach(parent, self, aux)
|
||||
struct device *parent;
|
||||
struct device *self;
|
||||
void *aux;
|
||||
{
|
||||
struct tc_softc *sc = (struct tc_softc *)self;
|
||||
struct confargs *nca;
|
||||
char namebuf[TC_ROM_LLEN+1];
|
||||
int i;
|
||||
|
||||
printf("\n");
|
||||
|
||||
/* keep our CPU description handy */
|
||||
sc->sc_desc = cpu_tcdesc(cputype);
|
||||
|
||||
#ifndef pmax /*XXX*/
|
||||
/* set up interrupt handlers */
|
||||
(*sc->sc_desc->tc_intr_setup)();
|
||||
set_iointr(sc->sc_desc->tc_iointr);
|
||||
#endif /*!PMAX*/
|
||||
|
||||
sc->sc_bus.ab_dv = (struct device *)sc;
|
||||
sc->sc_bus.ab_type = BUS_TC;
|
||||
sc->sc_bus.ab_intr_establish = tc_intr_establish;
|
||||
sc->sc_bus.ab_intr_disestablish = 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(nca) == 0)
|
||||
continue;
|
||||
|
||||
/* If no name, we have to see what might be there. */
|
||||
if (nca->ca_name == NULL) {
|
||||
if (tc_checkslot(nca, namebuf) == 0)
|
||||
continue;
|
||||
nca->ca_name = namebuf;
|
||||
}
|
||||
/* Tell the autoconfig machinery we've found the hardware. */
|
||||
config_found(self, nca, tcprint);
|
||||
}
|
||||
}
|
||||
|
||||
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 (sc->sc_desc->tcd_slots[ca->ca_slot].tsd_dense + ca->ca_offset);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
tc_intr_establish(ca, handler, val)
|
||||
struct confargs *ca;
|
||||
intr_handler_t handler;
|
||||
handler_arg_t val;
|
||||
{
|
||||
struct tc_softc *sc = tccd.cd_devs[0];
|
||||
|
||||
(*sc->sc_desc->tc_intr_establish)(ca, handler, val);
|
||||
}
|
||||
|
||||
void
|
||||
tc_intr_disestablish(ca)
|
||||
struct confargs *ca;
|
||||
{
|
||||
struct tc_softc *sc = tccd.cd_devs[0];
|
||||
|
||||
(*sc->sc_desc->tc_intr_disestablish)(ca);
|
||||
}
|
||||
|
||||
int
|
||||
tc_matchname(ca, name)
|
||||
struct confargs *ca;
|
||||
char *name;
|
||||
{
|
||||
|
||||
return (bcmp(name, ca->ca_name, TC_ROM_LLEN) == 0);
|
||||
}
|
||||
|
||||
int
|
||||
tc_checkdevmem(ca)
|
||||
struct confargs *ca;
|
||||
{
|
||||
u_int32_t *datap;
|
||||
|
||||
datap = (u_int32_t *)BUS_CVTADDR(ca);
|
||||
|
||||
/* 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(ca, namep)
|
||||
struct confargs *ca;
|
||||
char *namep;
|
||||
{
|
||||
struct tc_rommap *romp;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < ntc_slot_romoffs; i++) {
|
||||
romp = (struct tc_rommap *)
|
||||
(BUS_CVTADDR(ca) + 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);
|
||||
}
|
||||
|
||||
|
||||
/* hack for kn03 */
|
||||
|
||||
void
|
||||
tc_ds_ioasic_intr_setup ()
|
||||
{
|
||||
printf("not setting up TC intrs\n");
|
||||
}
|
||||
|
||||
void
|
||||
tc_ds_ioasic_intr_establish(ca, handler, val)
|
||||
struct confargs *ca;
|
||||
intr_handler_t handler;
|
||||
void *val;
|
||||
{
|
||||
int unit = (int) val;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
printf("tc_enable %s%d slot %d\n",
|
||||
ca->ca_name, (int)unit, ca->ca_slotpri);
|
||||
|
||||
#ifdef 1 /*DIAGNOSTIC*/ /*XXX*/
|
||||
if (tc_enable_interrupt == NULL)
|
||||
panic("tc_intr_establish: tc_enable not set\n");
|
||||
#endif
|
||||
|
||||
(*tc_enable_interrupt) (ca->ca_slotpri, handler, unit, 1);
|
||||
}
|
||||
|
||||
void
|
||||
tc_ds_ioasic_intr_disestablish(args)
|
||||
struct confargs *args;
|
||||
{
|
||||
/*(*tc_enable_interrupt) (ca->ca_slot, handler, 0);*/
|
||||
printf("cannot dis-establish TC intrs\n");
|
||||
}
|
||||
|
||||
void
|
||||
tc_ds_ioasic_iointr (framep, vec)
|
||||
void * framep;
|
||||
int vec;
|
||||
|
||||
|
||||
{
|
||||
printf("bogus interrupt handler\n");
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/* $NetBSD: tc.h,v 1.1 1995/08/07 07:07:50 jonathan 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TurboChannel-specific functions and structures.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A junk address to read from, to make sure writes are complete. See
|
||||
* System Programmer's Manual, section 9.3 (p. 9-4), and sacrifice a
|
||||
* chicken.
|
||||
*/
|
||||
#define MAGIC_READ do { \
|
||||
extern u_int32_t no_optimize; \
|
||||
no_optimize = *(u_int32_t *)phystok0seg(0x00000001f0080220); \
|
||||
} while (0);
|
||||
|
||||
#define TC_SPACE_IND 0xffffffffe0000003
|
||||
#define TC_SPACE_DENSE 0x0000000000000000
|
||||
#define TC_SPACE_DENSE_OFFSET 0x0000000007fffffc
|
||||
#define TC_SPACE_SPARSE 0x0000000010000000
|
||||
#define TC_SPACE_SPARSE_OFFSET 0x000000000ffffff8
|
||||
|
||||
#define TC_DENSE_TO_SPARSE(addr) \
|
||||
((void *) \
|
||||
(((u_int64_t)addr & TC_SPACE_IND) | \
|
||||
TC_SPACE_SPARSE | \
|
||||
(((u_int64_t)addr & TC_SPACE_DENSE_OFFSET) << 1)))
|
||||
|
||||
#define TC_SPARSE_TO_DENSE(addr) \
|
||||
((void *) \
|
||||
(((u_int64_t)addr & TC_SPACE_IND) | \
|
||||
TC_SPACE_DENSE | \
|
||||
(((u_int64_t)addr & TC_SPACE_SPARSE_OFFSET) >> 1)))
|
||||
|
||||
|
||||
#define TC_ROM_LLEN 8
|
||||
#define TC_ROM_SLEN 4
|
||||
#define TC_ROM_TEST_SIZE 16
|
||||
|
||||
#define TC_SLOT_ROM 0x000003e0
|
||||
#define TC_SLOT_PROTOROM 0x003c03e0
|
||||
|
||||
typedef struct tc_padchar {
|
||||
u_int8_t v;
|
||||
u_int8_t pad[3];
|
||||
} tc_padchar_t;
|
||||
|
||||
struct tc_rommap {
|
||||
tc_padchar_t tcr_width;
|
||||
tc_padchar_t tcr_stride;
|
||||
tc_padchar_t tcr_rsize;
|
||||
tc_padchar_t tcr_ssize;
|
||||
u_int8_t tcr_test[TC_ROM_TEST_SIZE];
|
||||
tc_padchar_t tcr_rev[TC_ROM_LLEN];
|
||||
tc_padchar_t tcr_vendname[TC_ROM_LLEN];
|
||||
tc_padchar_t tcr_modname[TC_ROM_LLEN];
|
||||
tc_padchar_t tcr_firmtype[TC_ROM_SLEN];
|
||||
};
|
||||
|
||||
/* The contents of a cfdata->cf_loc for a TurboChannel device */
|
||||
struct tc_cfloc {
|
||||
int cf_slot; /* Slot number */
|
||||
int cf_offset; /* XXX? Offset into slot. */
|
||||
int cf_vec;
|
||||
int cf_ipl;
|
||||
};
|
||||
|
||||
#define TC_SLOT_WILD -1 /* wildcarded slot */
|
||||
#define TC_OFFSET_WILD -1 /* wildcarded offset */
|
||||
#define TC_VEC_WILD -1 /* wildcarded vec */
|
||||
#define TC_IPL_WILD -1 /* wildcarded ipl */
|
||||
|
||||
struct tc_slot_desc {
|
||||
caddr_t tsd_dense;
|
||||
};
|
||||
|
||||
struct tc_cpu_desc {
|
||||
struct tc_slot_desc *tcd_slots;
|
||||
long tcd_nslots;
|
||||
struct confargs *tcd_devs;
|
||||
long tcd_ndevs;
|
||||
void (*tc_intr_setup) __P((void));
|
||||
void (*tc_intr_establish)
|
||||
__P((struct confargs *, intr_handler_t, void *));
|
||||
void (*tc_intr_disestablish) __P((struct confargs *));
|
||||
int (*tc_iointr) __P((u_int mask, u_int pc,
|
||||
u_int statusReg, u_int causeReg));
|
||||
};
|
||||
|
||||
int tc_intrnull __P((void *));
|
Loading…
Reference in New Issue