[BACK]Return to macebus.c CVS log [TXT][DIR] Up to [local] / sys / arch / sgi / localbus

Annotation of sys/arch/sgi/localbus/macebus.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: macebus.c,v 1.26 2007/07/09 21:40:24 jasper Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 2000-2004 Opsycon AB  (www.opsycon.se)
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
                     16:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     18:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
                     19:  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     20:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     21:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     23:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     24:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     25:  * SUCH DAMAGE.
                     26:  *
                     27:  */
                     28:
                     29: /*
                     30:  *  This is a combined macebus/crimebus driver. It handles
                     31:  *  configuration of all devices on the processor bus.
                     32:  */
                     33:
                     34: #include <sys/param.h>
                     35: #include <sys/systm.h>
                     36: #include <sys/kernel.h>
                     37: #include <sys/conf.h>
                     38: #include <sys/malloc.h>
                     39: #include <sys/device.h>
                     40: #include <sys/tty.h>
                     41: #include <sys/extent.h>
                     42: #include <net/netisr.h>
                     43: #include <uvm/uvm_extern.h>
                     44:
                     45: #include <dev/pci/pcidevs.h>
                     46: #include <dev/pci/pcivar.h>
                     47:
                     48: #include <dev/ic/comvar.h>
                     49:
                     50: #include <mips64/archtype.h>
                     51:
                     52: #include <machine/autoconf.h>
                     53: #include <machine/intr.h>
                     54: #include <machine/atomic.h>
                     55:
                     56: #include <sgi/localbus/macebus.h>
                     57: #include <sgi/localbus/crimebus.h>
                     58:
                     59: int macebusmatch(struct device *, void *, void *);
                     60: void macebusattach(struct device *, struct device *, void *);
                     61: int macebusprint(void *, const char *);
                     62: int macebusscan(struct device *, void *, void *);
                     63:
                     64: void *macebus_intr_establish(void *, u_long, int, int,
                     65:                        int (*)(void *), void *, char *);
                     66: void macebus_intr_disestablish(void *, void *);
                     67: void macebus_intr_makemasks(void);
                     68: void macebus_do_pending_int(int);
                     69: intrmask_t macebus_iointr(intrmask_t, struct trap_frame *);
                     70: intrmask_t macebus_aux(intrmask_t, struct trap_frame *);
                     71:
                     72: bus_addr_t macebus_pa_to_device(paddr_t);
                     73: paddr_t        macebus_device_to_pa(bus_addr_t);
                     74:
                     75: int maceticks;         /* Time tracker for special events */
                     76:
                     77: struct cfattach macebus_ca = {
                     78:        sizeof(struct device), macebusmatch, macebusattach
                     79: };
                     80:
                     81: struct cfdriver macebus_cd = {
                     82:        NULL, "macebus", DV_DULL, 1
                     83: };
                     84:
                     85: bus_space_t macebus_tag = {
                     86:        NULL,
                     87:        (bus_addr_t)MACEBUS_BASE,
                     88:        NULL,
                     89:        0,
                     90:        mace_read_1, mace_write_1,
                     91:        mace_read_2, mace_write_2,
                     92:        mace_read_4, mace_write_4,
                     93:        mace_read_8, mace_write_8,
                     94:        mace_space_map, mace_space_unmap, mace_space_region,
                     95: };
                     96:
                     97: bus_space_t crimebus_tag = {
                     98:        NULL,
                     99:        (bus_addr_t)CRIMEBUS_BASE,
                    100:        NULL,
                    101:        0,
                    102:        mace_read_1, mace_write_1,
                    103:        mace_read_2, mace_write_2,
                    104:        mace_read_4, mace_write_4,
                    105:        mace_read_8, mace_write_8,
                    106:        mace_space_map, mace_space_unmap, mace_space_region,
                    107: };
                    108:
                    109: bus_space_handle_t crime_h;
                    110: bus_space_handle_t mace_h;
                    111:
                    112: struct machine_bus_dma_tag mace_bus_dma_tag = {
                    113:        NULL,                   /* _cookie */
                    114:        _dmamap_create,
                    115:        _dmamap_destroy,
                    116:        _dmamap_load,
                    117:        _dmamap_load_mbuf,
                    118:        _dmamap_load_uio,
                    119:        _dmamap_load_raw,
                    120:        _dmamap_unload,
                    121:        _dmamap_sync,
                    122:        _dmamem_alloc,
                    123:        _dmamem_free,
                    124:        _dmamem_map,
                    125:        _dmamem_unmap,
                    126:        _dmamem_mmap,
                    127:        macebus_pa_to_device,
                    128:        macebus_device_to_pa,
                    129:        CRIME_MEMORY_MASK
                    130: };
                    131:
                    132: /*
                    133:  *  Match bus only to targets which have this bus.
                    134:  */
                    135: int
                    136: macebusmatch(struct device *parent, void *match, void *aux)
                    137: {
                    138:        if (sys_config.system_type == SGI_O2)
                    139:                return (1);
                    140:        return (0);
                    141: }
                    142:
                    143: int
                    144: macebusprint(void *aux, const char *macebus)
                    145: {
                    146: /* XXXX print flags */
                    147:        return (QUIET);
                    148: }
                    149:
                    150:
                    151: int
                    152: macebusscan(struct device *parent, void *child, void *args)
                    153: {
                    154:        struct device *dev = child;
                    155:        struct cfdata *cf = dev->dv_cfdata;
                    156:        struct confargs lba;
                    157:        struct abus lbus;
                    158:
                    159:        if (cf->cf_fstate == FSTATE_STAR) {
                    160:                printf("macebus '*' devs not allowed!\n");
                    161:                return 0;
                    162:        }
                    163:
                    164:        lba.ca_sys = cf->cf_loc[0];
                    165:        if (cf->cf_loc[1] == -1) {
                    166:                lba.ca_baseaddr = 0;
                    167:        } else {
                    168:                lba.ca_baseaddr = cf->cf_loc[1];
                    169:        }
                    170:        if (cf->cf_loc[2] == -1) {
                    171:                lba.ca_intr = 0;
                    172:                lba.ca_nintr = 0;
                    173:        } else {
                    174:                lba.ca_intr = cf->cf_loc[2];
                    175:                lba.ca_nintr = 1;
                    176:        }
                    177:
                    178:        lba.ca_bus = &lbus;
                    179:
                    180:        /* Fill in what is needed for probing */
                    181:        lba.ca_bus->ab_type = BUS_LOCAL;
                    182:        lba.ca_bus->ab_matchname = NULL;
                    183:        lba.ca_name = cf->cf_driver->cd_name;
                    184:        lba.ca_num = dev->dv_unit;
                    185:        lba.ca_iot = &macebus_tag;
                    186:        lba.ca_memt = &macebus_tag;
                    187:        lba.ca_dmat = &mace_bus_dma_tag;
                    188:
                    189:        return (*cf->cf_attach->ca_match)(parent, cf, &lba);
                    190: }
                    191:
                    192: void
                    193: macebusattach(struct device *parent, struct device *self, void *aux)
                    194: {
                    195:        struct device *dev;
                    196:        struct confargs lba;
                    197:        struct abus lbus;
                    198:        u_int32_t creg;
                    199:        u_int64_t mask;
                    200:
                    201:        /*
                    202:         *  Create an extent for the localbus control registers.
                    203:         */
                    204:        macebus_tag.bus_extent = extent_create("mace_space",
                    205:            macebus_tag.bus_base, macebus_tag.bus_base + 0x00400000,
                    206:            M_DEVBUF, NULL, 0, EX_NOCOALESCE | EX_NOWAIT);
                    207:
                    208:        crimebus_tag.bus_extent = extent_create("crime_space",
                    209:            crimebus_tag.bus_base, crimebus_tag.bus_base + 0x00400000,
                    210:            M_DEVBUF, NULL, 0, EX_NOCOALESCE | EX_NOWAIT);
                    211:
                    212:        /*
                    213:         *  Map and set up CRIME control registers.
                    214:         */
                    215:        if (bus_space_map(&crimebus_tag, 0x00000000, 0x400, 0, &crime_h)) {
                    216:                printf(": cannot map CRIME control registers\n");
                    217:                return;
                    218:        }
                    219:        hwmask_addr = (void *)(PHYS_TO_XKPHYS(CRIMEBUS_BASE, CCA_NC) +
                    220:            CRIME_INT_MASK);
                    221:
                    222:        creg = bus_space_read_8(&crimebus_tag, crime_h, CRIME_REVISION);
                    223:        printf(": crime rev %d.%d\n", (creg & 0xf0) >> 4, creg & 0xf);
                    224:
                    225:        bus_space_write_8(&crimebus_tag, crime_h, CRIME_CPU_ERROR_STAT, 0);
                    226:        bus_space_write_8(&crimebus_tag, crime_h, CRIME_MEM_ERROR_STAT, 0);
                    227:
                    228:        mask = 0;
                    229:        bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_MASK, mask);
                    230:        bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_SOFT, 0);
                    231:        bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_HARD, 0);
                    232:        bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_STAT, 0);
                    233:
                    234:
                    235:        /*
                    236:         *  Map and set up MACE ISA control registers.
                    237:         */
                    238:        if (bus_space_map(&macebus_tag, MACE_ISA_OFFS, 0x400, 0, &mace_h)) {
                    239:                printf("UH-OH! Can't map MACE ISA control registers!\n");
                    240:                return;
                    241:        }
                    242:
                    243:        bus_space_write_8(&macebus_tag, mace_h, MACE_ISA_INT_MASK, 0xffffffff);
                    244:        bus_space_write_8(&macebus_tag, mace_h, MACE_ISA_INT_STAT, 0);
                    245:
                    246:        /*
                    247:         *  Now attach all devices to macebus in proper order.
                    248:         */
                    249:        memset(&lba, 0, sizeof(lba));
                    250:        memset(&lbus, 0, sizeof(lbus));
                    251:        lba.ca_bus = &lbus;
                    252:        lba.ca_bus->ab_type = BUS_LOCAL;
                    253:        lba.ca_bus->ab_matchname = NULL;
                    254:        lba.ca_iot = &macebus_tag;
                    255:        lba.ca_memt = &macebus_tag;
                    256:        lba.ca_dmat = &mace_bus_dma_tag;
                    257:
                    258:        /*
                    259:         *  On O2 systems all interrupts are handled by the
                    260:         *  macebus interrupt handler. Register all except clock.
                    261:         */
                    262:        switch (sys_config.system_type) {
                    263:        case SGI_O2:
                    264:                set_intr(INTPRI_MACEIO, CR_INT_0, macebus_iointr);
                    265:                lba.ca_bus->ab_intr_establish = macebus_intr_establish;
                    266:                lba.ca_bus->ab_intr_disestablish = macebus_intr_disestablish;
                    267:                register_pending_int_handler(macebus_do_pending_int);
                    268:                break;
                    269:        default:
                    270:                panic("macebusscan: unknown macebus type!");
                    271:        }
                    272:
                    273:        /* DEBUG: Set up a handler called when clock interrupts go off. */
                    274:        set_intr(INTPRI_MACEAUX, CR_INT_5, macebus_aux);
                    275:
                    276:
                    277:        while ((dev = config_search(macebusscan, self, aux)) != NULL) {
                    278:                struct cfdata *cf;
                    279:
                    280:                cf = dev->dv_cfdata;
                    281:                lba.ca_sys = cf->cf_loc[0];
                    282:                if (cf->cf_loc[1] == -1)
                    283:                        lba.ca_baseaddr = 0;
                    284:                else
                    285:                        lba.ca_baseaddr = cf->cf_loc[1];
                    286:
                    287:                if (cf->cf_loc[2] == -1) {
                    288:                        lba.ca_intr = 0;
                    289:                        lba.ca_nintr = 0;
                    290:                } else {
                    291:                        lba.ca_intr= cf->cf_loc[2];
                    292:                        lba.ca_nintr = 1;
                    293:                }
                    294:                lba.ca_name = cf->cf_driver->cd_name;
                    295:                lba.ca_num = dev->dv_unit;
                    296:
                    297:                config_attach(self, dev, &lba, macebusprint);
                    298:        }
                    299: }
                    300:
                    301:
                    302: /*
                    303:  *  Bus access primitives. These are really ugly...
                    304:  */
                    305:
                    306: u_int8_t
                    307: mace_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
                    308: {
                    309:        return *(volatile u_int8_t *)(h + (o << 8) + 7);
                    310: }
                    311:
                    312: u_int16_t
                    313: mace_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
                    314: {
                    315:        panic("mace_read_2");
                    316: }
                    317:
                    318: u_int32_t
                    319: mace_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
                    320: {
                    321:        return *(volatile u_int32_t *)(h + o);
                    322: }
                    323:
                    324: u_int64_t
                    325: mace_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
                    326: {
                    327: #ifdef __LP64__
                    328:        return *(volatile u_int64_t *)(h + o);
                    329: #else
                    330:        return lp32_read8((u_int64_t *)(h + o));
                    331: #endif
                    332: }
                    333:
                    334: void
                    335: mace_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int8_t v)
                    336: {
                    337:        *(volatile u_int8_t *)(h + (o << 8) + 7) = v;
                    338: }
                    339:
                    340: void
                    341: mace_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t v)
                    342: {
                    343:        panic("mace_write_2");
                    344: }
                    345:
                    346: void
                    347: mace_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t v)
                    348: {
                    349:        *(volatile u_int32_t *)(h + o) = v;
                    350: }
                    351:
                    352: void
                    353: mace_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t v)
                    354: {
                    355: #ifdef __LP64__
                    356:        *(volatile u_int64_t *)(h + o) = v;
                    357: #else
                    358:        lp32_write8((u_int64_t *)(h + o), v);
                    359: #endif
                    360: }
                    361:
                    362: extern int extent_malloc_flags;
                    363:
                    364: int
                    365: mace_space_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size,
                    366:     int cacheable, bus_space_handle_t *bshp)
                    367: {
                    368:        bus_addr_t bpa;
                    369:        int error;
                    370:
                    371:        bpa = t->bus_base + offs;
                    372:
                    373:        /* Handle special mapping separately */
                    374:        if (bpa >= (MACEBUS_BASE + MACE_ISAX_OFFS) &&
                    375:            (bpa + size) < (MACEBUS_BASE + MACE_ISAX_OFFS + MACE_ISAX_SIZE)) {
                    376:                *bshp = PHYS_TO_XKPHYS(bpa, CCA_NC);
                    377:                return 0;
                    378:        }
                    379:
                    380:        if ((error = extent_alloc_region(t->bus_extent, bpa, size,
                    381:            EX_NOWAIT | extent_malloc_flags))) {
                    382:                return error;
                    383:        }
                    384:
                    385:        if ((error = bus_mem_add_mapping(bpa, size, cacheable, bshp))) {
                    386:                if (extent_free(t->bus_extent, bpa, size,
                    387:                    EX_NOWAIT | extent_malloc_flags)) {
                    388:                        printf("bus_space_map: pa %p, size %p\n", bpa, size);
                    389:                        printf("bus_space_map: can't free region\n");
                    390:                }
                    391:        }
                    392:
                    393:        return (error);
                    394: }
                    395:
                    396: void
                    397: mace_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
                    398: {
                    399:        bus_addr_t sva, paddr;
                    400:        bus_size_t off, len;
                    401:
                    402:        /* should this verify that the proper size is freed? */
                    403:        sva = trunc_page(bsh);
                    404:        off = bsh - sva;
                    405:        len = size+off;
                    406:
                    407:        if (IS_XKPHYS(bsh)) {
                    408:                paddr = XKPHYS_TO_PHYS(bsh);
                    409:                if (paddr >= (MACEBUS_BASE + MACE_ISAX_OFFS) &&
                    410:                    (paddr + size) <=
                    411:                    (MACEBUS_BASE + MACE_ISAX_OFFS + MACE_ISAX_SIZE))
                    412:                        return;
                    413:        }
                    414:
                    415:        if (pmap_extract(pmap_kernel(), bsh, (void *)&paddr) == 0) {
                    416:                printf("bus_space_unmap: no pa for va %p\n", bsh);
                    417:                return;
                    418:        }
                    419:
                    420:        uvm_km_free(kernel_map, sva, len);
                    421:
                    422:        if (extent_free(t->bus_extent, paddr, size,
                    423:            EX_NOWAIT | extent_malloc_flags)) {
                    424:                printf("bus_space_map: pa %p, size %p\n", paddr, size);
                    425:                printf("bus_space_map: can't free region\n");
                    426:        }
                    427: }
                    428:
                    429: int
                    430: mace_space_region(bus_space_tag_t t, bus_space_handle_t bsh,
                    431:     bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp)
                    432: {
                    433:        *nbshp = bsh + offset;
                    434:        return (0);
                    435: }
                    436:
                    437: /*
                    438:  * Macebus bus_dma helpers.
                    439:  * Mace accesses memory contiguously at 0x40000000 onwards.
                    440:  */
                    441:
                    442: bus_addr_t
                    443: macebus_pa_to_device(paddr_t pa)
                    444: {
                    445:        return (pa | CRIME_MEMORY_OFFSET);
                    446: }
                    447:
                    448: paddr_t
                    449: macebus_device_to_pa(bus_addr_t addr)
                    450: {
                    451:        paddr_t pa = (paddr_t)addr & CRIME_MEMORY_MASK;
                    452:
                    453:        if (pa >= 256 * 1024 * 1024)
                    454:                pa |= CRIME_MEMORY_OFFSET;
                    455:
                    456:        return (pa);
                    457: }
                    458:
                    459: /*
                    460:  *  Macebus interrupt handler driver.
                    461:  */
                    462:
                    463: intrmask_t mace_intem = 0x0;
                    464: static intrmask_t intrtype[INTMASKSIZE];
                    465: static intrmask_t intrmask[INTMASKSIZE];
                    466: static intrmask_t intrlevel[INTMASKSIZE];
                    467:
                    468: static int fakeintr(void *);
                    469: static int fakeintr(void *a) {return 0;}
                    470:
                    471: /*
                    472:  *  Establish an interrupt handler called from the dispatcher.
                    473:  *  The interrupt function established should return zero if
                    474:  *  there was nothing to serve (no int) and non zero when an
                    475:  *  interrupt was serviced.
                    476:  *  Interrupts are numbered from 1 and up where 1 maps to HW int 0.
                    477:  */
                    478: void *
                    479: macebus_intr_establish(void *icp, u_long irq, int type, int level,
                    480:     int (*ih_fun)(void *), void *ih_arg, char *ih_what)
                    481: {
                    482:        struct intrhand **p, *q, *ih;
                    483:        static struct intrhand fakehand = {NULL, fakeintr};
                    484:        int edge;
                    485:        extern int cold;
                    486:        static int initialized = 0;
                    487:
                    488:        if (!initialized) {
                    489:                /*INIT CODE HERE*/
                    490:                initialized = 1;
                    491:        }
                    492:
                    493:        if (irq > 62 || irq < 1) {
                    494:                panic("intr_establish: illegal irq %d", irq);
                    495:        }
                    496:        irq -= 1;       /* Adjust for 1 being first (0 is no int) */
                    497:
                    498:        /* no point in sleeping unless someone can free memory. */
                    499:        ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
                    500:        if (ih == NULL)
                    501:                panic("intr_establish: can't malloc handler info");
                    502:
                    503:        if (type == IST_NONE || type == IST_PULSE)
                    504:                panic("intr_establish: bogus type");
                    505:
                    506:        switch (intrtype[irq]) {
                    507:        case IST_EDGE:
                    508:        case IST_LEVEL:
                    509:                if (type == intrtype[irq])
                    510:                        break;
                    511:        }
                    512:
                    513:        switch (type) {
                    514:        case IST_EDGE:
                    515:                edge |= 1 << irq;
                    516:                break;
                    517:        case IST_LEVEL:
                    518:                edge &= ~(1 << irq);
                    519:                break;
                    520:        }
                    521:
                    522:        /*
                    523:         * Figure out where to put the handler.
                    524:         * This is O(N^2), but we want to preserve the order, and N is
                    525:         * generally small.
                    526:         */
                    527:        for (p = &intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
                    528:                ;
                    529:
                    530:        /*
                    531:         * Actually install a fake handler momentarily, since we might be doing
                    532:         * this with interrupts enabled and don't want the real routine called
                    533:         * until masking is set up.
                    534:         */
                    535:        fakehand.ih_level = level;
                    536:        *p = &fakehand;
                    537:
                    538:        macebus_intr_makemasks();
                    539:
                    540:        /*
                    541:         * Poke the real handler in now.
                    542:         */
                    543:        ih->ih_fun = ih_fun;
                    544:        ih->ih_arg = ih_arg;
                    545:        ih->ih_next = NULL;
                    546:        ih->ih_level = level;
                    547:        ih->ih_irq = irq;
                    548:        ih->ih_what = ih_what;
                    549:        evcount_attach(&ih->ih_count, ih_what, (void *)&ih->ih_irq,
                    550:            &evcount_intr);
                    551:        *p = ih;
                    552:
                    553:        return (ih);
                    554: }
                    555:
                    556: void
                    557: macebus_intr_disestablish(void *p1, void *p2)
                    558: {
                    559: }
                    560:
                    561: /*
                    562:  *  Regenerate interrupt masks to reflect reality.
                    563:  */
                    564: void
                    565: macebus_intr_makemasks(void)
                    566: {
                    567:        int irq, level;
                    568:        struct intrhand *q;
                    569:
                    570:        /* First, figure out which levels each IRQ uses. */
                    571:        for (irq = 0; irq < INTMASKSIZE; irq++) {
                    572:                int levels = 0;
                    573:                for (q = intrhand[irq]; q; q = q->ih_next)
                    574:                        levels |= 1 << q->ih_level;
                    575:                intrlevel[irq] = levels;
                    576:        }
                    577:
                    578:        /* Then figure out which IRQs use each level. */
                    579:        for (level = IPL_NONE; level < NIPLS; level++) {
                    580:                int irqs = 0;
                    581:                for (irq = 0; irq < INTMASKSIZE; irq++)
                    582:                        if (intrlevel[irq] & (1 << level))
                    583:                                irqs |= 1 << irq;
                    584:                imask[level] = irqs | SINT_ALLMASK;
                    585:        }
                    586:
                    587:        /*
                    588:         * There are tty, network and disk drivers that use free() at interrupt
                    589:         * time, so imp > (tty | net | bio).
                    590:         *
                    591:         * Enforce a hierarchy that gives slow devices a better chance at not
                    592:         * dropping data.
                    593:         */
                    594:        imask[IPL_NET] |= imask[IPL_BIO];
                    595:        imask[IPL_TTY] |= imask[IPL_NET];
                    596:        imask[IPL_VM] |= imask[IPL_TTY];
                    597:        imask[IPL_CLOCK] |= imask[IPL_VM] | SPL_CLOCKMASK;
                    598:
                    599:        /*
                    600:         * These are pseudo-levels.
                    601:         */
                    602:        imask[IPL_NONE] = 0;
                    603:        imask[IPL_HIGH] = -1;
                    604:
                    605:        /* And eventually calculate the complete masks. */
                    606:        for (irq = 0; irq < INTMASKSIZE; irq++) {
                    607:                int irqs = 1 << irq;
                    608:                for (q = intrhand[irq]; q; q = q->ih_next)
                    609:                        irqs |= imask[q->ih_level];
                    610:                intrmask[irq] = irqs | SINT_ALLMASK;
                    611:        }
                    612:
                    613:        /* Lastly, determine which IRQs are actually in use. */
                    614:        irq = 0;
                    615:        for (level = 0; level < INTMASKSIZE; level++) {
                    616:                if (intrhand[level]) {
                    617:                        irq |= 1 << level;
                    618:                }
                    619:        }
                    620:        mace_intem = irq & 0x0000ffff;
                    621:        hw_setintrmask(0);
                    622: }
                    623:
                    624: void
                    625: macebus_do_pending_int(int newcpl)
                    626: {
                    627: #if 0
                    628:        struct intrhand *ih;
                    629:        int vector;
                    630:        intrmask_t hwpend;
                    631:        struct trap_frame cf;
                    632:        static volatile int processing;
                    633:
                    634:        /* Don't recurse... but change the mask */
                    635:        if (processing) {
                    636:                __asm__ (" .set noreorder\n");
                    637:                cpl = newcpl;
                    638:                __asm__ (" sync\n .set reorder\n");
                    639:                return;
                    640:        }
                    641:        processing = 1;
                    642:
                    643:
                    644:        /* XXX Fake a trapframe for clock pendings... */
                    645:        cf.pc = (int)&macebus_do_pending_int;
                    646:        cf.sr = 0;
                    647:        cf.cpl = cpl;
                    648:
                    649:        /* Hard mask current cpl so we don't get any new pendings */
                    650:        hw_setintrmask(cpl);
                    651:
                    652:        /* Get what interrupt we should process */
                    653:        hwpend = ipending & ~newcpl;
                    654:        hwpend &= ~SINT_ALLMASK;
                    655:        atomic_clearbits_int(&ipending, hwpend);
                    656:
                    657:        /* Enable all non pending non masked hardware interrupts */
                    658:        __asm__ (" .set noreorder\n");
                    659:        cpl = (cpl & SINT_ALLMASK) | (newcpl & ~SINT_ALLMASK) | hwpend;
                    660:        __asm__ (" sync\n .set reorder\n");
                    661:        hw_setintrmask(cpl);
                    662:
                    663:        while (hwpend) {
                    664:                vector = ffs(hwpend) - 1;
                    665:                hwpend &= ~(1L << vector);
                    666:                ih = intrhand[vector];
                    667:                while (ih) {
                    668:                        ih->frame = &cf;
                    669:                        if ((*ih->ih_fun)(ih->ih_arg)) {
                    670:                                ih->ih_count.ec_count++;
                    671:                        }
                    672:                        ih = ih->ih_next;
                    673:                }
                    674:        }
                    675:
                    676:        /* Enable all processed pending hardware interrupts */
                    677:        __asm__ (" .set noreorder\n");
                    678:        cpl &= ~hwpend;
                    679:        __asm__ (" sync\n .set reorder\n");
                    680:        hw_setintrmask(cpl);
                    681:
                    682:        if ((ipending & SINT_CLOCKMASK) & ~newcpl) {
                    683:                atomic_clearbits_int(&ipending, SINT_CLOCKMASK);
                    684:                softclock();
                    685:        }
                    686:        if ((ipending & SINT_NETMASK) & ~newcpl) {
                    687:                extern int netisr;
                    688:                int isr;
                    689:
                    690:                atomic_clearbits_int(&ipending, SINT_NETMASK);
                    691:                while ((isr = netisr) != 0) {
                    692:                        atomic_clearbits_int(&netisr, isr);
                    693: #define        DONETISR(b,f)   if (isr & (1 << (b)))   f();
                    694: #include <net/netisr_dispatch.h>
                    695:                }
                    696:        }
                    697:
                    698: #ifdef notyet
                    699:        if ((ipending & SINT_TTYMASK) & ~newcpl) {
                    700:                atomic_clearbits_int(&ipending, SINT_TTYMASK);
                    701:                compoll(NULL);
                    702:        }
                    703: #endif
                    704:
                    705:        /* Update masks to new cpl. Order highly important! */
                    706:        __asm__ (" .set noreorder\n");
                    707:        cpl = newcpl;
                    708:        __asm__ (" sync\n .set reorder\n");
                    709:        hw_setintrmask(newcpl);
                    710:
                    711:        processing = 0;
                    712: #else
                    713:        /* Update masks to new cpl. Order highly important! */
                    714:        __asm__ (" .set noreorder\n");
                    715:        cpl = newcpl;
                    716:        __asm__ (" sync\n .set reorder\n");
                    717:        hw_setintrmask(newcpl);
                    718:        /* If we still have softints pending trigg processing */
                    719:        if (ipending & SINT_ALLMASK & ~newcpl)
                    720:                setsoftintr0();
                    721: #endif
                    722: }
                    723:
                    724: /*
                    725:  *  Process interrupts. The parameter pending has non-masked interrupts.
                    726:  */
                    727: intrmask_t
                    728: macebus_iointr(intrmask_t hwpend, struct trap_frame *cf)
                    729: {
                    730:        struct intrhand *ih;
                    731:        intrmask_t caught, vm;
                    732:        int v;
                    733:        intrmask_t pending;
                    734:        u_int64_t intstat, isastat, mask;
                    735:
                    736:        intstat = bus_space_read_8(&crimebus_tag, crime_h, CRIME_INT_STAT);
                    737:        intstat &= 0xffff;
                    738:
                    739:        isastat = bus_space_read_8(&macebus_tag, mace_h, MACE_ISA_INT_STAT);
                    740:        caught = 0;
                    741:
                    742:        /* Mask off masked interrupts and save them as pending */
                    743:        if (intstat & cf->cpl) {
                    744:                atomic_setbits_int(&ipending, intstat & cf->cpl);
                    745:                mask = bus_space_read_8(&crimebus_tag, crime_h, CRIME_INT_MASK);
                    746:                mask &= ~ipending;
                    747:                bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_MASK, mask);
                    748:                caught++;
                    749:        }
                    750:
                    751:        /* Scan all unmasked. Scan the first 16 for now */
                    752:        pending = intstat & ~cf->cpl;
                    753:        atomic_clearbits_int(&ipending, pending);
                    754:
                    755:        for (v = 0, vm = 1; pending != 0 && v < 16 ; v++, vm <<= 1) {
                    756:                if (pending & vm) {
                    757:                        ih = intrhand[v];
                    758:
                    759:                        while (ih) {
                    760:                                ih->frame = cf;
                    761:                                if ((*ih->ih_fun)(ih->ih_arg)) {
                    762:                                        caught |= vm;
                    763:                                        ih->ih_count.ec_count++;
                    764:                                }
                    765:                                ih = ih->ih_next;
                    766:                        }
                    767:                }
                    768:        }
                    769:
                    770:        if (caught)
                    771:                return CR_INT_0;
                    772:
                    773:        return 0;  /* Non found here */
                    774: }
                    775:
                    776:
                    777: /*
                    778:  *  Macebus auxilary functions run each clock interrupt.
                    779:  */
                    780: intrmask_t
                    781: macebus_aux(intrmask_t hwpend, struct trap_frame *cf)
                    782: {
                    783:        extern char idle[], e_idle[];
                    784:        u_int64_t mask;
                    785:
                    786:        mask = bus_space_read_8(&macebus_tag, mace_h, MACE_ISA_MISC_REG);
                    787:        mask |= MACE_ISA_MISC_RLED_OFF | MACE_ISA_MISC_GLED_OFF;
                    788:
                    789:        /* GREEN - Idle */
                    790:        /* AMBER - System mode */
                    791:        /* RED   - User Mode */
                    792:        if (cf->sr & SR_KSU_USER) {
                    793:                mask &= ~MACE_ISA_MISC_RLED_OFF;
                    794:        } else if (cf->pc >= (long)idle && cf->pc < (long)e_idle) {
                    795:                mask &= ~MACE_ISA_MISC_GLED_OFF;
                    796:        } else {
                    797:                mask &= ~(MACE_ISA_MISC_RLED_OFF | MACE_ISA_MISC_GLED_OFF);
                    798:        }
                    799:        bus_space_write_8(&macebus_tag, mace_h, MACE_ISA_MISC_REG, mask);
                    800:
                    801:        if (maceticks++ > 100*5) {
                    802:                maceticks = 0;
                    803:        }
                    804:
                    805:        return 0; /* Real clock int handler registers */
                    806: }

CVSweb