[BACK]Return to vme.c CVS log [TXT][DIR] Up to [local] / sys / arch / mvme88k / dev

Annotation of sys/arch/mvme88k/dev/vme.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: vme.c,v 1.46 2007/03/22 18:52:38 miod Exp $ */
                      2: /*
                      3:  * Copyright (c) 2004, Miodrag Vallat.
                      4:  * Copyright (c) 1999 Steve Murphree, Jr.
                      5:  * Copyright (c) 1995 Theo de Raadt
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  *
                     17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     18:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     19:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     20:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     21:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     22:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     23:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     24:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     25:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     26:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     27:  */
                     28:
                     29: #include <sys/param.h>
                     30: #include <sys/conf.h>
                     31: #include <sys/ioctl.h>
                     32: #include <sys/proc.h>
                     33: #include <sys/uio.h>
                     34: #include <sys/systm.h>
                     35: #include <sys/kernel.h>
                     36: #include <sys/device.h>
                     37:
                     38: #include <machine/autoconf.h>
                     39: #include <machine/cpu.h>
                     40:
                     41: #include "pcctwo.h"
                     42: #include "syscon.h"
                     43:
                     44: #include <mvme88k/dev/vme.h>
                     45: #if NSYSCON > 0
                     46: #include <machine/mvme188.h>
                     47: #include <mvme88k/dev/sysconreg.h>
                     48: #endif
                     49:
                     50: int    vmematch(struct device *, void *, void *);
                     51: void   vmeattach(struct device *, struct device *, void *);
                     52:
                     53: void   vme2chip_init(struct vmesoftc *);
                     54: void   vmesyscon_init(struct vmesoftc *);
                     55: u_long vme2chip_map(u_long, int);
                     56: int    vme2abort(void *);
                     57: int    sysconabort(void *);
                     58: int    vmeprint(void *, const char *);
                     59:
                     60: int vmebustype;
                     61: unsigned int vmevecbase;
                     62:
                     63: struct cfattach vme_ca = {
                     64:         sizeof(struct vmesoftc), vmematch, vmeattach
                     65: };
                     66:
                     67: struct cfdriver vme_cd = {
                     68:         NULL, "vme", DV_DULL
                     69: };
                     70:
                     71: /*
                     72:  * bus_space routines for VME mappings
                     73:  */
                     74:
                     75: int    vme_map(bus_addr_t, bus_size_t, int, bus_space_handle_t *);
                     76: void   vme_unmap(bus_space_handle_t, bus_size_t);
                     77: int    vme_subregion(bus_space_handle_t, bus_size_t, bus_size_t,
                     78:            bus_space_handle_t *);
                     79: void * vme_vaddr(bus_space_handle_t);
                     80:
                     81: const struct mvme88k_bus_space_tag vme_bustag = {
                     82:        vme_map,
                     83:        vme_unmap,
                     84:        vme_subregion,
                     85:        vme_vaddr
                     86: };
                     87:
                     88: /*
                     89:  * VME space mapping functions
                     90:  */
                     91:
                     92: int
                     93: vme_map(bus_addr_t addr, bus_size_t size, int flags, bus_space_handle_t *ret)
                     94: {
                     95:        vaddr_t map;
                     96:
                     97:        map = (vaddr_t)mapiodev((paddr_t)addr, size);
                     98:        if (map == NULL)
                     99:                return ENOMEM;
                    100:
                    101:        *ret = (bus_space_handle_t)map;
                    102:        return 0;
                    103: }
                    104:
                    105: void
                    106: vme_unmap(bus_space_handle_t handle, bus_size_t size)
                    107: {
                    108:        unmapiodev((vaddr_t)handle, size);
                    109: }
                    110:
                    111: int
                    112: vme_subregion(bus_space_handle_t handle, bus_addr_t offset, bus_size_t size,
                    113:     bus_space_handle_t *ret)
                    114: {
                    115:        *ret = handle + offset;
                    116:        return (0);
                    117: }
                    118:
                    119: void *
                    120: vme_vaddr(bus_space_handle_t handle)
                    121: {
                    122:        return (void *)handle;
                    123: }
                    124:
                    125: /*
                    126:  * Extra D16 access functions
                    127:  *
                    128:  * D16 cards will trigger bus errors on attempting to read or write more
                    129:  * than 16 bits on the bus. Given how the m88k processor works, this means
                    130:  * basically that all long (D32) accesses must be carefully taken care of.
                    131:  *
                    132:  * Since the kernels bcopy() and bzero() routines will use 32 bit accesses
                    133:  * for performance, here are specific D16-compatible routines. They will
                    134:  * also revert to D8 operations if neither of the operands is properly
                    135:  * aligned.
                    136:  */
                    137:
                    138: void d16_bcopy(const void *, void *, size_t);
                    139: void d16_bzero(void *, size_t);
                    140:
                    141: void
                    142: d16_bcopy(const void *src, void *dst, size_t len)
                    143: {
                    144:        if ((vaddr_t)src & 1 || (vaddr_t)dst & 1)
                    145:                bus_space_write_region_1(&vme_bustag, 0, (vaddr_t)dst,
                    146:                    (void *)src, len);
                    147:        else {
                    148:                bus_space_write_region_2(&vme_bustag, 0, (vaddr_t)dst,
                    149:                    (void *)src, len / 2);
                    150:                if (len & 1)
                    151:                        bus_space_write_1(&vme_bustag, 0,
                    152:                            dst + len - 1, *(u_int8_t *)(src + len - 1));
                    153:        }
                    154: }
                    155:
                    156: void
                    157: d16_bzero(void *dst, size_t len)
                    158: {
                    159:        if ((vaddr_t)dst & 1)
                    160:                bus_space_set_region_1(&vme_bustag, 0, (vaddr_t)dst, 0, len);
                    161:        else {
                    162:                bus_space_set_region_2(&vme_bustag, 0, (vaddr_t)dst, 0, len / 2);
                    163:                if (len & 1)
                    164:                        bus_space_write_1(&vme_bustag, 0, dst + len - 1, 0);
                    165:        }
                    166: }
                    167:
                    168: /*
                    169:  * Configuration glue
                    170:  */
                    171:
                    172: int
                    173: vmematch(parent, cf, args)
                    174:        struct device *parent;
                    175:        void *cf;
                    176:        void *args;
                    177: {
                    178: #ifdef MVME187
                    179:        if (brdtyp == BRD_8120)
                    180:                return (0);
                    181: #endif
                    182:        return (1);
                    183: }
                    184:
                    185: int
                    186: vmeprint(args, bus)
                    187:        void *args;
                    188:        const char *bus;
                    189: {
                    190:        struct confargs *ca = args;
                    191:
                    192:        printf(" addr 0x%x", ca->ca_paddr);
                    193:        if (ca->ca_ipl > 0)
                    194:                printf(" ipl %d", ca->ca_ipl);
                    195:        if (ca->ca_vec > 0)
                    196:                printf(" vec 0x%x", ca->ca_vec);
                    197:        return (UNCONF);
                    198: }
                    199:
                    200: int
                    201: vmescan(parent, child, args, bustype)
                    202:        struct device *parent;
                    203:        void *child, *args;
                    204:        int bustype;
                    205: {
                    206:        struct cfdata *cf = child;
                    207:        struct confargs oca, *ca = args;
                    208:
                    209:        bzero(&oca, sizeof oca);
                    210:        oca.ca_iot = &vme_bustag;
                    211:        oca.ca_dmat = ca->ca_dmat;
                    212:        oca.ca_bustype = bustype;
                    213:        oca.ca_paddr = cf->cf_loc[0];
                    214:        oca.ca_vec = cf->cf_loc[1];
                    215:        oca.ca_ipl = cf->cf_loc[2];
                    216:        if (oca.ca_ipl > 0 && oca.ca_vec < 0)
                    217:                oca.ca_vec = vme_findvec(-1);
                    218:        oca.ca_name = cf->cf_driver->cd_name;
                    219:
                    220:        if ((*cf->cf_attach->ca_match)(parent, cf, &oca) == 0)
                    221:                return (0);
                    222:
                    223:        config_attach(parent, cf, &oca, vmeprint);
                    224:        return (1);
                    225: }
                    226:
                    227: void
                    228: vmeattach(parent, self, args)
                    229:        struct device *parent, *self;
                    230:        void *args;
                    231: {
                    232:        struct vmesoftc *sc = (struct vmesoftc *)self;
                    233:        struct confargs *ca = args;
                    234:
                    235:        /*
                    236:         * This is a waste if we are attached to SYSCON - but then obio
                    237:         * mappings are free...
                    238:         */
                    239:        sc->sc_iot = ca->ca_iot;
                    240:        if (bus_space_map(sc->sc_iot, ca->ca_paddr, PAGE_SIZE, 0,
                    241:            &sc->sc_ioh) != 0) {
                    242:                printf(": can't map registers!\n");
                    243:                return;
                    244:        }
                    245:
                    246:        vmebustype = ca->ca_bustype;
                    247:
                    248:        switch (ca->ca_bustype) {
                    249: #if NPCCTWO > 0
                    250:        case BUS_PCCTWO:
                    251:        {
                    252:                u_int32_t vbr;
                    253:
                    254:                /* Sanity check that the BUG is set up right */
                    255:                vbr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_VBR);
                    256:                vmevecbase = VME2_GET_VBR1(vbr) + 0x10;
                    257:                if (vmevecbase >= 0x100) {
                    258:                        panic("Correct the VME Vector Base Registers "
                    259:                            "in the Bug ROM.\n"
                    260:                            "Suggested values are 0x60 for VME Vec0 and "
                    261:                            "0x70 for VME Vec1.");
                    262:                }
                    263:
                    264:                if ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_TCTL) &
                    265:                    VME2_TCTL_SCON) != 0)
                    266:                        printf(": system controller");
                    267:                printf("\n");
                    268:
                    269:                vme2chip_init(sc);
                    270:        }
                    271:                break;
                    272: #endif
                    273: #if NSYSCON > 0
                    274:        case BUS_SYSCON:
                    275:        {
                    276:                u_int8_t sconc;
                    277:
                    278:                vmevecbase = 0x60;  /* Hard coded for MVME188 */
                    279:                sconc = *(volatile u_int8_t *)MVME188_GLOBAL1;
                    280:                if (ISSET(sconc, M188_SYSCON))
                    281:                        printf(": system controller");
                    282:                printf("\n");
                    283:
                    284:                vmesyscon_init(sc);
                    285:        }
                    286:                break;
                    287: #endif
                    288:        }
                    289:
                    290:        while (config_found(self, NULL, NULL))
                    291:                ;
                    292: }
                    293:
                    294: /* find a VME vector based on what is in NVRAM settings. */
                    295: int
                    296: vme_findvec(int skip)
                    297: {
                    298:        return intr_findvec(vmevecbase, 0xff, skip);
                    299: }
                    300:
                    301: /*
                    302:  * make local addresses 1G-2G correspond to VME addresses 3G-4G,
                    303:  * as D32
                    304:  */
                    305:
                    306: #define VME2_D32STARTPHYS      (1*1024*1024*1024UL)
                    307: #define VME2_D32ENDPHYS                (2*1024*1024*1024UL)
                    308: #define VME2_D32STARTVME       (3*1024*1024*1024UL)
                    309: #define VME2_D32BITSVME                (3*1024*1024*1024UL)
                    310:
                    311: /*
                    312:  * make local addresses 3G-3.75G correspond to VME addresses 3G-3.75G,
                    313:  * as D16
                    314:  */
                    315: #define VME2_D16STARTPHYS      (3*1024*1024*1024UL)
                    316: #define VME2_D16ENDPHYS                (3*1024*1024*1024UL + 768*1024*1024UL)
                    317: #define VME2_A32D16STARTPHYS   (0xff000000UL)
                    318: #define VME2_A32D16ENDPHYS     (0xff7fffffUL)
                    319:
                    320:
                    321: /*
                    322:  * Returns a physical address mapping for a VME address & length.
                    323:  * Note: on some hardware it is not possible to create certain
                    324:  * mappings, ie. the MVME147 cannot do 32 bit accesses to VME bus
                    325:  * addresses from 0 to physmem.
                    326:  */
                    327: paddr_t
                    328: vmepmap(sc, vmeaddr, bustype)
                    329:        struct device *sc;
                    330:        off_t vmeaddr;
                    331:        int bustype;
                    332: {
                    333:        u_int32_t base = (u_int32_t)vmeaddr;    /* wrap around 4GB */
                    334:
                    335:        switch (vmebustype) {
                    336: #if NPCCTWO > 0 || NSYSCON > 0
                    337:        case BUS_PCCTWO:
                    338:        case BUS_SYSCON:
                    339:                switch (bustype) {
                    340:                case BUS_VMES:          /* D16 VME Transfers */
                    341: #ifdef DEBUG
                    342:                        printf("base 0x%8llx/0x%8x\n",
                    343:                            vmeaddr, base);
                    344: #endif
                    345:                        base = vme2chip_map(base, 16);
                    346: #ifdef DEBUG
                    347:                        if (base == NULL) {
                    348:                                printf("%s: cannot map pa 0x%x\n",
                    349:                                    sc->dv_xname, base);
                    350:                        }
                    351: #endif
                    352:                        break;
                    353:                case BUS_VMEL:          /* D32 VME Transfers */
                    354: #ifdef DEBUG
                    355:                        printf("base 0x%8llx/0x%8x\n",
                    356:                            vmeaddr, base);
                    357: #endif
                    358:                        base = vme2chip_map(base, 32);
                    359: #ifdef DEBUG
                    360:                        if (base == NULL) {
                    361:                                printf("%s: cannot map pa 0x%x\n",
                    362:                                    sc->dv_xname, base);
                    363:                        }
                    364: #endif
                    365:                        break;
                    366:                }
                    367:                break;
                    368: #endif
                    369:        default:
                    370:                return NULL;
                    371:        }
                    372:        return (base);
                    373: }
                    374:
                    375: static vaddr_t vmemap(struct vmesoftc *, off_t);
                    376: static void vmeunmap(paddr_t);
                    377:
                    378: /* if successful, returns the va of a vme bus mapping */
                    379: static __inline__ vaddr_t
                    380: vmemap(struct vmesoftc *sc, off_t vmeaddr)
                    381: {
                    382:        paddr_t pa;
                    383:
                    384:        pa = vmepmap((struct device *)sc, vmeaddr, BUS_VMES);
                    385:        if (pa == NULL)
                    386:                return (NULL);
                    387:        return mapiodev(pa, PAGE_SIZE);
                    388: }
                    389:
                    390: static __inline__ void
                    391: vmeunmap(vaddr_t va)
                    392: {
                    393:        unmapiodev(va, PAGE_SIZE);
                    394: }
                    395:
                    396: int
                    397: vmerw(sc, uio, flags, bus)
                    398:        struct device *sc;
                    399:        struct uio *uio;
                    400:        int flags;
                    401:        int bus;
                    402: {
                    403:        vaddr_t v;
                    404:        int c;
                    405:        struct iovec *iov;
                    406:        paddr_t vme;
                    407:        int error = 0;
                    408:
                    409:        while (uio->uio_resid > 0 && error == 0) {
                    410:                iov = uio->uio_iov;
                    411:                if (iov->iov_len == 0) {
                    412:                        uio->uio_iov++;
                    413:                        uio->uio_iovcnt--;
                    414:                        if (uio->uio_iovcnt < 0)
                    415:                                panic("vmerw");
                    416:                        continue;
                    417:                }
                    418:
                    419:                v = uio->uio_offset;
                    420:                c = min(iov->iov_len, MAXPHYS);
                    421:                if ((v & PGOFSET) + c > PAGE_SIZE) /* max 1 page at a time */
                    422:                        c = PAGE_SIZE - (v & PGOFSET);
                    423:                if (c == 0)
                    424:                        return 0;
                    425:                vme = vmemap((struct vmesoftc *)sc, v & ~PGOFSET);
                    426:                if (vme == NULL)
                    427:                        return EACCES;
                    428:                error = uiomove((void *)vme + (v & PGOFSET), c, uio);
                    429:                vmeunmap(vme);
                    430:        }
                    431:        return error;
                    432: }
                    433:
                    434: #ifdef MVME188
                    435: /*
                    436:  * Currently registered VME interrupt vectors for a given IPL, if they
                    437:  * are unique. Used to help the MVME188 interrupt handler when it's getting
                    438:  * behind.
                    439:  */
                    440: u_int vmevec_hints[8] = {
                    441:        (u_int)-1, (u_int)-1, (u_int)-1, (u_int)-1,
                    442:        (u_int)-1, (u_int)-1, (u_int)-1, (u_int)-1
                    443: };
                    444: #endif
                    445:
                    446: /*
                    447:  * On the VMEbus, only one cpu may be configured to respond to any
                    448:  * particular vme ipl. Therefore, it wouldn't make sense to globally
                    449:  * enable all the interrupts all the time -- it would not be possible
                    450:  * to put two cpu's and one vme card into a single cage. Rather, we
                    451:  * enable each vme interrupt only when we are attaching a device that
                    452:  * uses it. This makes it easier (though not trivial) to put two cpu
                    453:  * cards in one VME cage, and both can have some limited access to vme
                    454:  * interrupts (just can't share the same irq).
                    455:  * Obviously no check is made to see if another cpu is using that
                    456:  * interrupt. If you share you will lose.
                    457:  */
                    458:
                    459: int
                    460: vmeintr_establish(int vec, struct intrhand *ih, const char *name)
                    461: {
                    462:        struct vmesoftc *sc = (struct vmesoftc *) vme_cd.cd_devs[0];
                    463:        int rc;
                    464:
                    465: #ifdef DIAGNOSTIC
                    466:        if (ih->ih_ipl < 1 || ih->ih_ipl > 7)
                    467:                return (EINVAL);
                    468: #endif
                    469:
                    470:        switch (vmebustype) {
                    471: #if NPCCTWO > 0
                    472:        case BUS_PCCTWO:
                    473:                bus_space_write_4(sc->sc_iot, sc->sc_ioh, VME2_IRQEN,
                    474:                    bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_IRQEN) |
                    475:                    VME2_IRQ_VME(ih->ih_ipl));
                    476:                break;
                    477: #endif
                    478:        }
                    479:
                    480:        if ((rc = intr_establish(vec, ih, name)) != 0)
                    481:                return (rc);
                    482:
                    483: #ifdef MVME188
                    484:        if (vmevec_hints[ih->ih_ipl] == (u_int)-1)
                    485:                vmevec_hints[ih->ih_ipl] = vec;
                    486:        else
                    487:                vmevec_hints[ih->ih_ipl] = (u_int)-1;
                    488: #endif
                    489:
                    490:        return (0);
                    491: }
                    492:
                    493: #if NPCCTWO > 0
                    494: void
                    495: vme2chip_init(sc)
                    496:        struct vmesoftc *sc;
                    497: {
                    498:        u_int32_t ctl, irqen, master, master4mod;
                    499:
                    500:        /* turn off SYSFAIL LED */
                    501:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, VME2_TCTL,
                    502:            bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_TCTL) &
                    503:            ~VME2_TCTL_SYSFAIL);
                    504:
                    505:        /*
                    506:         * Display the VMEChip2 decoder status.
                    507:         */
                    508:        printf("%s: using BUG parameters\n", sc->sc_dev.dv_xname);
                    509:        ctl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_GCSRCTL);
                    510:        if (ctl & VME2_GCSRCTL_MDEN1) {
                    511:                master = bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_MASTER1);
                    512:                printf("%s: 1phys 0x%08lx-0x%08lx to VME 0x%08lx-0x%08lx\n",
                    513:                    sc->sc_dev.dv_xname, master << 16, master & 0xffff0000,
                    514:                    master << 16, master & 0xffff0000);
                    515:        }
                    516:        if (ctl & VME2_GCSRCTL_MDEN2) {
                    517:                master = bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_MASTER2);
                    518:                printf("%s: 2phys 0x%08lx-0x%08lx to VME 0x%08lx-0x%08lx\n",
                    519:                    sc->sc_dev.dv_xname, master << 16, master & 0xffff0000,
                    520:                    master << 16, master & 0xffff0000);
                    521:        }
                    522:        if (ctl & VME2_GCSRCTL_MDEN3) {
                    523:                master = bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_MASTER3);
                    524:                printf("%s: 3phys 0x%08lx-0x%08lx to VME 0x%08lx-0x%08lx\n",
                    525:                    sc->sc_dev.dv_xname, master << 16, master & 0xffff0000,
                    526:                    master << 16, master & 0xffff0000);
                    527:        }
                    528:        if (ctl & VME2_GCSRCTL_MDEN4) {
                    529:                master = bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_MASTER4);
                    530:                master4mod = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
                    531:                    VME2_MASTER4MOD);
                    532:                printf("%s: 4phys 0x%08lx-0x%08lx to VME 0x%08lx-0x%08lx\n",
                    533:                    sc->sc_dev.dv_xname, master << 16, master & 0xffff0000,
                    534:                    (master << 16) + (master4mod << 16),
                    535:                    (master & 0xffff0000) + (master4mod & 0xffff0000));
                    536:        }
                    537:
                    538:        /*
                    539:         * Map the VME irq levels to the cpu levels 1:1.
                    540:         * This is rather inflexible, but much easier.
                    541:         */
                    542:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, VME2_IRQL4,
                    543:            (7 << VME2_IRQL4_VME7SHIFT) | (6 << VME2_IRQL4_VME6SHIFT) |
                    544:            (5 << VME2_IRQL4_VME5SHIFT) | (4 << VME2_IRQL4_VME4SHIFT) |
                    545:            (3 << VME2_IRQL4_VME3SHIFT) | (2 << VME2_IRQL4_VME2SHIFT) |
                    546:            (1 << VME2_IRQL4_VME1SHIFT));
                    547:        printf("%s: vme to cpu irq level 1:1\n",sc->sc_dev.dv_xname);
                    548:
                    549:        /* Enable the reset switch */
                    550:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, VME2_TCTL, VME2_TCTL_RSWE |
                    551:            bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_TCTL));
                    552:        /* Set Watchdog timeout to about 1 minute */
                    553:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, VME2_TCR, VME2_TCR_64S |
                    554:            bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_TCR));
                    555:        /* Enable VMEChip2 Interrupts */
                    556:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, VME2_VBR, VME2_IOCTL1_MIEN |
                    557:            bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_VBR));
                    558:
                    559:        /*
                    560:         * Map the Software VME irq levels to the cpu level 7.
                    561:        */
                    562:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, VME2_IRQL3,
                    563:            (7 << VME2_IRQL3_SW7SHIFT) | (7 << VME2_IRQL3_SW6SHIFT) |
                    564:            (7 << VME2_IRQL3_SW5SHIFT) | (7 << VME2_IRQL3_SW4SHIFT) |
                    565:            (7 << VME2_IRQL3_SW3SHIFT) | (7 << VME2_IRQL3_SW2SHIFT) |
                    566:            (7 << VME2_IRQL3_SW1SHIFT));
                    567:
                    568:        /*
                    569:         * pseudo driver, abort interrupt handler
                    570:         */
                    571:        sc->sc_abih.ih_fn = vme2abort;
                    572:        sc->sc_abih.ih_arg = 0;
                    573:        sc->sc_abih.ih_wantframe = 1;
                    574:        sc->sc_abih.ih_ipl = IPL_NMI;
                    575:        intr_establish(110, &sc->sc_abih, sc->sc_dev.dv_xname);
                    576:
                    577:        irqen = bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_IRQEN);
                    578:        irqen |= VME2_IRQ_AB;
                    579:        /* bus_space_write_4(sc->sc_iot, sc->sc_ioh, VME2_IRQEN, irqen); */
                    580:
                    581:        /*
                    582:         * Enable ACFAIL interrupt, but disable Timer 1 interrupt - we
                    583:         * prefer it without for delay().
                    584:         */
                    585:        irqen = (irqen | VME2_IRQ_ACF) & ~VME2_IRQ_TIC1;
                    586:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, VME2_IRQEN, irqen);
                    587: }
                    588: #endif /* NPCCTWO */
                    589:
                    590: #if NSYSCON > 0
                    591: void
                    592: vmesyscon_init(sc)
                    593:        struct vmesoftc *sc;
                    594: {
                    595:        u_int32_t ucsr;
                    596:
                    597:        /*
                    598:         * Force a reasonable timeout for VME data transfers.
                    599:         * We can not disable this, this would cause autoconf to hang
                    600:         * on the first missing device we'll probe.
                    601:         */
                    602:        ucsr = *(volatile u_int32_t*)MVME188_UCSR;
                    603:        ucsr = (ucsr & ~VTOSELBITS) | VTO128US;
                    604:        *(volatile u_int32_t *)MVME188_UCSR = ucsr;
                    605: }
                    606: #endif /* NSYSCON */
                    607:
                    608: /*
                    609:  * A32 accesses on the MVME1[6789]x require setting up mappings in
                    610:  * the VME2 chip.
                    611:  * XXX VME address must be between 2G and 4G
                    612:  * XXX We only support D32 at the moment..
                    613:  * XXX smurph - This is bogus, get rid of it! Should check vme/syscon for offsets.
                    614:  */
                    615: u_long
                    616: vme2chip_map(base, dwidth)
                    617:        u_long base;
                    618:        int dwidth;
                    619: {
                    620:        /*
                    621:         * Since we are checking range for one page only, no need to check
                    622:         * for address wraparound.
                    623:         */
                    624:        switch (dwidth) {
                    625:        case 16:
                    626:                if (base < VME2_D16STARTPHYS ||
                    627:                    base + PAGE_SIZE > VME2_D16ENDPHYS)
                    628:                        return NULL;
                    629:                break;
                    630:        case 32:
                    631:                if (base < VME2_D32STARTPHYS ||
                    632:                    base + PAGE_SIZE > VME2_D32ENDPHYS)
                    633:                        return NULL;
                    634:                break;
                    635:        default:
                    636:                return NULL;
                    637:        }
                    638:        return base;
                    639: }
                    640:
                    641: #if NPCCTWO > 0
                    642: int
                    643: vme2abort(eframe)
                    644:        void *eframe;
                    645: {
                    646:        struct vmesoftc *sc = (struct vmesoftc *)vme_cd.cd_devs[0];
                    647:
                    648:        if ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, VME2_IRQSTAT) &
                    649:            VME2_IRQ_AB) == 0) {
                    650:                printf("%s: abort irq not set\n", sc->sc_dev.dv_xname);
                    651:                return (0);
                    652:        }
                    653:
                    654:        bus_space_write_4(sc->sc_iot, sc->sc_ioh, VME2_IRQCLR, VME2_IRQ_AB);
                    655:        nmihand(eframe);
                    656:        return (1);
                    657: }
                    658: #endif

CVSweb