diff options
Diffstat (limited to 'sys/arch/mvme88k/dev/vme.c')
-rw-r--r-- | sys/arch/mvme88k/dev/vme.c | 245 |
1 files changed, 117 insertions, 128 deletions
diff --git a/sys/arch/mvme88k/dev/vme.c b/sys/arch/mvme88k/dev/vme.c index 735f1037079..7e8b14fe3c9 100644 --- a/sys/arch/mvme88k/dev/vme.c +++ b/sys/arch/mvme88k/dev/vme.c @@ -1,4 +1,4 @@ -/* $NetBSD$ */ +/* $OpenBSD: vme.c,v 1.2 1998/12/15 05:52:31 smurph Exp $ */ /* * Copyright (c) 1995 Theo de Raadt @@ -45,6 +45,7 @@ #include <sys/device.h> #include <machine/autoconf.h> #include <machine/cpu.h> +#include <machine/frame.h> #include "pcctwo.h" @@ -56,8 +57,7 @@ void vmeattach __P((struct device *, struct device *, void *)); int vme1chip_init __P((struct vmesoftc *sc)); int vme2chip_init __P((struct vmesoftc *sc)); u_long vme2chip_map __P((u_long base, int len, int dwidth)); - -int vme2abort __P((void *cap, void *frame)); +int vme2abort __P((struct frame *frame)); static int vmebustype; @@ -70,37 +70,41 @@ struct cfdriver vme_cd = { }; int -vmematch(parent, self, args) +vmematch(parent, cf, args) struct device *parent; - void *self; + void *cf; void *args; { - /* XXX should we look at the id/rev in GCSR area? nivas */ - caddr_t base; - u_char id; - u_char rev; - struct cfdata *cf = self; struct confargs *ca = args; - /* - * If bus or name do not match, fail. - */ +#if NMC > 0 + if (ca->ca_bustype == BUS_MC) { + struct mcreg *mc = (struct mcreg *)ca->ca_master; - if (ca->ca_bustype != BUS_MAIN || - strcmp(cf->cf_driver->cd_name, "vme")) { - return 0; + if (mc->mc_ver & MC_VER_NOVME) + return (0); } - - if ((base = (caddr_t)cf->cf_loc[0]) == (caddr_t)-1) { - return 0; +#endif + return (1); } - ca->ca_size = 0x100; - ca->ca_paddr = base; - ca->ca_bustype = BUS_PCCTWO; +#if defined(MVME162) || defined(MVME167) || defined(MVME177) || defined (MVME187) +/* + * make local addresses 1G-2G correspond to VME addresses 3G-4G, + * as D32 + */ +#define VME2_D32STARTPHYS (1*1024*1024*1024UL) +#define VME2_D32ENDPHYS (2*1024*1024*1024UL) +#define VME2_D32STARTVME (3*1024*1024*1024UL) +#define VME2_D32BITSVME (3*1024*1024*1024UL) - return (1); -} +/* + * make local addresses 3G-3.75G correspond to VME addresses 3G-3.75G, + * as D16 + */ +#define VME2_D16STARTPHYS (3*1024*1024*1024UL) +#define VME2_D16ENDPHYS (3*1024*1024*1024UL + 768*1024*1024UL) +#endif /* * Returns a physical address mapping for a VME address & length. @@ -108,14 +112,14 @@ vmematch(parent, self, args) * mappings, ie. the MVME147 cannot do 32 bit accesses to VME bus * addresses from 0 to physmem. */ -caddr_t +void * vmepmap(sc, vmeaddr, len, bustype) struct vmesoftc *sc; - caddr_t vmeaddr; + void *vmeaddr; int len; int bustype; { - u_long base = (u_long)vmeaddr; + u_int32_t base = (u_int32_t)vmeaddr; len = roundup(len, NBPG); switch (vmebustype) { @@ -123,13 +127,18 @@ vmepmap(sc, vmeaddr, len, bustype) case BUS_PCC: switch (bustype) { case BUS_VMES: + printf("base 0x%8x/0x%8x len 0x%x\n", + vmeaddr, base, len); if (base > VME1_A16BASE && - (base+len - VME1_A16BASE) < VME1_A16D16LEN) + (base+len - VME1_A16BASE) < VME1_A16D16LEN) { base = base - VME1_A16BASE + VME1_A16D16BASE; - else if (base+len < VME1_A32D16LEN) - base = base + VME1_A32D16BASE; - else { - printf("%s: cannot map pa %x len %x\n", + printf("vmes1: base = 0x%8x\n", base); /* 1:1 */ + } else if (base > VME1_A32D16BASE && + base+len < VME1_A16BASE) { + /* 1:1 mapped */ + printf("vmes2: base = 0x%8x\n", base); + } else { + printf("%s: cannot map pa 0x%x len 0x%x\n", sc->sc_dev.dv_xname, base, len); return (NULL); } @@ -140,7 +149,7 @@ vmepmap(sc, vmeaddr, len, bustype) else if (base+len < VME1_A32D16LEN) /* HACK! */ base = base + VME1_A32D16BASE; else { - printf("%s: cannot map pa %x len %x\n", + printf("%s: cannot map pa 0x%x len 0x%x\n", sc->sc_dev.dv_xname, base, len); return (NULL); } @@ -153,15 +162,19 @@ vmepmap(sc, vmeaddr, len, bustype) case BUS_PCCTWO: switch (bustype) { case BUS_VMES: + /*printf("base %x len %d\n", base, len);*/ if (base > VME2_A16BASE && - (base+len-VME2_A16BASE) < VME2_A16D16LEN) + (base+len-VME2_A16BASE) < VME2_A16D16LEN) { + /* XXX busted? */ base = base - VME2_A16BASE + VME2_A16D16BASE; - else if (base > VME2_A24BASE && - (base+len-VME2_A24BASE) < VME2_A24D16LEN) - base = base - VME2_A24BASE + VME2_A24D16BASE; - else if ((base+len) < VME2_A32D16LEN) + } else if (base > VME2_A24BASE && + (base+len-VME2_A24BASE) < VME2_A24D16LEN) { + base = base - VME2_A24BASE + VME2_D16STARTPHYS; + } else if ((base+len) < VME2_A32D16LEN) { + /* XXX busted? */ base = base + VME2_A32D16BASE; - else { + } else { + printf("vme2chip_map\n"); base = vme2chip_map(base, len, 16); if (base == NULL) return (NULL); @@ -181,38 +194,32 @@ vmepmap(sc, vmeaddr, len, bustype) break; #endif } - return ((caddr_t)base); + return ((void *)base); } /* if successful, returns the va of a vme bus mapping */ -caddr_t +void * vmemap(sc, vmeaddr, len, bustype) struct vmesoftc *sc; - caddr_t vmeaddr; + void *vmeaddr; int len; int bustype; { - caddr_t pa, va; - extern vm_offset_t iomap_mapin(vm_offset_t, vm_size_t, boolean_t); + void *pa, *va; - pa = vmepmap(sc, pa, len, bustype); + pa = vmepmap(sc, vmeaddr, len, bustype); if (pa == NULL) return (NULL); -#if 0 - va = (caddr_t)iomap_mapin((vm_offset_t)pa, len, 1); -#endif - va = pa; + va = mapiodev(pa, len); return (va); } void vmeunmap(va, len) - caddr_t va; + void *va; int len; { -#if 0 - iomap_mapout(va, len); -#endif + unmapiodev(va, len); } int @@ -225,7 +232,7 @@ vmerw(sc, uio, flags, bus) register vm_offset_t o, v; register int c; register struct iovec *iov; - caddr_t vme; + void *vme; int error = 0; while (uio->uio_resid > 0 && error == 0) { @@ -244,13 +251,13 @@ vmerw(sc, uio, flags, bus) c = NBPG - (v & PGOFSET); if (c == 0) return (0); - vme = vmemap(sc, (caddr_t)(v & ~PGOFSET), + vme = vmemap(sc, (void *)(v & ~PGOFSET), NBPG, BUS_VMES); if (vme == NULL) { error = EFAULT; /* XXX? */ continue; } - error = uiomove((caddr_t)vme + (v & PGOFSET), c, uio); + error = uiomove((void *)vme + (v & PGOFSET), c, uio); vmeunmap(vme, NBPG); } return (error); @@ -259,14 +266,15 @@ vmerw(sc, uio, flags, bus) int vmeprint(args, bus) void *args; - char *bus; + const char *bus; { struct confargs *ca = args; + printf(" addr 0x%x", ca->ca_offset); + if (ca->ca_vec > 0) + printf(" vec 0x%x", ca->ca_vec); if (ca->ca_ipl > 0) printf(" ipl %d", ca->ca_ipl); - if (ca->ca_vec > 0) - printf(" vec %d", ca->ca_vec); return (UNCONF); } @@ -288,31 +296,30 @@ vmescan(parent, child, args, bustype) bzero(&oca, sizeof oca); oca.ca_bustype = bustype; - oca.ca_paddr = (caddr_t)cf->cf_loc[0]; - oca.ca_size = cf->cf_loc[1]; - oca.ca_ipl = cf->cf_loc[2]; - oca.ca_vec = cf->cf_loc[3]; - - /* - * Assign a vector if the config file did not specify - * one. - */ - -#ifdef notyet + oca.ca_paddr = (void *)cf->cf_loc[0]; + oca.ca_len = cf->cf_loc[1]; + oca.ca_vec = cf->cf_loc[2]; + oca.ca_ipl = cf->cf_loc[3]; if (oca.ca_ipl > 0 && oca.ca_vec == -1) - oca.ca_vec = intr_freevec(); -#endif /* notyet */ + oca.ca_vec = intr_findvec(255, 0); + if (oca.ca_len == -1) + oca.ca_len = 4096; - oca.ca_vaddr = (void *)vmemap(sc, oca.ca_paddr, oca.ca_size, - oca.ca_bustype); + oca.ca_offset = (u_int)oca.ca_paddr; + oca.ca_vaddr = vmemap(sc, oca.ca_paddr, oca.ca_len, oca.ca_bustype); if (!oca.ca_vaddr) oca.ca_vaddr = (void *)-1; - oca.ca_parent = (void *)sc; + oca.ca_master = (void *)sc; + oca.ca_name = cf->cf_driver->cd_name; if ((*cf->cf_attach->ca_match)(parent, cf, &oca) == 0) { if (oca.ca_vaddr != (void *)-1) - vmeunmap(oca.ca_vaddr, oca.ca_size); + vmeunmap(oca.ca_vaddr, oca.ca_len); return (0); } + /* + * If match works, the driver is responsible for + * vmunmap()ing if it does not need the mapping. + */ config_attach(parent, cf, &oca, vmeprint); return (1); } @@ -351,8 +358,6 @@ vmeattach(parent, self, args) vme2chip_init(sc); break; #endif - default: - printf(" unknown parent bus %x", ca->ca_bustype); } while (config_found(self, NULL, NULL)) @@ -418,23 +423,8 @@ vme1chip_init(sc) } #endif -#if defined(MVME162) || defined(MVME167) || defined(MVME177) || defined(MVME187) - -/* - * make local addresses 1G-2G correspond to VME addresses 3G-4G, - * as D32 - */ -#define VME2_D32STARTPHYS (1*1024*1024*1024UL) -#define VME2_D32ENDPHYS (2*1024*1024*1024UL) -#define VME2_D32STARTVME (3*1024*1024*1024UL) -#define VME2_D32BITSVME (3*1024*1024*1024UL) -/* - * make local addresses 3G-3.75G correspond to VME addresses 3G-3.75G, - * as D16 - */ -#define VME2_D16STARTPHYS (3*1024*1024*1024UL) -#define VME2_D16ENDPHYS (3*1024*1024*1024UL + 768*1024*1024UL) +#if defined(MVME162) || defined(MVME167) || defined(MVME177) || defined (MVME187) /* * XXX what AM bits should be used for the D32/D16 mappings? @@ -451,48 +441,47 @@ vme2chip_init(sc) ctl = vme2->vme2_masterctl; -#if 0 - /* unused decoders 1 & 2 */ - printf("%s: phys 0x%08x-0x%08x to VMExxx 0x%08x-0x%08x\n", + /* unused decoders 1 */ + vme2->vme2_master1 = 0; + ctl &= ~(VME2_MASTERCTL_ALL << VME2_MASTERCTL_1SHIFT); + printf("%s: 1phys 0x%08x-0x%08x to VMExxx 0x%08x-0x%08x\n", sc->sc_dev.dv_xname, vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000, vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000); - printf("%s: phys 0x%08x-0x%08x to VMExxx 0x%08x-0x%08x\n", + + /* unused decoders 2 */ + vme2->vme2_master2 = 0; + ctl &= ~(VME2_MASTERCTL_ALL << VME2_MASTERCTL_2SHIFT); + printf("%s: 2phys 0x%08x-0x%08x to VMExxx 0x%08x-0x%08x\n", sc->sc_dev.dv_xname, vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000, vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000); -#endif - /* setup a D16 space */ + /* setup a A24D16 space */ vme2->vme2_master3 = ((VME2_D16ENDPHYS-1) & 0xffff0000) | (VME2_D16STARTPHYS >> 16); ctl &= ~(VME2_MASTERCTL_ALL << VME2_MASTERCTL_3SHIFT); - ctl |= (VME2_MASTERCTL_AM32SP | VME2_MASTERCTL_D16) << + ctl |= (VME2_MASTERCTL_D16 | VME2_MASTERCTL_AM24UD) << VME2_MASTERCTL_3SHIFT; -#if 0 - printf("%s: phys 0x%08x-0x%08x to VMED16 0x%08x-0x%08x\n", + printf("%s: 3phys 0x%08x-0x%08x to VMED16 0x%08x-0x%08x\n", sc->sc_dev.dv_xname, - VME2_D16STARTPHYS, VME2_D16ENDPHYS-1, - VME2_D16STARTPHYS, VME2_D16ENDPHYS-1); -#endif + vme2->vme2_master3 << 16, vme2->vme2_master3 & 0xffff0000, + vme2->vme2_master3 << 16, vme2->vme2_master3 & 0xffff0000); - /* setup a D32 space */ + /* setup a A32D32 space */ vme2->vme2_master4 = ((VME2_D32ENDPHYS-1) & 0xffff0000) | (VME2_D32STARTPHYS >> 16); vme2->vme2_master4mod = (VME2_D32STARTVME & 0xffff0000) | (VME2_D32BITSVME >> 16); ctl &= ~(VME2_MASTERCTL_ALL << VME2_MASTERCTL_4SHIFT); - ctl |= (VME2_MASTERCTL_AM32SP) << + ctl |= (VME2_MASTERCTL_AM32UD) << VME2_MASTERCTL_4SHIFT; -#if 0 - printf("%s: phys 0x%08x-0x%08x to VMED32 0x%08x-0x%08x\n", + printf("%s: 4phys 0x%08x-0x%08x to VMED32 0x%08x-0x%08x\n", sc->sc_dev.dv_xname, - VME2_D32STARTPHYS, VME2_D32ENDPHYS-1, - VME2_D32STARTVME, VME2_D32STARTVME | ~VME2_D32BITSVME); -#endif + vme2->vme2_master4 << 16, vme2->vme2_master4 & 0xffff0000, + vme2->vme2_master4 << 16, vme2->vme2_master4 & 0xffff0000); vme2->vme2_masterctl = ctl; - ctl = vme2->vme2_gcsrctl; /* enable A16 short IO map decoder (0xffffxxxx) */ @@ -520,11 +509,10 @@ vme2chip_init(sc) (6 << VME2_IRQL4_VME6SHIFT) | (5 << VME2_IRQL4_VME5SHIFT) | (4 << VME2_IRQL4_VME4SHIFT) | (3 << VME2_IRQL4_VME3SHIFT) | (2 << VME2_IRQL4_VME2SHIFT) | (1 << VME2_IRQL4_VME1SHIFT); - /* - * disable all interrupts, they will be enabled by each - * driver when it configures - */ - vme2->vme2_irqen = 0; + printf("%s: vme2_irql4 = 0x%08x\n", sc->sc_dev.dv_xname, + vme2->vme2_irql4); + +#if NPCCTWO > 0 if (vmebustype == BUS_PCCTWO){ /* * pseudo driver, abort interrupt handler @@ -539,7 +527,8 @@ vme2chip_init(sc) intr_establish(110, &sc->sc_abih); vme2->vme2_irqen |= VME2_IRQ_AB; } - +#endif + vme2->vme2_irqen = vme2->vme2_irqen | VME2_IRQ_ACF; } /* @@ -565,22 +554,22 @@ vme2chip_map(base, len, dwidth) return (base - VME2_D32STARTVME + VME2_D32STARTPHYS); } } -#if 1 + +#if NPCCTWO > 0 int -vme2abort(void *cap, void *frame) +vme2abort(frame) + struct frame *frame; { struct vmesoftc *sc = (struct vmesoftc *) vme_cd.cd_devs[0]; struct vme2reg *vme2 = (struct vme2reg *)sc->sc_vaddr; - extern void nmihand(void *); - if (!(vme2->vme2_irqstat & VME2_IRQ_AB)) { - printf("vme2abort irq not set\n"); - return 0; + if (vme2->vme2_irqstat & VME2_IRQ_AB == 0) { + printf("%s: vme2chip irq not set\n", sc->sc_dev.dv_xname); + return (0); } - vme2->vme2_irqclr = VME2_IRQ_AB; nmihand(frame); - return 1; + return (1); } #endif #endif /* MVME1[678]x */ |