[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     ! 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