summaryrefslogtreecommitdiff
path: root/sys/arch/alpha/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/alpha/pci')
-rw-r--r--sys/arch/alpha/pci/apecs.c248
-rw-r--r--sys/arch/alpha/pci/apecs_isa.c421
-rw-r--r--sys/arch/alpha/pci/apecs_pci.c398
-rw-r--r--sys/arch/alpha/pci/apecsreg.h8
-rw-r--r--sys/arch/alpha/pci/apecsvar.h72
-rw-r--r--sys/arch/alpha/pci/cia.c176
-rw-r--r--sys/arch/alpha/pci/cia_isa.c346
-rw-r--r--sys/arch/alpha/pci/cia_pci.c222
-rw-r--r--sys/arch/alpha/pci/ciareg.h51
-rw-r--r--sys/arch/alpha/pci/ciavar.h69
-rw-r--r--sys/arch/alpha/pci/lca.c210
-rw-r--r--sys/arch/alpha/pci/lca_isa.c346
-rw-r--r--sys/arch/alpha/pci/lca_pci.c226
-rw-r--r--sys/arch/alpha/pci/lcareg.h55
-rw-r--r--sys/arch/alpha/pci/lcavar.h68
-rw-r--r--sys/arch/alpha/pci/pci_2100_a50.c134
-rw-r--r--sys/arch/alpha/pci/pci_2100_a50.h32
-rw-r--r--sys/arch/alpha/pci/pci_axppci_33.c204
-rw-r--r--sys/arch/alpha/pci/pci_axppci_33.h32
-rw-r--r--sys/arch/alpha/pci/pci_chipset.h74
-rw-r--r--sys/arch/alpha/pci/pci_kn20aa.c294
-rw-r--r--sys/arch/alpha/pci/pci_kn20aa.h36
-rw-r--r--sys/arch/alpha/pci/pci_machdep.c258
-rw-r--r--sys/arch/alpha/pci/pci_machdep.h53
-rw-r--r--sys/arch/alpha/pci/pcivga.c110
-rw-r--r--sys/arch/alpha/pci/pcivgavar.h29
-rw-r--r--sys/arch/alpha/pci/sio.c116
-rw-r--r--sys/arch/alpha/pci/sio_pic.c117
-rw-r--r--sys/arch/alpha/pci/siovar.h36
-rw-r--r--sys/arch/alpha/pci/tga.c226
-rw-r--r--sys/arch/alpha/pci/tgareg.h7
-rw-r--r--sys/arch/alpha/pci/tgavar.h30
-rw-r--r--sys/arch/alpha/pci/wscons.c9
-rw-r--r--sys/arch/alpha/pci/wsconsvar.h40
34 files changed, 3485 insertions, 1268 deletions
diff --git a/sys/arch/alpha/pci/apecs.c b/sys/arch/alpha/pci/apecs.c
index 7648f2cdd7e..76fd9fec019 100644
--- a/sys/arch/alpha/pci/apecs.c
+++ b/sys/arch/alpha/pci/apecs.c
@@ -1,4 +1,4 @@
-/* $NetBSD: apecs.c,v 1.3 1995/08/03 01:16:47 cgd Exp $ */
+/* $NetBSD: apecs.c,v 1.4 1995/11/23 02:37:11 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -35,37 +35,31 @@
#include <vm/vm.h>
#include <machine/autoconf.h>
-#include <machine/pio.h>
#include <machine/rpb.h>
#include <dev/isa/isareg.h>
#include <dev/isa/isavar.h>
-#include <alpha/isa/isa_dma.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
-#include <alpha/pci/pci_chipset.h>
#include <alpha/pci/apecsreg.h>
+#include <alpha/pci/apecsvar.h>
int apecsmatch __P((struct device *, void *, void *));
void apecsattach __P((struct device *, struct device *, void *));
struct cfdriver apecscd = {
- NULL, "apecs", apecsmatch, apecsattach, DV_DULL, sizeof(struct device)
+ NULL, "apecs", apecsmatch, apecsattach, DV_DULL,
+ sizeof(struct apecs_softc)
};
static int apecsprint __P((void *, char *pnp));
-#ifdef DEC_2100_A50
-extern void pci_2100_a50_pickintr __P((void));
-#endif
-
#define REGVAL(r) (*(int32_t *)phystok0seg(r))
-static int nsgmapent = 1024;
-static vm_offset_t sgmap_pci_base = 0x800000;
-/*static */struct sgmapent *sgmap;
-static char /* * */ sgbitmap[1024 / NBBY];
+/* There can be only one. */
+int apecsfound;
+struct apecs_config apecs_configuration;
int
apecsmatch(parent, match, aux)
@@ -73,9 +67,14 @@ apecsmatch(parent, match, aux)
void *match, *aux;
{
struct cfdata *cf = match;
- struct confargs *pa = aux;
+ struct confargs *ca = aux;
- /* XXX */
+ /* Make sure that we're looking for an APECS. */
+ if (strcmp(ca->ca_name, apecscd.cd_name) != 0)
+ return (0);
+
+ if (apecsfound)
+ return (0);
return (1);
}
@@ -84,18 +83,36 @@ apecsmatch(parent, match, aux)
* Set up the chipset's function pointers.
*/
void
-apecs_init()
+apecs_init(acp)
+ struct apecs_config *acp;
{
- int pass2_epic;
-
- pass2_epic = (REGVAL(EPIC_DCSR) & EPIC_DCSR_PASS2) != 0;
- isadma_fcns = &apecs_isadma_fcns;
- isa_pio_fcns = &apecs_pio_fcns;
- if (!pass2_epic)
- pci_cs_fcns = &apecs_p1e_cs_fcns;
- else
- pci_cs_fcns = &apecs_p2e_cs_fcns;
+ acp->ac_comanche_pass2 =
+ (REGVAL(COMANCHE_ED) & COMANCHE_ED_PASS2) != 0;
+ acp->ac_memwidth =
+ (REGVAL(COMANCHE_GCR) & COMANCHE_GCR_WIDEMEM) != 0 ? 128 : 64;
+ acp->ac_epic_pass2 =
+ (REGVAL(EPIC_DCSR) & EPIC_DCSR_PASS2) != 0;
+
+ /*
+ * Can't set up SGMAP data here; can be called before malloc().
+ */
+
+ acp->ac_conffns = &apecs_conf_fns;
+ acp->ac_confarg = acp;
+ acp->ac_dmafns = &apecs_dma_fns;
+ acp->ac_dmaarg = acp;
+ /* Interrupt routines set up in 'attach' */
+ acp->ac_memfns = &apecs_mem_fns;
+ acp->ac_memarg = acp;
+ acp->ac_piofns = &apecs_pio_fns;
+ acp->ac_pioarg = acp;
+
+ /* Turn off DMA window enables in PCI Base Reg 1. */
+ REGVAL(EPIC_PCI_BASE_1) = 0;
+ wbflush();
+
+ /* XXX SGMAP? */
}
void
@@ -104,46 +121,61 @@ apecsattach(parent, self, aux)
void *aux;
{
struct confargs *ca = aux;
- struct confargs nca;
- int pass2_comanche, widemem, pass2_epic;
+ struct apecs_softc *sc = (struct apecs_softc *)self;
+ struct apecs_config *acp;
+ struct pci_attach_args pa;
- pass2_comanche = (REGVAL(COMANCHE_ED) & COMANCHE_ED_PASS2) != 0;
- widemem = (REGVAL(COMANCHE_GCR) & COMANCHE_GCR_WIDEMEM) != 0;
- pass2_epic = (REGVAL(EPIC_DCSR) & EPIC_DCSR_PASS2) != 0;
+ /* note that we've attached the chipset; can't have 2 APECSes. */
+ apecsfound = 1;
- sgmap = (struct sgmapent *)malloc(1024 * sizeof(struct sgmapent),
- M_DEVBUF, M_WAITOK);
+ /*
+ * set up the chipset's info; done once at console init time
+ * (maybe), but doesn't hurt to do twice.
+ */
+ acp = sc->sc_acp = &apecs_configuration;
+ apecs_init(acp);
+
+ /* XXX SGMAP FOO */
printf(": DECchip %s Core Logic chipset\n",
- widemem ? "21072" : "21071");
+ acp->ac_memwidth == 128 ? "21072" : "21071");
printf("%s: DC21071-CA pass %d, %d-bit memory bus\n",
- self->dv_xname, pass2_comanche ? 2 : 1, widemem ? 128 : 64);
- printf("%s: DC21071-DA pass %d\n", self->dv_xname, pass2_epic ? 2 : 1);
+ self->dv_xname, acp->ac_comanche_pass2 ? 2 : 1, acp->ac_memwidth);
+ printf("%s: DC21071-DA pass %d\n", self->dv_xname,
+ acp->ac_epic_pass2 ? 2 : 1);
/* XXX print bcache size */
- if (!pass2_epic)
+ if (!acp->ac_epic_pass2)
printf("WARNING: 21071-DA NOT PASS2... NO BETS...\n");
- /* set up the chipset's functions */
- apecs_init();
-
switch (hwrpb->rpb_type) {
#if defined(DEC_2100_A50)
case ST_DEC_2100_A50:
- pci_2100_a50_pickintr();
+ pci_2100_a50_pickintr(acp->ac_conffns, acp->ac_confarg,
+ acp->ac_piofns, acp->ac_pioarg,
+ &acp->ac_intrfns, &acp->ac_intrarg);
break;
#endif
default:
panic("apecsattach: shouldn't be here, really...");
}
- /* attach the PCI bus that hangs off of it... */
- nca.ca_name = "pci";
- nca.ca_slot = 0;
- nca.ca_offset = 0;
- nca.ca_bus = NULL;
- if (!config_found(self, &nca, apecsprint))
- panic("apecsattach: couldn't attach PCI bus");
+ pa.pa_bus = 0;
+ pa.pa_maxdev = 32;
+ pa.pa_burstlog2 = 8;
+
+ pa.pa_conffns = acp->ac_conffns;
+ pa.pa_confarg = acp->ac_confarg;
+ pa.pa_dmafns = acp->ac_dmafns;
+ pa.pa_dmaarg = acp->ac_dmaarg;
+ pa.pa_intrfns = acp->ac_intrfns;
+ pa.pa_intrarg = acp->ac_intrarg;
+ pa.pa_memfns = acp->ac_memfns;
+ pa.pa_memarg = acp->ac_memarg;
+ pa.pa_piofns = acp->ac_piofns;
+ pa.pa_pioarg = acp->ac_pioarg;
+
+ config_found(self, &pa, apecsprint);
}
static int
@@ -151,121 +183,11 @@ apecsprint(aux, pnp)
void *aux;
char *pnp;
{
- register struct confargs *ca = aux;
-
- if (pnp)
- printf("%s at %s", ca->ca_name, pnp);
- return (UNCONF);
-}
-
-vm_offset_t /* XXX? */
-apecs_sgmap_alloc(va, npg, nocross, waitok)
- caddr_t va;
- int npg;
- vm_size_t nocross;
- int waitok;
-{
- int s;
- int base, i, stride;
-
-#ifdef DIAGNOSTIC
- /* Quick sanity checks. */
- if ((vm_offset_t)va & PGOFSET)
- panic("apecs_sgmap_alloc: va not page aligned");
- if ((nocross & (nocross - 1)) != 0 || nocross == 0)
- panic("apecs_sgmap_alloc: bogus alignment 0x%lx", nocross);
- if (npg <= 0)
- panic("apecs_sgmap_alloc: not allocating anything");
- if (npg > nsgmapent)
- panic("apecs_sgmap_alloc: insane allocation");
- if (ptoa(npg) > nocross)
- panic("apecs_sgmap_alloc: must cross boundary");
-#endif
-
- stride = atop(nocross);
-#ifdef DIAGNOSTIC
- if (stride > nsgmapent)
- panic("apecs_sgmap_alloc: cheesy implementation loses");
-#endif
-
-top:
- s = splhigh();
- for (base = 0; base < nsgmapent; base += stride) {
- for (i = base; i < base + npg; i++)
- if (isset(sgbitmap, i))
- goto nextstride;
- break;
-nextstride:
- }
- if (base < nsgmapent) /* found a free chunk, claim it */
- for (i = base; i < base + npg; i++)
- setbit(sgbitmap, i);
- splx(s);
-
- if (base >= nsgmapent) { /* didn't find a free chunk */
- if (!waitok)
- return 0;
- tsleep(&sgmap, PRIBIO+1, "sgmap", 0);
- goto top;
- }
-
- for (i = base; i < base + npg; i++) {
-#ifdef DIAGNOSTIC
- if ((sgmap[i].val & SGMAPENT_EVAL) != 0)
- panic("apecs_sgmap_alloc: unallocated entry valid");
-#endif
- sgmap[i].val = SGMAP_MAKEENTRY(atop(vtophys(va)));
- va += PAGE_SIZE;
- }
-
- /* Invalidate old cached entries. */
- REGVAL(EPIC_TBIA) = 1;
-
- /* Return the PCI address. */
- return (ptoa(base) + sgmap_pci_base);
-}
-
-void
-apecs_sgmap_dealloc(pa, npg)
- vm_offset_t pa;
- int npg;
-{
- int i, pfn;
-
-#ifdef DIAGNOSTIC
- /* Quick sanity checks. */
- if (pa & PGOFSET)
- panic("apecs_sgmap_dealloc: pa not page aligned");
- if (npg <= 0)
- panic("apecs_sgmap_dealloc: not deallocating anything");
- if (npg > nsgmapent)
- panic("apecs_sgmap_dealloc: insane deallocation");
-#endif
-
- pfn = atop(pa - sgmap_pci_base);
-#ifdef DIAGNOSTIC
- /* Bounds check the deallocation range. Paranoid about wraparound. */
- if (pfn < 0 || pfn >= nsgmapent || (pfn + npg) >= nsgmapent)
- panic("apecs_sgmap_dealloc: pa out of range (%s)",
- pfn < 0 ? "too low" : "too high");
-#endif
-
- for (i = 0; i < npg; i++) {
-#ifdef DIAGNOSTIC
- /* Make sure it's actually allocated. */
- if (isclr(sgbitmap, i + pfn))
- panic("apecs_sgmap_dealloc: multiple frees: entry %d",
- i + pfn);
-#endif
-
- /* Clear the entries and the allocation map bits. */
- clrbit(sgbitmap, i + pfn);
- sgmap[i + pfn].val &= ~SGMAPENT_EVAL;
- }
-
- /* Invalidate old cached entries. */
- REGVAL(EPIC_TBIA) = 1;
+ register struct pci_attach_args *pa = aux;
- /* Wake up anybody waiting for map entries. */
- wakeup(&sgmap);
+ /* only PCIs can attach to APECSes; easy. */
+ if (pnp)
+ printf("pci at %s", pnp);
+ printf(" bus %d", pa->pa_bus);
+ return (UNCONF);
}
diff --git a/sys/arch/alpha/pci/apecs_isa.c b/sys/arch/alpha/pci/apecs_isa.c
index d4bdb482f08..1d2729475dc 100644
--- a/sys/arch/alpha/pci/apecs_isa.c
+++ b/sys/arch/alpha/pci/apecs_isa.c
@@ -1,4 +1,4 @@
-/* $NetBSD: apecs_isa.c,v 1.3 1995/08/03 01:16:53 cgd Exp $ */
+/* $NetBSD: apecs_isa.c,v 1.4 1995/11/23 02:37:13 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -30,65 +30,88 @@
#include <sys/param.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
+#include <sys/device.h>
#include <vm/vm.h>
-#include <machine/pio.h>
-
-#include <dev/isa/isareg.h>
-#include <dev/isa/isadmavar.h>
-#include <alpha/isa/isa_dma.h>
+#include <dev/isa/isavar.h>
#include <alpha/pci/apecsreg.h>
+#include <alpha/pci/apecsvar.h>
-static u_int8_t apecs_inb __P((int port));
-/* static void apecs_insb __P((int port, void *addr, int cnt)); */
-#define apecs_insb 0 /* XXX */
-static u_int16_t apecs_inw __P((int port));
-/* static void apecs_insw __P((int port, void *addr, int cnt)); */
-#define apecs_insw 0 /* XXX */
-u_int32_t apecs_inl __P((int port));
-/* static void apecs_insl __P((int port, void *addr, int cnt)); */
-#define apecs_insl 0 /* XXX */
+/*
+ * Allocation/deallocation functions.
+ */
+int apecs_pio_alloc __P((void *, isa_iooffset_t, isa_iosize_t));
+int apecs_pio_dealloc __P((void *, isa_iooffset_t, isa_iosize_t));
-static void apecs_outb __P((int port, u_int8_t datum));
-/* static void apecs_outsb __P((int port, void *addr, int cnt)); */
+/*
+ * Byte functions.
+ */
+isa_byte_t apecs_inb __P((void *, isa_iooffset_t));
+#define apecs_insb 0 /* XXX */
+void apecs_outb __P((void *, isa_iooffset_t, isa_byte_t));
#define apecs_outsb 0 /* XXX */
-static void apecs_outw __P((int port, u_int16_t datum));
-/* static void apecs_outsw __P((int port, void *addr, int cnt)); */
+
+/*
+ * Word functions.
+ */
+isa_word_t apecs_inw __P((void *, isa_iooffset_t));
+#define apecs_insw 0 /* XXX */
+void apecs_outw __P((void *, isa_iooffset_t, isa_word_t));
#define apecs_outsw 0 /* XXX */
-static void apecs_outl __P((int port, u_int32_t datum));
-/* static void apecs_outsl __P((int port, void *addr, int cnt)); */
+
+/*
+ * Longword functions.
+ */
+isa_long_t apecs_inl __P((void *, isa_iooffset_t));
+#define apecs_insl 0 /* XXX */
+void apecs_outl __P((void *, isa_iooffset_t, isa_long_t));
#define apecs_outsl 0 /* XXX */
-struct isa_pio_fcns apecs_pio_fcns = {
+__const struct pci_pio_fns apecs_pio_fns = {
+ /* Allocation/deallocation functions. */
+ apecs_pio_alloc, apecs_pio_dealloc,
+
+ /* Byte functions. */
apecs_inb, apecs_insb,
- apecs_inw, apecs_insw,
- apecs_inl, apecs_insl,
apecs_outb, apecs_outsb,
+
+ /* Word functions. */
+ apecs_inw, apecs_insw,
apecs_outw, apecs_outsw,
+
+ /* Longword functions. */
+ apecs_inl, apecs_insl,
apecs_outl, apecs_outsl,
};
-static int apecs_isadma_map __P((caddr_t addr, vm_size_t size,
- vm_offset_t *mappings, int flags));
-static void apecs_isadma_unmap __P((caddr_t addr, vm_size_t size,
- int nmappings, vm_offset_t *mappings));
-static void apecs_isadma_copytobuf __P((caddr_t addr, vm_size_t size,
- int nmappings, vm_offset_t *mappings));
-static void apecs_isadma_copyfrombuf __P((caddr_t addr, vm_size_t size,
- int nmappings, vm_offset_t *mappings));
-
-struct isadma_fcns apecs_isadma_fcns = {
- apecs_isadma_map, apecs_isadma_unmap,
- apecs_isadma_copytobuf, apecs_isadma_copyfrombuf,
-};
+int
+apecs_pio_alloc(ipfarg, start, size)
+ void *ipfarg;
+ isa_iooffset_t start;
+ isa_iosize_t size;
+{
-u_int8_t
-apecs_inb(ioaddr)
- int ioaddr;
+ /* XXX should do something */
+}
+
+int
+apecs_pio_dealloc(ipfarg, start, size)
+ void *ipfarg;
+ isa_iooffset_t start;
+ isa_iosize_t size;
+{
+
+ /* XXX should do something */
+}
+
+isa_byte_t
+apecs_inb(ipfa, ioaddr)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
{
u_int32_t *port, val;
- u_int8_t rval;
+ isa_byte_t rval;
int offset;
wbflush();
@@ -101,81 +124,86 @@ apecs_inb(ioaddr)
return rval;
}
-u_int16_t
-apecs_inw(ioaddr)
- int ioaddr;
+void
+apecs_outb(ipfa, ioaddr, val)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+ isa_byte_t val;
{
- u_int32_t *port, val;
- u_int16_t rval;
+ u_int32_t *port, nval;
int offset;
- wbflush();
offset = ioaddr & 3;
- port = (int32_t *)phystok0seg(APECS_PCI_SIO | 1 << 3 | ioaddr << 5);
- val = *port;
- rval = ((val) >> (8 * offset)) & 0xffff;
- rval = val & 0xffff;
-
-panic("inw(0x%x) => 0x%x @ %p => 0x%x\n", ioaddr, val, port, rval);
+ nval = val /*<< (8 * offset)*/;
+ nval = val << (8 * offset);
+ port = (int32_t *)phystok0seg(APECS_PCI_SIO | 0 << 3 | ioaddr << 5);
- return rval;
+ *port = nval;
+ wbflush();
}
-u_int32_t
-apecs_inl(ioaddr)
- int ioaddr;
+isa_word_t
+apecs_inw(ipfa, ioaddr)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
{
u_int32_t *port, val;
- u_int32_t rval;
+ isa_word_t rval;
int offset;
wbflush();
offset = ioaddr & 3;
- port = (int32_t *)phystok0seg(APECS_PCI_SIO | 3 << 3 | ioaddr << 5);
+ port = (int32_t *)phystok0seg(APECS_PCI_SIO | 1 << 3 | ioaddr << 5);
val = *port;
- rval = ((val) >> (8 * offset)) & 0xffffffff;
- rval = val & 0xffffffff;
+ rval = ((val) >> (8 * offset)) & 0xffff;
+ rval = val & 0xffff;
+
+panic("inw(0x%x) => 0x%x @ %p => 0x%x\n", ioaddr, val, port, rval);
return rval;
}
void
-apecs_outb(ioaddr, val)
- int ioaddr;
- u_int8_t val;
+apecs_outw(ipfa, ioaddr, val)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+ isa_word_t val;
{
u_int32_t *port, nval;
int offset;
offset = ioaddr & 3;
nval = val /*<< (8 * offset)*/;
- nval = val << (8 * offset);
- port = (int32_t *)phystok0seg(APECS_PCI_SIO | 0 << 3 | ioaddr << 5);
+ port = (int32_t *)phystok0seg(APECS_PCI_SIO | 1 << 3 | ioaddr << 5);
*port = nval;
wbflush();
}
-void
-apecs_outw(ioaddr, val)
- int ioaddr;
- u_int16_t val;
+isa_long_t
+apecs_inl(ipfa, ioaddr)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
{
- u_int32_t *port, nval;
+ u_int32_t *port, val;
+ isa_long_t rval;
int offset;
+ wbflush();
offset = ioaddr & 3;
- nval = val /*<< (8 * offset)*/;
- port = (int32_t *)phystok0seg(APECS_PCI_SIO | 1 << 3 | ioaddr << 5);
+ port = (int32_t *)phystok0seg(APECS_PCI_SIO | 3 << 3 | ioaddr << 5);
+ val = *port;
+ rval = ((val) >> (8 * offset)) & 0xffffffff;
+ rval = val & 0xffffffff;
- *port = nval;
- wbflush();
+ return rval;
}
void
-apecs_outl(ioaddr, val)
- int ioaddr;
- u_int32_t val;
+apecs_outl(ipfa, ioaddr, val)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+ isa_long_t val;
{
u_int32_t *port, nval;
int offset;
@@ -188,156 +216,131 @@ apecs_outl(ioaddr, val)
wbflush();
}
-static caddr_t bounced_addr;
-static caddr_t bounce_buffer;
-static vm_size_t bounce_size;
+/* XXX XXX XXX */
+
+#define pf(fn, args) fn args { panic(__STRING(fn)); }
+
+void pf(apecs_dma_cascade, (void *idfa, isa_drq_t chan))
+void pf(apecs_dma_copytobuf, ())
+void pf(apecs_dma_copyfrombuf, ())
+void pf(apecs_dma_start, (void *idfa, vm_offset_t addr,
+ isa_msize_t size, isa_drq_t chan, int flags))
+void pf(apecs_dma_abort, (void *idfa, isa_drq_t chan))
+void pf(apecs_dma_done, (void *idfa, isa_drq_t chan))
+
+int apecs_dma_map __P((void *, vm_offset_t, isa_msize_t,
+ isa_moffset_t *, int));
+void apecs_dma_unmap __P((void *, vm_offset_t, isa_msize_t, int,
+ isa_moffset_t *));
+
+__const struct isa_dma_fns apecs_dma_fns = {
+ apecs_dma_cascade,
+ apecs_dma_map,
+ apecs_dma_unmap,
+ apecs_dma_copytobuf,
+ apecs_dma_copyfrombuf,
+ apecs_dma_start,
+ apecs_dma_abort,
+ apecs_dma_done,
+};
int
-apecs_isadma_map(addr, size, mappings, flags)
- caddr_t addr;
- vm_size_t size;
- vm_offset_t *mappings;
+apecs_dma_map(idfa, va, isasize, mappingsp, flags)
+ void *idfa;
+ vm_offset_t va;
+ isa_msize_t isasize;
+ isa_moffset_t *mappingsp;
int flags;
{
- vm_offset_t off, truncaddr;
- vm_offset_t isa_truncpa; /* XXX? */
- vm_size_t alignment;
- int i, npages, waitok;
-
- /*
- * ISADMA_MAP_{,NO}BOUNCE and ISADMA_MAP_{CONTIG,SCATTER} are
- * completely ignored, because all allocations will be in the
- * low 16M and will be contiguous. I LOVE VIRTUAL DMA!
- */
-
- truncaddr = trunc_page(addr);
- off = (vm_offset_t)addr - truncaddr;
- npages = num_pages(size + off);
- if (npages == 0)
- panic("apecs_isadma_map: map nothing");
-
- alignment = 64 * 1024;
- if ((flags & ISADMA_MAP_16BIT) != 0)
- alignment <<= 1;
- waitok = (flags & ISADMA_MAP_WAITOK) != 0;
-
- if (npages > atop(alignment)) {
- int s;
- void *tmpbb;
-
- /*
- * Allocate a bounce buffer.
- */
- s = splhigh();
-retry:
- while (bounce_buffer != NULL) {
- /*
- * If a bounce buffer is in use and we can't
- * wait, bug out now, otherwise sleep.
- */
- if (!waitok) {
- splx(s);
- return 0;
- }
-
- tsleep(&bounce_buffer, PRIBIO+1, "apecsbb", 0);
- }
-
- /*
- * Try to allocate a bounce buffer.
- */
- tmpbb = malloc(alignment, M_DEVBUF,
- waitok ? M_WAITOK : M_NOWAIT);
- if (tmpbb == NULL) { /* couldn't wait, and failed */
- splx(s);
- return 0;
- }
-
- /*
- * If we slept in malloc() and somebody else got it,
- * give it up and try it again!
- */
- if (bounce_buffer != NULL) {
- free(tmpbb, M_DEVBUF);
- goto retry;
- }
-
- /*
- * It's ours, all ours!
- */
- bounce_buffer = tmpbb;
- splx(s);
-
- bounced_addr = addr;
- bounce_size = size;
- truncaddr = (vm_offset_t)bounce_buffer;
- npages = atop(alignment);
+ struct apecs_config *acp = idfa;
+ long todo;
+ int i;
+
+ if (ISA_DMA_NEEDCONTIG(flags) && isasize > NBPG ||
+ ISA_DMA_SIZEBOUND(flags) != ISA_DMA_SIZEBOUND_NONE ||
+ ISA_DMA_ADDRBOUND(flags) != ISA_DMA_ADDRBOUND_NONE)
+ panic("apecs_dma_map: punt");
+
+ i = 0;
+ todo = isasize;
+
+ while (todo > 0) {
+ mappingsp[i] = vtophys(va) | 0x40000000;
+#if 0
+ printf("a_pd_m mapping %d: %lx -> %lx -> %lx\n", i, va,
+ vtophys(va), mappingsp[i]);
+#endif
+ i++;
+ todo -= PAGE_SIZE - (va - trunc_page(va));
+ va += PAGE_SIZE - (va - trunc_page(va));
}
-
- isa_truncpa = apecs_sgmap_alloc(truncaddr, npages, alignment, waitok);
-
- mappings[0] = isa_truncpa + off;
- for (i = 1; i < npages; i++)
- mappings[i] = isa_truncpa + ptoa(i);
-
- return (npages);
+ return (i);
}
void
-apecs_isadma_unmap(addr, size, nmappings, mappings)
- caddr_t addr;
- vm_size_t size;
+apecs_dma_unmap(idfa, va, isasize, nmappings, mappingsp)
+ void *idfa;
+ vm_offset_t va;
+ isa_msize_t isasize;
int nmappings;
- vm_offset_t *mappings;
+ isa_moffset_t *mappingsp;
{
- int npages;
-
- npages = nmappings;
- if (npages == 0)
- panic("apecs_isadma_unmap: unmap nothing");
- apecs_sgmap_dealloc(trunc_page(mappings[0]), npages);
-
- if (addr == bounced_addr) {
- /*
- * Free the bounce buffer and wake up anybody who
- * wants to bounce.
- */
- bounced_addr = NULL;
- bounce_size = 0;
- free(bounce_buffer, M_DEVBUF);
- bounce_buffer = NULL;
- wakeup(&bounce_buffer);
- }
+
+ printf("apecs_dma_unmap: called\n");
}
-void
-apecs_isadma_copytobuf(addr, size, nmappings, mappings)
- caddr_t addr;
- vm_size_t size;
- int nmappings;
- vm_offset_t *mappings;
+vm_offset_t apecs_mem_map __P((void *, isa_moffset_t, isa_msize_t, int));
+void apecs_mem_unmap __P((void *, vm_offset_t, isa_msize_t));
+
+#if 0
+void apecs_mem_copytoisa __P((void *, char *, vm_offset_t,
+ isa_moffset_t, isa_msize_t));
+void apecs_mem_copyfromisa __P((void *, char *, vm_offset_t,
+ isa_moffset_t, isa_msize_t));
+void apecs_mem_zero __P((void *, vm_offset_t, isa_moffset_t,
+ isa_msize_t));
+#else
+void pf(apecs_mem_copytoisa, ())
+void pf(apecs_mem_copyfromisa, ())
+void pf(apecs_mem_zero, ())
+#endif
+
+__const struct isa_mem_fns apecs_mem_fns = {
+ apecs_mem_map,
+ apecs_mem_unmap,
+ apecs_mem_copytoisa,
+ apecs_mem_copyfromisa,
+ apecs_mem_zero,
+};
+
+vm_offset_t
+apecs_mem_map(imfa, isapa, isasize, cacheable)
+ void *imfa;
+ isa_moffset_t isapa;
+ isa_msize_t isasize;
+ int cacheable;
{
+ vm_offset_t sbpa;
- if (addr != bounced_addr)
- return;
+ /* XXX sanity checks on sizes, use of windows, etc. */
- log(LOG_NOTICE, "apecs_isa_copytobuf: copied %d byte buffer\n",
- bounce_size);
- bcopy(addr, bounce_buffer, bounce_size);
+ /* XXX MAGIC NUMBERS */
+ if (cacheable)
+ sbpa = (isapa & 0xffffffff) | APECS_PCI_DENSE;
+ else
+ sbpa = ((isapa & 0x7ffffff) << 5) | APECS_PCI_SPARSE;
+
+ return phystok0seg(sbpa);
}
void
-apecs_isadma_copyfrombuf(addr, size, nmappings, mappings)
- caddr_t addr;
- vm_size_t size;
- int nmappings;
- vm_offset_t *mappings;
+apecs_mem_unmap(imfa, va, isasize)
+ void *imfa;
+ vm_offset_t va;
+ isa_msize_t isasize;
{
- if (addr != bounced_addr)
- return;
+ /* XXX sanity checks on va */
- log(LOG_NOTICE, "apecs_isa_copyfrombuf: copied %d byte buffer\n",
- bounce_size);
- bcopy(bounce_buffer, addr, bounce_size);
+ /* Nothing to do; mapping was done in direct-mapped segment. */
}
diff --git a/sys/arch/alpha/pci/apecs_pci.c b/sys/arch/alpha/pci/apecs_pci.c
index c8ca57bbff7..42be1862efa 100644
--- a/sys/arch/alpha/pci/apecs_pci.c
+++ b/sys/arch/alpha/pci/apecs_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: apecs_pci.c,v 1.3 1995/08/03 01:16:57 cgd Exp $ */
+/* $NetBSD: apecs_pci.c,v 1.4 1995/11/23 02:37:16 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -33,330 +33,190 @@
#include <sys/device.h>
#include <vm/vm.h>
-#include <machine/autoconf.h>
-#include <machine/pio.h>
-
-#include <dev/isa/isavar.h>
-
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
-#include <alpha/pci/pci_chipset.h>
#include <alpha/pci/apecsreg.h>
+#include <alpha/pci/apecsvar.h>
-void apecs_setup __P((void));
-pcitag_t apecs_make_tag __P((int, int, int));
-pcireg_t apecs_conf_read __P((pcitag_t, int));
-void apecs_conf_write __P((pcitag_t, int, pcireg_t));
-int apecs_map_io __P((pcitag_t, int, int *));
-int apecs_map_mem __P((pcitag_t, int, vm_offset_t *, vm_offset_t *));
-int apecs_pcidma_map __P((caddr_t, vm_size_t, vm_offset_t *));
-void apecs_pcidma_unmap __P((caddr_t, vm_size_t, int, vm_offset_t *));
+pci_confreg_t apecs_conf_read __P((void *, pci_conftag_t, pci_confoffset_t));
+void apecs_conf_write __P((void *, pci_conftag_t,
+ pci_confoffset_t, pci_confreg_t));
+int apecs_find_io __P((void *, pci_conftag_t,
+ pci_confoffset_t, pci_iooffset_t *, pci_iosize_t *));
+int apecs_find_mem __P((void *, pci_conftag_t,
+ pci_confoffset_t, pci_moffset_t *, pci_msize_t *, int *));
-struct pci_cs_fcns apecs_p1e_cs_fcns = { /* XXX WHAT'S DIFFERENT? */
- apecs_setup,
- apecs_make_tag,
+__const struct pci_conf_fns apecs_conf_fns = {
apecs_conf_read,
apecs_conf_write,
- apecs_map_io,
- apecs_map_mem,
- apecs_pcidma_map,
- apecs_pcidma_unmap,
+ apecs_find_io,
+ apecs_find_mem,
};
-struct pci_cs_fcns apecs_p2e_cs_fcns = { /* XXX WHAT'S DIFFERENT? */
- apecs_setup,
- apecs_make_tag,
- apecs_conf_read,
- apecs_conf_write,
- apecs_map_io,
- apecs_map_mem,
- apecs_pcidma_map,
- apecs_pcidma_unmap,
-};
-
-#define REGVAL(r) (*(u_int32_t *)phystok0seg(r))
-
-void
-apecs_setup()
-{
-
- /*
- * Set up PCI bus mastering DMA windows on the APECS chip.
- *
- * What the PROM wants:
- * a 1G direct-mapped window that maps the PCI address
- * space from 4G -> 5G to memory addresses 0 -> 1G,
- * set up in window two.
- *
- * What we want:
- * a 1G direct-mapped window that maps the PCI address
- * space from 0 -> 1G to memory addresses 0 -> 1G.
- *
- * Unless we satisfy the PROM, we can't live through a reboot.
- * If we don't do what we want, I have to write more code.
-
- * So:
- * Leave window two alone, map window 1 the way I want it.
- *
- * XXX verify that windows don't overlap
- * XXX be trickier
- * XXX magic numbers
- */
-
-#if 0 /* should be routine to dump regs */
- printf("old base1 was 0x%x\n", REGVAL(EPIC_PCI_BASE_1));
- printf("old mask1 was 0x%x\n", REGVAL(EPIC_PCI_MASK_1));
- printf("old tbase1 was 0x%x\n", REGVAL(EPIC_TBASE_1));
-
- printf("old base2 was 0x%x\n", REGVAL(EPIC_PCI_BASE_2));
- printf("old mask2 was 0x%x\n", REGVAL(EPIC_PCI_MASK_2));
- printf("old tbase2 was 0x%x\n", REGVAL(EPIC_TBASE_2));
-#endif
-
-#if 0 /* XXX STUPID PROM; MUST LEAVE WINDOW 2 ALONE. See above */
- /* Turn off DMA window enables in PCI Base Reg 2. */
- REGVAL(EPIC_PCI_BASE_2) = 0;
-
- /* Set up Translated Base Register 2; translate to sybBus addr 0. */
- REGVAL(EPIC_TBASE_2) = 0;
-
- /* Set up PCI mask register 2; map 1G space. */
- REGVAL(EPIC_PCI_MASK_2) = 0x3ff00000;
-
- /* Enable window 2; from PCI address 4G, direct mapped. */
- REGVAL(EPIC_PCI_BASE_2) = 0x40080000;
-#endif /* STUPID PROM */
-
- /* Turn off DMA window enables in PCI Base Reg 1. */
- REGVAL(EPIC_PCI_BASE_1) = 0;
-
- /* Set up Translated Base Register 1; translate to sybBus addr 0. */
-{ /* XXX */
-extern struct sgmapent *sgmap;
- REGVAL(EPIC_TBASE_1) = vtophys(sgmap) >> 1;
-} /* XXX */
-
- /* Set up PCI mask register 1; map 8MB space. */
- REGVAL(EPIC_PCI_MASK_1) = 0x00700000;
-
- /* Enable window 1; from PCI address 8MB, direct mapped. */
- REGVAL(EPIC_PCI_BASE_1) = 0x008c0000;
-
- /*
- * Should set up HAXR1 and HAXR2... However, the PROM again
- * wants them where they're set to be...
- */
-#if 0
- printf("old haxr0 was 0x%x\n", REGVAL(EPIC_HAXR0));
- printf("old haxr1 was 0x%x\n", REGVAL(EPIC_HAXR1));
- printf("old haxr2 was 0x%x\n", REGVAL(EPIC_HAXR2));
-#endif
-
-#if 0 /* XXX STUPID PROM */
- /* HAXR0 is wired zero; no op. */
- REGVAL(EPIC_HAXR0) = 0;
-
- /* HAXR1: maps PCI memory space above 16M. 16M -> 2G+16M. */
- REGVAL(EPIC_HAXR1) = 0x80000000;
-
- /* HAXR2: maps PCI I/O space above 256K. 256K -> 256k. */
- REGVAL(EPIC_HAXR2) = 0;
-#endif
-}
-
-pcitag_t
-apecs_make_tag(bus, device, function)
- int bus, device, function;
-{
- pcitag_t tag;
-
- if (bus >= 256 || device >= 32 || function >= 8)
- panic("apecs_make_tag: bad request");
-
- tag = (bus << 21) | (device << 16) | (function << 13);
-#if 0
- printf("apecs_make_tag: bus %d, device %d, function %d -> 0x%lx\n", bus,
- device, function, tag);
-#endif
- return tag;
-}
-
-pcireg_t
-apecs_conf_read(tag, offset)
- pcitag_t tag;
- int offset; /* XXX */
+pci_confreg_t
+apecs_conf_read(cpv, tag, offset)
+ void *cpv;
+ pci_conftag_t tag;
+ pci_confoffset_t offset;
{
- pcireg_t *datap, data;
- int reg = offset >> 2; /* XXX */
+ struct apecs_config *acp = cpv;
+ pci_confreg_t *datap, data;
+ int s, secondary, ba;
+ int32_t old_haxr2; /* XXX */
+
+ secondary = PCI_TAG_BUS(tag) != 0;
+ if (secondary) {
+ s = splhigh();
+ old_haxr2 = REGVAL(EPIC_HAXR2);
+ wbflush();
+ REGVAL(EPIC_HAXR2) = old_haxr2 | 0x1;
+ wbflush();
+ }
- if ((tag & 0x1fe00000) != 0) {
- panic("apecs_conf_read: bus != 0?");
+ datap = (pci_confreg_t *)phystok0seg(APECS_PCI_CONF |
+ tag << 5UL | /* XXX */
+ (offset & ~0x03) << 5 | /* XXX */
+ 0 << 5 | /* XXX */
+ 0x3 << 3); /* XXX */
+ data = (pci_confreg_t)-1;
+ if (!(ba = badaddr(datap, sizeof *datap)))
+ data = *datap;
+
+ if (secondary) {
+ wbflush();
+ REGVAL(EPIC_HAXR2) = old_haxr2;
+ wbflush();
+ splx(s);
}
- /* XXX FILL IN HAXR2 bits. */
- datap = (pcireg_t *)
- phystok0seg(APECS_PCI_CONF | tag | reg << 7 | 0 << 5 | 0x3 << 3);
- if (badaddr(datap, sizeof *datap))
- return ((pcireg_t)-1);
- data = *datap;
#if 0
- printf("apecs_conf_read: tag 0x%lx, reg 0x%lx -> %x @ %p\n", tag, reg,
- data, datap);
+ printf("apecs_conf_read: tag 0x%lx, reg 0x%lx -> %x @ %p%s\n", tag, reg,
+ data, datap, ba ? " (badaddr)" : "");
#endif
+
return data;
}
void
-apecs_conf_write(tag, offset, data)
- pcitag_t tag;
- int offset; /* XXX */
- pcireg_t data;
+apecs_conf_write(cpv, tag, offset, data)
+ void *cpv;
+ pci_conftag_t tag;
+ pci_confoffset_t offset;
+ pci_confreg_t data;
{
- pcireg_t *datap;
- int reg = offset >> 2; /* XXX */
+ struct apecs_config *acp = cpv;
+ pci_confreg_t *datap;
+ int s, secondary;
+ int32_t old_haxr2; /* XXX */
+
+ secondary = PCI_TAG_BUS(tag) != 0;
+ if (secondary) {
+ s = splhigh();
+ old_haxr2 = REGVAL(EPIC_HAXR2);
+ wbflush();
+ REGVAL(EPIC_HAXR2) = old_haxr2 | 0x1;
+ wbflush();
+ }
- if ((tag & 0x1fe00000) != 0) {
- panic("apecs_conf_read: bus != 0?");
+ datap = (pci_confreg_t *)phystok0seg(APECS_PCI_CONF |
+ tag << 5UL | /* XXX */
+ (offset & ~0x03) << 5 | /* XXX */
+ 0 << 5 | /* XXX */
+ 0x3 << 3); /* XXX */
+ *datap = data;
+
+ if (secondary) {
+ wbflush();
+ REGVAL(EPIC_HAXR2) = old_haxr2;
+ wbflush();
+ splx(s);
}
- /* XXX FILL IN HAXR2 bits. */
- datap = (pcireg_t *)
- phystok0seg(APECS_PCI_CONF | tag | reg << 7 | 0 << 5 | 0x3 << 3);
#if 0
printf("apecs_conf_write: tag 0x%lx, reg 0x%lx -> 0x%x @ %p\n", tag,
reg, data, datap);
#endif
- *datap = data;
}
int
-apecs_map_io(tag, reg, iobasep)
- pcitag_t tag;
- int reg;
- int *iobasep;
+apecs_find_io(cpv, tag, reg, iobasep, sizep)
+ void *cpv;
+ pci_conftag_t tag;
+ pci_confoffset_t reg;
+ pci_iooffset_t *iobasep;
+ pci_iosize_t *sizep;
{
- pcireg_t data;
- int pci_iobase;
+ struct apecs_config *acp = cpv;
+ pci_confreg_t addrdata, sizedata;
+ pci_iooffset_t pci_iobase;
- if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3))
+ if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3))
panic("apecs_map_io: bad request");
- data = pci_conf_read(tag, reg);
+ addrdata = PCI_CONF_READ(acp->ac_conffns, acp->ac_confarg, tag, reg);
- if ((data & PCI_MAP_IO) == 0)
+ PCI_CONF_WRITE(acp->ac_conffns, acp->ac_confarg, tag, reg, 0xffffffff);
+ sizedata = PCI_CONF_READ(acp->ac_conffns, acp->ac_confarg, tag, reg);
+ PCI_CONF_WRITE(acp->ac_conffns, acp->ac_confarg, tag, reg, addrdata);
+
+ if (PCI_MAPREG_TYPE(addrdata) == PCI_MAPREG_TYPE_MEM)
panic("apecs_map_io: attempt to I/O map an memory region");
- /* figure out where it was mapped... */
- pci_iobase = data & PCI_MAP_MEMORY_ADDRESS_MASK; /* PCI I/O addr */
+ if (iobasep != NULL)
+ *iobasep = PCI_MAPREG_IO_ADDRESS(addrdata);
+ if (sizep != NULL)
+ *sizep = ~PCI_MAPREG_IO_ADDRESS(sizedata) + 1;
- return (pci_iobase);
+ return (0);
}
int
-apecs_map_mem(tag, reg, vap, pap)
- pcitag_t tag;
- int reg;
- vm_offset_t *vap, *pap;
+apecs_find_mem(cpv, tag, reg, paddrp, sizep, cacheablep)
+ void *cpv;
+ pci_conftag_t tag;
+ pci_confoffset_t reg;
+ pci_moffset_t *paddrp;
+ pci_msize_t *sizep;
+ int *cacheablep;
{
- pcireg_t data;
- vm_offset_t pci_pa, sb_pa;
+ struct apecs_config *acp = cpv;
+ pci_confreg_t addrdata, sizedata;
- if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3))
+ if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3))
panic("apecs_map_mem: bad request");
/*
- * "HERE WE GO AGAIN!!!"
- *
- * The PROM has already mapped the device for us. The PROM is
- * our friend. We wouldn't want to make the PROM unhappy.
- *
- * So, we take the address that's been assigned (already) to
- * the register, and figure out what physical and virtual addresses
- * go with it...
+ * The PROM has mapped the device for us. We take the address
+ * that's been assigned to the register, and figure out what
+ * physical and virtual addresses go with it...
*/
- /*
- * Section 6.2.5.1, `Address Maps', says that a device which wants 2^n
- * bytes of memory will hardwire the bottom n bits of the address to 0.
- * As recommended, we write all 1s and see what we get back.
- */
- data = pci_conf_read(tag, reg);
+ addrdata = PCI_CONF_READ(acp->ac_conffns, acp->ac_confarg, tag, reg);
+
+ PCI_CONF_WRITE(acp->ac_conffns, acp->ac_confarg, tag, reg, 0xffffffff);
+ sizedata = PCI_CONF_READ(acp->ac_conffns, acp->ac_confarg, tag, reg);
+ PCI_CONF_WRITE(acp->ac_conffns, acp->ac_confarg, tag, reg, addrdata);
- if (data & PCI_MAP_IO)
+ if (PCI_MAPREG_TYPE(addrdata) == PCI_MAPREG_TYPE_IO)
panic("apecs_map_mem: attempt to memory map an I/O region");
- switch (data & PCI_MAP_MEMORY_TYPE_MASK) {
- case PCI_MAP_MEMORY_TYPE_32BIT:
+ switch (PCI_MAPREG_MEM_TYPE(addrdata)) {
+ case PCI_MAPREG_MEM_TYPE_32BIT:
+ case PCI_MAPREG_MEM_TYPE_32BIT_1M:
break;
- case PCI_MAP_MEMORY_TYPE_32BIT_1M:
- printf("apecs_map_mem: attempt to map restricted 32-bit region\n");
- return EOPNOTSUPP;
- case PCI_MAP_MEMORY_TYPE_64BIT:
- printf("apecs_map_mem: attempt to map 64-bit region\n");
- return EOPNOTSUPP;
+ case PCI_MAPREG_MEM_TYPE_64BIT:
+/* XXX */ printf("apecs_map_mem: attempt to map 64-bit region\n");
+/* XXX */ break;
default:
printf("apecs_map_mem: reserved mapping type\n");
return EINVAL;
}
- /* figure out where it was mapped... */
- pci_pa = data & PCI_MAP_MEMORY_ADDRESS_MASK; /* PCI bus address */
-
- /* calcluate sysBus address -- should be a better way to get space */
- if (data & PCI_MAP_MEMORY_CACHABLE) {
- /* Dense space */
- sb_pa = (pci_pa & 0xffffffff) | (3L << 32); /* XXX */
- } else {
- /* Sparse space */
- sb_pa = ((pci_pa & 0x7ffffff) << 5) | (2L << 32); /* XXX */
- }
-
- /* and tell the driver. */
- *vap = phystok0seg(sb_pa);
- *pap = pci_pa;
-
-#if 0
- printf("pci_map_mem: memory mapped at 0x%lx\n", *pap);
- printf("pci_map_mem: virtual 0x%lx\n", *vap);
-#endif
+ if (paddrp != NULL)
+ *paddrp = PCI_MAPREG_MEM_ADDRESS(addrdata); /* PCI addr */
+ if (sizep != NULL)
+ *sizep = ~PCI_MAPREG_MEM_ADDRESS(sizedata) + 1;
+ if (cacheablep != NULL)
+ *cacheablep = PCI_MAPREG_MEM_CACHEABLE(addrdata);
return 0;
}
-
-int
-apecs_pcidma_map(addr, size, mappings)
- caddr_t addr;
- vm_size_t size;
- vm_offset_t *mappings;
-{
- vm_offset_t va;
- long todo;
- int i;
-
- i = 0;
- va = (vm_offset_t)addr;
- todo = size;
-
- while (todo > 0) {
- mappings[i] = vtophys(va) | 0x40000000;
-#if 0
- printf("a_pd_m mapping %d: %lx -> %lx -> %lx\n", i, va,
- vtophys(va), mappings[i]);
-#endif
- i++;
- todo -= PAGE_SIZE - (va - trunc_page(va));
- va += PAGE_SIZE - (va - trunc_page(va));
- }
- return (i);
-}
-
-void
-apecs_pcidma_unmap(addr, size, nmappings, mappings)
- caddr_t addr;
- vm_size_t size;
- int nmappings;
- vm_offset_t *mappings;
-{
-
- /* maybe XXX if diagnostic, check that mapping happened. */
- printf("apecs_pcidma_unmap: nada\n");
-}
diff --git a/sys/arch/alpha/pci/apecsreg.h b/sys/arch/alpha/pci/apecsreg.h
index 186173f2bb7..864bfac54fe 100644
--- a/sys/arch/alpha/pci/apecsreg.h
+++ b/sys/arch/alpha/pci/apecsreg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: apecsreg.h,v 1.2 1995/08/03 01:17:04 cgd Exp $ */
+/* $NetBSD: apecsreg.h,v 1.3 1995/11/23 02:37:19 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -34,6 +34,8 @@
* Sheet'' (DEC order number EC-QAEMA-TE), pages 4-1 - 4-27, 10-21 - 10-38.
*/
+#define REGVAL(r) (*(int32_t *)phystok0seg(r))
+
/*
* Base addresses
*/
@@ -278,7 +280,9 @@
#define EPIC_HAXR1_EADDR 0xf8000000
#define EPIC_HAXR2 (EPIC_BASE + 0x01c0) /* Host Addr Extn 2 */
-#define EPIC_HAXR2_CONF_ADDR 0x00000003
+#define EPIC_HAXR2_CONF_TYPE 0x00000003
+#define EPIC_HAXR2_CONF_TYPO0 0x00000000
+#define EPIC_HAXR2_CONF_TYPE1 0x00000001
#define EPIC_HAXR2_RSVD 0x00fffffc
#define EPIC_HAXR2_EADDR 0xff000000
diff --git a/sys/arch/alpha/pci/apecsvar.h b/sys/arch/alpha/pci/apecsvar.h
new file mode 100644
index 00000000000..a63cc275922
--- /dev/null
+++ b/sys/arch/alpha/pci/apecsvar.h
@@ -0,0 +1,72 @@
+/* $NetBSD: apecsvar.h,v 1.1 1995/11/23 02:37:21 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <dev/isa/isavar.h>
+#include <dev/pci/pcivar.h>
+
+/*
+ * An APECS chipset's configuration.
+ *
+ * All of the information that the chipset-specific functions need to
+ * do their dirty work (and more!).
+ */
+struct apecs_config {
+ int ac_comanche_pass2;
+ int ac_epic_pass2;
+ int ac_memwidth;
+
+ __const struct pci_conf_fns *ac_conffns;
+ void *ac_confarg;
+
+ __const struct pci_dma_fns *ac_dmafns;
+ void *ac_dmaarg;
+
+ __const struct pci_intr_fns *ac_intrfns;
+ void *ac_intrarg;
+
+ __const struct pci_mem_fns *ac_memfns;
+ void *ac_memarg;
+
+ __const struct pci_pio_fns *ac_piofns;
+ void *ac_pioarg;
+};
+
+struct apecs_softc {
+ struct device sc_dev;
+
+ struct apecs_config *sc_acp;
+};
+
+extern __const struct pci_conf_fns apecs_conf_fns;
+extern __const struct pci_dma_fns apecs_dma_fns;
+/* pci interrupt functions handled elsewhere */
+extern __const struct pci_mem_fns apecs_mem_fns;
+extern __const struct pci_pio_fns apecs_pio_fns;
+
+void apecs_init __P((struct apecs_config *));
diff --git a/sys/arch/alpha/pci/cia.c b/sys/arch/alpha/pci/cia.c
new file mode 100644
index 00000000000..fa2f49fc6cc
--- /dev/null
+++ b/sys/arch/alpha/pci/cia.c
@@ -0,0 +1,176 @@
+/* $NetBSD: cia.c,v 1.1 1995/11/23 02:37:24 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+#include <vm/vm.h>
+
+#include <machine/autoconf.h>
+#include <machine/rpb.h>
+
+#include <dev/isa/isareg.h>
+#include <dev/isa/isavar.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <alpha/pci/ciareg.h>
+#include <alpha/pci/ciavar.h>
+#if defined(DEC_KN20AA)
+#include <alpha/pci/pci_kn20aa.h>
+#endif
+
+int ciamatch __P((struct device *, void *, void *));
+void ciaattach __P((struct device *, struct device *, void *));
+
+struct cfdriver ciacd = {
+ NULL, "cia", ciamatch, ciaattach, DV_DULL,
+ sizeof(struct cia_softc)
+};
+
+static int ciaprint __P((void *, char *pnp));
+
+#define REGVAL(r) (*(int32_t *)phystok0seg(r))
+
+/* There can be only one. */
+int ciafound;
+struct cia_config cia_configuration;
+
+int
+ciamatch(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct cfdata *cf = match;
+ struct confargs *ca = aux;
+
+ /* Make sure that we're looking for a CIA. */
+ if (strcmp(ca->ca_name, ciacd.cd_name) != 0)
+ return (0);
+
+ if (ciafound)
+ return (0);
+
+ return (1);
+}
+
+/*
+ * Set up the chipset's function pointers.
+ */
+void
+cia_init(ccp)
+ struct cia_config *ccp;
+{
+
+ /*
+ * Can't set up SGMAP data here; can be called before malloc().
+ */
+
+ ccp->cc_conffns = &cia_conf_fns;
+ ccp->cc_confarg = ccp;
+ ccp->cc_dmafns = &cia_dma_fns;
+ ccp->cc_dmaarg = ccp;
+ /* Interrupt routines set up in 'attach' */
+ ccp->cc_memfns = &cia_mem_fns;
+ ccp->cc_memarg = ccp;
+ ccp->cc_piofns = &cia_pio_fns;
+ ccp->cc_pioarg = ccp;
+}
+
+void
+ciaattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct confargs *ca = aux;
+ struct cia_softc *sc = (struct cia_softc *)self;
+ struct cia_config *ccp;
+ struct pci_attach_args pa;
+
+ /* note that we've attached the chipset; can't have 2 CIAs. */
+ ciafound = 1;
+
+ /*
+ * set up the chipset's info; done once at console init time
+ * (maybe), but doesn't hurt to do twice.
+ */
+ ccp = sc->sc_ccp = &cia_configuration;
+ cia_init(ccp);
+
+ /* XXX print chipset information */
+ printf("\n");
+
+ switch (hwrpb->rpb_type) {
+#if defined(DEC_KN20AA)
+ case ST_DEC_KN20AA:
+ pci_kn20aa_pickintr(ccp->cc_conffns, ccp->cc_confarg,
+ ccp->cc_piofns, ccp->cc_pioarg,
+ &ccp->cc_intrfns, &ccp->cc_intrarg);
+#ifdef EVCNT_COUNTERS
+ evcnt_attach(self, "intr", &kn20aa_intr_evcnt);
+#endif
+ break;
+#endif
+ default:
+ panic("ciaattach: shouldn't be here, really...");
+ }
+
+ pa.pa_bus = 0;
+ pa.pa_maxdev = 32;
+ pa.pa_burstlog2 = 8;
+
+ pa.pa_conffns = ccp->cc_conffns;
+ pa.pa_confarg = ccp->cc_confarg;
+ pa.pa_dmafns = ccp->cc_dmafns;
+ pa.pa_dmaarg = ccp->cc_dmaarg;
+ pa.pa_intrfns = ccp->cc_intrfns;
+ pa.pa_intrarg = ccp->cc_intrarg;
+ pa.pa_memfns = ccp->cc_memfns;
+ pa.pa_memarg = ccp->cc_memarg;
+ pa.pa_piofns = ccp->cc_piofns;
+ pa.pa_pioarg = ccp->cc_pioarg;
+
+ config_found(self, &pa, ciaprint);
+}
+
+static int
+ciaprint(aux, pnp)
+ void *aux;
+ char *pnp;
+{
+ register struct pci_attach_args *pa = aux;
+
+ /* only PCIs can attach to CIAs; easy. */
+ if (pnp)
+ printf("pci at %s", pnp);
+ printf(" bus %d", pa->pa_bus);
+ return (UNCONF);
+}
diff --git a/sys/arch/alpha/pci/cia_isa.c b/sys/arch/alpha/pci/cia_isa.c
new file mode 100644
index 00000000000..6ccb0ae4a3e
--- /dev/null
+++ b/sys/arch/alpha/pci/cia_isa.c
@@ -0,0 +1,346 @@
+/* $NetBSD: cia_isa.c,v 1.1 1995/11/23 02:37:26 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/malloc.h>
+#include <sys/syslog.h>
+#include <sys/device.h>
+#include <vm/vm.h>
+
+#include <dev/isa/isavar.h>
+
+#include <alpha/pci/ciareg.h>
+#include <alpha/pci/ciavar.h>
+
+/*
+ * Allocation/deallocation functions.
+ */
+int cia_pio_alloc __P((void *, isa_iooffset_t, isa_iosize_t));
+int cia_pio_dealloc __P((void *, isa_iooffset_t, isa_iosize_t));
+
+/*
+ * Byte functions.
+ */
+isa_byte_t cia_inb __P((void *, isa_iooffset_t));
+#define cia_insb 0 /* XXX */
+void cia_outb __P((void *, isa_iooffset_t, isa_byte_t));
+#define cia_outsb 0 /* XXX */
+
+/*
+ * Word functions.
+ */
+isa_word_t cia_inw __P((void *, isa_iooffset_t));
+#define cia_insw 0 /* XXX */
+void cia_outw __P((void *, isa_iooffset_t, isa_word_t));
+#define cia_outsw 0 /* XXX */
+
+/*
+ * Longword functions.
+ */
+isa_long_t cia_inl __P((void *, isa_iooffset_t));
+#define cia_insl 0 /* XXX */
+void cia_outl __P((void *, isa_iooffset_t, isa_long_t));
+#define cia_outsl 0 /* XXX */
+
+__const struct pci_pio_fns cia_pio_fns = {
+ /* Allocation/deallocation functions. */
+ cia_pio_alloc, cia_pio_dealloc,
+
+ /* Byte functions. */
+ cia_inb, cia_insb,
+ cia_outb, cia_outsb,
+
+ /* Word functions. */
+ cia_inw, cia_insw,
+ cia_outw, cia_outsw,
+
+ /* Longword functions. */
+ cia_inl, cia_insl,
+ cia_outl, cia_outsl,
+};
+
+int
+cia_pio_alloc(ipfarg, start, size)
+ void *ipfarg;
+ isa_iooffset_t start;
+ isa_iosize_t size;
+{
+
+ /* XXX should do something */
+}
+
+int
+cia_pio_dealloc(ipfarg, start, size)
+ void *ipfarg;
+ isa_iooffset_t start;
+ isa_iosize_t size;
+{
+
+ /* XXX should do something */
+}
+
+isa_byte_t
+cia_inb(ipfa, ioaddr)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+{
+ u_int32_t *port, val;
+ isa_byte_t rval;
+ int offset;
+
+ wbflush();
+ offset = ioaddr & 3;
+ port = (int32_t *)phystok0seg(CIA_PCI_SIO0 | 0 << 3 | ioaddr << 5);
+ val = *port;
+ rval = ((val) >> (8 * offset)) & 0xff;
+/* rval = val & 0xff; */
+
+ return rval;
+}
+
+void
+cia_outb(ipfa, ioaddr, val)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+ isa_byte_t val;
+{
+ u_int32_t *port, nval;
+ int offset;
+
+ offset = ioaddr & 3;
+ nval = val /*<< (8 * offset)*/;
+ nval = val << (8 * offset);
+ port = (int32_t *)phystok0seg(CIA_PCI_SIO0 | 0 << 3 | ioaddr << 5);
+
+ *port = nval;
+ wbflush();
+}
+
+isa_word_t
+cia_inw(ipfa, ioaddr)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+{
+ u_int32_t *port, val;
+ isa_word_t rval;
+ int offset;
+
+ wbflush();
+ offset = ioaddr & 3;
+ port = (int32_t *)phystok0seg(CIA_PCI_SIO0 | 1 << 3 | ioaddr << 5);
+ val = *port;
+ rval = ((val) >> (8 * offset)) & 0xffff;
+ rval = val & 0xffff;
+
+panic("inw(0x%x) => 0x%x @ %p => 0x%x\n", ioaddr, val, port, rval);
+
+ return rval;
+}
+
+void
+cia_outw(ipfa, ioaddr, val)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+ isa_word_t val;
+{
+ u_int32_t *port, nval;
+ int offset;
+
+ offset = ioaddr & 3;
+ nval = val /*<< (8 * offset)*/;
+ port = (int32_t *)phystok0seg(CIA_PCI_SIO0 | 1 << 3 | ioaddr << 5);
+
+ *port = nval;
+ wbflush();
+}
+
+isa_long_t
+cia_inl(ipfa, ioaddr)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+{
+ u_int32_t *port, val;
+ isa_long_t rval;
+ int offset;
+
+ wbflush();
+ offset = ioaddr & 3;
+ port = (int32_t *)phystok0seg(CIA_PCI_SIO0 | 3 << 3 | ioaddr << 5);
+ val = *port;
+ rval = ((val) >> (8 * offset)) & 0xffffffff;
+ rval = val & 0xffffffff;
+
+ return rval;
+}
+
+void
+cia_outl(ipfa, ioaddr, val)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+ isa_long_t val;
+{
+ u_int32_t *port, nval;
+ int offset;
+
+ offset = ioaddr & 3;
+ nval = val /*<< (8 * offset)*/;
+ port = (int32_t *)phystok0seg(CIA_PCI_SIO0 | 3 << 3 | ioaddr << 5);
+
+ *port = nval;
+ wbflush();
+}
+
+/* XXX XXX XXX */
+
+#define pf(fn, args) fn args { panic(__STRING(fn)); }
+
+void pf(cia_dma_cascade, (void *idfa, isa_drq_t chan))
+void pf(cia_dma_copytobuf, ())
+void pf(cia_dma_copyfrombuf, ())
+void pf(cia_dma_start, (void *idfa, vm_offset_t addr,
+ isa_msize_t size, isa_drq_t chan, int flags))
+void pf(cia_dma_abort, (void *idfa, isa_drq_t chan))
+void pf(cia_dma_done, (void *idfa, isa_drq_t chan))
+
+int cia_dma_map __P((void *, vm_offset_t, isa_msize_t,
+ isa_moffset_t *, int));
+void cia_dma_unmap __P((void *, vm_offset_t, isa_msize_t, int,
+ isa_moffset_t *));
+
+__const struct isa_dma_fns cia_dma_fns = {
+ cia_dma_cascade,
+ cia_dma_map,
+ cia_dma_unmap,
+ cia_dma_copytobuf,
+ cia_dma_copyfrombuf,
+ cia_dma_start,
+ cia_dma_abort,
+ cia_dma_done,
+};
+
+int
+cia_dma_map(idfa, va, isasize, mappingsp, flags)
+ void *idfa;
+ vm_offset_t va;
+ isa_msize_t isasize;
+ isa_moffset_t *mappingsp;
+ int flags;
+{
+ struct apecs_config *acp = idfa;
+ long todo;
+ int i;
+
+ if (ISA_DMA_NEEDCONTIG(flags) && isasize > NBPG ||
+ ISA_DMA_SIZEBOUND(flags) != ISA_DMA_SIZEBOUND_NONE ||
+ ISA_DMA_ADDRBOUND(flags) != ISA_DMA_ADDRBOUND_NONE)
+ panic("cia_dma_map: punt");
+
+ i = 0;
+ todo = isasize;
+
+ while (todo > 0) {
+ mappingsp[i] = vtophys(va) | 0x40000000;
+#if 0
+ printf("a_pd_m mapping %d: %lx -> %lx -> %lx\n", i, va,
+ vtophys(va), mappingsp[i]);
+#endif
+ i++;
+ todo -= PAGE_SIZE - (va - trunc_page(va));
+ va += PAGE_SIZE - (va - trunc_page(va));
+ }
+ return (i);
+}
+
+void
+cia_dma_unmap(idfa, va, isasize, nmappings, mappingsp)
+ void *idfa;
+ vm_offset_t va;
+ isa_msize_t isasize;
+ int nmappings;
+ isa_moffset_t *mappingsp;
+{
+
+ printf("cia_dma_unmap: called\n");
+}
+
+vm_offset_t cia_mem_map __P((void *, isa_moffset_t, isa_msize_t, int));
+void cia_mem_unmap __P((void *, vm_offset_t, isa_msize_t));
+
+#if 0
+void cia_mem_copytoisa __P((void *, char *, vm_offset_t,
+ isa_moffset_t, isa_msize_t));
+void cia_mem_copyfromisa __P((void *, char *, vm_offset_t,
+ isa_moffset_t, isa_msize_t));
+void cia_mem_zero __P((void *, vm_offset_t, isa_moffset_t,
+ isa_msize_t));
+#else
+void pf(cia_mem_copytoisa, ())
+void pf(cia_mem_copyfromisa, ())
+void pf(cia_mem_zero, ())
+#endif
+
+__const struct isa_mem_fns cia_mem_fns = {
+ cia_mem_map,
+ cia_mem_unmap,
+ cia_mem_copytoisa,
+ cia_mem_copyfromisa,
+ cia_mem_zero,
+};
+
+vm_offset_t
+cia_mem_map(imfa, isapa, isasize, cacheable)
+ void *imfa;
+ isa_moffset_t isapa;
+ isa_msize_t isasize;
+ int cacheable;
+{
+ vm_offset_t sbpa;
+
+ /* XXX sanity checks on sizes, use of windows, etc. */
+
+ /* XXX MAGIC NUMBERS */
+ if (cacheable)
+ sbpa = (isapa & 0xffffffff) | CIA_PCI_DENSE;
+ else
+ sbpa = ((isapa & 0x7ffffff) << 5) | CIA_PCI_SPARSE0;
+
+ return phystok0seg(sbpa);
+}
+
+void
+cia_mem_unmap(imfa, va, isasize)
+ void *imfa;
+ vm_offset_t va;
+ isa_msize_t isasize;
+{
+
+ /* XXX sanity checks on va */
+
+ /* Nothing to do; mapping was done in direct-mapped segment. */
+}
diff --git a/sys/arch/alpha/pci/cia_pci.c b/sys/arch/alpha/pci/cia_pci.c
new file mode 100644
index 00000000000..ef918cd84d6
--- /dev/null
+++ b/sys/arch/alpha/pci/cia_pci.c
@@ -0,0 +1,222 @@
+/* $NetBSD: cia_pci.c,v 1.1 1995/11/23 02:37:29 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <vm/vm.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <alpha/pci/ciareg.h>
+#include <alpha/pci/ciavar.h>
+
+pci_confreg_t cia_conf_read __P((void *, pci_conftag_t, pci_confoffset_t));
+void cia_conf_write __P((void *, pci_conftag_t,
+ pci_confoffset_t, pci_confreg_t));
+int cia_find_io __P((void *, pci_conftag_t,
+ pci_confoffset_t, pci_iooffset_t *, pci_iosize_t *));
+int cia_find_mem __P((void *, pci_conftag_t,
+ pci_confoffset_t, pci_moffset_t *, pci_msize_t *, int *));
+
+__const struct pci_conf_fns cia_conf_fns = {
+ cia_conf_read,
+ cia_conf_write,
+ cia_find_io,
+ cia_find_mem,
+};
+
+pci_confreg_t
+cia_conf_read(cpv, tag, offset)
+ void *cpv;
+ pci_conftag_t tag;
+ pci_confoffset_t offset;
+{
+ struct cia_config *acp = cpv;
+ pci_confreg_t *datap, data;
+ int s, secondary, ba;
+ int32_t old_haxr2; /* XXX */
+
+ secondary = PCI_TAG_BUS(tag) != 0;
+ if (secondary) {
+ s = splhigh();
+ old_haxr2 = REGVAL(CIA_CSRS + 0x480); /* XXX */
+ wbflush();
+ REGVAL(CIA_CSRS + 0x480) = old_haxr2 | 0x1; /* XXX */
+ wbflush();
+ }
+
+ datap = (pci_confreg_t *)phystok0seg(CIA_PCI_CONF |
+ tag << 5UL | /* XXX */
+ (offset & ~0x03) << 5 | /* XXX */
+ 0 << 5 | /* XXX */
+ 0x3 << 3); /* XXX */
+ data = (pci_confreg_t)-1;
+ if (!(ba = badaddr(datap, sizeof *datap)))
+ data = *datap;
+
+ if (secondary) {
+ wbflush();
+ REGVAL(CIA_CSRS + 0x480) = old_haxr2; /* XXX */
+ wbflush();
+ splx(s);
+ }
+
+#if 0
+ printf("cia_conf_read: tag 0x%lx, reg 0x%lx -> %x @ %p%s\n", tag, reg,
+ data, datap, ba ? " (badaddr)" : "");
+#endif
+
+ return data;
+}
+
+void
+cia_conf_write(cpv, tag, offset, data)
+ void *cpv;
+ pci_conftag_t tag;
+ pci_confoffset_t offset;
+ pci_confreg_t data;
+{
+ struct cia_config *acp = cpv;
+ pci_confreg_t *datap;
+ int s, secondary;
+ int32_t old_haxr2; /* XXX */
+
+ secondary = PCI_TAG_BUS(tag) != 0;
+ if (secondary) {
+ s = splhigh();
+ old_haxr2 = REGVAL(CIA_CSRS + 0x480); /* XXX */
+ wbflush();
+ REGVAL(CIA_CSRS + 0x480) = old_haxr2 | 0x1; /* XXX */
+ wbflush();
+ }
+
+ datap = (pci_confreg_t *)phystok0seg(CIA_PCI_CONF |
+ tag << 5UL | /* XXX */
+ (offset & ~0x03) << 5 | /* XXX */
+ 0 << 5 | /* XXX */
+ 0x3 << 3); /* XXX */
+ *datap = data;
+
+ if (secondary) {
+ wbflush();
+ REGVAL(CIA_CSRS + 0x480) = old_haxr2; /* XXX */
+ wbflush();
+ splx(s);
+ }
+
+#if 0
+ printf("cia_conf_write: tag 0x%lx, reg 0x%lx -> 0x%x @ %p\n", tag,
+ reg, data, datap);
+#endif
+}
+
+int
+cia_find_io(cpv, tag, reg, iobasep, sizep)
+ void *cpv;
+ pci_conftag_t tag;
+ pci_confoffset_t reg;
+ pci_iooffset_t *iobasep;
+ pci_iosize_t *sizep;
+{
+ struct cia_config *acp = cpv;
+ pci_confreg_t addrdata, sizedata;
+ pci_iooffset_t pci_iobase;
+
+ if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3))
+ panic("cia_map_io: bad request");
+
+ addrdata = PCI_CONF_READ(acp->cc_conffns, acp->cc_confarg, tag, reg);
+
+ PCI_CONF_WRITE(acp->cc_conffns, acp->cc_confarg, tag, reg, 0xffffffff);
+ sizedata = PCI_CONF_READ(acp->cc_conffns, acp->cc_confarg, tag, reg);
+ PCI_CONF_WRITE(acp->cc_conffns, acp->cc_confarg, tag, reg, addrdata);
+
+ if (PCI_MAPREG_TYPE(addrdata) == PCI_MAPREG_TYPE_MEM)
+ panic("cia_map_io: attempt to I/O map an memory region");
+
+ if (iobasep != NULL)
+ *iobasep = PCI_MAPREG_IO_ADDRESS(addrdata);
+ if (sizep != NULL)
+ *sizep = ~PCI_MAPREG_IO_ADDRESS(sizedata) + 1;
+
+ return (0);
+}
+
+int
+cia_find_mem(cpv, tag, reg, paddrp, sizep, cacheablep)
+ void *cpv;
+ pci_conftag_t tag;
+ pci_confoffset_t reg;
+ pci_moffset_t *paddrp;
+ pci_msize_t *sizep;
+ int *cacheablep;
+{
+ struct cia_config *acp = cpv;
+ pci_confreg_t addrdata, sizedata;
+
+ if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3))
+ panic("cia_map_mem: bad request");
+
+ /*
+ * The PROM has mapped the device for us. We take the address
+ * that's been assigned to the register, and figure out what
+ * physical and virtual addresses go with it...
+ */
+ addrdata = PCI_CONF_READ(acp->cc_conffns, acp->cc_confarg, tag, reg);
+
+ PCI_CONF_WRITE(acp->cc_conffns, acp->cc_confarg, tag, reg, 0xffffffff);
+ sizedata = PCI_CONF_READ(acp->cc_conffns, acp->cc_confarg, tag, reg);
+ PCI_CONF_WRITE(acp->cc_conffns, acp->cc_confarg, tag, reg, addrdata);
+
+ if (PCI_MAPREG_TYPE(addrdata) == PCI_MAPREG_TYPE_IO)
+ panic("cia_map_mem: attempt to memory map an I/O region");
+
+ switch (PCI_MAPREG_MEM_TYPE(addrdata)) {
+ case PCI_MAPREG_MEM_TYPE_32BIT:
+ case PCI_MAPREG_MEM_TYPE_32BIT_1M:
+ break;
+ case PCI_MAPREG_MEM_TYPE_64BIT:
+/* XXX */ printf("cia_map_mem: attempt to map 64-bit region\n");
+/* XXX */ break;
+ default:
+ printf("cia_map_mem: reserved mapping type\n");
+ return EINVAL;
+ }
+
+ if (paddrp != NULL)
+ *paddrp = PCI_MAPREG_MEM_ADDRESS(addrdata); /* PCI addr */
+ if (sizep != NULL)
+ *sizep = ~PCI_MAPREG_MEM_ADDRESS(sizedata) + 1;
+ if (cacheablep != NULL)
+ *cacheablep = PCI_MAPREG_MEM_CACHEABLE(addrdata);
+
+ return 0;
+}
diff --git a/sys/arch/alpha/pci/ciareg.h b/sys/arch/alpha/pci/ciareg.h
new file mode 100644
index 00000000000..5fc6ae9435a
--- /dev/null
+++ b/sys/arch/alpha/pci/ciareg.h
@@ -0,0 +1,51 @@
+/* $NetBSD: ciareg.h,v 1.1 1995/11/23 02:37:31 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * 21171 Chipset registers and constants.
+ *
+ * Taken from XXX
+ */
+
+#define REGVAL(r) (*(int32_t *)phystok0seg(r))
+
+/*
+ * Base addresses
+ */
+#define CIA_PCI_SPARSE0 0x8000000000L
+#define CIA_PCI_SPARSE1 0x8400000000L
+#define CIA_PCI_SPARSE2 0x8500000000L
+#define CIA_PCI_SIO0 0x8580000000L
+#define CIA_PCI_SIO1 0x85c0000000L
+#define CIA_PCI_DENSE 0x8600000000L
+#define CIA_PCI_CONF 0x8700000000L
+#define CIA_PCI_IACK 0x8720000000L
+#define CIA_CSRS 0x8740000000L
+#define CIA_PCI_MC_CSRS 0x8750000000L
+#define CIA_PCI_ATRANS 0x8760000000L
diff --git a/sys/arch/alpha/pci/ciavar.h b/sys/arch/alpha/pci/ciavar.h
new file mode 100644
index 00000000000..d9241010d89
--- /dev/null
+++ b/sys/arch/alpha/pci/ciavar.h
@@ -0,0 +1,69 @@
+/* $NetBSD: ciavar.h,v 1.1 1995/11/23 02:37:35 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <dev/isa/isavar.h>
+#include <dev/pci/pcivar.h>
+
+/*
+ * A 21171 chipset's configuration.
+ *
+ * All of the information that the chipset-specific functions need to
+ * do their dirty work (and more!).
+ */
+struct cia_config {
+ __const struct pci_conf_fns *cc_conffns;
+ void *cc_confarg;
+
+ __const struct pci_dma_fns *cc_dmafns;
+ void *cc_dmaarg;
+
+ __const struct pci_intr_fns *cc_intrfns;
+ void *cc_intrarg;
+
+ __const struct pci_mem_fns *cc_memfns;
+ void *cc_memarg;
+
+ __const struct pci_pio_fns *cc_piofns;
+ void *cc_pioarg;
+};
+
+struct cia_softc {
+ struct device sc_dev;
+
+ struct cia_config *sc_ccp;
+ /* XXX SGMAP info */
+};
+
+extern __const struct pci_conf_fns cia_conf_fns;
+extern __const struct pci_dma_fns cia_dma_fns;
+/* pci interrupt functions handled elsewhere */
+extern __const struct pci_mem_fns cia_mem_fns;
+extern __const struct pci_pio_fns cia_pio_fns;
+
+void cia_init __P((struct cia_config *));
diff --git a/sys/arch/alpha/pci/lca.c b/sys/arch/alpha/pci/lca.c
new file mode 100644
index 00000000000..ac6514fee99
--- /dev/null
+++ b/sys/arch/alpha/pci/lca.c
@@ -0,0 +1,210 @@
+/* $NetBSD: lca.c,v 1.1 1995/11/23 02:37:38 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Jeffrey Hsu
+ *
+ * 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/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+#include <vm/vm.h>
+
+#include <machine/autoconf.h>
+#include <machine/rpb.h>
+
+#include <dev/isa/isareg.h>
+#include <dev/isa/isavar.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <alpha/pci/lcareg.h>
+#include <alpha/pci/lcavar.h>
+
+int lcamatch __P((struct device *, void *, void *));
+void lcaattach __P((struct device *, struct device *, void *));
+
+struct cfdriver lcacd = {
+ NULL, "lca", lcamatch, lcaattach, DV_DULL,
+ sizeof(struct lca_softc)
+};
+
+static int lcaprint __P((void *, char *pnp));
+
+/* There can be only one. */
+int lcafound;
+struct lca_config lca_configuration;
+
+int
+lcamatch(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct cfdata *cf = match;
+ struct confargs *ca = aux;
+
+ /* Make sure that we're looking for a LCA. */
+ if (strcmp(ca->ca_name, lcacd.cd_name) != 0)
+ return (0);
+
+ if (lcafound)
+ return (0);
+
+ return (1);
+}
+
+/*
+ * Set up the chipset's function pointers.
+ */
+void
+lca_init(lcp)
+ struct lca_config *lcp;
+{
+
+ /*
+ * Can't set up SGMAP data here; can be called before malloc().
+ */
+
+ lcp->lc_conffns = &lca_conf_fns;
+ lcp->lc_confarg = lcp;
+ lcp->lc_dmafns = &lca_dma_fns;
+ lcp->lc_dmaarg = lcp;
+ /* Interrupt routines set up in 'attach' */
+ lcp->lc_memfns = &lca_mem_fns;
+ lcp->lc_memarg = lcp;
+ lcp->lc_piofns = &lca_pio_fns;
+ lcp->lc_pioarg = lcp;
+
+/*
+printf("lca_init: before IOC_HAE=0x%x\n", REGVAL(LCA_IOC_HAE));
+ REGVAL(LCA_IOC_HAE) = 0; */
+
+ REGVAL(LCA_IOC_CONF) = 0;
+
+ /* Turn off DMA window enables in Window Base Registers */
+/* REGVAL(LCA_IOC_W_BASE0) = 0;
+ REGVAL(LCA_IOC_W_BASE1) = 0; */
+ wbflush();
+}
+
+#ifdef notdef
+void
+lca_init_sgmap(lcp)
+ struct lca_config *lcp;
+{
+
+ /* XXX */
+ lcp->lc_sgmap = malloc(1024 * 8, M_DEVBUF, M_WAITOK);
+ bzero(lcp->lc_sgmap, 1024 * 8); /* clear all entries. */
+
+ REGVAL(LCA_IOC_W_BASE0) = 0;
+ wbflush();
+
+ /* Set up Translated Base Register 1; translate to sybBus addr 0. */
+ /* check size against APEC XXX JH */
+ REGVAL(LCA_IOC_T_BASE_0) = vtophys(lcp->lc_sgmap) >> 1;
+
+ /* Set up PCI mask register 1; map 8MB space. */
+ REGVAL(LCA_IOC_W_MASK0) = 0x00700000;
+
+ /* Enable window 1; from PCI address 8MB, direct mapped. */
+ REGVAL(LCA_IOC_W_BASE0) = 0x300800000;
+ wbflush();
+}
+#endif
+
+void
+lcaattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct confargs *ca = aux;
+ struct lca_softc *sc = (struct lca_softc *)self;
+ struct lca_config *lcp;
+ struct pci_attach_args pa;
+
+ /* note that we've attached the chipset; can't have 2 LCAs. */
+ /* Um, not sure about this. XXX JH */
+ lcafound = 1;
+
+ /*
+ * set up the chipset's info; done once at console init time
+ * (maybe), but doesn't hurt to do twice.
+ */
+ lcp = sc->sc_lcp = &lca_configuration;
+ lca_init(lcp);
+#ifdef notdef
+ lca_init_sgmap(lcp);
+#endif
+
+ /* XXX print chipset information */
+ printf("\n");
+
+ switch (hwrpb->rpb_type) {
+#if defined(DEC_AXPPCI_33)
+ case ST_DEC_AXPPCI_33:
+ pci_axppci_33_pickintr(lcp->lc_conffns, lcp->lc_confarg,
+ lcp->lc_piofns, lcp->lc_pioarg,
+ &lcp->lc_intrfns, &lcp->lc_intrarg);
+ break;
+#endif
+ default:
+ panic("lcaattach: shouldn't be here, really...");
+ }
+
+ pa.pa_bus = 0;
+ pa.pa_maxdev = 13;
+ pa.pa_burstlog2 = 8;
+
+ pa.pa_conffns = lcp->lc_conffns;
+ pa.pa_confarg = lcp->lc_confarg;
+ pa.pa_dmafns = lcp->lc_dmafns;
+ pa.pa_dmaarg = lcp->lc_dmaarg;
+ pa.pa_intrfns = lcp->lc_intrfns;
+ pa.pa_intrarg = lcp->lc_intrarg;
+ pa.pa_memfns = lcp->lc_memfns;
+ pa.pa_memarg = lcp->lc_memarg;
+ pa.pa_piofns = lcp->lc_piofns;
+ pa.pa_pioarg = lcp->lc_pioarg;
+
+ config_found(self, &pa, lcaprint);
+}
+
+static int
+lcaprint(aux, pnp)
+ void *aux;
+ char *pnp;
+{
+ register struct pci_attach_args *pa = aux;
+
+ /* what does this do? XXX JH */
+ /* only PCIs can attach to LCAes; easy. */
+ if (pnp)
+ printf("pci at %s", pnp);
+ printf(" bus %d", pa->pa_bus);
+ return (UNCONF);
+}
diff --git a/sys/arch/alpha/pci/lca_isa.c b/sys/arch/alpha/pci/lca_isa.c
new file mode 100644
index 00000000000..205d8708663
--- /dev/null
+++ b/sys/arch/alpha/pci/lca_isa.c
@@ -0,0 +1,346 @@
+/* $NetBSD: lca_isa.c,v 1.1 1995/11/23 02:37:40 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Jeffrey Hsu
+ *
+ * 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/malloc.h>
+#include <sys/syslog.h>
+#include <sys/device.h>
+#include <vm/vm.h>
+
+#include <dev/isa/isavar.h>
+
+#include <alpha/pci/lcareg.h>
+#include <alpha/pci/lcavar.h>
+
+/*
+ * Allocation/deallocation functions.
+ */
+int lca_pio_alloc __P((void *, isa_iooffset_t, isa_iosize_t));
+int lca_pio_dealloc __P((void *, isa_iooffset_t, isa_iosize_t));
+
+/*
+ * Byte functions.
+ */
+isa_byte_t lca_inb __P((void *, isa_iooffset_t));
+#define lca_insb 0 /* XXX */
+void lca_outb __P((void *, isa_iooffset_t, isa_byte_t));
+#define lca_outsb 0 /* XXX */
+
+/*
+ * Word functions.
+ */
+isa_word_t lca_inw __P((void *, isa_iooffset_t));
+#define lca_insw 0 /* XXX */
+void lca_outw __P((void *, isa_iooffset_t, isa_word_t));
+#define lca_outsw 0 /* XXX */
+
+/*
+ * Longword functions.
+ */
+isa_long_t lca_inl __P((void *, isa_iooffset_t));
+#define lca_insl 0 /* XXX */
+void lca_outl __P((void *, isa_iooffset_t, isa_long_t));
+#define lca_outsl 0 /* XXX */
+
+__const struct pci_pio_fns lca_pio_fns = {
+ /* Allocation/deallocation functions. */
+ lca_pio_alloc, lca_pio_dealloc,
+
+ /* Byte functions. */
+ lca_inb, lca_insb,
+ lca_outb, lca_outsb,
+
+ /* Word functions. */
+ lca_inw, lca_insw,
+ lca_outw, lca_outsw,
+
+ /* Longword functions. */
+ lca_inl, lca_insl,
+ lca_outl, lca_outsl,
+};
+
+int
+lca_pio_alloc(ipfarg, start, size)
+ void *ipfarg;
+ isa_iooffset_t start;
+ isa_iosize_t size;
+{
+
+ /* XXX should do something */
+}
+
+int
+lca_pio_dealloc(ipfarg, start, size)
+ void *ipfarg;
+ isa_iooffset_t start;
+ isa_iosize_t size;
+{
+
+ /* XXX should do something */
+}
+
+isa_byte_t
+lca_inb(ipfa, ioaddr)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+{
+ u_int32_t *port, val;
+ isa_byte_t rval;
+ int offset;
+
+ wbflush();
+ offset = ioaddr & 3;
+ port = (int32_t *)phystok0seg(LCA_PCI_SIO | 0 << 3 | ioaddr << 5);
+ val = *port;
+ rval = ((val) >> (8 * offset)) & 0xff;
+/* rval = val & 0xff; */
+
+ return rval;
+}
+
+void
+lca_outb(ipfa, ioaddr, val)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+ isa_byte_t val;
+{
+ u_int32_t *port, nval;
+ int offset;
+
+ offset = ioaddr & 3;
+ nval = val /*<< (8 * offset)*/;
+ nval = val << (8 * offset);
+ port = (int32_t *)phystok0seg(LCA_PCI_SIO | 0 << 3 | ioaddr << 5);
+
+ *port = nval;
+ wbflush();
+}
+
+isa_word_t
+lca_inw(ipfa, ioaddr)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+{
+ u_int32_t *port, val;
+ isa_word_t rval;
+ int offset;
+
+ wbflush();
+ offset = ioaddr & 3;
+ port = (int32_t *)phystok0seg(LCA_PCI_SIO | 1 << 3 | ioaddr << 5);
+ val = *port;
+ rval = ((val) >> (8 * offset)) & 0xffff;
+ rval = val & 0xffff;
+
+panic("inw(0x%x) => 0x%x @ %p => 0x%x\n", ioaddr, val, port, rval);
+
+ return rval;
+}
+
+void
+lca_outw(ipfa, ioaddr, val)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+ isa_word_t val;
+{
+ u_int32_t *port, nval;
+ int offset;
+
+ offset = ioaddr & 3;
+ nval = val /*<< (8 * offset)*/;
+ port = (int32_t *)phystok0seg(LCA_PCI_SIO | 1 << 3 | ioaddr << 5);
+
+ *port = nval;
+ wbflush();
+}
+
+isa_long_t
+lca_inl(ipfa, ioaddr)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+{
+ u_int32_t *port, val;
+ isa_long_t rval;
+ int offset;
+
+ wbflush();
+ offset = ioaddr & 3;
+ port = (int32_t *)phystok0seg(LCA_PCI_SIO | 3 << 3 | ioaddr << 5);
+ val = *port;
+ rval = ((val) >> (8 * offset)) & 0xffffffff;
+ rval = val & 0xffffffff;
+
+ return rval;
+}
+
+void
+lca_outl(ipfa, ioaddr, val)
+ void *ipfa;
+ isa_iooffset_t ioaddr;
+ isa_long_t val;
+{
+ u_int32_t *port, nval;
+ int offset;
+
+ offset = ioaddr & 3;
+ nval = val /*<< (8 * offset)*/;
+ port = (int32_t *)phystok0seg(LCA_PCI_SIO | 3 << 3 | ioaddr << 5);
+
+ *port = nval;
+ wbflush();
+}
+
+/* XXX XXX XXX */
+
+#define pf(fn, args) fn args { panic(__STRING(fn)); }
+
+void pf(lca_dma_cascade, (void *idfa, isa_drq_t chan))
+void pf(lca_dma_copytobuf, ())
+void pf(lca_dma_copyfrombuf, ())
+void pf(lca_dma_start, (void *idfa, vm_offset_t addr,
+ isa_msize_t size, isa_drq_t chan, int flags))
+void pf(lca_dma_abort, (void *idfa, isa_drq_t chan))
+void pf(lca_dma_done, (void *idfa, isa_drq_t chan))
+
+int lca_dma_map __P((void *, vm_offset_t, isa_msize_t,
+ isa_moffset_t *, int));
+void lca_dma_unmap __P((void *, vm_offset_t, isa_msize_t, int,
+ isa_moffset_t *));
+
+__const struct isa_dma_fns lca_dma_fns = {
+ lca_dma_cascade,
+ lca_dma_map,
+ lca_dma_unmap,
+ lca_dma_copytobuf,
+ lca_dma_copyfrombuf,
+ lca_dma_start,
+ lca_dma_abort,
+ lca_dma_done,
+};
+
+int
+lca_dma_map(idfa, va, isasize, mappingsp, flags)
+ void *idfa;
+ vm_offset_t va;
+ isa_msize_t isasize;
+ isa_moffset_t *mappingsp;
+ int flags;
+{
+ struct lca_config *acp = idfa;
+ long todo;
+ int i;
+
+ if (ISA_DMA_NEEDCONTIG(flags) && isasize > NBPG ||
+ ISA_DMA_SIZEBOUND(flags) != ISA_DMA_SIZEBOUND_NONE ||
+ ISA_DMA_ADDRBOUND(flags) != ISA_DMA_ADDRBOUND_NONE)
+ panic("lca_dma_map: punt");
+
+ i = 0;
+ todo = isasize;
+
+ while (todo > 0) {
+ mappingsp[i] = vtophys(va) | 0x40000000;
+#if 0
+ printf("a_pd_m mapping %d: %lx -> %lx -> %lx\n", i, va,
+ vtophys(va), mappingsp[i]);
+#endif
+ i++;
+ todo -= PAGE_SIZE - (va - trunc_page(va));
+ va += PAGE_SIZE - (va - trunc_page(va));
+ }
+ return (i);
+}
+
+void
+lca_dma_unmap(idfa, va, isasize, nmappings, mappingsp)
+ void *idfa;
+ vm_offset_t va;
+ isa_msize_t isasize;
+ int nmappings;
+ isa_moffset_t *mappingsp;
+{
+
+ printf("lca_dma_unmap: called\n");
+}
+
+vm_offset_t lca_mem_map __P((void *, isa_moffset_t, isa_msize_t, int));
+void lca_mem_unmap __P((void *, vm_offset_t, isa_msize_t));
+
+#if 0
+void lca_mem_copytoisa __P((void *, char *, vm_offset_t,
+ isa_moffset_t, isa_msize_t));
+void lca_mem_copyfromisa __P((void *, char *, vm_offset_t,
+ isa_moffset_t, isa_msize_t));
+void lca_mem_zero __P((void *, vm_offset_t, isa_moffset_t,
+ isa_msize_t));
+#else
+void pf(lca_mem_copytoisa, ())
+void pf(lca_mem_copyfromisa, ())
+void pf(lca_mem_zero, ())
+#endif
+
+__const struct isa_mem_fns lca_mem_fns = {
+ lca_mem_map,
+ lca_mem_unmap,
+ lca_mem_copytoisa,
+ lca_mem_copyfromisa,
+ lca_mem_zero,
+};
+
+vm_offset_t
+lca_mem_map(imfa, isapa, isasize, cacheable)
+ void *imfa;
+ isa_moffset_t isapa;
+ isa_msize_t isasize;
+ int cacheable;
+{
+ vm_offset_t sbpa;
+
+ /* XXX sanity checks on sizes, use of windows, etc. */
+
+ /* XXX MAGIC NUMBERS */
+ if (cacheable)
+ sbpa = (isapa & 0xffffffff) | LCA_PCI_DENSE;
+ else
+ sbpa = ((isapa & 0x7ffffff) << 5) | LCA_PCI_SPARSE;
+
+ return phystok0seg(sbpa);
+}
+
+void
+lca_mem_unmap(imfa, va, isasize)
+ void *imfa;
+ vm_offset_t va;
+ isa_msize_t isasize;
+{
+
+ /* XXX sanity checks on va */
+
+ /* Nothing to do; mapping was done in direct-mapped segment. */
+}
diff --git a/sys/arch/alpha/pci/lca_pci.c b/sys/arch/alpha/pci/lca_pci.c
new file mode 100644
index 00000000000..1b151dcefb9
--- /dev/null
+++ b/sys/arch/alpha/pci/lca_pci.c
@@ -0,0 +1,226 @@
+/* $NetBSD: lca_pci.c,v 1.1 1995/11/23 02:37:42 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Jeffrey Hsu
+ *
+ * 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/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <vm/vm.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <alpha/pci/lcareg.h>
+#include <alpha/pci/lcavar.h>
+
+pci_confreg_t lca_conf_read __P((void *, pci_conftag_t, pci_confoffset_t));
+void lca_conf_write __P((void *, pci_conftag_t,
+ pci_confoffset_t, pci_confreg_t));
+int lca_find_io __P((void *, pci_conftag_t,
+ pci_confoffset_t, pci_iooffset_t *, pci_iosize_t *));
+int lca_find_mem __P((void *, pci_conftag_t,
+ pci_confoffset_t, pci_moffset_t *, pci_msize_t *, int *));
+
+__const struct pci_conf_fns lca_conf_fns = {
+ lca_conf_read,
+ lca_conf_write,
+ lca_find_io,
+ lca_find_mem,
+};
+
+pci_confreg_t
+lca_conf_read(cpv, tag, offset)
+ void *cpv;
+ pci_conftag_t tag;
+ pci_confoffset_t offset;
+{
+ pci_confreg_t *datap, data;
+ int s, secondary, ba;
+ int32_t old_ioc_conf; /* XXX */
+ u_int64_t dev_sel;
+
+ dev_sel = 1 << PCI_TAG_DEVICE(tag) + 11;
+
+ secondary = PCI_TAG_BUS(tag) != 0;
+ if (secondary) {
+ s = splhigh();
+ old_ioc_conf = REGVAL(LCA_IOC_CONF);
+ wbflush();
+ REGVAL(LCA_IOC_CONF) = old_ioc_conf | 0x1;
+ wbflush();
+ }
+
+ datap = (pci_confreg_t *)phystok0seg(LCA_PCI_CONF |
+ dev_sel << 5UL | /* XXX */
+ (offset & ~0x03) << 5 | /* XXX */
+ 0 << 5 | /* XXX */
+ 0x3 << 3); /* XXX */
+ data = (pci_confreg_t)-1;
+ if (!(ba = badaddr(datap, sizeof *datap)))
+ data = *datap;
+
+ if (secondary) {
+ wbflush();
+ REGVAL(LCA_IOC_CONF) = old_ioc_conf;
+ wbflush();
+ splx(s);
+ }
+
+#if 0
+ printf("lca_conf_read: tag 0x%x, offset 0x%x -> %x @ %p%s\n", tag,
+ offset, data, datap, ba ? " (badaddr)" : "");
+#endif
+
+ return data;
+}
+
+void
+lca_conf_write(cpv, tag, offset, data)
+ void *cpv;
+ pci_conftag_t tag;
+ pci_confoffset_t offset;
+ pci_confreg_t data;
+{
+ pci_confreg_t *datap;
+ int s, secondary;
+ int32_t old_ioc_conf; /* XXX */
+ int32_t dev_sel;
+
+ dev_sel = 1 << PCI_TAG_DEVICE(tag) + 11;
+
+ secondary = PCI_TAG_BUS(tag) != 0;
+ if (secondary) {
+ s = splhigh();
+ old_ioc_conf = REGVAL(LCA_IOC_CONF);
+ wbflush();
+ REGVAL(LCA_IOC_CONF) = old_ioc_conf | 0x1;
+ wbflush();
+ }
+
+ datap = (pci_confreg_t *)phystok0seg(LCA_PCI_CONF |
+ dev_sel << 5UL | /* XXX */
+ (offset & ~0x03) << 5 | /* XXX */
+ 0 << 5 | /* XXX */
+ 0x3 << 3); /* XXX */
+ *datap = data;
+
+ if (secondary) {
+ wbflush();
+ REGVAL(LCA_IOC_CONF) = old_ioc_conf;
+ wbflush();
+ splx(s);
+ }
+
+#if 0
+ printf("lca_conf_write: tag 0x%x, offset 0x%x -> 0x%x @ %p\n", tag,
+ offset, data, datap);
+#endif
+}
+
+int
+lca_find_io(cpv, tag, reg, iobasep, sizep)
+ void *cpv;
+ pci_conftag_t tag;
+ pci_confoffset_t reg;
+ pci_iooffset_t *iobasep;
+ pci_iosize_t *sizep;
+{
+ struct lca_config *lcp = cpv;
+ pci_confreg_t addrdata, sizedata;
+ pci_iooffset_t pci_iobase;
+
+ if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3))
+ panic("lca_map_io: bad request");
+
+ addrdata = PCI_CONF_READ(lcp->lc_conffns, lcp->lc_confarg, tag, reg);
+
+ PCI_CONF_WRITE(lcp->lc_conffns, lcp->lc_confarg, tag, reg, 0xffffffff);
+ sizedata = PCI_CONF_READ(lcp->lc_conffns, lcp->lc_confarg, tag, reg);
+ PCI_CONF_WRITE(lcp->lc_conffns, lcp->lc_confarg, tag, reg, addrdata);
+
+ if (PCI_MAPREG_TYPE(addrdata) == PCI_MAPREG_TYPE_MEM)
+ panic("lca_map_io: attempt to I/O map an memory region");
+
+ if (iobasep != NULL)
+ *iobasep = PCI_MAPREG_IO_ADDRESS(addrdata);
+ if (sizep != NULL)
+ *sizep = ~PCI_MAPREG_IO_ADDRESS(sizedata) + 1;
+
+ return (0);
+}
+
+int
+lca_find_mem(cpv, tag, reg, paddrp, sizep, cacheablep)
+ void *cpv;
+ pci_conftag_t tag;
+ pci_confoffset_t reg;
+ pci_moffset_t *paddrp;
+ pci_msize_t *sizep;
+ int *cacheablep;
+{
+ struct lca_config *lcp = cpv;
+ pci_confreg_t addrdata, sizedata;
+
+ if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3))
+ panic("lca_map_mem: bad request");
+
+ /*
+ * The PROM has mapped the device for us. We take the address
+ * that's been assigned to the register, and figure out what
+ * physical and virtual addresses go with it...
+ */
+ addrdata = PCI_CONF_READ(lcp->lc_conffns, lcp->lc_confarg, tag, reg);
+
+ PCI_CONF_WRITE(lcp->lc_conffns, lcp->lc_confarg, tag, reg, 0xffffffff);
+ sizedata = PCI_CONF_READ(lcp->lc_conffns, lcp->lc_confarg, tag, reg);
+ PCI_CONF_WRITE(lcp->lc_conffns, lcp->lc_confarg, tag, reg, addrdata);
+
+ if (PCI_MAPREG_TYPE(addrdata) == PCI_MAPREG_TYPE_IO)
+ panic("lca_map_mem: attempt to memory map an I/O region");
+
+ switch (PCI_MAPREG_MEM_TYPE(addrdata)) {
+ case PCI_MAPREG_MEM_TYPE_32BIT:
+ case PCI_MAPREG_MEM_TYPE_32BIT_1M:
+ break;
+ case PCI_MAPREG_MEM_TYPE_64BIT:
+/* XXX */ printf("lca_map_mem: attempt to map 64-bit region\n");
+/* XXX */ break;
+ default:
+ printf("lca_map_mem: reserved mapping type\n");
+ return EINVAL;
+ }
+
+ if (paddrp != NULL)
+ *paddrp = PCI_MAPREG_MEM_ADDRESS(addrdata); /* PCI addr */
+ if (sizep != NULL)
+ *sizep = ~PCI_MAPREG_MEM_ADDRESS(sizedata) + 1;
+ if (cacheablep != NULL)
+ *cacheablep = PCI_MAPREG_MEM_CACHEABLE(addrdata);
+
+ return 0;
+}
diff --git a/sys/arch/alpha/pci/lcareg.h b/sys/arch/alpha/pci/lcareg.h
new file mode 100644
index 00000000000..ac876e3110d
--- /dev/null
+++ b/sys/arch/alpha/pci/lcareg.h
@@ -0,0 +1,55 @@
+/* $NetBSD: lcareg.h,v 1.1 1995/11/23 02:37:44 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Jeffrey Hsu
+ *
+ * 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.
+ */
+
+/*
+ * 21066 chip registers
+ */
+
+#define REGVAL(r) (*(int32_t *)phystok0seg(r))
+
+/*
+ * Base addresses
+ */
+#define LCA_IOC_BASE 0x180000000L /* LCA IOC Regs */
+#define LCA_PCI_SIO 0x1c0000000L /* PCI Sp. I/O Space */
+#define LCA_PCI_CONF 0x1e0000000L /* PCI Conf. Space */
+#define LCA_PCI_SPARSE 0x200000000L /* PCI Sparse Space */
+#define LCA_PCI_DENSE 0x300000000L /* PCI Dense Space */
+
+#define LCA_IOC_HAE LCA_IOC_BASE /* Host Address Extension */
+
+#define LCA_IOC_CONF (LCA_IOC_BASE + 0x020) /* Configuration Cycle Type */
+
+#define LCA_IOC_W_BASE0 (LCA_IOC_BASE + 0x100) /* Window Base */
+#define LCA_IOC_W_MASK0 (LCA_IOC_BASE + 0x140) /* Window Mask */
+#define LCA_IOC_W_T_BASE0 (LCA_IOC_BASE + 0x180) /* Translated Base */
+
+#define LCA_IOC_W_BASE1 (LCA_IOC_BASE + 0x120) /* Window Base */
+#define LCA_IOC_W_MASK1 (LCA_IOC_BASE + 0x160) /* Window Mask */
+#define LCA_IOC_W_T_BASE1 (LCA_IOC_BASE + 0x1a0) /* Translated Base */
diff --git a/sys/arch/alpha/pci/lcavar.h b/sys/arch/alpha/pci/lcavar.h
new file mode 100644
index 00000000000..80c70807172
--- /dev/null
+++ b/sys/arch/alpha/pci/lcavar.h
@@ -0,0 +1,68 @@
+/* $NetBSD: lcavar.h,v 1.1 1995/11/23 02:37:47 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Jeffrey Hsu
+ *
+ * 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 <dev/isa/isavar.h>
+#include <dev/pci/pcivar.h>
+
+/*
+ * LCA chipset's configuration.
+ *
+ * All of the information that the chipset-specific functions need to
+ * do their dirty work (and more!).
+ */
+struct lca_config {
+ __const struct pci_conf_fns *lc_conffns;
+ void *lc_confarg;
+
+ __const struct pci_dma_fns *lc_dmafns;
+ void *lc_dmaarg;
+
+ __const struct pci_intr_fns *lc_intrfns;
+ void *lc_intrarg;
+
+ __const struct pci_mem_fns *lc_memfns;
+ void *lc_memarg;
+
+ __const struct pci_pio_fns *lc_piofns;
+ void *lc_pioarg;
+};
+
+struct lca_softc {
+ struct device sc_dev;
+
+ struct lca_config *sc_lcp;
+};
+
+extern __const struct pci_conf_fns lca_conf_fns;
+extern __const struct pci_dma_fns lca_dma_fns;
+/* pci interrupt functions handled elsewhere */
+extern __const struct pci_mem_fns lca_mem_fns;
+extern __const struct pci_pio_fns lca_pio_fns;
+
+void lca_init __P((struct lca_config *));
diff --git a/sys/arch/alpha/pci/pci_2100_a50.c b/sys/arch/alpha/pci/pci_2100_a50.c
index 9390f581e54..c33a9a83b0e 100644
--- a/sys/arch/alpha/pci/pci_2100_a50.c
+++ b/sys/arch/alpha/pci/pci_2100_a50.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_2100_a50.c,v 1.2 1995/08/03 01:17:10 cgd Exp $ */
+/* $NetBSD: pci_2100_a50.c,v 1.3 1995/11/23 02:37:49 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -33,68 +33,54 @@
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/device.h>
-
#include <vm/vm.h>
#include <dev/isa/isavar.h>
-#include <alpha/isa/isa_intr.h>
-
-#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
-#include <alpha/pci/pci_chipset.h>
+#include <dev/pci/pcivar.h>
-void pci_2100_a50_attach __P((struct device *, struct device *, void *));
-void *pci_2100_a50_map_int __P((pcitag_t, pci_intrlevel, int (*) (void *),
- void *, int));
+#include <alpha/pci/apecsvar.h>
-struct pci_cfg_fcns pci_2100_a50_sio1_cfg_fcns = { /* XXX diff? */
- pci_2100_a50_attach, pci_2100_a50_map_int,
-};
+#include <alpha/pci/pci_2100_a50.h>
+#include <alpha/pci/siovar.h>
-struct pci_cfg_fcns pci_2100_a50_sio2_cfg_fcns = {
- pci_2100_a50_attach, pci_2100_a50_map_int,
-};
+#include "sio.h"
-void
-pci_2100_a50_attach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-{
- int bus, device;
+void *dec_2100_a50_pci_map_int __P((void *, pci_conftag_t,
+ pci_intr_pin_t, pci_intr_line_t, pci_intrlevel_t,
+ int (*func)(void *), void *));
+void dec_2100_a50_pci_unmap_int __P((void *, void *));
-#if 0
- for (bus = 0; bus <= 255; bus++)
-#else
- /*
- * XXX
- * Some current chipsets do wacky things with bus numbers > 0.
- * This seems like a violation of protocol, but the PCI BIOS does
- * allow one to query the maximum bus number, and eventually we
- * should do so.
- */
- for (bus = 0; bus <= 0; bus++)
-#endif
- for (device = 0; device <= 31; device++)
- pci_attach_subdev(self, bus, device);
-}
+__const struct pci_intr_fns dec_2100_a50_pci_intr_fns = {
+ dec_2100_a50_pci_map_int,
+ dec_2100_a50_pci_unmap_int,
+};
void *
-pci_2100_a50_map_int(tag, level, func, arg, pin)
- pcitag_t tag;
- pci_intrlevel level;
+dec_2100_a50_pci_map_int(acv, tag, pin, line, level, func, arg)
+ void *acv;
+ pci_conftag_t tag;
+ pci_intr_pin_t pin;
+ pci_intr_line_t line;
+ pci_intrlevel_t level;
int (*func) __P((void *));
void *arg;
- int pin;
{
+ struct apecs_config *acp = acv;
int bus, device, pirq;
- pcireg_t pirqreg;
- u_int8_t line;
+ pci_confreg_t irreg, pirqreg;
+ u_int8_t pirqline;
- bus = (tag >> 21) & 0xff; /* XXX */
- device = (tag >> 16) & 0x1f;
+ if (pin == 0) {
+ /* No IRQ used. */
+ return 0;
+ }
+ if (pin > 4) {
+ printf("pci_map_int: bad interrupt pin %d\n", pin);
+ return NULL;
+ }
- if (bus != 0) /* XXX */
- return NULL;
+ device = PCI_TAG_DEVICE(tag);
switch (device) {
case 6: /* NCR SCSI */
@@ -147,43 +133,65 @@ pci_2100_a50_map_int(tag, level, func, arg, pin)
break;
}
- pirqreg = pci_conf_read(pci_make_tag(0, 7, 0), 0x60); /* XXX */
+ pirqreg = PCI_CONF_READ(acp->ac_conffns, acp->ac_confarg,
+ PCI_MAKE_TAG(0, 7, 0), 0x60); /* XXX */
#if 0
printf("pci_2100_a50_map_int: device %d pin %c: pirq %d, reg = %x\n",
device, '@' + pin, pirq, pirqreg);
#endif
- line = (pirqreg >> (pirq * 8)) & 0xff;
- if ((line & 0x80) != 0)
+ pirqline = (pirqreg >> (pirq * 8)) & 0xff;
+ if ((pirqline & 0x80) != 0)
return 0; /* not routed? */
- line &= 0xf;
+ pirqline &= 0xf;
#if 0
printf("pci_2100_a50_map_int: device %d pin %c: mapped to line %d\n",
- device, '@' + pin, line);
+ device, '@' + pin, pirqline);
#endif
- return isa_intr_establish(line, ISA_IST_LEVEL, pcilevel_to_isa(level),
+#if NSIO
+ return ISA_INTR_ESTABLISH(&sio_isa_intr_fns, NULL, /* XXX */
+ pirqline, ISA_IST_LEVEL, pci_intrlevel_to_isa(level),
func, arg);
+#else
+ panic("dec_2100_a50_pci_map_int: no sio!");
+#endif
+}
+
+void
+dec_2100_a50_pci_unmap_int(pifa, cookie)
+ void *pifa;
+ void *cookie;
+{
+
+ panic("dec_2100_a50_pci_unmap_int not implemented"); /* XXX */
}
void
-pci_2100_a50_pickintr()
+pci_2100_a50_pickintr(pcf, pcfa, ppf, ppfa, pifp, pifap)
+ __const struct pci_conf_fns *pcf;
+ __const struct pci_pio_fns *ppf;
+ void *pcfa, *ppfa;
+ __const struct pci_intr_fns **pifp;
+ void **pifap;
{
- pcireg_t sioclass;
+ pci_confreg_t sioclass;
int sioII;
/* XXX MAGIC NUMBER */
- sioclass = pci_conf_read(pci_make_tag(0, 7, 0), PCI_CLASS_REG);
+ sioclass = PCI_CONF_READ(pcf, pcfa, PCI_MAKE_TAG(0, 7, 0),
+ PCI_CLASS_REG);
sioII = (sioclass & 0xff) >= 3;
- if (!sioII)
- printf("WARNING: SIO NOT SIO II... NO BETS...\n");
if (!sioII)
- pci_cfg_fcns = &pci_2100_a50_sio1_cfg_fcns;
- else
- pci_cfg_fcns = &pci_2100_a50_sio2_cfg_fcns;
+ printf("WARNING: SIO NOT SIO II... NO BETS...\n");
- isa_intr_fcns = &sio_intr_fcns;
- (*isa_intr_fcns->isa_intr_setup)();
- set_iointr(isa_intr_fcns->isa_iointr);
+ *pifp = &dec_2100_a50_pci_intr_fns;
+ *pifap = pcfa; /* XXX assumes apecs_config ptr */
+#if NSIO
+ sio_intr_setup(ppf, ppfa);
+ set_iointr(&sio_iointr);
+#else
+ panic("pci_2100_a50_pickintr: no I/O interrupt handler (no sio)");
+#endif
}
diff --git a/sys/arch/alpha/pci/pci_2100_a50.h b/sys/arch/alpha/pci/pci_2100_a50.h
new file mode 100644
index 00000000000..08c22aef089
--- /dev/null
+++ b/sys/arch/alpha/pci/pci_2100_a50.h
@@ -0,0 +1,32 @@
+/* $NetBSD: pci_2100_a50.h,v 1.1 1995/11/23 02:37:51 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+void pci_2100_a50_pickintr __P((__const struct pci_conf_fns *, void *,
+ __const struct pci_pio_fns *, void *,
+ __const struct pci_intr_fns **, void **));
diff --git a/sys/arch/alpha/pci/pci_axppci_33.c b/sys/arch/alpha/pci/pci_axppci_33.c
new file mode 100644
index 00000000000..74fb338e91f
--- /dev/null
+++ b/sys/arch/alpha/pci/pci_axppci_33.c
@@ -0,0 +1,204 @@
+/* $NetBSD: pci_axppci_33.c,v 1.1 1995/11/23 02:37:54 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Jeffrey Hsu
+ *
+ * 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/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/device.h>
+#include <vm/vm.h>
+
+#include <dev/isa/isavar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <alpha/pci/lcavar.h>
+
+#include <alpha/pci/pci_axppci_33.h>
+
+#include <alpha/pci/siovar.h>
+
+#include "sio.h"
+
+void *dec_axppci_33_pci_map_int __P((void *, pci_conftag_t,
+ pci_intr_pin_t, pci_intr_line_t, pci_intrlevel_t,
+ int (*func)(void *), void *));
+void dec_axppci_33_pci_unmap_int __P((void *, void *));
+
+__const struct pci_intr_fns dec_axppci_33_pci_intr_fns = {
+ dec_axppci_33_pci_map_int,
+ dec_axppci_33_pci_unmap_int,
+};
+
+void *
+dec_axppci_33_pci_map_int(lcv, tag, pin, line, level, func, arg)
+ void *lcv;
+ pci_conftag_t tag;
+ pci_intr_pin_t pin;
+ pci_intr_line_t line;
+ pci_intrlevel_t level;
+ int (*func) __P((void *));
+ void *arg;
+{
+ struct lca_config *lcp = lcv;
+ int bus, device, pirq;
+ pci_confreg_t irreg, pirqreg;
+ u_int8_t pirqline;
+
+ if (pin == 0) {
+ /* No IRQ used. */
+ return 0;
+ }
+ if (pin > 4) {
+ printf("dec_axppci_33_map_int: bad interrupt pin %d\n", pin);
+ return NULL;
+ }
+
+ device = PCI_TAG_DEVICE(tag);
+
+ switch (device) {
+ case 6: /* NCR SCSI */
+ pirq = 3;
+ break;
+
+ case 11: /* slot 1 */
+ switch (pin) {
+ case PCI_INTERRUPT_PIN_A:
+ case PCI_INTERRUPT_PIN_D:
+ pirq = 0;
+ break;
+ case PCI_INTERRUPT_PIN_B:
+ pirq = 2;
+ break;
+ case PCI_INTERRUPT_PIN_C:
+ pirq = 1;
+ break;
+ };
+ break;
+
+ case 12: /* slot 2 */
+ switch (pin) {
+ case PCI_INTERRUPT_PIN_A:
+ case PCI_INTERRUPT_PIN_D:
+ pirq = 1;
+ break;
+ case PCI_INTERRUPT_PIN_B:
+ pirq = 0;
+ break;
+ case PCI_INTERRUPT_PIN_C:
+ pirq = 2;
+ break;
+ };
+ break;
+
+ case 8: /* slot 3 */
+ switch (pin) {
+ case PCI_INTERRUPT_PIN_A:
+ case PCI_INTERRUPT_PIN_D:
+ pirq = 2;
+ break;
+ case PCI_INTERRUPT_PIN_B:
+ pirq = 1;
+ break;
+ case PCI_INTERRUPT_PIN_C:
+ pirq = 0;
+ break;
+ };
+ break;
+ default:
+ printf("dec_axppci_33_pci_map_int: unknown device %d\n",
+ device);
+ panic("dec_axppci_33_pci_map_int: bad device number");
+ }
+
+#define LCA_SIO_DEVICE 7 /* XXX */
+
+ pirqreg = PCI_CONF_READ(lcp->lc_conffns, lcp->lc_confarg,
+ PCI_MAKE_TAG(0, LCA_SIO_DEVICE, 0), 0x60); /* XXX */
+#if 0
+ printf("dec_pci_axppci_33_map_int: device %d pin %c: pirq %d, reg = %x\n",
+ device, '@' + pin, pirq, pirqreg);
+#endif
+ pirqline = (pirqreg >> (pirq * 8)) & 0xff;
+ if ((pirqline & 0x80) != 0)
+ return 0; /* not routed? */
+ pirqline &= 0xf;
+
+#if 0
+ printf("dec_pci_axppci_33_map_int: device %d pin %c: mapped to line %d\n",
+ device, '@' + pin, pirqline);
+#endif
+
+#if NSIO
+ return ISA_INTR_ESTABLISH(&sio_isa_intr_fns, NULL, /* XXX */
+ pirqline, ISA_IST_LEVEL, pci_intrlevel_to_isa(level),
+ func, arg);
+#else
+ panic("dec_axppci_33_pci_map_int: no sio!");
+#endif
+}
+
+void
+dec_axppci_33_pci_unmap_int(pifa, cookie)
+ void *pifa;
+ void *cookie;
+{
+
+ panic("dec_axppci_33_pci_unmap_int not implemented"); /* XXX */
+}
+
+void
+pci_axppci_33_pickintr(pcf, pcfa, ppf, ppfa, pifp, pifap)
+ __const struct pci_conf_fns *pcf;
+ __const struct pci_pio_fns *ppf;
+ void *pcfa, *ppfa;
+ __const struct pci_intr_fns **pifp;
+ void **pifap;
+{
+ pci_confreg_t sioclass;
+ int sioII;
+
+ /* XXX MAGIC NUMBER */
+ sioclass = PCI_CONF_READ(pcf, pcfa, PCI_MAKE_TAG(0, LCA_SIO_DEVICE, 0),
+ PCI_CLASS_REG);
+ sioII = (sioclass & 0xff) >= 3;
+
+ if (!sioII)
+ printf("WARNING: SIO NOT SIO II... NO BETS...\n");
+
+ *pifp = &dec_axppci_33_pci_intr_fns;
+ *pifap = pcfa; /* XXX assumes apecs_config ptr */
+#if NSIO
+ sio_intr_setup(ppf, ppfa);
+ set_iointr(&sio_iointr);
+#else
+ panic("pci_axppci_33_pickintr: no I/O interrupt handler (no sio)");
+#endif
+}
diff --git a/sys/arch/alpha/pci/pci_axppci_33.h b/sys/arch/alpha/pci/pci_axppci_33.h
new file mode 100644
index 00000000000..342eb0dfd71
--- /dev/null
+++ b/sys/arch/alpha/pci/pci_axppci_33.h
@@ -0,0 +1,32 @@
+/* $NetBSD: pci_axppci_33.h,v 1.1 1995/11/23 02:37:56 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Jeffrey Hsu
+ *
+ * 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.
+ */
+
+void pci_axppci_33_pickintr __P((__const struct pci_conf_fns *, void *,
+ __const struct pci_pio_fns *, void *,
+ __const struct pci_intr_fns **, void **));
diff --git a/sys/arch/alpha/pci/pci_chipset.h b/sys/arch/alpha/pci/pci_chipset.h
deleted file mode 100644
index 4d333aee27e..00000000000
--- a/sys/arch/alpha/pci/pci_chipset.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* $NetBSD: pci_chipset.h,v 1.3 1995/08/03 01:17:14 cgd Exp $ */
-
-/*
- * Copyright (c) 1995 Carnegie-Mellon University.
- * All rights reserved.
- *
- * Author: Chris G. Demetriou
- *
- * Permission to use, copy, modify and distribute this software and
- * its documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-/*
- * Function switch to implement the various PCI bus interfaces.
- * XXX this probably needs some work...
- */
-
-struct pci_cs_fcns {
- void (*cs_setup) __P((void));
- pcitag_t (*cs_make_tag) __P((int, int, int));
- pcireg_t (*cs_conf_read) __P((pcitag_t, int));
- void (*cs_conf_write) __P((pcitag_t, int, pcireg_t));
- int (*cs_map_io) __P((pcitag_t, int, int *));
- int (*cs_map_mem) __P((pcitag_t, int, vm_offset_t *,
- vm_offset_t *));
- int (*cs_pcidma_map) __P((caddr_t, vm_size_t,
- vm_offset_t *));
- void (*cs_pcidma_unmap) __P((caddr_t, vm_size_t, int,
- vm_offset_t *));
-};
-
-struct pci_cs_fcns *pci_cs_fcns;
-extern struct pci_cs_fcns apecs_p1e_cs_fcns;
-extern struct pci_cs_fcns apecs_p2e_cs_fcns;
-extern struct pci_cs_fcns lca_cs_fcns;
-
-
-/*
- * Function switch to implement the various PCI configuration schemes.
- * XXX this probably needs some work...
- */
-
-struct pci_cfg_fcns {
- void (*cfg_attach) __P((struct device *, struct
- device *, void *));
- void *(*cfg_map_int) __P((pcitag_t, pci_intrlevel,
- int (*) (void *), void *, int));
-};
-
-struct pci_cfg_fcns *pci_cfg_fcns;
-extern struct pci_cfg_fcns pci_2100_a50_sio1_cfg_fcns;
-extern struct pci_cfg_fcns pci_2100_a50_sio2_cfg_fcns;
-
-/*
- * Miscellaneous functions.
- */
-isa_intrlevel pcilevel_to_isa __P((pci_intrlevel));
diff --git a/sys/arch/alpha/pci/pci_kn20aa.c b/sys/arch/alpha/pci/pci_kn20aa.c
new file mode 100644
index 00000000000..c5c64d636b8
--- /dev/null
+++ b/sys/arch/alpha/pci/pci_kn20aa.c
@@ -0,0 +1,294 @@
+/* $NetBSD: pci_kn20aa.c,v 1.1 1995/11/23 02:38:00 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+#include <sys/syslog.h>
+
+#include <vm/vm.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <alpha/pci/ciareg.h>
+#include <alpha/pci/ciavar.h>
+
+#include <alpha/pci/pci_kn20aa.h>
+
+#ifndef EVCNT_COUNTERS
+#include <machine/intrcnt.h>
+#endif
+
+#include "sio.h"
+#if NSIO
+#include <alpha/pci/siovar.h>
+#endif
+
+void *kn20aa_pci_map_int __P((void *, pci_conftag_t, pci_intr_pin_t,
+ pci_intr_line_t, pci_intrlevel_t, int (*func)(void *), void *));
+void kn20aa_pci_unmap_int __P((void *, void *));
+
+__const struct pci_intr_fns kn20aa_pci_intr_fns = {
+ kn20aa_pci_map_int,
+ kn20aa_pci_unmap_int,
+};
+
+#define KN20AA_PCEB_IRQ 31
+#define KN20AA_MAX_IRQ 32
+#define PCI_STRAY_MAX 5
+
+struct kn20aa_intrhand {
+ TAILQ_ENTRY(kn20aa_intrhand) ih_q;
+ int (*ih_fun)();
+ void *ih_arg;
+ u_long ih_count;
+ int ih_level;
+};
+TAILQ_HEAD(kn20aa_intrchain, kn20aa_intrhand);
+
+struct kn20aa_intrchain kn20aa_pci_intrs[KN20AA_MAX_IRQ];
+int kn20aa_pci_strayintrcnt[KN20AA_MAX_IRQ];
+#ifdef EVCNT_COUNTERS
+struct evcnt kn20aa_intr_evcnt;
+#endif
+
+void kn20aa_pci_strayintr __P((int irq));
+void kn20aa_iointr __P((void *framep, int vec));
+void kn20aa_enable_intr __P((int irq));
+struct kn20aa_intrhand *kn20aa_attach_intr __P((struct kn20aa_intrchain *,
+ pci_intrlevel_t, int (*) (void *), void *));
+
+void
+pci_kn20aa_pickintr(pcf, pcfa, ppf, ppfa, pifp, pifap)
+ __const struct pci_conf_fns *pcf;
+ __const struct pci_pio_fns *ppf;
+ void *pcfa, *ppfa;
+ __const struct pci_intr_fns **pifp;
+ void **pifap;
+{
+ int i;
+ struct kn20aa_intrhand *nintrhand;
+
+
+ for (i = 0; i < KN20AA_MAX_IRQ; i++)
+ TAILQ_INIT(&kn20aa_pci_intrs[i]);
+
+ *pifp = &kn20aa_pci_intr_fns;
+ *pifap = NULL; /* XXX ? */
+
+#if NSIO
+ sio_intr_setup(ppf, ppfa);
+#endif
+
+ set_iointr(kn20aa_iointr);
+
+#if NSIO
+ kn20aa_enable_intr(KN20AA_PCEB_IRQ);
+#if 0 /* XXX init PCEB interrupt handler? */
+ kn20aa_attach_intr(&kn20aa_pci_intrs[KN20AA_PCEB_IRQ], ???, ???, ???);
+#endif
+#endif
+}
+
+void *
+kn20aa_pci_map_int(ccv, tag, pin, line, level, func, arg)
+ void *ccv;
+ pci_conftag_t tag;
+ pci_intr_pin_t pin;
+ pci_intr_line_t line;
+ pci_intrlevel_t level;
+ int (*func) __P((void *));
+ void *arg;
+{
+ int device;
+ int kn20aa_slot, kn20aa_irq;
+ void *ih;
+
+ if (pin == 0) {
+ /* No IRQ used. */
+ return 0;
+ }
+ if (pin > 4) {
+ printf("pci_map_int: bad interrupt pin %d\n", pin);
+ return NULL;
+ }
+
+ /*
+ * Slot->interrupt translation. Appears to work, though it
+ * may not hold up forever.
+ *
+ * The DEC engineers who did this hardware obviously engaged
+ * in random drug testing.
+ */
+ switch (device = PCI_TAG_DEVICE(tag)) {
+ case 11:
+ case 12:
+ kn20aa_slot = (device - 11) + 0;
+ break;
+
+ case 7:
+ kn20aa_slot = 2;
+ break;
+
+ case 8:
+ kn20aa_slot = 4;
+ break;
+
+ case 9:
+ kn20aa_slot = 3;
+ break;
+
+ default:
+ panic("pci_kn20aa_map_int: invalid device number %d\n",
+ device);
+ }
+
+ kn20aa_irq = (kn20aa_slot * 4) + pin - 1;
+ if (kn20aa_irq > KN20AA_MAX_IRQ)
+ panic("pci_kn20aa_map_int: kn20aa_irq too large (%d)\n",
+ kn20aa_irq);
+
+#if 0
+ printf("kn20aa_attach_intr: func 0x%lx, arg 0x%lx, level %d, irq %d\n",
+ func, arg, level, kn20aa_irq);
+#endif
+
+ ih = kn20aa_attach_intr(&kn20aa_pci_intrs[kn20aa_irq], level,
+ func, arg);
+ kn20aa_enable_intr(kn20aa_irq);
+ return (ih);
+}
+
+void
+kn20aa_pci_unmap_int(pifa, cookie)
+ void *pifa;
+ void *cookie;
+{
+
+ panic("kn20aa_pci_unmap_int not implemented"); /* XXX */
+}
+
+/*
+ * caught a stray interrupt; notify if not too many seen already.
+ */
+void
+kn20aa_pci_strayintr(irq)
+ int irq;
+{
+
+ if (++kn20aa_pci_strayintrcnt[irq] <= PCI_STRAY_MAX)
+ log(LOG_ERR, "stray PCI interrupt %d%s\n", irq,
+ kn20aa_pci_strayintrcnt[irq] >= PCI_STRAY_MAX ?
+ "; stopped logging" : "");
+}
+
+void
+kn20aa_iointr(framep, vec)
+ void *framep;
+ int vec;
+{
+ struct kn20aa_intrhand *ih;
+ int irq, handled;
+
+ if (vec >= 0x900) {
+ if (vec >= 0x900 + (KN20AA_MAX_IRQ << 4))
+ panic("kn20aa_iointr: vec 0x%x out of range\n", vec);
+ irq = (vec - 0x900) >> 4;
+
+#ifdef EVCNT_COUNTERS
+ kn20aa_intr_evcnt.ev_count++;
+#else
+ if (KN20AA_MAX_IRQ != INTRCNT_KN20AA_IRQ_LEN)
+ panic("kn20aa interrupt counter sizes inconsistent");
+ intrcnt[INTRCNT_KN20AA_IRQ + irq]++;
+#endif
+
+ for (ih = kn20aa_pci_intrs[irq].tqh_first, handled = 0;
+ ih != NULL; ih = ih->ih_q.tqe_next) {
+ int rv;
+
+ rv = (*ih->ih_fun)(ih->ih_arg);
+
+ ih->ih_count++;
+ handled = handled || (rv != 0);
+ }
+ if (!handled)
+ kn20aa_pci_strayintr(irq);
+ return;
+ }
+ if (vec >= 0x800) {
+#if NSIO
+ sio_iointr(framep, vec);
+#endif
+ return;
+ }
+ panic("kn20aa_iointr: weird vec 0x%x\n", vec);
+}
+
+void
+kn20aa_enable_intr(irq)
+ int irq;
+{
+
+ /*
+ * From disassembling the OSF/1 source code:
+ * the following appears to enable a given interrupt request.
+ * "blech." I'd give valuable body parts for better docs or
+ * for a good decompiler.
+ */
+ wbflush();
+ REGVAL(0x8780000000L + 0x40L) |= (1 << irq); /* XXX */
+ wbflush();
+}
+
+struct kn20aa_intrhand *
+kn20aa_attach_intr(chain, level, func, arg)
+ struct kn20aa_intrchain *chain;
+ pci_intrlevel_t level;
+ int (*func) __P((void *));
+ void *arg;
+{
+ struct kn20aa_intrhand *nintrhand;
+
+ nintrhand = (struct kn20aa_intrhand *)
+ malloc(sizeof *nintrhand, M_DEVBUF, M_WAITOK);
+
+ nintrhand->ih_fun = func;
+ nintrhand->ih_arg = arg;
+ nintrhand->ih_count = 0;
+ nintrhand->ih_level = level;
+ TAILQ_INSERT_TAIL(chain, nintrhand, ih_q);
+
+ return (nintrhand);
+}
diff --git a/sys/arch/alpha/pci/pci_kn20aa.h b/sys/arch/alpha/pci/pci_kn20aa.h
new file mode 100644
index 00000000000..4e499317ea0
--- /dev/null
+++ b/sys/arch/alpha/pci/pci_kn20aa.h
@@ -0,0 +1,36 @@
+/* $NetBSD: pci_kn20aa.h,v 1.1 1995/11/23 02:38:05 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+void pci_kn20aa_pickintr __P((__const struct pci_conf_fns *, void *,
+ __const struct pci_pio_fns *, void *,
+ __const struct pci_intr_fns **, void **));
+
+#ifdef EVCNT_COUNTERS
+extern struct evcnt kn20aa_intr_evcnt;
+#endif
diff --git a/sys/arch/alpha/pci/pci_machdep.c b/sys/arch/alpha/pci/pci_machdep.c
index bacb5273362..02eb57caeaa 100644
--- a/sys/arch/alpha/pci/pci_machdep.c
+++ b/sys/arch/alpha/pci/pci_machdep.c
@@ -1,32 +1,30 @@
-/* $NetBSD: pci_machdep.c,v 1.2 1995/08/03 00:33:58 cgd Exp $ */
+/* $NetBSD: pci_machdep.c,v 1.3 1995/11/23 02:38:07 cgd Exp $ */
/*
- * Copyright (c) 1994 Charles Hannum. All rights reserved.
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Charles Hannum.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
+ * 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
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
*/
/*
@@ -43,206 +41,56 @@
#include <vm/vm.h>
#include <dev/isa/isavar.h>
-#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
-#include <alpha/pci/pci_chipset.h>
#include "pcivga.h"
-#include "tga.h"
-
-int pcimatch __P((struct device *, void *, void *));
-void pciattach __P((struct device *, struct device *, void *));
-
-struct cfdriver pcicd = {
- NULL, "pci", pcimatch, pciattach, DV_DULL, sizeof(struct device)
-};
-
-int
-pcimatch(parent, match, aux)
- struct device *parent;
- void *match, *aux;
-{
-
- return 1;
-}
-
-void
-pciattach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-{
-
- printf("\n");
- (*pci_cs_fcns->cs_setup)();
- (*pci_cfg_fcns->cfg_attach)(parent, self, aux);
-}
-
-pcitag_t
-pci_make_tag(bus, device, function)
- int bus, device, function;
-{
-
- return (*pci_cs_fcns->cs_make_tag)(bus, device, function);
-}
-
-pcireg_t
-pci_conf_read(tag, offset)
- pcitag_t tag;
- int offset; /* XXX */
-{
-
- return (*pci_cs_fcns->cs_conf_read)(tag, offset);
-}
-
-void
-pci_conf_write(tag, offset, data)
- pcitag_t tag;
- int offset; /* XXX */
- pcireg_t data;
-{
-
- (*pci_cs_fcns->cs_conf_write)(tag, offset, data);
-}
-
-int
-pci_map_io(tag, reg, iobasep)
- pcitag_t tag;
- int reg;
- int *iobasep;
-{
-
- return (*pci_cs_fcns->cs_map_io)(tag, reg, iobasep);
-}
-
-int
-pci_map_mem(tag, reg, vap, pap)
- pcitag_t tag;
- int reg;
- vm_offset_t *vap, *pap;
-{
-
- return (*pci_cs_fcns->cs_map_mem)(tag, reg, vap, pap);
-}
-
-int
-pcidma_map(addr, size, mappings)
- caddr_t addr;
- vm_size_t size;
- vm_offset_t *mappings;
-{
-
- return (*pci_cs_fcns->cs_pcidma_map)(addr, size, mappings);
-}
-
-void
-pcidma_unmap(addr, size, nmappings, mappings)
- caddr_t addr;
- vm_size_t size;
- int nmappings;
- vm_offset_t *mappings;
-{
-
- (*pci_cs_fcns->cs_pcidma_unmap)(addr, size, nmappings, mappings);
-}
-
-void *
-pci_map_int(tag, level, func, arg)
- pcitag_t tag;
- pci_intrlevel level;
- int (*func) __P((void *));
- void *arg;
-{
- pcireg_t data;
- int pin;
-
- data = pci_conf_read(tag, PCI_INTERRUPT_REG);
-
- pin = PCI_INTERRUPT_PIN(data);
-
- if (pin == 0) {
- /* No IRQ used. */
- return 0;
- }
-
- if (pin > 4) {
- printf("pci_map_int: bad interrupt pin %d\n", pin);
- return NULL;
- }
-
- return (*pci_cfg_fcns->cfg_map_int)(tag, level, func, arg, pin);
-}
-
-isa_intrlevel
-pcilevel_to_isa(level)
- pci_intrlevel level;
-{
-
- switch (level) {
- case PCI_IPL_NONE:
- return (ISA_IPL_NONE);
-
- case PCI_IPL_BIO:
- return (ISA_IPL_BIO);
-
- case PCI_IPL_NET:
- return (ISA_IPL_NET);
-
- case PCI_IPL_TTY:
- return (ISA_IPL_TTY);
-
- case PCI_IPL_CLOCK:
- return (ISA_IPL_CLOCK);
+#if NPCIVGA
+#include <alpha/pci/pcivgavar.h>
+#endif
- default:
- panic("pcilevel_to_isa: unknown level %d\n", level);
- }
-}
+#include "tga.h"
+#if NTGA
+#include <alpha/pci/tgavar.h>
+#endif
void
-pci_display_console(bus, device, function)
- int bus, device, function;
+pci_display_console(pcf, pcfa, pmf, pmfa, ppf, ppfa, bus, device, function)
+ __const struct pci_conf_fns *pcf;
+ __const struct pci_mem_fns *pmf;
+ __const struct pci_pio_fns *ppf;
+ void *pcfa, *pmfa, *ppfa;
+ pci_bus_t bus;
+ pci_device_t device;
+ pci_function_t function;
{
- pcitag_t tag;
- pcireg_t id, class;
-
- /* XXX */
- tag = pci_make_tag(bus, device, function);
+ pci_conftag_t tag;
+ pci_confreg_t id, class;
- id = pci_conf_read(tag, PCI_ID_REG);
+ tag = PCI_MAKE_TAG(bus, device, function);
+ id = PCI_CONF_READ(pcf, pcfa, tag, PCI_ID_REG);
if (id == 0 || id == 0xffffffff)
panic("pci_display_console: no device at %d/%d/%d",
bus, device, function);
- class = pci_conf_read(tag, PCI_CLASS_REG);
-
- if (PCI_CLASS(class) != PCI_CLASS_DISPLAY &&
- !(PCI_CLASS(class) == PCI_CLASS_PREHISTORIC &&
- PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA))
- panic("pci_display_console: device at %d/%d/%d not a display",
- bus, device, function);
+ class = PCI_CONF_READ(pcf, pcfa, tag, PCI_CLASS_REG);
- if ((PCI_CLASS(class) == PCI_CLASS_DISPLAY &&
- PCI_SUBCLASS(class) == PCI_SUBCLASS_DISPLAY_VGA) ||
- (PCI_CLASS(class) == PCI_CLASS_PREHISTORIC &&
- PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA)) {
#if NPCIVGA
- pcivga_console(bus, device, function);
-#else
- panic("pci_display_console: pcivga is console, not configured");
-#endif
+ if (DEVICE_IS_PCIVGA(class, id)) {
+ pcivga_console(pcf, pcfa, pmf, pmfa, ppf, ppfa, bus,
+ device, function);
return;
}
+#endif
- if (PCI_VENDOR(id) == PCI_VENDOR_DEC &&
- PCI_PRODUCT(id) == PCI_PRODUCT_DEC_21030) {
#if NTGA
- tga_console(bus, device, function);
-#else
- panic("pci_display_console: tga is console, not configured");
-#endif
+ if (DEVICE_IS_TGA(class, id)) {
+ tga_console(pcf, pcfa, pmf, pmfa, ppf, ppfa, bus,
+ device, function);
return;
}
+#endif
- panic("pci_display_console: unsupported device at %d/%d/%d",
+ panic("pci_display_console: unconfigured device at %d/%d/%d",
bus, device, function);
}
diff --git a/sys/arch/alpha/pci/pci_machdep.h b/sys/arch/alpha/pci/pci_machdep.h
deleted file mode 100644
index 6f4a8459b6e..00000000000
--- a/sys/arch/alpha/pci/pci_machdep.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* $NetBSD: pci_machdep.h,v 1.1 1995/06/28 01:26:01 cgd Exp $ */
-
-/*
- * Copyright (c) 1994 Charles Hannum. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Charles Hannum.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Machine-specific definitions for PCI autoconfiguration.
- *
- * See the comments in pci_machdep.c for more explanation.
- */
-
-/*
- * Configuration tag; created from a {bus,device,function} triplet by
- * pci_make_tag(), and passed to pci_conf_read() and pci_conf_write().
- * We could instead always pass the {bus,device,function} triplet to
- * the read and write routines, but this would cause extra overhead.
- */
-typedef u_long pcitag_t;
-
-/*
- * Type of a value read from or written to a configuration register.
- * Always 32 bits.
- */
-typedef u_int32_t pcireg_t;
-
-extern int pci_mode;
-extern int pci_mode_detect __P((void));
diff --git a/sys/arch/alpha/pci/pcivga.c b/sys/arch/alpha/pci/pcivga.c
index b155f8f5951..10b2f3cbbec 100644
--- a/sys/arch/alpha/pci/pcivga.c
+++ b/sys/arch/alpha/pci/pcivga.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pcivga.c,v 1.2 1995/08/03 01:17:17 cgd Exp $ */
+/* $NetBSD: pcivga.c,v 1.3 1995/11/23 02:38:11 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -35,7 +35,6 @@
#include <machine/autoconf.h>
#include <machine/pte.h>
-#include <machine/pio.h>
#include <dev/pseudo/ansicons.h>
#include <dev/pci/pcireg.h>
@@ -43,6 +42,7 @@
#include <dev/pci/pcidevs.h>
#include <alpha/pci/pcivgavar.h>
+#include <alpha/pci/wsconsvar.h>
int pcivgamatch __P((struct device *, void *, void *));
void pcivgaattach __P((struct device *, struct device *, void *));
@@ -52,8 +52,19 @@ struct cfdriver pcivgacd = {
sizeof(struct pcivga_softc)
};
+void pcivga_getdevconfig __P((__const struct pci_conf_fns *, void *,
+ __const struct pci_mem_fns *, void *,
+ __const struct pci_pio_fns *, void *,
+ pci_conftag_t tag, struct pcivga_devconfig *dc));
+
struct pcivga_devconfig pcivga_console_dc;
+void pcivga_cursor __P((void *, int, int));
+void pcivga_putstr __P((void *, int, int, char *, int));
+void pcivga_copycols __P((void *, int, int, int,int));
+void pcivga_erasecols __P((void *, int, int, int));
+void pcivga_copyrows __P((void *, int, int, int));
+void pcivga_eraserows __P((void *, int, int));
void pcivga_bell __P((void *)); /* XXX */
struct ansicons_functions pcivga_acf = {
@@ -74,54 +85,43 @@ pcivgamatch(parent, match, aux)
void *match, *aux;
{
struct cfdata *cf = match;
- struct pci_attach_args *pa = aux;
+ struct pcidev_attach_args *pda = aux;
/*
* If it's prehistoric/vga or display/vga, we match.
*/
- if ((PCI_CLASS(pa->pa_class) == PCI_CLASS_PREHISTORIC &&
- PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_PREHISTORIC_VGA) ||
- (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY &&
- PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA))
+ if (PCI_CLASS(pda->pda_class) == PCI_CLASS_PREHISTORIC &&
+ PCI_SUBCLASS(pda->pda_class) == PCI_SUBCLASS_PREHISTORIC_VGA)
+ return (1);
+ if (PCI_CLASS(pda->pda_class) == PCI_CLASS_DISPLAY &&
+ PCI_SUBCLASS(pda->pda_class) == PCI_SUBCLASS_DISPLAY_VGA)
return (1);
return (0);
}
void
-pcivga_getdevconfig(tag, dc)
- pcitag_t tag;
+pcivga_getdevconfig(pcf, pcfa, pmf, pmfa, ppf, ppfa, tag, dc)
+ __const struct pci_conf_fns *pcf;
+ __const struct pci_mem_fns *pmf;
+ __const struct pci_pio_fns *ppf;
+ void *pcfa, *pmfa, *ppfa;
+ pci_conftag_t tag;
struct pcivga_devconfig *dc;
{
+ dc->dc_pcf = pcf;
+ dc->dc_pcfa = pcfa;
+ dc->dc_pmf = pmf;
+ dc->dc_pmfa = pmfa;
+ dc->dc_ppf = ppf;
+ dc->dc_ppfa = ppfa;
dc->dc_pcitag = tag;
-#if 0
- vm_offset_t pciva, pcipa;
- int i;
-
- dc->dc_vaddr = 0;
- if (pci_map_mem(tag, 0x10, &dc->dc_vaddr, &pcipa))
- return;
-#endif
-
-#if 0
- int i;
- pcireg_t old;
-
- printf("\n");
- for (i = PCI_MAP_REG_START; i < PCI_MAP_REG_END; i += 4) {
- old = pci_conf_read(tag, i);
- pci_conf_write(tag, i, 0xffffffff);
- printf("pcivga_getdevconfig: ");
- printf("mapping reg @ %d = 0x%x (mask 0x%x)\n",
- i, old, pci_conf_read(tag, i));
- pci_conf_write(tag, i, old);
- }
- printf("foo");
-#endif
+ /* XXX deal with mapping foo */
- dc->dc_crtat = (u_short *)phystok0seg(0xb8000 | (3L << 32)); /* XXX */
+ /* XXX */
+ dc->dc_crtat = (u_short *)PCI_MEM_MAP(pmf, pmfa, 0xb8000, 0x8000, 1);
dc->dc_iobase = 0x3d4; /* XXX */
dc->dc_nrow = 25;
@@ -141,26 +141,29 @@ pcivgaattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
- struct pci_attach_args *pa = aux;
+ struct pcidev_attach_args *pda = aux;
struct pcivga_softc *sc = (struct pcivga_softc *)self;
char devinfo[256];
int console;
- console = (pa->pa_tag == pcivga_console_dc.dc_pcitag);
+ console = (pda->pda_tag == pcivga_console_dc.dc_pcitag);
if (console)
sc->sc_dc = &pcivga_console_dc;
else {
sc->sc_dc = (struct pcivga_devconfig *)
malloc(sizeof(struct pcivga_devconfig), M_DEVBUF, M_WAITOK);
- pcivga_getdevconfig(pa->pa_tag, sc->sc_dc);
+ pcivga_getdevconfig(pda->pda_conffns, pda->pda_confarg,
+ pda->pda_memfns, pda->pda_memarg, pda->pda_piofns,
+ pda->pda_memarg, pda->pda_tag, sc->sc_dc);
}
if (sc->sc_dc->dc_crtat == NULL) {
printf(": couldn't map memory space; punt!\n");
return;
}
- pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, NULL);
- printf(": %s (revision 0x%x)\n", devinfo, PCI_REVISION(pa->pa_class));
+ pci_devinfo(pda->pda_id, pda->pda_class, 0, devinfo);
+ printf(": %s (rev. 0x%02x)\n", devinfo,
+ PCI_REVISION(pda->pda_class));
#if 0
if (sc->sc_dc->dc_tgaconf == NULL) {
@@ -209,21 +212,28 @@ tgammap(dev, offset, nprot)
#endif
void
-pcivga_console(bus, device, function)
- int bus, device, function;
+pcivga_console(pcf, pcfa, pmf, pmfa, ppf, ppfa, bus, device, function)
+ __const struct pci_conf_fns *pcf;
+ __const struct pci_mem_fns *pmf;
+ __const struct pci_pio_fns *ppf;
+ void *pcfa, *pmfa, *ppfa;
+ pci_bus_t bus;
+ pci_device_t device;
+ pci_function_t function;
{
struct pcivga_devconfig *dcp = &pcivga_console_dc;
- pcivga_getdevconfig(pci_make_tag(bus, device, function), dcp);
+ pcivga_getdevconfig(pcf, pcfa, pmf, pmfa, ppf, ppfa,
+ PCI_MAKE_TAG(bus, device, function), dcp);
/* sanity checks */
if (dcp->dc_crtat == NULL)
- panic("pcivga_console(%d, %d, %d): couldn't map memory space",
- bus, device, function);
+ panic("pcivga_console(%d, %d): couldn't map memory space",
+ device, function);
#if 0
if (dcp->dc_pcivgaconf == NULL)
- panic("pcivga_console(%d, %d, %d): unknown board configuration",
- bus, device, function);
+ panic("pcivga_console(%d, %d): unknown board configuration",
+ device, function);
#endif
wsc_console(&dcp->dc_ansicons, &pcivga_acf, dcp,
@@ -265,10 +275,10 @@ pcivga_cursor(id, row, col)
pos = row * dc->dc_ncol + col;
- outb(dc->dc_iobase, 14);
- outb(dc->dc_iobase+1, pos >> 8);
- outb(dc->dc_iobase, 15);
- outb(dc->dc_iobase+1, pos);
+ OUTB(dc->dc_ppf, dc->dc_ppfa, dc->dc_iobase, 14);
+ OUTB(dc->dc_ppf, dc->dc_ppfa, dc->dc_iobase+1, pos >> 8);
+ OUTB(dc->dc_ppf, dc->dc_ppfa, dc->dc_iobase, 15);
+ OUTB(dc->dc_ppf, dc->dc_ppfa, dc->dc_iobase+1, pos);
}
void
diff --git a/sys/arch/alpha/pci/pcivgavar.h b/sys/arch/alpha/pci/pcivgavar.h
index 049fd2dca51..579ad4ca0a4 100644
--- a/sys/arch/alpha/pci/pcivgavar.h
+++ b/sys/arch/alpha/pci/pcivgavar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pcivgavar.h,v 1.2 1995/08/03 01:17:21 cgd Exp $ */
+/* $NetBSD: pcivgavar.h,v 1.3 1995/11/23 02:38:13 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -27,8 +27,17 @@
* rights to redistribute these changes.
*/
+#include <dev/pseudo/ansicons.h>
+
struct pcivga_devconfig {
- pcitag_t dc_pcitag; /* PCI tag */
+ __const struct pci_conf_fns *dc_pcf;
+ void *dc_pcfa;
+ __const struct pci_mem_fns *dc_pmf;
+ void *dc_pmfa;
+ __const struct pci_pio_fns *dc_ppf;
+ void *dc_ppfa;
+
+ pci_tag_t dc_pcitag; /* PCI tag */
u_int16_t *dc_crtat; /* VGA screen memory */
int dc_iobase; /* VGA I/O address */
@@ -52,9 +61,13 @@ struct pcivga_softc {
#define PCIVGA_CURSOR_OFF -1 /* pass to pcivga_cpos to disable */
-void pcivga_cursor __P((void *, int, int));
-void pcivga_putstr __P((void *, int, int, char *, int));
-void pcivga_copycols __P((void *, int, int, int,int));
-void pcivga_erasecols __P((void *, int, int, int));
-void pcivga_copyrows __P((void *, int, int, int));
-void pcivga_eraserows __P((void *, int, int));
+#define DEVICE_IS_PCIVGA(class, id) \
+ ((PCI_CLASS(class) == PCI_CLASS_DISPLAY && \
+ PCI_SUBCLASS(class) == PCI_SUBCLASS_DISPLAY_VGA) || \
+ (PCI_CLASS(class) == PCI_CLASS_PREHISTORIC && \
+ PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA))
+
+void pcivga_console __P((__const struct pci_conf_fns *, void *,
+ __const struct pci_mem_fns *, void *,
+ __const struct pci_pio_fns *, void *,
+ pci_bus_t, pci_device_t, pci_function_t));
diff --git a/sys/arch/alpha/pci/sio.c b/sys/arch/alpha/pci/sio.c
index 5e37a5e0edc..a8b6b8a0a24 100644
--- a/sys/arch/alpha/pci/sio.c
+++ b/sys/arch/alpha/pci/sio.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sio.c,v 1.2 1995/08/03 01:17:25 cgd Exp $ */
+/* $NetBSD: sio.c,v 1.3 1995/11/23 02:38:16 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -32,11 +32,14 @@
#include <sys/kernel.h>
#include <sys/device.h>
+#include <dev/isa/isavar.h>
+#include <dev/eisa/eisavar.h>
+
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
-#include <machine/autoconf.h>
+#include <alpha/pci/siovar.h>
int siomatch __P((struct device *, void *, void *));
void sioattach __P((struct device *, struct device *, void *));
@@ -45,6 +48,12 @@ struct cfdriver siocd = {
NULL, "sio", siomatch, sioattach, DV_DULL, sizeof(struct device)
};
+int pcebmatch __P((struct device *, void *, void *));
+
+struct cfdriver pcebcd = {
+ NULL, "pceb", pcebmatch, sioattach, DV_DULL, sizeof(struct device)
+};
+
static int sioprint __P((void *, char *pnp));
int
@@ -53,10 +62,25 @@ siomatch(parent, match, aux)
void *match, *aux;
{
struct cfdata *cf = match;
- struct pci_attach_args *pa = aux;
+ struct pcidev_attach_args *pda = aux;
+
+ if (PCI_VENDOR(pda->pda_id) != PCI_VENDOR_INTEL ||
+ PCI_PRODUCT(pda->pda_id) != PCI_PRODUCT_INTEL_SIO)
+ return (0);
+
+ return (1);
+}
+
+int
+pcebmatch(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct cfdata *cf = match;
+ struct pcidev_attach_args *pda = aux;
- if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL ||
- PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_SIO)
+ if (PCI_VENDOR(pda->pda_id) != PCI_VENDOR_INTEL ||
+ PCI_PRODUCT(pda->pda_id) != PCI_PRODUCT_INTEL_PCEB)
return (0);
return (1);
@@ -67,31 +91,56 @@ sioattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
- struct pci_attach_args *pa = aux;
- struct confargs nca;
- u_int rev;
- char *type;
-
- rev = pa->pa_class & 0xff;
- if (rev < 3) {
- type = "I";
- /* XXX PCI IRQ MAPPING FUNCTION */
- } else {
- type = "II";
- /* XXX PCI IRQ MAPPING FUNCTION */
+ struct pcidev_attach_args *pda = aux;
+ struct isa_attach_args ia;
+ struct eisa_attach_args ea;
+ int sio, haseisa;
+ char devinfo[256];
+
+ sio = (PCI_PRODUCT(pda->pda_id) == PCI_PRODUCT_INTEL_SIO);
+ haseisa = (PCI_PRODUCT(pda->pda_id) == PCI_PRODUCT_INTEL_PCEB);
+
+ pci_devinfo(pda->pda_id, pda->pda_class, 0, devinfo);
+ printf(": %s (rev. 0x%02x)\n", devinfo,
+ PCI_REVISION(pda->pda_class));
+
+ if (sio) {
+ pci_revision_t rev;
+
+ rev = PCI_REVISION(pda->pda_class);
+
+ if (rev < 3)
+ printf("%s: WARNING: SIO I SUPPORT UNTESTED\n",
+ self->dv_xname);
+ }
+
+#ifdef EVCNT_COUNTERS
+ evcnt_attach(self, "intr", &sio_intr_evcnt);
+#endif
+
+ ia.ia_bus = BUS_ISA;
+ ia.ia_dmafns = pda->pda_dmafns;
+ ia.ia_dmaarg = pda->pda_dmaarg;
+ ia.ia_intrfns = &sio_isa_intr_fns;
+ ia.ia_intrarg = NULL; /* XXX needs nothing */
+ ia.ia_memfns = pda->pda_memfns;
+ ia.ia_memarg = pda->pda_memarg;
+ ia.ia_piofns = pda->pda_piofns;
+ ia.ia_pioarg = pda->pda_pioarg;
+ config_found(self, &ia, sioprint);
+
+ if (haseisa) {
+ ea.ea_bus = BUS_EISA;
+ ea.ea_dmafns = pda->pda_dmafns;
+ ea.ea_dmaarg = pda->pda_dmaarg;
+ ea.ea_intrfns = &sio_isa_intr_fns;
+ ea.ea_intrarg = NULL; /* XXX needs nothing */
+ ea.ea_memfns = pda->pda_memfns;
+ ea.ea_memarg = pda->pda_memarg;
+ ea.ea_piofns = pda->pda_piofns;
+ ea.ea_pioarg = pda->pda_pioarg;
+ config_found(self, &ea, sioprint);
}
- printf(": Saturn %s PCI->ISA bridge (revision 0x%x)\n", type, rev);
- if (rev < 3)
- printf("%s: WARNING: SIO I SUPPORT UNTESTED\n",
- parent->dv_xname);
-
- /* attach the ISA bus that hangs off of it... */
- nca.ca_name = "isa";
- nca.ca_slot = 0;
- nca.ca_offset = 0;
- nca.ca_bus = NULL;
- if (!config_found(self, &nca, sioprint))
- panic("sioattach: couldn't attach ISA bus");
}
static int
@@ -99,9 +148,14 @@ sioprint(aux, pnp)
void *aux;
char *pnp;
{
- register struct confargs *ca = aux;
+ register struct isa_attach_args *ia = aux;
+
+ /*
+ * XXX Assumes that the first fields of 'struct isa_attach_args'
+ * XXX and 'struct eisa_attach_args' are the same.
+ */
if (pnp)
- printf("%s at %s", ca->ca_name, pnp);
+ printf("%s at %s", isa_bustype_name(ia->ia_bus), pnp);
return (UNCONF);
}
diff --git a/sys/arch/alpha/pci/sio_pic.c b/sys/arch/alpha/pci/sio_pic.c
index e2f7e8cefdb..ec24ec96c5c 100644
--- a/sys/arch/alpha/pci/sio_pic.c
+++ b/sys/arch/alpha/pci/sio_pic.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sio_pic.c,v 1.1 1995/06/28 01:26:13 cgd Exp $ */
+/* $NetBSD: sio_pic.c,v 1.2 1995/11/23 02:38:19 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -33,11 +33,15 @@
#include <sys/malloc.h>
#include <sys/syslog.h>
-#include <dev/isa/isavar.h>
#include <dev/isa/isareg.h>
-#include <alpha/isa/isa_intr.h>
+#include <dev/isa/isavar.h>
+#include <alpha/pci/siovar.h>
+
+#ifndef EVCNT_COUNTERS
+#include <machine/intrcnt.h>
+#endif
-#include <machine/pio.h>
+#include "sio.h"
/*
* To add to the long history of wonderful PROM console traits,
@@ -49,18 +53,25 @@
*/
#define BROKEN_PROM_CONSOLE
-static void sio_intr_setup __P((void));
-static void *sio_intr_establish __P((int intr, isa_intrtype type,
- isa_intrlevel level, int (*ih_fun)(void *), void *ih_arg));
-static void sio_intr_disestablish __P((void *handler));
-static void sio_iointr __P((void *framep, int vec));
+/*
+ * Private functions and variables.
+ */
+static void *sio_intr_establish __P((void *, isa_irq_t,
+ isa_intrsharetype_t, isa_intrlevel_t,
+ int (*)(void *), void *));
+static void sio_intr_disestablish __P((void *, void *));
+static void sio_strayintr __P((isa_irq_t));
-struct isa_intr_fcns sio_intr_fcns = {
- sio_intr_setup, sio_intr_establish,
- sio_intr_disestablish, sio_iointr,
-};
+static __const struct isa_pio_fns *sio_ipf; /* XXX */
+static void *sio_ipfa; /* XXX */
-static void sio_strayintr __P((int irq));
+void sio_intr_setup __P((__const struct isa_pio_fns *, void *));
+void sio_iointr __P((void *framep, int vec));
+
+struct isa_intr_fns sio_isa_intr_fns = {
+ sio_intr_establish,
+ sio_intr_disestablish,
+};
/*
* Interrupt handler chains. sio_intr_establish() inserts a handler into
@@ -78,8 +89,11 @@ struct intrhand {
#define ICU_LEN 16 /* number of ISA IRQs */
static struct intrhand *sio_intrhand[ICU_LEN];
-static isa_intrtype sio_intrtype[ICU_LEN];
+static isa_intrsharetype_t sio_intrsharetype[ICU_LEN];
static u_long sio_strayintrcnt[ICU_LEN];
+#ifdef EVCNT_COUNTERS
+struct evcnt sio_intr_evcnt;
+#endif
#ifndef STRAY_MAX
#ifdef BROKEN_PROM_CONSOLE
@@ -112,7 +126,7 @@ u_int8_t initial_elcr[2];
void
sio_setirqstat(irq, enabled, type)
int irq, enabled;
- isa_intrtype type;
+ isa_intrsharetype_t type;
{
u_int8_t ocw1[2], elcr[2];
int icu, bit;
@@ -122,15 +136,15 @@ sio_setirqstat(irq, enabled, type)
enabled ? "enabled" : "disabled", isa_intr_typename(type));
#endif
- sio_intrtype[irq] = type;
+ sio_intrsharetype[irq] = type;
icu = irq / 8;
bit = irq % 8;
- ocw1[0] = inb(IO_ICU1 + 1);
- ocw1[1] = inb(IO_ICU2 + 1);
- elcr[0] = inb(0x4d0); /* XXX */
- elcr[1] = inb(0x4d1); /* XXX */
+ ocw1[0] = INB(sio_ipf, sio_ipfa, IO_ICU1 + 1);
+ ocw1[1] = INB(sio_ipf, sio_ipfa, IO_ICU2 + 1);
+ elcr[0] = INB(sio_ipf, sio_ipfa, 0x4d0); /* XXX */
+ elcr[1] = INB(sio_ipf, sio_ipfa, 0x4d1); /* XXX */
/*
* interrupt enable: set bit to mask (disable) interrupt.
@@ -174,25 +188,30 @@ sio_setirqstat(irq, enabled, type)
}
#endif
- outb(IO_ICU1 + 1, ocw1[0]);
- outb(IO_ICU2 + 1, ocw1[1]);
- outb(0x4d0, elcr[0]); /* XXX */
- outb(0x4d1, elcr[1]); /* XXX */
+ OUTB(sio_ipf, sio_ipfa, IO_ICU1 + 1, ocw1[0]);
+ OUTB(sio_ipf, sio_ipfa, IO_ICU2 + 1, ocw1[1]);
+ OUTB(sio_ipf, sio_ipfa, 0x4d0, elcr[0]); /* XXX */
+ OUTB(sio_ipf, sio_ipfa, 0x4d1, elcr[1]); /* XXX */
}
void
-sio_intr_setup()
+sio_intr_setup(ipf, ipfa)
+ __const struct isa_pio_fns *ipf;
+ void *ipfa;
{
int i;
+ sio_ipf = ipf;
+ sio_ipfa = ipfa;
+
#ifdef BROKEN_PROM_CONSOLE
/*
* Remember the initial values, because the prom is stupid.
*/
- initial_ocw1[0] = inb(IO_ICU1 + 1);
- initial_ocw1[1] = inb(IO_ICU2 + 1);
- initial_elcr[0] = inb(0x4d0); /* XXX */
- initial_elcr[1] = inb(0x4d1); /* XXX */
+ initial_ocw1[0] = INB(sio_ipf, sio_ipfa, IO_ICU1 + 1);
+ initial_ocw1[1] = INB(sio_ipf, sio_ipfa, IO_ICU2 + 1);
+ initial_elcr[0] = INB(sio_ipf, sio_ipfa, 0x4d0); /* XXX */
+ initial_elcr[1] = INB(sio_ipf, sio_ipfa, 0x4d1); /* XXX */
#if 0
printf("initial_ocw1[0] = 0x%x\n", initial_ocw1[0]);
printf("initial_ocw1[1] = 0x%x\n", initial_ocw1[1]);
@@ -245,10 +264,11 @@ sio_intr_setup()
}
void *
-sio_intr_establish(irq, type, level, ih_fun, ih_arg)
- int irq;
- isa_intrtype type;
- isa_intrlevel level;
+sio_intr_establish(siifa, irq, type, level, ih_fun, ih_arg)
+ void *siifa;
+ isa_irq_t irq;
+ isa_intrsharetype_t type;
+ isa_intrlevel_t level;
int (*ih_fun)(void *);
void *ih_arg;
{
@@ -260,19 +280,19 @@ sio_intr_establish(irq, type, level, ih_fun, ih_arg)
if (ih == NULL)
panic("sio_intr_establish: can't malloc handler info");
- if (irq < 0 || irq > ICU_LEN || type == ISA_IST_NONE)
+ if (irq > ICU_LEN || type == ISA_IST_NONE)
panic("sio_intr_establish: bogus irq or type");
- switch (sio_intrtype[irq]) {
+ switch (sio_intrsharetype[irq]) {
case ISA_IST_EDGE:
case ISA_IST_LEVEL:
- if (type == sio_intrtype[irq])
+ if (type == sio_intrsharetype[irq])
break;
case ISA_IST_PULSE:
if (type != ISA_IST_NONE)
panic("intr_establish: can't share %s with %s",
- isa_intr_typename(sio_intrtype[irq]),
- isa_intr_typename(type));
+ isa_intrsharetype_name(sio_intrsharetype[irq]),
+ isa_intrsharetype_name(type));
break;
}
@@ -301,7 +321,8 @@ sio_intr_establish(irq, type, level, ih_fun, ih_arg)
}
void
-sio_intr_disestablish(handler)
+sio_intr_disestablish(siifa, handler)
+ void *siifa;
void *handler;
{
@@ -317,7 +338,7 @@ sio_intr_disestablish(handler)
*/
void
sio_strayintr(irq)
- int irq;
+ isa_irq_t irq;
{
if (++sio_strayintrcnt[irq] <= STRAY_MAX)
@@ -340,6 +361,14 @@ sio_iointr(framep, vec)
panic("sio_iointr: irq out of range (%d)", irq);
#endif
+#ifdef EVCNT_COUNTERS
+ sio_intr_evcnt.ev_count++;
+#else
+ if (ICU_LEN != INTRCNT_ISA_IRQ_LEN)
+ panic("sio interrupt counter sizes inconsistent");
+ intrcnt[INTRCNT_ISA_IRQ + irq]++;
+#endif
+
/*
* We cdr down the intrhand chain, calling each handler with
* its appropriate argument;
@@ -373,6 +402,8 @@ sio_iointr(framep, vec)
* by the interrupt handler.
*/
if (irq > 7)
- outb(IO_ICU2 + 0, 0x20 | (irq & 0x07)); /* XXX */
- outb(IO_ICU1 + 0, 0x20 | (irq > 7 ? 2 : irq)); /* XXX */
+ OUTB(sio_ipf, sio_ipfa,
+ IO_ICU2 + 0, 0x20 | (irq & 0x07)); /* XXX */
+ OUTB(sio_ipf, sio_ipfa,
+ IO_ICU1 + 0, 0x20 | (irq > 7 ? 2 : irq)); /* XXX */
}
diff --git a/sys/arch/alpha/pci/siovar.h b/sys/arch/alpha/pci/siovar.h
new file mode 100644
index 00000000000..746b9a89abb
--- /dev/null
+++ b/sys/arch/alpha/pci/siovar.h
@@ -0,0 +1,36 @@
+/* $NetBSD: siovar.h,v 1.1 1995/11/23 02:38:22 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+void sio_intr_setup __P((__const struct isa_pio_fns *, void *));
+void sio_iointr __P((void *framep, int vec));
+
+#ifdef EVCNT_COUNTERS
+extern struct evcnt sio_intr_evcnt;
+#endif
+extern __const struct isa_intr_fns sio_isa_intr_fns;
diff --git a/sys/arch/alpha/pci/tga.c b/sys/arch/alpha/pci/tga.c
index 0be0c2dd238..739c0d812c1 100644
--- a/sys/arch/alpha/pci/tga.c
+++ b/sys/arch/alpha/pci/tga.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tga.c,v 1.2 1995/08/03 01:17:28 cgd Exp $ */
+/* $NetBSD: tga.c,v 1.3 1995/11/23 02:38:25 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -32,8 +32,9 @@
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/malloc.h>
+#include <sys/conf.h>
-#include <dev/pseudo/raster.h>
+#include <dev/rcons/raster.h>
#include <dev/pseudo/rcons.h>
#include <dev/pseudo/ansicons.h>
@@ -43,6 +44,7 @@
#include <alpha/pci/tgareg.h>
#include <alpha/pci/tgavar.h>
#include <alpha/pci/bt485reg.h>
+#include <alpha/pci/wsconsvar.h>
#include <machine/autoconf.h>
#include <machine/pte.h>
@@ -54,11 +56,20 @@ struct cfdriver tgacd = {
NULL, "tga", tgamatch, tgaattach, DV_DULL, sizeof(struct tga_softc)
};
+int tga_identify __P((tga_reg_t *));
+__const struct tga_conf *tga_getconf __P((int));
+void tga_getdevconfig __P((__const struct pci_conf_fns *, void *,
+ __const struct pci_mem_fns *, void *,
+ pci_conftag_t tag, struct tga_devconfig *dc));
+
+void tga_bell __P((void *)); /* XXX */
+
struct tga_devconfig tga_console_dc;
-int tga_identify __P((tga_reg_t *));
-struct tga_conf *tga_getconf __P((int));
-void tga_bell __P((void *));
+#if 0
+dev_decl(tga, mmap);
+dev_decl(tga, ioctl);
+#endif
struct ansicons_functions tga_acf = {
tga_bell,
@@ -72,19 +83,23 @@ struct ansicons_functions tga_acf = {
#define TGAUNIT(dev) minor(dev)
-struct tga_ramdac_conf tga_ramdac_bt463 = {
+void tga_builtin_set_cpos __P((struct tga_devconfig *, int, int));
+void tga_builtin_get_cpos __P((struct tga_devconfig *, int *, int *));
+
+__const struct tga_ramdac_conf tga_ramdac_bt463 = {
"Bt463",
-#if 0
- XXX,
- YYY,
-#endif
+ tga_builtin_set_cpos,
+ tga_builtin_get_cpos,
/* XXX */
};
+void tga_bt485_wr_reg __P((volatile tga_reg_t *, u_int, u_int8_t));
+u_int8_t tga_bt485_rd_reg __P((volatile tga_reg_t *, u_int));
+
void tga_bt485_set_cpos __P((struct tga_devconfig *, int, int));
void tga_bt485_get_cpos __P((struct tga_devconfig *, int *, int *));
-struct tga_ramdac_conf tga_ramdac_bt485 = {
+__const struct tga_ramdac_conf tga_ramdac_bt485 = {
"Bt485",
tga_bt485_set_cpos,
tga_bt485_get_cpos,
@@ -96,7 +111,7 @@ struct tga_ramdac_conf tga_ramdac_bt485 = {
#undef MB
#define MB * 1024 * 1024
-struct tga_conf tga_configs[TGA_TYPE_UNKNOWN] = {
+__const struct tga_conf tga_configs[TGA_TYPE_UNKNOWN] = {
/* TGA_TYPE_T8_01 */
{
"T8-01",
@@ -177,10 +192,10 @@ tgamatch(parent, match, aux)
void *match, *aux;
{
struct cfdata *cf = match;
- struct pci_attach_args *pa = aux;
+ struct pcidev_attach_args *pda = aux;
- if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_DEC ||
- PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_DEC_21030)
+ if (PCI_VENDOR(pda->pda_id) != PCI_VENDOR_DEC ||
+ PCI_PRODUCT(pda->pda_id) != PCI_PRODUCT_DEC_21030)
return (0);
return (1);
@@ -241,7 +256,7 @@ tga_identify(regs)
return (type);
}
-struct tga_conf *
+__const struct tga_conf *
tga_getconf(type)
int type;
{
@@ -253,31 +268,51 @@ tga_getconf(type)
}
void
-tga_getdevconfig(tag, dc)
- pcitag_t tag;
+tga_getdevconfig(pcf, pcfa, pmf, pmfa, tag, dc)
+ __const struct pci_conf_fns *pcf;
+ __const struct pci_mem_fns *pmf;
+ void *pcfa, *pmfa;
+ pci_conftag_t tag;
struct tga_devconfig *dc;
{
- struct tga_conf *tgac;
- struct tga_ramdac_conf *tgar;
+ __const struct tga_conf *tgac;
+ __const struct tga_ramdac_conf *tgar;
struct raster *rap;
struct rcons *rcp;
- vm_offset_t pcipa;
- int i;
+ pci_msize_t pcisize;
+ int i, cacheable;
+
+ dc->dc_pcf = pcf;
+ dc->dc_pcfa = pcfa;
+ dc->dc_pmf = pmf;
+ dc->dc_pmfa = pmfa;
dc->dc_pcitag = tag;
- dc->dc_vaddr = 0;
- if (pci_map_mem(tag, 0x10, &dc->dc_vaddr, &pcipa))
+ /* XXX MAGIC NUMBER */
+ PCI_FIND_MEM(pcf, pcfa, tag, 0x10, &dc->dc_pcipaddr, &pcisize,
+ &cacheable);
+ if (!cacheable) /* sanity */
+ panic("tga_getdevconfig: memory not cacheable?");
+
+ dc->dc_vaddr = PCI_MEM_MAP(pmf, pmfa, dc->dc_pcipaddr, pcisize, 1);
+ if (dc->dc_vaddr == 0)
return;
- /* PA filled in by pci_map_mem is the PCI-bus PA, i.e. not shifted */
- dc->dc_paddr = k0segtophys(dc->dc_vaddr);
+ dc->dc_paddr = k0segtophys(dc->dc_vaddr); /* XXX */
dc->dc_regs = (tga_reg_t *)(dc->dc_vaddr + TGA_MEM_CREGS);
dc->dc_tga_type = tga_identify(dc->dc_regs);
tgac = dc->dc_tgaconf = tga_getconf(dc->dc_tga_type);
if (tgac == NULL)
return;
+
+#if 0
+ /* XXX on the Alpha, pcisize = 4 * cspace_size. */
+ if (tgac->tgac_cspace_size != pcisize) /* sanity */
+ panic("tga_getdevconfig: memory size mismatch?");
+#endif
+
tgar = tgac->tgac_ramdac;
switch (dc->dc_regs[TGA_REG_VHCR] & 0x1ff) { /* XXX */
@@ -306,6 +341,13 @@ tga_getdevconfig(tag, dc)
dc->dc_regs[TGA_REG_VVBR] = 1;
dc->dc_videobase = dc->dc_vaddr + tgac->tgac_dbuf[0] +
1 * tgac->tgac_vvbr_units;
+
+ /*
+ * Set all bits in the pixel mask, to enable writes to all pixels.
+ * It seems that the console firmware clears some of them
+ * under some circumstances, which causes cute vertical stripes.
+ */
+ dc->dc_regs[TGA_REG_GPXR_P] = 0xffffffff;
/* disable the cursor */
(*tgar->tgar_set_cpos)(dc, TGA_CURSOR_OFF, 0);
@@ -342,19 +384,19 @@ tgaattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
- struct pci_attach_args *pa = aux;
+ struct pcidev_attach_args *pda = aux;
struct tga_softc *sc = (struct tga_softc *)self;
pci_revision_t rev;
- pcireg_t pci_intrdata;
int console;
- console = (pa->pa_tag == tga_console_dc.dc_pcitag);
+ console = (pda->pda_tag == tga_console_dc.dc_pcitag);
if (console)
sc->sc_dc = &tga_console_dc;
else {
sc->sc_dc = (struct tga_devconfig *)
malloc(sizeof(struct tga_devconfig), M_DEVBUF, M_WAITOK);
- tga_getdevconfig(pa->pa_tag, sc->sc_dc);
+ tga_getdevconfig(pda->pda_conffns, pda->pda_confarg,
+ pda->pda_memfns, pda->pda_memarg, pda->pda_tag, sc->sc_dc);
}
if (sc->sc_dc->dc_vaddr == NULL) {
printf(": couldn't map memory space; punt!\n");
@@ -362,7 +404,7 @@ tgaattach(parent, self, aux)
}
printf(": DC21030 ");
- rev = PCI_REVISION(pa->pa_class);
+ rev = PCI_REVISION(pda->pda_class);
switch (rev) {
case 1: case 2: case 3:
printf("step %c", 'A' + rev - 1);
@@ -381,23 +423,11 @@ tgaattach(parent, self, aux)
printf("board type %s\n", sc->sc_dc->dc_tgaconf->tgac_name);
printf("%s: %d x %d, %dbpp, %s RAMDAC\n", sc->sc_dev.dv_xname,
sc->sc_dc->dc_wid, sc->sc_dc->dc_ht,
- sc->sc_dc->dc_tgaconf->tgac_phys_depth,
+ sc->sc_dc->dc_tgaconf->tgac_phys_depth,
sc->sc_dc->dc_tgaconf->tgac_ramdac->tgar_name);
-#if 0
- /* not done here; printed by wscons attach. */
- if (console)
- printf("%s: console\n", sc->sc_dev.dv_xname);
-#endif
#if 0
- pci_intrdata = pci_conf_read(sc->sc_pcitag, PCI_INTERRUPT_REG);
- if (PCI_INTERRUPT_PIN(pci_intrdata) != PCI_INTERRUPT_PIN_NONE) {
- sc->sc_intr = pci_map_int(sc->sc_pcitag, PCI_IPL_TTY,
- tgaintr, sc);
- if (sc->sc_intr == NULL)
- printf("%s: WARNING: couldn't map interrupt\n",
- sc->sc_dev.dv_xname);
- }
+ /* XXX intr foo? */
#endif
if (!wscattach_output(self, console, &sc->sc_dc->dc_ansicons, &tga_acf,
@@ -408,35 +438,7 @@ tgaattach(parent, self, aux)
}
}
-int
-tgaopen(dev, flag, mode, p)
- dev_t dev;
- int flag, mode;
- struct proc *p;
-{
- struct tga_softc *sc;
- int unit = TGAUNIT(dev);
-
- if (unit >= tgacd.cd_ndevs)
- return ENXIO;
- sc = tgacd.cd_devs[unit];
- if ((sc = tgacd.cd_devs[unit]) == NULL || sc->sc_dc->dc_tgaconf == NULL)
- return ENXIO;
-
- return (0);
-}
-
-int
-tgaclose(dev, flag, mode, p)
- dev_t dev;
- int flag, mode;
- struct proc *p;
-{
- struct tga_softc *sc = tgacd.cd_devs[TGAUNIT(dev)];
-
- return (0);
-}
-
+#if 0
int
tgaioctl(dev, cmd, data, flag, p)
dev_t dev;
@@ -462,6 +464,7 @@ tgammap(dev, offset, nprot)
return -1;
return alpha_btop(sc->sc_dc->dc_paddr + offset);
}
+#endif
void
tga_bell(id)
@@ -472,6 +475,43 @@ tga_bell(id)
printf("tga_bell: not implemented\n");
}
+void
+tga_builtin_set_cpos(dc, x, y)
+ struct tga_devconfig *dc;
+ int x, y;
+{
+
+ if (x == TGA_CURSOR_OFF || y == TGA_CURSOR_OFF) {
+
+ dc->dc_regs[TGA_REG_VVVR] &= ~0x04; /* XXX */
+ wbflush();
+ return;
+ }
+
+ /*
+ * TGA builtin cursor is 0-based, and position is top-left corner.
+ */
+ dc->dc_regs[TGA_REG_CXYR] =
+ (x & 0xfff) | ((y & 0xfff) << 12); /* XXX */
+ wbflush();
+}
+
+void
+tga_builtin_get_cpos(dc, xp, yp)
+ struct tga_devconfig *dc;
+ int *xp, *yp;
+{
+ tga_reg_t regval;
+
+ if ((dc->dc_regs[TGA_REG_VVVR] & 0x04) == 0) { /* XXX */
+ *xp = *yp = TGA_CURSOR_OFF;
+ return;
+ }
+
+ regval = dc->dc_regs[TGA_REG_CXYR];
+ *xp = regval & 0xfff; /* XXX */
+ *yp = (regval >> 12) & 0xfff; /* XXX */
+}
/*
* Bt485-specific functions.
@@ -521,6 +561,7 @@ tga_bt485_set_cpos(dc, x, y)
regval &= ~0x03; /* XXX */
regval |= 0x00; /* XXX */
tga_bt485_wr_reg(dc->dc_regs, BT485_REG_COMMAND_2, regval);
+ return;
}
/*
@@ -531,14 +572,14 @@ tga_bt485_set_cpos(dc, x, y)
y += 64;
/* XXX CONSTANTS */
- tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_X_LOW,
- x & 0xff);
- tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_X_HIGH,
- (x >> 8) & 0x0f);
- tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_Y_LOW,
- y & 0xff);
- tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_Y_HIGH,
- (y >> 8) & 0x0f);
+ tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_X_LOW/*,
+ x & 0xff*/);
+ tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_X_HIGH/*,
+ (x >> 8) & 0x0f*/);
+ tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_Y_LOW/*,
+ y & 0xff*/);
+ tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_Y_HIGH/*,
+ (y >> 8) & 0x0f*/);
}
void
@@ -573,20 +614,27 @@ tga_bt485_get_cpos(dc, xp, yp)
}
void
-tga_console(bus, device, function)
- int bus, device, function;
+tga_console(pcf, pcfa, pmf, pmfa, ppf, ppfa, bus, device, function)
+ __const struct pci_conf_fns *pcf;
+ __const struct pci_mem_fns *pmf;
+ __const struct pci_pio_fns *ppf;
+ void *pcfa, *pmfa, *ppfa;
+ pci_bus_t bus;
+ pci_device_t device;
+ pci_function_t function;
{
struct tga_devconfig *dcp = &tga_console_dc;
- tga_getdevconfig(pci_make_tag(bus, device, function), dcp);
+ tga_getdevconfig(pcf, pcfa, pmf, pmfa,
+ PCI_MAKE_TAG(bus, device, function), dcp);
/* sanity checks */
if (dcp->dc_vaddr == NULL)
- panic("tga_console(%d, %d, %d): couldn't map memory space",
- bus, device, function);
+ panic("tga_console(%d, %d): couldn't map memory space",
+ device, function);
if (dcp->dc_tgaconf == NULL)
- panic("tga_console(%d, %d, %d): unknown board configuration",
- bus, device, function);
+ panic("tga_console(%d, %d): unknown board configuration",
+ device, function);
wsc_console(&dcp->dc_ansicons, &tga_acf, &dcp->dc_rcons,
dcp->dc_rcons.rc_maxrow, dcp->dc_rcons.rc_maxcol, 0, 0);
diff --git a/sys/arch/alpha/pci/tgareg.h b/sys/arch/alpha/pci/tgareg.h
index 80b37557860..6c335cf9a28 100644
--- a/sys/arch/alpha/pci/tgareg.h
+++ b/sys/arch/alpha/pci/tgareg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: tgareg.h,v 1.2 1995/08/03 01:17:34 cgd Exp $ */
+/* $NetBSD: tgareg.h,v 1.3 1995/11/23 02:38:28 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -27,6 +27,9 @@
* rights to redistribute these changes.
*/
+#ifndef _ALPHA_PCI_TGAREG_H_
+#define _ALPHA_PCI_TGAREG_H_
+
/*
* Device-specific PCI register offsets and contents.
*/
@@ -152,3 +155,5 @@ typedef int32_t tga_reg_t;
#define TGA_REG_SCSR 0x07e /* Command Status */
/* reserved 0x07f */
+
+#endif /* _ALPHA_PCI_TGAREG_H_ */
diff --git a/sys/arch/alpha/pci/tgavar.h b/sys/arch/alpha/pci/tgavar.h
index 8ce95ddd87b..b1ab195c624 100644
--- a/sys/arch/alpha/pci/tgavar.h
+++ b/sys/arch/alpha/pci/tgavar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: tgavar.h,v 1.2 1995/08/03 01:17:37 cgd Exp $ */
+/* $NetBSD: tgavar.h,v 1.3 1995/11/23 02:38:31 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -27,6 +27,11 @@
* rights to redistribute these changes.
*/
+#include <alpha/pci/tgareg.h>
+#include <dev/rcons/raster.h>
+#include <dev/pseudo/rcons.h>
+#include <dev/pseudo/ansicons.h>
+
struct tga_devconfig;
struct tga_ramdac_conf {
@@ -42,7 +47,7 @@ struct tga_ramdac_conf {
struct tga_conf {
char *tgac_name; /* name for this board type */
- struct tga_ramdac_conf
+ __const struct tga_ramdac_conf
*tgac_ramdac; /* the RAMDAC type; see above */
int tgac_phys_depth; /* physical frame buffer depth */
vm_size_t tgac_cspace_size; /* core space size */
@@ -58,12 +63,20 @@ struct tga_conf {
};
struct tga_devconfig {
- pcitag_t dc_pcitag; /* PCI tag */
+ __const struct pci_conf_fns *dc_pcf;
+ void *dc_pcfa;
+ __const struct pci_mem_fns *dc_pmf;
+ void *dc_pmfa;
+ __const struct pci_pio_fns *dc_ppf;
+ void *dc_ppfa;
+
+ pci_conftag_t dc_pcitag; /* PCI tag */
+ pci_moffset_t dc_pcipaddr; /* PCI phys addr. */
tga_reg_t *dc_regs; /* registers; XXX: need aliases */
int dc_tga_type; /* the device type; see below */
- struct tga_conf *dc_tgaconf; /* device buffer configuration */
+ __const struct tga_conf *dc_tgaconf; /* device buffer configuration */
vm_offset_t dc_vaddr; /* memory space virtual base address */
vm_offset_t dc_paddr; /* memory space physical base address */
@@ -96,3 +109,12 @@ struct tga_softc {
#define TGA_TYPE_UNKNOWN 7 /* unknown */
#define TGA_CURSOR_OFF -1 /* pass to tgar_cpos to disable */
+
+#define DEVICE_IS_TGA(class, id) \
+ (PCI_VENDOR(id) == PCI_VENDOR_DEC && \
+ PCI_PRODUCT(id) == PCI_PRODUCT_DEC_21030)
+
+void tga_console __P((__const struct pci_conf_fns *, void *,
+ __const struct pci_mem_fns *, void *,
+ __const struct pci_pio_fns *, void *,
+ pci_bus_t, pci_device_t, pci_function_t));
diff --git a/sys/arch/alpha/pci/wscons.c b/sys/arch/alpha/pci/wscons.c
index 8307e1d0d07..fa5a988cf09 100644
--- a/sys/arch/alpha/pci/wscons.c
+++ b/sys/arch/alpha/pci/wscons.c
@@ -1,4 +1,4 @@
-/* $NetBSD: wscons.c,v 1.2 1995/08/03 01:17:40 cgd Exp $ */
+/* $NetBSD: wscons.c,v 1.3 1995/11/23 02:38:36 cgd Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
@@ -39,6 +39,7 @@
#include <dev/cons.h>
#include <dev/pseudo/ansicons.h>
+#include <alpha/pci/wsconsvar.h>
#define NWSC 16 /* XXX XXX XXX */
@@ -105,6 +106,7 @@ wscattach_output(dev, console, acp, acf, acfarg, mrow, mcol, crow, ccol)
}
wsc_sc[nextowsc].sc_flags |= WSC_OUTPUT;
+ wsc_sc[nextowsc].sc_tty = ttymalloc();
printf("wsc%d: %s attached as output\n", nextowsc, dev->dv_xname);
if (console)
@@ -149,9 +151,8 @@ wscopen(dev, flag, mode, p)
return ENXIO;
if (!sc->sc_tty)
- tp = sc->sc_tty = ttymalloc();
- else
- tp = sc->sc_tty;
+ panic("wscopen: no tty!");
+ tp = sc->sc_tty;
tp->t_oproc = wscstart;
tp->t_param = wscparam;
diff --git a/sys/arch/alpha/pci/wsconsvar.h b/sys/arch/alpha/pci/wsconsvar.h
new file mode 100644
index 00000000000..77347e07faa
--- /dev/null
+++ b/sys/arch/alpha/pci/wsconsvar.h
@@ -0,0 +1,40 @@
+/* $NetBSD: wsconsvar.h,v 1.1 1995/11/23 02:38:39 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+struct device;
+struct ansicons;
+struct ansicons_functions;
+
+int wscattach_output __P((struct device *, int, struct ansicons *,
+ struct ansicons_functions *, void *, int, int, int, int));
+void wscattach_input __P((struct device *, void *, int (*)(void *),
+ void (*)(void *, int)));
+void wscons_kbdinput __P((char *));
+void wsc_console __P((struct ansicons *, struct ansicons_functions *,
+ void *, int, int, int, int));