[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

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