diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-12-14 03:54:39 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-12-14 03:54:39 +0000 |
commit | f12226068d16673eea9adafe99388f1061d3309f (patch) | |
tree | 90cb542d279e793d072ffc6e9f1f1add1f07179e /sys/arch/alpha/pci/apecs.c | |
parent | 470d0389b66fade522060561cc0c6ba36e01e7cb (diff) |
update to netbsd
Diffstat (limited to 'sys/arch/alpha/pci/apecs.c')
-rw-r--r-- | sys/arch/alpha/pci/apecs.c | 248 |
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); } |