summaryrefslogtreecommitdiff
path: root/sys/arch/alpha/pci/apecs.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-12-14 03:54:39 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-12-14 03:54:39 +0000
commitf12226068d16673eea9adafe99388f1061d3309f (patch)
tree90cb542d279e793d072ffc6e9f1f1add1f07179e /sys/arch/alpha/pci/apecs.c
parent470d0389b66fade522060561cc0c6ba36e01e7cb (diff)
update to netbsd
Diffstat (limited to 'sys/arch/alpha/pci/apecs.c')
-rw-r--r--sys/arch/alpha/pci/apecs.c248
1 files changed, 85 insertions, 163 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);
}