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

Annotation of sys/arch/hppa/dev/mongoose.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: mongoose.c,v 1.17 2004/11/08 20:54:04 miod Exp $      */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 1998-2003 Michael Shalayeff
        !             5:  * All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  *
        !            16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            18:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            19:  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
        !            20:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            21:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            22:  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            24:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
        !            25:  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
        !            26:  * THE POSSIBILITY OF SUCH DAMAGE.
        !            27:  */
        !            28:
        !            29: #include <sys/param.h>
        !            30: #include <sys/systm.h>
        !            31: #include <sys/device.h>
        !            32: #include <sys/reboot.h>
        !            33:
        !            34: #include <machine/bus.h>
        !            35: #include <machine/iomod.h>
        !            36: #include <machine/autoconf.h>
        !            37:
        !            38: #include <hppa/dev/cpudevs.h>
        !            39: #include <hppa/dev/viper.h>
        !            40:
        !            41: #include <dev/eisa/eisareg.h>
        !            42: #include <dev/eisa/eisavar.h>
        !            43:
        !            44: #include <dev/isa/isareg.h>
        !            45: #include <dev/isa/isavar.h>
        !            46:
        !            47: #include <hppa/dev/mongoosereg.h>
        !            48: #include <hppa/dev/mongoosevar.h>
        !            49:
        !            50: void   mgattach_gedoens(struct device *, struct device *, void *);
        !            51: int    mgmatch_gedoens(struct device *, void *, void *);
        !            52:
        !            53: struct cfattach mg_gedoens_ca = {
        !            54:        sizeof(struct mongoose_softc), mgmatch_gedoens, mgattach_gedoens
        !            55: };
        !            56:
        !            57: struct cfdriver mongoose_cd = {
        !            58:        NULL, "mongoose", DV_DULL
        !            59: };
        !            60:
        !            61: /* TODO: DMA guts */
        !            62:
        !            63: void
        !            64: mg_eisa_attach_hook(struct device *parent, struct device *self,
        !            65:        struct eisabus_attach_args *mg)
        !            66: {
        !            67: }
        !            68:
        !            69: int
        !            70: mg_intr_map(void *v, u_int irq, eisa_intr_handle_t *ehp)
        !            71: {
        !            72:        *ehp = irq;
        !            73:        return 0;
        !            74: }
        !            75:
        !            76: const char *
        !            77: mg_intr_string(void *v, int irq)
        !            78: {
        !            79:        static char buf[16];
        !            80:
        !            81:        snprintf(buf, sizeof buf, "isa irq %d", irq);
        !            82:        return buf;
        !            83: }
        !            84:
        !            85: void
        !            86: mg_isa_attach_hook(struct device *parent, struct device *self,
        !            87:        struct isabus_attach_args *iba)
        !            88: {
        !            89:
        !            90: }
        !            91:
        !            92: void *
        !            93: mg_intr_establish(void *v, int irq, int type, int pri,
        !            94:        int (*handler)(void *), void *arg, const char *name)
        !            95: {
        !            96:        struct hppa_isa_iv *iv;
        !            97:        struct mongoose_softc *sc = v;
        !            98:        volatile u_int8_t *imr, *pic;
        !            99:
        !           100:        if (!sc || irq < 0 || irq >= MONGOOSE_NINTS ||
        !           101:            (0 <= irq && irq < MONGOOSE_NINTS && sc->sc_iv[irq].iv_handler))
        !           102:                return NULL;
        !           103:
        !           104:        if (type != IST_LEVEL && type != IST_EDGE) {
        !           105: #ifdef DEBUG
        !           106:                printf("%s: bad interrupt level (%d)\n", sc->sc_dev.dv_xname,
        !           107:                    type);
        !           108: #endif
        !           109:                return NULL;
        !           110:        }
        !           111:
        !           112:        iv = &sc->sc_iv[irq];
        !           113:        if (iv->iv_handler) {
        !           114: #ifdef DEBUG
        !           115:                printf("%s: irq %d already established\n", sc->sc_dev.dv_xname,
        !           116:                    irq);
        !           117: #endif
        !           118:                return NULL;
        !           119:        }
        !           120:
        !           121:        iv->iv_name = name;
        !           122:        iv->iv_pri = pri;
        !           123:        iv->iv_handler = handler;
        !           124:        iv->iv_arg = arg;
        !           125:
        !           126:        if (irq < 8) {
        !           127:                imr = &sc->sc_ctrl->imr0;
        !           128:                pic = &sc->sc_ctrl->pic0;
        !           129:        } else {
        !           130:                imr = &sc->sc_ctrl->imr1;
        !           131:                pic = &sc->sc_ctrl->pic1;
        !           132:                irq -= 8;
        !           133:        }
        !           134:
        !           135:        *imr |= 1 << irq;
        !           136:        *pic |= (type == IST_LEVEL) << irq;
        !           137:
        !           138:        /* TODO: ack it? */
        !           139:
        !           140:        return iv;
        !           141: }
        !           142:
        !           143: void
        !           144: mg_intr_disestablish(void *v, void *cookie)
        !           145: {
        !           146:        struct hppa_isa_iv *iv = cookie;
        !           147:        struct mongoose_softc *sc = v;
        !           148:        int irq = iv - sc->sc_iv;
        !           149:        volatile u_int8_t *imr;
        !           150:
        !           151:        if (!sc || !cookie)
        !           152:                return;
        !           153:
        !           154:        if (irq < 8)
        !           155:                imr = &sc->sc_ctrl->imr0;
        !           156:        else
        !           157:                imr = &sc->sc_ctrl->imr1;
        !           158:        *imr &= ~(1 << irq);
        !           159:        /* TODO: ack it? */
        !           160:
        !           161:        iv->iv_handler = NULL;
        !           162: }
        !           163:
        !           164: int
        !           165: mg_intr_check(void *v, int irq, int type)
        !           166: {
        !           167:        return 0;
        !           168: }
        !           169:
        !           170: int
        !           171: mg_intr(void *v)
        !           172: {
        !           173:        struct mongoose_softc *sc = v;
        !           174:        struct hppa_isa_iv *iv;
        !           175:        int s, irq = 0;
        !           176:
        !           177:        iv = &sc->sc_iv[irq];
        !           178:        s = splraise(iv->iv_pri);
        !           179:        (iv->iv_handler)(iv->iv_arg);
        !           180:        splx(s);
        !           181:
        !           182:        return 0;
        !           183: }
        !           184:
        !           185: int
        !           186: mg_eisa_iomap(void *v, bus_addr_t addr, bus_size_t size, int cacheable,
        !           187:        bus_space_handle_t *bshp)
        !           188: {
        !           189:        struct mongoose_softc *sc = v;
        !           190:
        !           191:        /* see if it's ISA space we are mapping */
        !           192:        if (0x100 <= addr && addr < 0x400) {
        !           193: #define        TOISA(a) ((((a) & 0x3f8) << 9) + ((a) & 7))
        !           194:                size = TOISA(addr + size) - TOISA(addr);
        !           195:                addr = TOISA(addr);
        !           196:        }
        !           197:
        !           198:        return (sc->sc_bt->hbt_map)(NULL, sc->sc_iomap + addr, size,
        !           199:                                    cacheable, bshp);
        !           200: }
        !           201:
        !           202: int
        !           203: mg_eisa_memmap(void *v, bus_addr_t addr, bus_size_t size, int cacheable,
        !           204:        bus_space_handle_t *bshp)
        !           205: {
        !           206:        /* TODO: eisa memory map */
        !           207:        return -1;
        !           208: }
        !           209:
        !           210: void
        !           211: mg_eisa_memunmap(void *v, bus_space_handle_t bsh, bus_size_t size)
        !           212: {
        !           213:        /* TODO: eisa memory unmap */
        !           214: }
        !           215:
        !           216: void
        !           217: mg_isa_barrier(void *v, bus_space_handle_t h, bus_size_t o, bus_size_t l, int op)
        !           218: {
        !           219:        sync_caches();
        !           220: }
        !           221:
        !           222: u_int16_t
        !           223: mg_isa_r2(void *v, bus_space_handle_t h, bus_size_t o)
        !           224: {
        !           225:        register u_int16_t r = *((volatile u_int16_t *)(h + o));
        !           226:        return letoh16(r);
        !           227: }
        !           228:
        !           229: u_int32_t
        !           230: mg_isa_r4(void *v, bus_space_handle_t h, bus_size_t o)
        !           231: {
        !           232:        register u_int32_t r = *((volatile u_int32_t *)(h + o));
        !           233:        return letoh32(r);
        !           234: }
        !           235:
        !           236: void
        !           237: mg_isa_w2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv)
        !           238: {
        !           239:        *((volatile u_int16_t *)(h + o)) = htole16(vv);
        !           240: }
        !           241:
        !           242: void
        !           243: mg_isa_w4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv)
        !           244: {
        !           245:        *((volatile u_int32_t *)(h + o)) = htole32(vv);
        !           246: }
        !           247:
        !           248: void
        !           249: mg_isa_rm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
        !           250: {
        !           251:        h += o;
        !           252:        while (c--)
        !           253:                *(a++) = letoh16(*(volatile u_int16_t *)h);
        !           254: }
        !           255:
        !           256: void
        !           257: mg_isa_rm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
        !           258: {
        !           259:        h += o;
        !           260:        while (c--)
        !           261:                *(a++) = letoh32(*(volatile u_int32_t *)h);
        !           262: }
        !           263:
        !           264: void
        !           265: mg_isa_wm_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
        !           266: {
        !           267:        register u_int16_t r;
        !           268:        h += o;
        !           269:        while (c--) {
        !           270:                r = *(a++);
        !           271:                *(volatile u_int16_t *)h = htole16(r);
        !           272:        }
        !           273: }
        !           274:
        !           275: void
        !           276: mg_isa_wm_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
        !           277: {
        !           278:        register u_int32_t r;
        !           279:        h += o;
        !           280:        while (c--) {
        !           281:                r = *(a++);
        !           282:                *(volatile u_int32_t *)h = htole32(r);
        !           283:        }
        !           284: }
        !           285:
        !           286: void
        !           287: mg_isa_sm_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
        !           288: {
        !           289:        vv = htole16(vv);
        !           290:        h += o;
        !           291:        while (c--)
        !           292:                *(volatile u_int16_t *)h = vv;
        !           293: }
        !           294:
        !           295: void
        !           296: mg_isa_sm_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
        !           297: {
        !           298:        vv = htole32(vv);
        !           299:        h += o;
        !           300:        while (c--)
        !           301:                *(volatile u_int32_t *)h = vv;
        !           302: }
        !           303:
        !           304: void
        !           305: mg_isa_rr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t *a, bus_size_t c)
        !           306: {
        !           307:        register u_int16_t r;
        !           308:        h += o;
        !           309:        while (c--) {
        !           310:                r = *((volatile u_int16_t *)h)++;
        !           311:                *(a++) = letoh16(r);
        !           312:        }
        !           313: }
        !           314:
        !           315: void
        !           316: mg_isa_rr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t *a, bus_size_t c)
        !           317: {
        !           318:        register u_int32_t r;
        !           319:        h += o;
        !           320:        while (c--) {
        !           321:                r = *((volatile u_int32_t *)h)++;
        !           322:                *(a++) = letoh32(r);
        !           323:        }
        !           324: }
        !           325:
        !           326: void
        !           327: mg_isa_wr_2(void *v, bus_space_handle_t h, bus_size_t o, const u_int16_t *a, bus_size_t c)
        !           328: {
        !           329:        register u_int16_t r;
        !           330:        h += o;
        !           331:        while (c--) {
        !           332:                r = *(a++);
        !           333:                *((volatile u_int16_t *)h)++ = htole16(r);
        !           334:        }
        !           335: }
        !           336:
        !           337: void
        !           338: mg_isa_wr_4(void *v, bus_space_handle_t h, bus_size_t o, const u_int32_t *a, bus_size_t c)
        !           339: {
        !           340:        register u_int32_t r;
        !           341:        h += o;
        !           342:        while (c--) {
        !           343:                r = *(a++);
        !           344:                *((volatile u_int32_t *)h)++ = htole32(r);
        !           345:        }
        !           346: }
        !           347:
        !           348: void
        !           349: mg_isa_sr_2(void *v, bus_space_handle_t h, bus_size_t o, u_int16_t vv, bus_size_t c)
        !           350: {
        !           351:        vv = htole16(vv);
        !           352:        h += o;
        !           353:        while (c--)
        !           354:                *((volatile u_int16_t *)h)++ = vv;
        !           355: }
        !           356:
        !           357: void
        !           358: mg_isa_sr_4(void *v, bus_space_handle_t h, bus_size_t o, u_int32_t vv, bus_size_t c)
        !           359: {
        !           360:        vv = htole32(vv);
        !           361:        h += o;
        !           362:        while (c--)
        !           363:                *((volatile u_int32_t *)h)++ = vv;
        !           364: }
        !           365:
        !           366: int
        !           367: mgattach_common(sc)
        !           368:        struct mongoose_softc *sc;
        !           369: {
        !           370:        struct hppa_bus_space_tag *bt;
        !           371:        union mongoose_attach_args ea;
        !           372:        char brid[EISA_IDSTRINGLEN];
        !           373:
        !           374:        viper_eisa_en();
        !           375:
        !           376:        /* BUS RESET */
        !           377:        sc->sc_ctrl->nmi_ext = MONGOOSE_NMI_BUSRESET;
        !           378:        DELAY(1);
        !           379:        sc->sc_ctrl->nmi_ext = 0;
        !           380:        DELAY(100);
        !           381:
        !           382:        /* determine eisa board id */
        !           383:        {
        !           384:                u_int8_t id[4], *p;
        !           385:                p = (u_int8_t *)(sc->sc_iomap + EISA_SLOTOFF_VID);
        !           386:                id[0] = *p++;
        !           387:                id[1] = *p++;
        !           388:                id[2] = *p++;
        !           389:                id[3] = *p++;
        !           390:
        !           391:                brid[0] = EISA_VENDID_0(id);
        !           392:                brid[1] = EISA_VENDID_1(id);
        !           393:                brid[2] = EISA_VENDID_2(id);
        !           394:                brid[3] = EISA_PRODID_0(id + 2);
        !           395:                brid[4] = EISA_PRODID_1(id + 2);
        !           396:                brid[5] = EISA_PRODID_2(id + 2);
        !           397:                brid[6] = EISA_PRODID_3(id + 2);
        !           398:                brid[7] = '\0';
        !           399:        }
        !           400:
        !           401:        printf (": %s rev %d, %d MHz\n", brid, sc->sc_regs->version,
        !           402:                (sc->sc_regs->clock? 33 : 25));
        !           403:        sc->sc_regs->liowait = 1;       /* disable isa wait states */
        !           404:        sc->sc_regs->lock    = 1;       /* bus unlock */
        !           405:
        !           406:        /* attach EISA */
        !           407:        sc->sc_ec.ec_v = sc;
        !           408:        sc->sc_ec.ec_attach_hook = mg_eisa_attach_hook;
        !           409:        sc->sc_ec.ec_intr_establish = mg_intr_establish;
        !           410:        sc->sc_ec.ec_intr_disestablish = mg_intr_disestablish;
        !           411:        sc->sc_ec.ec_intr_string = mg_intr_string;
        !           412:        sc->sc_ec.ec_intr_map = mg_intr_map;
        !           413:        /* inherit the bus tags for eisa from the mainbus */
        !           414:        bt = &sc->sc_eiot;
        !           415:        bcopy(sc->sc_bt, bt, sizeof(*bt));
        !           416:        bt->hbt_cookie = sc;
        !           417:        bt->hbt_map = mg_eisa_iomap;
        !           418: #define        R(n)    bt->__CONCAT(hbt_,n) = &__CONCAT(mg_isa_,n)
        !           419:        /* R(barrier); */
        !           420:        R(r2); R(r4); R(w2); R(w4);
        !           421:        R(rm_2);R(rm_4);R(wm_2);R(wm_4);R(sm_2);R(sm_4);
        !           422:        R(rr_2);R(rr_4);R(wr_2);R(wr_4);R(sr_2);R(sr_4);
        !           423:
        !           424:        bt = &sc->sc_ememt;
        !           425:        bcopy(sc->sc_bt, bt, sizeof(*bt));
        !           426:        bt->hbt_cookie = sc;
        !           427:        bt->hbt_map = mg_eisa_memmap;
        !           428:        bt->hbt_unmap = mg_eisa_memunmap;
        !           429:        /* attachment guts */
        !           430:        ea.mongoose_eisa.eba_busname = "eisa";
        !           431:        ea.mongoose_eisa.eba_iot = &sc->sc_eiot;
        !           432:        ea.mongoose_eisa.eba_memt = &sc->sc_ememt;
        !           433:        ea.mongoose_eisa.eba_dmat = NULL /* &sc->sc_edmat */;
        !           434:        ea.mongoose_eisa.eba_ec = &sc->sc_ec;
        !           435:        config_found((struct device *)sc, &ea.mongoose_eisa, mgprint);
        !           436:
        !           437:        sc->sc_ic.ic_v = sc;
        !           438:        sc->sc_ic.ic_attach_hook = mg_isa_attach_hook;
        !           439:        sc->sc_ic.ic_intr_establish = mg_intr_establish;
        !           440:        sc->sc_ic.ic_intr_disestablish = mg_intr_disestablish;
        !           441:        sc->sc_ic.ic_intr_check = mg_intr_check;
        !           442:        /* inherit the bus tags for isa from the eisa */
        !           443:        bt = &sc->sc_imemt;
        !           444:        bcopy(&sc->sc_ememt, bt, sizeof(*bt));
        !           445:        bt = &sc->sc_iiot;
        !           446:        bcopy(&sc->sc_eiot, bt, sizeof(*bt));
        !           447:        /* TODO: DMA tags */
        !           448:        /* attachment guts */
        !           449:        ea.mongoose_isa.iba_busname = "isa";
        !           450:        ea.mongoose_isa.iba_iot = &sc->sc_iiot;
        !           451:        ea.mongoose_isa.iba_memt = &sc->sc_imemt;
        !           452: #if NISADMA > 0
        !           453:        ea.mongoose_isa.iba_dmat = &sc->sc_idmat;
        !           454: #endif
        !           455:        ea.mongoose_isa.iba_ic = &sc->sc_ic;
        !           456:        config_found((struct device *)sc, &ea.mongoose_isa, mgprint);
        !           457: #undef R
        !           458:
        !           459:        return (0);
        !           460: }
        !           461:
        !           462: int
        !           463: mgprint(aux, pnp)
        !           464:        void *aux;
        !           465:        const char *pnp;
        !           466: {
        !           467:        union mongoose_attach_args *ea = aux;
        !           468:
        !           469:        if (pnp)
        !           470:                printf ("%s at %s", ea->mongoose_name, pnp);
        !           471:
        !           472:        return (UNCONF);
        !           473: }
        !           474:
        !           475: int
        !           476: mgmatch_gedoens(parent, cfdata, aux)
        !           477:        struct device *parent;
        !           478:        void *cfdata;
        !           479:        void *aux;
        !           480: {
        !           481:        register struct confargs *ca = aux;
        !           482:        /* struct cfdata *cf = cfdata; */
        !           483:        bus_space_handle_t ioh;
        !           484:
        !           485:        if (ca->ca_type.iodc_type != HPPA_TYPE_BHA ||
        !           486:            (ca->ca_type.iodc_sv_model != HPPA_BHA_EISA &&
        !           487:             ca->ca_type.iodc_sv_model != HPPA_BHA_WEISA))
        !           488:                return 0;
        !           489:
        !           490:        if (bus_space_map(ca->ca_iot, ca->ca_hpa + MONGOOSE_MONGOOSE,
        !           491:            IOMOD_HPASIZE, 0, &ioh))
        !           492:                return 0;
        !           493:
        !           494:        /* XXX check EISA signature */
        !           495:
        !           496:        bus_space_unmap(ca->ca_iot, ioh, IOMOD_HPASIZE);
        !           497:
        !           498:        return 1;
        !           499: }
        !           500:
        !           501: void
        !           502: mgattach_gedoens(parent, self, aux)
        !           503:        struct device *parent;
        !           504:        struct device *self;
        !           505:        void *aux;
        !           506: {
        !           507:        register struct confargs *ca = aux;
        !           508:        register struct mongoose_softc *sc = (struct mongoose_softc *)self;
        !           509:
        !           510:        sc->sc_bt = ca->ca_iot;
        !           511:        sc->sc_iomap = ca->ca_hpa;
        !           512:        sc->sc_regs = (struct mongoose_regs *)(ca->ca_hpa + MONGOOSE_MONGOOSE);
        !           513:        sc->sc_ctrl = (struct mongoose_ctrl *)(ca->ca_hpa + MONGOOSE_CTRL);
        !           514:
        !           515:        if (mgattach_common(sc) != 0)
        !           516:                return;
        !           517:
        !           518:        /* attach interrupt */
        !           519:        sc->sc_ih = cpu_intr_establish(IPL_HIGH, ca->ca_irq,
        !           520:                                       mg_intr, sc, sc->sc_dev.dv_xname);
        !           521: }

CVSweb