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

Annotation of sys/arch/hp300/dev/isabr.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: isabr.c,v 1.2 2007/01/14 17:54:45 miod Exp $  */
                      2:
                      3: /*
                      4:  * Copyright (c) 2007 Miodrag Vallat.
                      5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice, this permission notice, and the disclaimer below
                      9:  * appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     16:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     17:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  */
                     19:
                     20: /*
                     21:  * HP 9000/4xx model `t' single ISA slot attachment
                     22:  */
                     23:
                     24: #include <sys/param.h>
                     25: #include <sys/systm.h>
                     26: #include <sys/device.h>
                     27: #include <sys/extent.h>
                     28: #include <sys/malloc.h>
                     29:
                     30: #include <machine/autoconf.h>
                     31: #include <machine/bus.h>
                     32: #include <machine/cpu.h>
                     33: #include <machine/hp300spu.h>
                     34:
                     35: #include <uvm/uvm_extern.h>
                     36:
                     37: #include <dev/isa/isareg.h>
                     38: #include <dev/isa/isavar.h>
                     39:
                     40: #include <hp300/dev/frodoreg.h>
                     41: #include <hp300/dev/frodovar.h>
                     42: #include <hp300/dev/isabrreg.h>
                     43:
                     44: int    isabr_match(struct device *, void *, void *);
                     45: void   isabr_attach(struct device *, struct device *, void *);
                     46: int    isabr_print(void *, const char *);
                     47:
                     48: struct isabr_softc {
                     49:        struct device    sc_dev;
                     50:        struct extent   *sc_io_extent;
                     51:        struct extent   *sc_mem_extent;
                     52: };
                     53:
                     54: struct cfattach isabr_ca = {
                     55:        sizeof(struct isabr_softc), isabr_match, isabr_attach
                     56: };
                     57:
                     58: struct cfdriver isabr_cd = {
                     59:        NULL, "isabr", DV_DULL
                     60: };
                     61:
                     62: struct isabr_softc *isabr;
                     63:
                     64: int    isabr_bus_space_setup(struct isabr_softc *, struct frodo_attach_args *,
                     65:            struct isabus_attach_args *);
                     66:
                     67: int
                     68: isabr_match(struct device *parent, void *match, void *aux)
                     69: {
                     70:        struct frodo_attach_args *fa = aux;
                     71:        static int isa_matched = 0;
                     72:
                     73:        if (isa_matched != 0)
                     74:                return (0);
                     75:
                     76:        if (strcmp(fa->fa_name, isabr_cd.cd_name) != 0)
                     77:                return (0);
                     78:
                     79:        /*
                     80:         * We assume parent has checked our physical existence for us.
                     81:         */
                     82:
                     83:        return (isa_matched = 1);
                     84: }
                     85:
                     86: void
                     87: isabr_attach(struct device *parent, struct device *self, void *aux)
                     88: {
                     89:        struct isabus_attach_args iba;
                     90:        struct isabr_softc *sc = (struct isabr_softc *)self;
                     91:        struct frodo_attach_args *faa = (struct frodo_attach_args *)aux;
                     92:
                     93:        bzero(&iba, sizeof(iba));
                     94:
                     95:        if (isabr_bus_space_setup(sc, faa, &iba) != 0) {
                     96:                printf(": can not initialize bus_space\n");
                     97:                return;
                     98:        }
                     99:        printf("\n");
                    100:
                    101:        iba.iba_busname = "isa";
                    102:        config_found(self, &iba, isabr_print);
                    103: }
                    104:
                    105: int
                    106: isabr_print(void *aux, const char *pnp)
                    107: {
                    108:        if (pnp)
                    109:                printf("isa at %s", pnp);
                    110:        return (UNCONF);
                    111: }
                    112:
                    113: /*
                    114:  * ISA support functions
                    115:  */
                    116:
                    117: void
                    118: isa_attach_hook(struct device *parent, struct device *self,
                    119:     struct isabus_attach_args *iba)
                    120: {
                    121:        iba->iba_ic = parent;   /* isabr0 */
                    122: }
                    123:
                    124: /*
                    125:  * Interrupt handling.
                    126:  *
                    127:  * We are currently registering ISA interrupt handlers as Frodo interrupt
                    128:  * handlers directly. We can because model `t' only have a single slot.
                    129:  *
                    130:  * Eventually this should be replaced with an isabr interrupt dispatcher,
                    131:  * allowing multiple interrupts on the same Frodo line. This would also
                    132:  * move the ISA-specific acknowledge out of non-ISA Frodo lines processing.
                    133:  * And this would allow a real intr_disestablish function.
                    134:  */
                    135: void *
                    136: isa_intr_establish(isa_chipset_tag_t ic, int irq, int type, int level,
                    137:     int (*handler)(void *), void *arg, char *name)
                    138: {
                    139:        struct isabr_softc *sc = (struct isabr_softc *)ic;
                    140:        struct isr *isr;
                    141:        int fline;
                    142:
                    143:        /*
                    144:         * Frodo is configured for edge interrupts.
                    145:         */
                    146:        if (type != IST_EDGE) {
                    147: #ifdef DIAGNOSTIC
                    148:                printf("%s: non-edge interrupt type not supported on hp300\n",
                    149:                    name);
                    150: #endif
                    151:                return (NULL);
                    152:        }
                    153:
                    154:        switch (irq) {
                    155:        case 3:
                    156:        case 4:
                    157:        case 5:
                    158:        case 6:
                    159:                fline = FRODO_INTR_ILOW;
                    160:                break;
                    161:        case 7:
                    162:        case 9:
                    163:        case 10:
                    164:        case 11:
                    165:                fline = FRODO_INTR_IMID;
                    166:                break;
                    167:        case 12:
                    168:        case 14:
                    169:        case 15:
                    170:                fline = FRODO_INTR_IHI;
                    171:                break;
                    172:        default:
                    173: #ifdef DIAGNOSTIC
                    174:                printf("%s: ISA irq %d not available on " MACHINE "\n", name);
                    175: #endif
                    176:                return (NULL);
                    177:        }
                    178:
                    179:        isr = (struct isr *)malloc(sizeof(struct isr), M_DEVBUF, M_NOWAIT);
                    180:        if (isr == NULL)
                    181:                return (NULL);
                    182:
                    183:        isr->isr_func = handler;
                    184:        isr->isr_arg = arg;
                    185:        isr->isr_priority = level;
                    186:
                    187:        if (frodo_intr_establish(sc->sc_dev.dv_parent, fline, isr, name) == 0)
                    188:                return (isr);
                    189:
                    190:        free(isr, M_DEVBUF);
                    191:        return (NULL);
                    192: }
                    193:
                    194: void
                    195: isa_intr_disestablish(isa_chipset_tag_t ic, void *cookie)
                    196: {
                    197: #if 0
                    198:        struct isabr_softc *sc = (struct isabr_softc *)ic;
                    199:        struct isr *isr = cookie;
                    200:
                    201:        /* XXX how to find fline back? */
                    202:        frodo_intr_disestablish(sc->dv_parent, fline);
                    203:        free(isr, M_DEVBUF);
                    204: #else
                    205:        panic("isa_intr_disestablish");
                    206: #endif
                    207: }
                    208:
                    209: /*
                    210:  * Implementation of bus_space mapping for the hp300 isa slot.
                    211:  *
                    212:  * Everything is memory mapped, but the I/O space is scattered for better
                    213:  * userland access control granularity, should we ever provide iopl
                    214:  * facilities, thus i/o space accesses need their own routines set, while
                    215:  * memory space simply reuse the ``canonical'' bus_space routines.
                    216:  *
                    217:  * For the I/O space, all bus_space_map allocations are extended to a 8 ports
                    218:  * granularity, so that they span entire, contiguous pages; the handle value
                    219:  * however needs to keep track of the in-page offset if the first port is
                    220:  * not aligned to a ``line'' boundary.
                    221:  *
                    222:  * I.e, a bus_space_map(0x302, 0xe) call will map the 0x300-0x30f area,
                    223:  * and return a pointer the 0x302 port. Access routines will then, from
                    224:  * this pointer, construct a (0x300, 0x02) tuple, which they can use to
                    225:  * access the remainder of the range.
                    226:  */
                    227:
                    228: /*
                    229:  * ISA I/O space
                    230:  */
                    231:
                    232: int    hp300_isa_io_map(bus_addr_t, bus_size_t, int, bus_space_handle_t *);
                    233: void   hp300_isa_io_unmap(bus_space_handle_t, bus_size_t);
                    234: int    hp300_isa_io_subregion(bus_space_handle_t, bus_size_t, bus_size_t,
                    235:            bus_space_handle_t *);
                    236: void * hp300_isa_io_vaddr(bus_space_handle_t);
                    237:
                    238: u_int8_t hp300_isa_io_bsr1(bus_space_handle_t, bus_size_t);
                    239: u_int16_t hp300_isa_io_bsr2(bus_space_handle_t, bus_size_t);
                    240: u_int32_t hp300_isa_io_bsr4(bus_space_handle_t, bus_size_t);
                    241: u_int16_t __hp300_isa_io_bsr2(bus_space_handle_t, bus_size_t);
                    242: u_int32_t __hp300_isa_io_bsr4(bus_space_handle_t, bus_size_t);
                    243: void   hp300_isa_io_bsrm1(bus_space_handle_t, bus_size_t, u_int8_t *, size_t);
                    244: void   hp300_isa_io_bsrm2(bus_space_handle_t, bus_size_t, u_int16_t *, size_t);
                    245: void   hp300_isa_io_bsrm4(bus_space_handle_t, bus_size_t, u_int32_t *, size_t);
                    246: void   hp300_isa_io_bsrrm2(bus_space_handle_t, bus_size_t, u_int8_t *, size_t);
                    247: void   hp300_isa_io_bsrrm4(bus_space_handle_t, bus_size_t, u_int8_t *, size_t);
                    248: void   hp300_isa_io_bsrr1(bus_space_handle_t, bus_size_t, u_int8_t *, size_t);
                    249: void   hp300_isa_io_bsrr2(bus_space_handle_t, bus_size_t, u_int16_t *, size_t);
                    250: void   hp300_isa_io_bsrr4(bus_space_handle_t, bus_size_t, u_int32_t *, size_t);
                    251: void   hp300_isa_io_bsrrr2(bus_space_handle_t, bus_size_t, u_int8_t *, size_t);
                    252: void   hp300_isa_io_bsrrr4(bus_space_handle_t, bus_size_t, u_int8_t *, size_t);
                    253: void   hp300_isa_io_bsw1(bus_space_handle_t, bus_size_t, u_int8_t);
                    254: void   hp300_isa_io_bsw2(bus_space_handle_t, bus_size_t, u_int16_t);
                    255: void   hp300_isa_io_bsw4(bus_space_handle_t, bus_size_t, u_int32_t);
                    256: void   __hp300_isa_io_bsw2(bus_space_handle_t, bus_size_t, u_int16_t);
                    257: void   __hp300_isa_io_bsw4(bus_space_handle_t, bus_size_t, u_int32_t);
                    258: void   hp300_isa_io_bswm1(bus_space_handle_t, bus_size_t, const u_int8_t *, size_t);
                    259: void   hp300_isa_io_bswm2(bus_space_handle_t, bus_size_t, const u_int16_t *, size_t);
                    260: void   hp300_isa_io_bswm4(bus_space_handle_t, bus_size_t, const u_int32_t *, size_t);
                    261: void   hp300_isa_io_bswrm2(bus_space_handle_t, bus_size_t, const u_int8_t *, size_t);
                    262: void   hp300_isa_io_bswrm4(bus_space_handle_t, bus_size_t, const u_int8_t *, size_t);
                    263: void   hp300_isa_io_bswr1(bus_space_handle_t, bus_size_t, const u_int8_t *, size_t);
                    264: void   hp300_isa_io_bswr2(bus_space_handle_t, bus_size_t, const u_int16_t *, size_t);
                    265: void   hp300_isa_io_bswr4(bus_space_handle_t, bus_size_t, const u_int32_t *, size_t);
                    266: void   hp300_isa_io_bswrr2(bus_space_handle_t, bus_size_t, const u_int8_t *, size_t);
                    267: void   hp300_isa_io_bswrr4(bus_space_handle_t, bus_size_t, const u_int8_t *, size_t);
                    268: void   hp300_isa_io_bssm1(bus_space_handle_t, bus_size_t, u_int8_t, size_t);
                    269: void   hp300_isa_io_bssm2(bus_space_handle_t, bus_size_t, u_int16_t, size_t);
                    270: void   hp300_isa_io_bssm4(bus_space_handle_t, bus_size_t, u_int32_t, size_t);
                    271: void   hp300_isa_io_bssr1(bus_space_handle_t, bus_size_t, u_int8_t, size_t);
                    272: void   hp300_isa_io_bssr2(bus_space_handle_t, bus_size_t, u_int16_t, size_t);
                    273: void   hp300_isa_io_bssr4(bus_space_handle_t, bus_size_t, u_int32_t, size_t);
                    274:
                    275: struct hp300_bus_space_tag hp300_isa_io_tag = {
                    276:        hp300_isa_io_map,
                    277:        hp300_isa_io_unmap,
                    278:        hp300_isa_io_subregion,
                    279:        hp300_isa_io_vaddr,
                    280:
                    281:        hp300_isa_io_bsr1,
                    282:        hp300_isa_io_bsr2,
                    283:        hp300_isa_io_bsr4,
                    284:
                    285:        hp300_isa_io_bsrm1,
                    286:        hp300_isa_io_bsrm2,
                    287:        hp300_isa_io_bsrm4,
                    288:
                    289:        hp300_isa_io_bsrrm2,
                    290:        hp300_isa_io_bsrrm4,
                    291:
                    292:        hp300_isa_io_bsrr1,
                    293:        hp300_isa_io_bsrr2,
                    294:        hp300_isa_io_bsrr4,
                    295:
                    296:        hp300_isa_io_bsrrr2,
                    297:        hp300_isa_io_bsrrr4,
                    298:
                    299:        hp300_isa_io_bsw1,
                    300:        hp300_isa_io_bsw2,
                    301:        hp300_isa_io_bsw4,
                    302:
                    303:        hp300_isa_io_bswm1,
                    304:        hp300_isa_io_bswm2,
                    305:        hp300_isa_io_bswm4,
                    306:
                    307:        hp300_isa_io_bswrm2,
                    308:        hp300_isa_io_bswrm4,
                    309:
                    310:        hp300_isa_io_bswr1,
                    311:        hp300_isa_io_bswr2,
                    312:        hp300_isa_io_bswr4,
                    313:
                    314:        hp300_isa_io_bswrr2,
                    315:        hp300_isa_io_bswrr4,
                    316:
                    317:        hp300_isa_io_bssm1,
                    318:        hp300_isa_io_bssm2,
                    319:        hp300_isa_io_bssm4,
                    320:
                    321:        hp300_isa_io_bssr1,
                    322:        hp300_isa_io_bssr2,
                    323:        hp300_isa_io_bssr4
                    324: };
                    325:
                    326: int
                    327: hp300_isa_io_map(bus_addr_t bpa, bus_size_t size, int flags,
                    328:     bus_space_handle_t *bshp)
                    329: {
                    330:        int error;
                    331:        u_int iobase, iosize, npg;
                    332:        vaddr_t va;
                    333:        paddr_t pa;
                    334:
                    335: #ifdef DEBUG
                    336:        printf("isa_io_map(%04x, %04x)", bpa, size);
                    337: #endif
                    338:
                    339:        /*
                    340:         * Reserve the range in the allocation extent.
                    341:         */
                    342:        if (bpa < IO_ISABEGIN || bpa + size > IO_ISAEND + 1) {
                    343: #ifdef DEBUG
                    344:                printf(" outside available range\n");
                    345: #endif
                    346:                return (ERANGE);
                    347:        }
                    348:        error = extent_alloc_region(isabr->sc_io_extent, bpa, size,
                    349:            EX_MALLOCOK);
                    350:        if (error != 0) {
                    351: #ifdef DEBUG
                    352:                printf(" overlaps extent\n");
                    353: #endif
                    354:                return (error);
                    355:        }
                    356:
                    357:        /*
                    358:         * Round the allocation to a multiple of 8 bytes, to end up
                    359:         * with entire pages.
                    360:         */
                    361:        iobase = bpa & ~(ISABR_IOPORT_LINE - 1);
                    362:        iosize = ((bpa + size + (ISABR_IOPORT_LINE - 1)) &
                    363:            ~(ISABR_IOPORT_LINE - 1)) - iobase;
                    364:
                    365:        /*
                    366:         * Compute how many pages will be necessary to map this range.
                    367:         */
                    368:        npg = iosize / ISABR_IOPORT_LINE;
                    369: #ifdef DEBUG
                    370:        printf("->(%04x, %04x)=%d@", iobase, iosize, npg);
                    371: #endif
                    372:
                    373:        /*
                    374:         * Allocate virtual address space to map this space in.
                    375:         */
                    376:        va = uvm_km_valloc(kernel_map, ptoa(npg));
                    377:        if (va == 0) {
                    378: #ifdef DEBUG
                    379:                printf("NULL\n");
                    380: #endif
                    381:                extent_free(isabr->sc_io_extent, bpa, size, EX_MALLOCOK);
                    382:                return (ENOMEM);
                    383:        }
                    384:
                    385:        *bshp = (bus_space_handle_t)(va + (bpa - iobase));
                    386:
                    387:        pa = ISABR_IOPORT_BASE + ISAADDR(iobase);
                    388: #ifdef DEBUG
                    389:        printf("%08x (ret %08x) pa %08x\n", va, *bshp, pa);
                    390: #endif
                    391:
                    392:        while (npg != 0) {
                    393:                pmap_kenter_cache(va, pa, PG_RW | PG_CI);
                    394:                npg--;
                    395:                va += PAGE_SIZE;
                    396:                pa += PAGE_SIZE;
                    397:        }
                    398:        pmap_update(pmap_kernel());
                    399:
                    400:        return (0);
                    401: }
                    402:
                    403: void
                    404: hp300_isa_io_unmap(bus_space_handle_t bsh, bus_size_t size)
                    405: {
                    406:        u_int iobase, iosize, npg;
                    407:        vaddr_t va;
                    408:        paddr_t pa;
                    409:
                    410: #ifdef DEBUG
                    411:        printf("isa_io_unmap(%08x, %04x)", bsh, size);
                    412: #endif
                    413:
                    414:        /*
                    415:         * Find the pa matching this allocation, and the I/O port base
                    416:         * from it.
                    417:         */
                    418:        va = (vaddr_t)bsh;
                    419:        if (pmap_extract(pmap_kernel(), va, &pa) == FALSE) {
                    420: #ifdef DEBUG
                    421:                printf("-> no pa\n");
                    422: #endif
                    423:                return; /* XXX be vocal? */
                    424:        }
                    425:
                    426: #ifdef DEBUG
                    427:        printf("-> pa %08x ", pa);
                    428: #endif
                    429:        pa -= ISABR_IOPORT_BASE;
                    430:        iobase = ISAPORT(pa);
                    431:        if (iobase < IO_ISABEGIN || iobase > IO_ISAEND) {
                    432: #ifdef DEBUG
                    433:                printf("iobase %08x???\n", iobase);
                    434: #endif
                    435:                return; /* XXX be vocal? */
                    436:        }
                    437:
                    438:        iosize = size + (iobase & (ISABR_IOPORT_LINE - 1)) +
                    439:            (ISABR_IOPORT_LINE - 1);
                    440:        npg = iosize / ISABR_IOPORT_LINE;
                    441: #ifdef DEBUG
                    442:        printf(" range %04x-%04x: %d\n", iobase, size, npg);
                    443: #endif
                    444:
                    445:        pmap_kremove(va, ptoa(npg));
                    446:        pmap_update(pmap_kernel());
                    447:        uvm_km_free(kernel_map, va, ptoa(npg));
                    448:
                    449:        (void)extent_free(isabr->sc_io_extent, (u_long)iobase, size,
                    450:            EX_MALLOCOK);
                    451: }
                    452:
                    453: /*
                    454:  * Round down an I/O space bus_space_handle, so that it points to the
                    455:  * beginning of a page.
                    456:  * This is gonna be hell when we support ports above 0x400.
                    457:  */
                    458: #define        REALIGN_IO_HANDLE(h, o) \
                    459: do { \
                    460:        u_int tmp; \
                    461:        tmp = (h) & (ISABR_IOPORT_LINE - 1); \
                    462:        (h) -= tmp; \
                    463:        (o) += tmp; \
                    464: } while (0)
                    465:
                    466: /* ARGSUSED */
                    467: int
                    468: hp300_isa_io_subregion(bus_space_handle_t bsh, bus_size_t offset,
                    469:     bus_size_t size, bus_space_handle_t *nbshp)
                    470: {
                    471:        REALIGN_IO_HANDLE(bsh, offset);
                    472:        bsh += ISAADDR(offset);
                    473:        *nbshp = bsh;
                    474:        return (0);
                    475: }
                    476:
                    477: void *
                    478: hp300_isa_io_vaddr(bus_space_handle_t h)
                    479: {
                    480:        return (NULL);
                    481: }
                    482:
                    483: /* bus_space_read_X */
                    484:
                    485: u_int8_t
                    486: hp300_isa_io_bsr1(bus_space_handle_t bsh, bus_size_t offset)
                    487: {
                    488:        vaddr_t va;
                    489:        u_int8_t rc;
                    490:
                    491:        REALIGN_IO_HANDLE(bsh, offset);
                    492:        va = (vaddr_t)bsh + ISAADDR(offset);
                    493:        rc = *(volatile u_int8_t *)va;
                    494: #ifdef DEBUG
                    495:        printf("R%03x(%x):%02x\t", offset, va, rc);
                    496: #endif
                    497:        return (rc);
                    498: }
                    499:
                    500: u_int16_t
                    501: __hp300_isa_io_bsr2(bus_space_handle_t bsh, bus_size_t offset)
                    502: {
                    503:        u_int16_t rc;
                    504:        vaddr_t va;
                    505:
                    506:        if (offset & 1) {
                    507:                rc = hp300_isa_io_bsr1(bsh, offset + 1) << 8;
                    508:                rc |= hp300_isa_io_bsr1(bsh, offset);
                    509:        } else {
                    510:                REALIGN_IO_HANDLE(bsh, offset);
                    511:                va = (vaddr_t)bsh + ISAADDR(offset);
                    512:                rc = *(volatile u_int16_t *)va;
                    513:        }
                    514: #ifdef DEBUG
                    515:        printf("R%03x:%04x\t", offset, rc);
                    516: #endif
                    517:        return (rc);
                    518: }
                    519:
                    520: u_int16_t
                    521: hp300_isa_io_bsr2(bus_space_handle_t bsh, bus_size_t offset)
                    522: {
                    523:        u_int16_t rc;
                    524:
                    525:        rc = __hp300_isa_io_bsr2(bsh, offset);
                    526:        return (letoh16(rc));
                    527: }
                    528:
                    529: u_int32_t
                    530: __hp300_isa_io_bsr4(bus_space_handle_t bsh, bus_size_t offset)
                    531: {
                    532:        u_int32_t rc;
                    533:        vaddr_t va;
                    534:
                    535:        if (offset & 3) {
                    536:                rc = hp300_isa_io_bsr1(bsh, offset + 3) << 24;
                    537:                rc |= hp300_isa_io_bsr1(bsh, offset + 2) << 16;
                    538:                rc |= hp300_isa_io_bsr1(bsh, offset + 1) << 8;
                    539:                rc |= hp300_isa_io_bsr1(bsh, offset);
                    540:        } else {
                    541:                REALIGN_IO_HANDLE(bsh, offset);
                    542:                va = (vaddr_t)bsh + ISAADDR(offset);
                    543:                rc = *(volatile u_int32_t *)va;
                    544:        }
                    545: #ifdef DEBUG
                    546:        printf("R%03x:%08x\t", offset, rc);
                    547: #endif
                    548:        return (rc);
                    549: }
                    550:
                    551: u_int32_t
                    552: hp300_isa_io_bsr4(bus_space_handle_t bsh, bus_size_t offset)
                    553: {
                    554:        u_int32_t rc;
                    555:
                    556:        rc = __hp300_isa_io_bsr4(bsh, offset);
                    557:        return (letoh32(rc));
                    558: }
                    559:
                    560: /* bus_space_read_multi_X */
                    561:
                    562: void
                    563: hp300_isa_io_bsrm1(bus_space_handle_t h, bus_size_t offset,
                    564:             u_int8_t *a, size_t c)
                    565: {
                    566:        while ((int)--c >= 0)
                    567:                *a++ = hp300_isa_io_bsr1(h, offset);
                    568: }
                    569:
                    570: void
                    571: hp300_isa_io_bsrm2(bus_space_handle_t h, bus_size_t offset,
                    572:             u_int16_t *a, size_t c)
                    573: {
                    574:        while ((int)--c >= 0)
                    575:                *a++ = hp300_isa_io_bsr2(h, offset);
                    576: }
                    577:
                    578: void
                    579: hp300_isa_io_bsrm4(bus_space_handle_t h, bus_size_t offset,
                    580:             u_int32_t *a, size_t c)
                    581: {
                    582:        while ((int)--c >= 0)
                    583:                *a++ = hp300_isa_io_bsr4(h, offset);
                    584: }
                    585:
                    586: /* bus_space_read_raw_multi_X */
                    587:
                    588: void
                    589: hp300_isa_io_bsrrm2(bus_space_handle_t h, bus_size_t offset,
                    590:             u_int8_t *a, size_t c)
                    591: {
                    592:        while ((int)--c >= 0) {
                    593:                *(u_int16_t *)a = __hp300_isa_io_bsr2(h, offset);
                    594:                a += 2;
                    595:        }
                    596: }
                    597:
                    598: void
                    599: hp300_isa_io_bsrrm4(bus_space_handle_t h, bus_size_t offset,
                    600:             u_int8_t *a, size_t c)
                    601: {
                    602:        while ((int)--c >= 0) {
                    603:                *(u_int32_t *)a = __hp300_isa_io_bsr4(h, offset);
                    604:                a += 4;
                    605:        }
                    606: }
                    607:
                    608: /* bus_space_read_region_X */
                    609:
                    610: void
                    611: hp300_isa_io_bsrr1(bus_space_handle_t h, bus_size_t offset,
                    612:             u_int8_t *a, size_t c)
                    613: {
                    614:        while ((int)--c >= 0)
                    615:                *a++ = hp300_isa_io_bsr1(h, offset++);
                    616: }
                    617:
                    618: void
                    619: hp300_isa_io_bsrr2(bus_space_handle_t h, bus_size_t offset,
                    620:             u_int16_t *a, size_t c)
                    621: {
                    622:        while ((int)--c >= 0) {
                    623:                *a++ = hp300_isa_io_bsr2(h, offset);
                    624:                offset += 2;
                    625:        }
                    626: }
                    627:
                    628: void
                    629: hp300_isa_io_bsrr4(bus_space_handle_t h, bus_size_t offset,
                    630:             u_int32_t *a, size_t c)
                    631: {
                    632:        while ((int)--c >= 0) {
                    633:                *a++ = hp300_isa_io_bsr4(h, offset);
                    634:                offset += 4;
                    635:        }
                    636: }
                    637:
                    638: /* bus_space_read_raw_region_X */
                    639:
                    640: void
                    641: hp300_isa_io_bsrrr2(bus_space_handle_t h, bus_size_t offset,
                    642:             u_int8_t *a, size_t c)
                    643: {
                    644:        c >>= 1;
                    645:        while ((int)--c >= 0) {
                    646:                *(u_int16_t *)a = __hp300_isa_io_bsr2(h, offset);
                    647:                offset += 2;
                    648:                a += 2;
                    649:        }
                    650: }
                    651:
                    652: void
                    653: hp300_isa_io_bsrrr4(bus_space_handle_t h, bus_size_t offset,
                    654:             u_int8_t *a, size_t c)
                    655: {
                    656:        c >>= 2;
                    657:        while ((int)--c >= 0) {
                    658:                *(u_int32_t *)a = __hp300_isa_io_bsr4(h, offset);
                    659:                offset += 4;
                    660:                a += 4;
                    661:        }
                    662: }
                    663:
                    664: /* bus_space_write_X */
                    665:
                    666: void
                    667: hp300_isa_io_bsw1(bus_space_handle_t h, bus_size_t offset, u_int8_t v)
                    668: {
                    669:        vaddr_t va;
                    670:
                    671:        REALIGN_IO_HANDLE(h, offset);
                    672:        va = (vaddr_t)h + ISAADDR(offset);
                    673:        *(volatile u_int8_t *)va = v;
                    674: #ifdef DEBUG
                    675:        printf("W%03x:%02x\t", offset, v);
                    676: #endif
                    677: }
                    678:
                    679: void
                    680: __hp300_isa_io_bsw2(bus_space_handle_t h, bus_size_t offset, u_int16_t v)
                    681: {
                    682:        vaddr_t va;
                    683:
                    684:        if (offset & 1) {
                    685:                hp300_isa_io_bsw1(h, offset + 1, v >> 8);
                    686:                hp300_isa_io_bsw1(h, offset, v);
                    687:        } else {
                    688:                REALIGN_IO_HANDLE(h, offset);
                    689:                va = (vaddr_t)h + ISAADDR(offset);
                    690:                *(volatile u_int16_t *)va = v;
                    691:        }
                    692: #ifdef DEBUG
                    693:        printf("W%03x:%04x\t", offset, v);
                    694: #endif
                    695: }
                    696:
                    697: void
                    698: hp300_isa_io_bsw2(bus_space_handle_t h, bus_size_t offset, u_int16_t v)
                    699: {
                    700:        __hp300_isa_io_bsw2(h, offset, htole16(v));
                    701: }
                    702:
                    703: void
                    704: __hp300_isa_io_bsw4(bus_space_handle_t h, bus_size_t offset, u_int32_t v)
                    705: {
                    706:        vaddr_t va;
                    707:
                    708:        if (offset & 3) {
                    709:                hp300_isa_io_bsw1(h, offset + 3, v >> 24);
                    710:                hp300_isa_io_bsw1(h, offset + 2, v >> 16);
                    711:                hp300_isa_io_bsw1(h, offset + 1, v >> 8);
                    712:                hp300_isa_io_bsw1(h, offset, v);
                    713:        } else {
                    714:                REALIGN_IO_HANDLE(h, offset);
                    715:                va = (vaddr_t)h + ISAADDR(offset);
                    716:                *(volatile u_int32_t *)va = v;
                    717:        }
                    718: #ifdef DEBUG
                    719:        printf("W%03x:%08x\t", offset, v);
                    720: #endif
                    721: }
                    722:
                    723: void
                    724: hp300_isa_io_bsw4(bus_space_handle_t h, bus_size_t offset, u_int32_t v)
                    725: {
                    726:        __hp300_isa_io_bsw4(h, offset, htole32(v));
                    727: }
                    728:
                    729: /* bus_space_write_multi_X */
                    730:
                    731: void
                    732: hp300_isa_io_bswm1(bus_space_handle_t h, bus_size_t offset,
                    733:             const u_int8_t *a, size_t c)
                    734: {
                    735:        while ((int)--c >= 0)
                    736:                hp300_isa_io_bsw1(h, offset, *a++);
                    737: }
                    738:
                    739: void
                    740: hp300_isa_io_bswm2(bus_space_handle_t h, bus_size_t offset,
                    741:             const u_int16_t *a, size_t c)
                    742: {
                    743:        while ((int)--c >= 0)
                    744:                hp300_isa_io_bsw2(h, offset, *a++);
                    745: }
                    746:
                    747: void
                    748: hp300_isa_io_bswm4(bus_space_handle_t h, bus_size_t offset,
                    749:             const u_int32_t *a, size_t c)
                    750: {
                    751:        while ((int)--c >= 0)
                    752:                hp300_isa_io_bsw4(h, offset, *a++);
                    753: }
                    754:
                    755: /* bus_space_write_raw_multi_X */
                    756:
                    757: void
                    758: hp300_isa_io_bswrm2(bus_space_handle_t h, bus_size_t offset,
                    759:             const u_int8_t *a, size_t c)
                    760: {
                    761:        while ((int)--c >= 0) {
                    762:                __hp300_isa_io_bsw2(h, offset, *(u_int16_t *)a);
                    763:                a += 2;
                    764:        }
                    765: }
                    766:
                    767: void
                    768: hp300_isa_io_bswrm4(bus_space_handle_t h, bus_size_t offset,
                    769:             const u_int8_t *a, size_t c)
                    770: {
                    771:        while ((int)--c >= 0) {
                    772:                __hp300_isa_io_bsw4(h, offset, *(u_int32_t *)a);
                    773:                a += 4;
                    774:        }
                    775: }
                    776:
                    777: /* bus_space_write_region_X */
                    778:
                    779: void
                    780: hp300_isa_io_bswr1(bus_space_handle_t h, bus_size_t offset,
                    781:             const u_int8_t *a, size_t c)
                    782: {
                    783:        while ((int)--c >= 0)
                    784:                hp300_isa_io_bsw1(h, offset++, *a++);
                    785: }
                    786:
                    787: void
                    788: hp300_isa_io_bswr2(bus_space_handle_t h, bus_size_t offset,
                    789:             const u_int16_t *a, size_t c)
                    790: {
                    791:        while ((int)--c >= 0) {
                    792:                hp300_isa_io_bsw2(h, offset, *a++);
                    793:                offset += 2;
                    794:        }
                    795: }
                    796:
                    797: void
                    798: hp300_isa_io_bswr4(bus_space_handle_t h, bus_size_t offset,
                    799:             const u_int32_t *a, size_t c)
                    800: {
                    801:        while ((int)--c >= 0) {
                    802:                hp300_isa_io_bsw4(h, offset, *a++);
                    803:                offset += 4;
                    804:        }
                    805: }
                    806:
                    807: /* bus_space_write_raw_region_X */
                    808:
                    809: void
                    810: hp300_isa_io_bswrr2(bus_space_handle_t h, bus_size_t offset,
                    811:             const u_int8_t *a, size_t c)
                    812: {
                    813:        c >>= 1;
                    814:        while ((int)--c >= 0) {
                    815:                __hp300_isa_io_bsw2(h, offset, *(u_int16_t *)a);
                    816:                offset += 2;
                    817:                a += 2;
                    818:        }
                    819: }
                    820:
                    821: void
                    822: hp300_isa_io_bswrr4(bus_space_handle_t h, bus_size_t offset,
                    823:             const u_int8_t *a, size_t c)
                    824: {
                    825:        c >>= 2;
                    826:        while ((int)--c >= 0) {
                    827:                __hp300_isa_io_bsw4(h, offset, *(u_int32_t *)a);
                    828:                offset += 4;
                    829:                a += 4;
                    830:        }
                    831: }
                    832:
                    833: /* bus_space_set_multi_X */
                    834:
                    835: void
                    836: hp300_isa_io_bssm1(bus_space_handle_t h, bus_size_t offset,
                    837:             u_int8_t v, size_t c)
                    838: {
                    839:        while ((int)--c >= 0)
                    840:                hp300_isa_io_bsw1(h, offset, v);
                    841: }
                    842:
                    843: void
                    844: hp300_isa_io_bssm2(bus_space_handle_t h, bus_size_t offset,
                    845:             u_int16_t v, size_t c)
                    846: {
                    847:        while ((int)--c >= 0)
                    848:                hp300_isa_io_bsw2(h, offset, v);
                    849: }
                    850:
                    851: void
                    852: hp300_isa_io_bssm4(bus_space_handle_t h, bus_size_t offset,
                    853:             u_int32_t v, size_t c)
                    854: {
                    855:        while ((int)--c >= 0)
                    856:                hp300_isa_io_bsw4(h, offset, v);
                    857: }
                    858:
                    859: /* bus_space_set_region_X */
                    860:
                    861: void
                    862: hp300_isa_io_bssr1(bus_space_handle_t h, bus_size_t offset,
                    863:             u_int8_t v, size_t c)
                    864: {
                    865:        while ((int)--c >= 0)
                    866:                hp300_isa_io_bsw1(h, offset++, v);
                    867: }
                    868:
                    869: void
                    870: hp300_isa_io_bssr2(bus_space_handle_t h, bus_size_t offset,
                    871:             u_int16_t v, size_t c)
                    872: {
                    873:        while ((int)--c >= 0) {
                    874:                hp300_isa_io_bsw2(h, offset, v);
                    875:                offset += 2;
                    876:        }
                    877: }
                    878:
                    879: void
                    880: hp300_isa_io_bssr4(bus_space_handle_t h, bus_size_t offset,
                    881:             u_int32_t v, size_t c)
                    882: {
                    883:        while ((int)--c >= 0) {
                    884:                hp300_isa_io_bsw4(h, offset, v);
                    885:                offset += 4;
                    886:        }
                    887: }
                    888:
                    889: /*
                    890:  * ISA memory space
                    891:  */
                    892:
                    893: int    hp300_isa_mem_map(bus_addr_t, bus_size_t, int, bus_space_handle_t *);
                    894: void   hp300_isa_mem_unmap(bus_space_handle_t, bus_size_t);
                    895:
                    896: int
                    897: hp300_isa_mem_map(bus_addr_t bpa, bus_size_t size, int flags,
                    898:     bus_space_handle_t *bshp)
                    899: {
                    900:        int error;
                    901:        bus_addr_t membase;
                    902:        bus_size_t rsize;
                    903:        vaddr_t va;
                    904:        paddr_t pa;
                    905:        pt_entry_t template;
                    906:
                    907:        /*
                    908:         * Reserve the range in the allocation extent.
                    909:         */
                    910:        if (bpa < IOM_BEGIN || bpa + size > IOM_END)
                    911:                return (ERANGE);
                    912:        error = extent_alloc_region(isabr->sc_mem_extent, bpa, size,
                    913:            EX_MALLOCOK);
                    914:        if (error != 0)
                    915:                return (error);
                    916:
                    917:        /*
                    918:         * Allocate virtual address space to map this space in.
                    919:         */
                    920:        membase = trunc_page(bpa);
                    921:        rsize = round_page(bpa + size) - membase;
                    922:        va = uvm_km_valloc(kernel_map, rsize);
                    923:        if (va == 0) {
                    924:                extent_free(isabr->sc_mem_extent, bpa, size, EX_MALLOCOK);
                    925:                return (ENOMEM);
                    926:        }
                    927:
                    928:        *bshp = (bus_space_handle_t)(va + (bpa - membase));
                    929:
                    930:        pa = membase + (ISABR_IOMEM_BASE - IOM_BEGIN);
                    931:
                    932:        if (flags & BUS_SPACE_MAP_CACHEABLE)
                    933:                template = PG_RW;
                    934:        else
                    935:                template = PG_RW | PG_CI;
                    936:
                    937:        while (rsize != 0) {
                    938:                pmap_kenter_cache(va, pa, template);
                    939:                rsize -= PAGE_SIZE;
                    940:                va += PAGE_SIZE;
                    941:                pa += PAGE_SIZE;
                    942:        }
                    943:        pmap_update(pmap_kernel());
                    944:
                    945:        return (0);
                    946: }
                    947:
                    948: void
                    949: hp300_isa_mem_unmap(bus_space_handle_t bsh, bus_size_t size)
                    950: {
                    951:        vaddr_t va;
                    952:        vsize_t rsize;
                    953:
                    954:        va = trunc_page((vaddr_t)bsh);
                    955:        rsize = round_page((vaddr_t)bsh + size) - va;
                    956:
                    957:        pmap_kremove(va, rsize);
                    958:        pmap_update(pmap_kernel());
                    959:        uvm_km_free(kernel_map, va, rsize);
                    960:
                    961:        (void)extent_free(isabr->sc_mem_extent, (u_long)bsh, size, EX_MALLOCOK);
                    962: }
                    963:
                    964: struct hp300_bus_space_tag hp300_isa_mem_tag;  /* will be filled in */
                    965:
                    966: /*
                    967:  * ISA bus_space initialization.
                    968:  * This creates the necessary accounting elements and initializes the
                    969:  * memory space bus_space_tag.
                    970:  */
                    971:
                    972: int
                    973: isabr_bus_space_setup(struct isabr_softc *sc, struct frodo_attach_args *faa,
                    974:     struct isabus_attach_args *iba)
                    975: {
                    976:        /*
                    977:         * Create the space extents.
                    978:         * We only use them to prevent multiple allocations of the same areas.
                    979:         */
                    980:
                    981:        sc->sc_io_extent = extent_create("isa_io", IO_ISABEGIN,
                    982:            IO_ISAEND + 1, M_DEVBUF, NULL, 0, EX_NOWAIT | EX_MALLOCOK);
                    983:        if (sc->sc_io_extent == NULL)
                    984:                return (ENOMEM);
                    985:
                    986:        sc->sc_mem_extent = extent_create("isa_mem", IOM_BEGIN,
                    987:            IOM_END, M_DEVBUF, NULL, 0, EX_NOWAIT | EX_MALLOCOK);
                    988:        if (sc->sc_mem_extent == NULL) {
                    989:                extent_destroy(sc->sc_io_extent);
                    990:                return (ENOMEM);
                    991:        }
                    992:
                    993:        iba->iba_iot = &hp300_isa_io_tag;
                    994:        bcopy(faa->fa_tag, &hp300_isa_mem_tag,
                    995:            sizeof(struct hp300_bus_space_tag));
                    996:        hp300_isa_mem_tag.bs_map = hp300_isa_mem_map;
                    997:        hp300_isa_mem_tag.bs_unmap = hp300_isa_mem_unmap;
                    998:        iba->iba_memt = &hp300_isa_mem_tag;
                    999:
                   1000:        isabr = sc;
                   1001:
                   1002:        return (0);
                   1003: }

CVSweb