[BACK]Return to ioapic.c CVS log [TXT][DIR] Up to [local] / sys / arch / amd64 / amd64

Annotation of sys/arch/amd64/amd64/ioapic.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: ioapic.c,v 1.12 2007/02/22 19:46:16 marco Exp $       */
        !             2: /*     $NetBSD: ioapic.c,v 1.6 2003/05/15 13:30:31 fvdl Exp $  */
        !             3:
        !             4: /*-
        !             5:  * Copyright (c) 2000 The NetBSD Foundation, Inc.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * This code is derived from software contributed to The NetBSD Foundation
        !             9:  * by RedBack Networks Inc.
        !            10:  *
        !            11:  * Author: Bill Sommerfeld
        !            12:  *
        !            13:  * Redistribution and use in source and binary forms, with or without
        !            14:  * modification, are permitted provided that the following conditions
        !            15:  * are met:
        !            16:  * 1. Redistributions of source code must retain the above copyright
        !            17:  *    notice, this list of conditions and the following disclaimer.
        !            18:  * 2. Redistributions in binary form must reproduce the above copyright
        !            19:  *    notice, this list of conditions and the following disclaimer in the
        !            20:  *    documentation and/or other materials provided with the distribution.
        !            21:  * 3. All advertising materials mentioning features or use of this software
        !            22:  *    must display the following acknowledgement:
        !            23:  *        This product includes software developed by the NetBSD
        !            24:  *        Foundation, Inc. and its contributors.
        !            25:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            26:  *    contributors may be used to endorse or promote products derived
        !            27:  *    from this software without specific prior written permission.
        !            28:  *
        !            29:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            30:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            31:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            32:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            33:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            34:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            35:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            36:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            37:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            38:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            39:  * POSSIBILITY OF SUCH DAMAGE.
        !            40:  */
        !            41:
        !            42:
        !            43: /*
        !            44:  * Copyright (c) 1999 Stefan Grefen
        !            45:  *
        !            46:  * Redistribution and use in source and binary forms, with or without
        !            47:  * modification, are permitted provided that the following conditions
        !            48:  * are met:
        !            49:  * 1. Redistributions of source code must retain the above copyright
        !            50:  *    notice, this list of conditions and the following disclaimer.
        !            51:  * 2. Redistributions in binary form must reproduce the above copyright
        !            52:  *    notice, this list of conditions and the following disclaimer in the
        !            53:  *    documentation and/or other materials provided with the distribution.
        !            54:  * 3. All advertising materials mentioning features or use of this software
        !            55:  *    must display the following acknowledgement:
        !            56:  *      This product includes software developed by the NetBSD
        !            57:  *      Foundation, Inc. and its contributors.
        !            58:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            59:  *    contributors may be used to endorse or promote products derived
        !            60:  *    from this software without specific prior written permission.
        !            61:  *
        !            62:  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
        !            63:  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            64:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            65:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE
        !            66:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            67:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            68:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            69:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            70:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            71:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            72:  * SUCH DAMAGE.
        !            73:  */
        !            74:
        !            75: #include <sys/param.h>
        !            76: #include <sys/systm.h>
        !            77: #include <sys/device.h>
        !            78: #include <sys/malloc.h>
        !            79:
        !            80: #include <machine/bus.h>
        !            81: #include <machine/isa_machdep.h> /* XXX intrhand */
        !            82:
        !            83: #include <uvm/uvm_extern.h>
        !            84: #include <machine/i82093reg.h>
        !            85: #include <machine/i82093var.h>
        !            86:
        !            87: #include <machine/i82489reg.h>
        !            88: #include <machine/i82489var.h>
        !            89:
        !            90: #include <machine/pmap.h>
        !            91:
        !            92: #include <machine/mpbiosvar.h>
        !            93:
        !            94: #if !defined(MPBIOS) && !defined(MPACPI)
        !            95: #error "ioapic needs at least one of the MPBIOS or MPACPI options"
        !            96: #endif
        !            97:
        !            98: /*
        !            99:  * XXX locking
        !           100:  */
        !           101:
        !           102: int     ioapic_match(struct device *, void *, void *);
        !           103: void    ioapic_attach(struct device *, struct device *, void *);
        !           104:
        !           105: extern int x86_mem_add_mapping(bus_addr_t, bus_size_t,
        !           106:     int, bus_space_handle_t *); /* XXX XXX */
        !           107:
        !           108: void ioapic_hwmask(struct pic *, int);
        !           109: void ioapic_hwunmask(struct pic *, int);
        !           110: void ioapic_addroute(struct pic *, struct cpu_info *, int, int, int);
        !           111: void ioapic_delroute(struct pic *, struct cpu_info *, int, int, int);
        !           112: void apic_set_redir(struct ioapic_softc *, int, int, struct cpu_info *);
        !           113:
        !           114: int apic_verbose = 0;
        !           115:
        !           116: int ioapic_bsp_id = 0;
        !           117: int ioapic_cold = 1;
        !           118:
        !           119: struct ioapic_softc *ioapics;   /* head of linked list */
        !           120: int nioapics = 0;               /* number attached */
        !           121: static int ioapic_vecbase;
        !           122:
        !           123: void ioapic_set_id(struct ioapic_softc *);
        !           124:
        !           125: static __inline u_long
        !           126: ioapic_lock(struct ioapic_softc *sc)
        !           127: {
        !           128:        u_long flags;
        !           129:
        !           130:        flags = read_psl();
        !           131:        disable_intr();
        !           132:        mtx_enter(&sc->sc_pic.pic_mutex);
        !           133:        return flags;
        !           134: }
        !           135:
        !           136: static __inline void
        !           137: ioapic_unlock(struct ioapic_softc *sc, u_long flags)
        !           138: {
        !           139:        mtx_leave(&sc->sc_pic.pic_mutex);
        !           140:        write_psl(flags);
        !           141: }
        !           142:
        !           143: /*
        !           144:  * Register read/write routines.
        !           145:  */
        !           146: static __inline  u_int32_t
        !           147: ioapic_read_ul(struct ioapic_softc *sc,int regid)
        !           148: {
        !           149:        u_int32_t val;
        !           150:
        !           151:        *(sc->sc_reg) = regid;
        !           152:        val = *sc->sc_data;
        !           153:
        !           154:        return val;
        !           155:
        !           156: }
        !           157:
        !           158: static __inline  void
        !           159: ioapic_write_ul(struct ioapic_softc *sc,int regid, u_int32_t val)
        !           160: {
        !           161:        *(sc->sc_reg) = regid;
        !           162:        *(sc->sc_data) = val;
        !           163: }
        !           164:
        !           165: static __inline u_int32_t
        !           166: ioapic_read(struct ioapic_softc *sc, int regid)
        !           167: {
        !           168:        u_int32_t val;
        !           169:        u_long flags;
        !           170:
        !           171:        flags = ioapic_lock(sc);
        !           172:        val = ioapic_read_ul(sc, regid);
        !           173:        ioapic_unlock(sc, flags);
        !           174:        return val;
        !           175: }
        !           176:
        !           177: static __inline  void
        !           178: ioapic_write(struct ioapic_softc *sc,int regid, int val)
        !           179: {
        !           180:        u_long flags;
        !           181:
        !           182:        flags = ioapic_lock(sc);
        !           183:        ioapic_write_ul(sc, regid, val);
        !           184:        ioapic_unlock(sc, flags);
        !           185: }
        !           186:
        !           187: struct ioapic_softc *
        !           188: ioapic_find(int apicid)
        !           189: {
        !           190:        struct ioapic_softc *sc;
        !           191:
        !           192:        if (apicid == MPS_ALL_APICS) {  /* XXX mpbios-specific */
        !           193:                /*
        !           194:                 * XXX kludge for all-ioapics interrupt support
        !           195:                 * on single ioapic systems
        !           196:                 */
        !           197:                if (nioapics <= 1)
        !           198:                        return ioapics;
        !           199:                panic("unsupported: all-ioapics interrupt with >1 ioapic");
        !           200:        }
        !           201:
        !           202:        for (sc = ioapics; sc != NULL; sc = sc->sc_next)
        !           203:                if (sc->sc_apicid == apicid)
        !           204:                        return sc;
        !           205:
        !           206:        return NULL;
        !           207: }
        !           208:
        !           209: /*
        !           210:  * For the case the I/O APICs were configured using ACPI, there must
        !           211:  * be an option to match global ACPI interrupts with APICs.
        !           212:  */
        !           213: struct ioapic_softc *
        !           214: ioapic_find_bybase(int vec)
        !           215: {
        !           216:        struct ioapic_softc *sc;
        !           217:
        !           218:        for (sc = ioapics; sc != NULL; sc = sc->sc_next) {
        !           219:                if (vec >= sc->sc_apic_vecbase &&
        !           220:                    vec < (sc->sc_apic_vecbase + sc->sc_apic_sz))
        !           221:                        return sc;
        !           222:        }
        !           223:
        !           224:        return NULL;
        !           225: }
        !           226:
        !           227: static __inline void
        !           228: ioapic_add(struct ioapic_softc *sc)
        !           229: {
        !           230:        sc->sc_next = ioapics;
        !           231:        ioapics = sc;
        !           232:        nioapics++;
        !           233: }
        !           234:
        !           235: void
        !           236: ioapic_print_redir (struct ioapic_softc *sc, char *why, int pin)
        !           237: {
        !           238:        u_int32_t redirlo = ioapic_read(sc, IOAPIC_REDLO(pin));
        !           239:        u_int32_t redirhi = ioapic_read(sc, IOAPIC_REDHI(pin));
        !           240:
        !           241:        apic_format_redir(sc->sc_pic.pic_dev.dv_xname, why, pin, redirhi,
        !           242:            redirlo);
        !           243: }
        !           244:
        !           245: struct cfattach ioapic_ca = {
        !           246:        sizeof(struct ioapic_softc), ioapic_match, ioapic_attach
        !           247: };
        !           248:
        !           249: struct cfdriver ioapic_cd = {
        !           250:        NULL, "ioapic", DV_DULL
        !           251: };
        !           252:
        !           253: int
        !           254: ioapic_match(struct device *parent, void *v, void *aux)
        !           255: {
        !           256:        struct apic_attach_args *aaa = (struct apic_attach_args *) aux;
        !           257:        struct cfdata *match = v;
        !           258:
        !           259:        if (strcmp(aaa->aaa_name, match->cf_driver->cd_name) == 0)
        !           260:                return 1;
        !           261:        return 0;
        !           262: }
        !           263:
        !           264: /* Reprogram the APIC ID, and check that it actually got set. */
        !           265: void
        !           266: ioapic_set_id(struct ioapic_softc *sc) {
        !           267:        u_int8_t apic_id;
        !           268:
        !           269:        ioapic_write(sc, IOAPIC_ID,
        !           270:            (ioapic_read(sc, IOAPIC_ID) & ~IOAPIC_ID_MASK) |
        !           271:            (sc->sc_apicid << IOAPIC_ID_SHIFT));
        !           272:
        !           273:        apic_id = (ioapic_read(sc, IOAPIC_ID) & IOAPIC_ID_MASK) >>
        !           274:            IOAPIC_ID_SHIFT;
        !           275:
        !           276:        if (apic_id != sc->sc_apicid)
        !           277:                printf(", can't remap to apid %d\n", sc->sc_apicid);
        !           278:        else
        !           279:                printf(", remapped to apid %d\n", sc->sc_apicid);
        !           280: }
        !           281:
        !           282: /*
        !           283:  * can't use bus_space_xxx as we don't have a bus handle ...
        !           284:  */
        !           285: void
        !           286: ioapic_attach(struct device *parent, struct device *self, void *aux)
        !           287: {
        !           288:        struct ioapic_softc *sc = (struct ioapic_softc *)self;
        !           289:        struct apic_attach_args  *aaa = (struct apic_attach_args  *) aux;
        !           290:        int apic_id;
        !           291:        bus_space_handle_t bh;
        !           292:        u_int32_t ver_sz;
        !           293:        int i;
        !           294:
        !           295:        sc->sc_flags = aaa->flags;
        !           296:        sc->sc_apicid = aaa->apic_id;
        !           297:
        !           298:        printf(" apid %d", aaa->apic_id);
        !           299:
        !           300:        if (ioapic_find(aaa->apic_id) != NULL) {
        !           301:                printf(", duplicate apic id (ignored)\n");
        !           302:                return;
        !           303:        }
        !           304:
        !           305:        ioapic_add(sc);
        !           306:
        !           307:        printf(" pa 0x%lx", aaa->apic_address);
        !           308:
        !           309:        if (x86_mem_add_mapping(aaa->apic_address, PAGE_SIZE, 0, &bh) != 0) {
        !           310:                printf(", map failed\n");
        !           311:                return;
        !           312:        }
        !           313:        sc->sc_reg = (volatile u_int32_t *)(bh + IOAPIC_REG);
        !           314:        sc->sc_data = (volatile u_int32_t *)(bh + IOAPIC_DATA);
        !           315:
        !           316:        sc->sc_pic.pic_type = PIC_IOAPIC;
        !           317:        mtx_init(&sc->sc_pic.pic_mutex, IPL_NONE);
        !           318:        sc->sc_pic.pic_hwmask = ioapic_hwmask;
        !           319:        sc->sc_pic.pic_hwunmask = ioapic_hwunmask;
        !           320:        sc->sc_pic.pic_addroute = ioapic_addroute;
        !           321:        sc->sc_pic.pic_delroute = ioapic_delroute;
        !           322:        sc->sc_pic.pic_edge_stubs = ioapic_edge_stubs;
        !           323:        sc->sc_pic.pic_level_stubs = ioapic_level_stubs;
        !           324:
        !           325:        ver_sz = ioapic_read(sc, IOAPIC_VER);
        !           326:        sc->sc_apic_vers = (ver_sz & IOAPIC_VER_MASK) >> IOAPIC_VER_SHIFT;
        !           327:        sc->sc_apic_sz = (ver_sz & IOAPIC_MAX_MASK) >> IOAPIC_MAX_SHIFT;
        !           328:        sc->sc_apic_sz++;
        !           329:
        !           330:        if (aaa->apic_vecbase != -1)
        !           331:                sc->sc_apic_vecbase = aaa->apic_vecbase;
        !           332:        else {
        !           333:                /*
        !           334:                 * XXX this assumes ordering of ioapics in the table.
        !           335:                 * Only needed for broken BIOS workaround (see mpbios.c)
        !           336:                 */
        !           337:                sc->sc_apic_vecbase = ioapic_vecbase;
        !           338:                ioapic_vecbase += sc->sc_apic_sz;
        !           339:        }
        !           340:
        !           341:        if (mp_verbose) {
        !           342:                printf(", %s mode",
        !           343:                    aaa->flags & IOAPIC_PICMODE ? "PIC" : "virtual wire");
        !           344:        }
        !           345:
        !           346:        printf(", version %x, %d pins\n", sc->sc_apic_vers, sc->sc_apic_sz);
        !           347:
        !           348:        apic_id = (ioapic_read(sc, IOAPIC_ID) & IOAPIC_ID_MASK) >>
        !           349:            IOAPIC_ID_SHIFT;
        !           350:
        !           351:        sc->sc_pins = malloc(sizeof(struct ioapic_pin) * sc->sc_apic_sz,
        !           352:            M_DEVBUF, M_WAITOK);
        !           353:
        !           354:        for (i=0; i<sc->sc_apic_sz; i++) {
        !           355:                sc->sc_pins[i].ip_next = NULL;
        !           356:                sc->sc_pins[i].ip_map = NULL;
        !           357:                sc->sc_pins[i].ip_vector = 0;
        !           358:                sc->sc_pins[i].ip_type = IST_NONE;
        !           359:        }
        !           360:
        !           361:        /*
        !           362:         * In case the APIC is not initialized to the correct ID
        !           363:         * do it now.
        !           364:         * Maybe we should record the original ID for interrupt
        !           365:         * mapping later ...
        !           366:         */
        !           367:        if (apic_id != sc->sc_apicid) {
        !           368:                printf("%s: misconfigured as apic %d",
        !           369:                    sc->sc_pic.pic_dev.dv_xname, apic_id);
        !           370:                ioapic_set_id(sc);
        !           371:        }
        !           372: #if 0
        !           373:        /* output of this was boring. */
        !           374:        if (mp_verbose)
        !           375:                for (i=0; i<sc->sc_apic_sz; i++)
        !           376:                        ioapic_print_redir(sc, "boot", i);
        !           377: #endif
        !           378: }
        !           379:
        !           380: void
        !           381: apic_set_redir(struct ioapic_softc *sc, int pin, int idt_vec,
        !           382:     struct cpu_info *ci)
        !           383: {
        !           384:        u_int32_t redlo;
        !           385:        u_int32_t redhi = 0;
        !           386:        int delmode;
        !           387:
        !           388:        struct ioapic_pin *pp;
        !           389:        struct mp_intr_map *map;
        !           390:
        !           391:        pp = &sc->sc_pins[pin];
        !           392:        map = pp->ip_map;
        !           393:        redlo = (map == NULL) ? IOAPIC_REDLO_MASK : map->redir;
        !           394:        delmode = (redlo & IOAPIC_REDLO_DEL_MASK) >> IOAPIC_REDLO_DEL_SHIFT;
        !           395:
        !           396:        /* XXX magic numbers */
        !           397:        if ((delmode != 0) && (delmode != 1))
        !           398:                ;
        !           399:        else if (pp->ip_type == IST_NONE) {
        !           400:                redlo |= IOAPIC_REDLO_MASK;
        !           401:        } else {
        !           402:                redlo |= (idt_vec & 0xff);
        !           403:                redlo &= ~IOAPIC_REDLO_DEL_MASK;
        !           404:                redlo |= (IOAPIC_REDLO_DEL_FIXED << IOAPIC_REDLO_DEL_SHIFT);
        !           405:                redlo &= ~IOAPIC_REDLO_DSTMOD;
        !           406:
        !           407:                /*
        !           408:                 * Destination: BSP CPU
        !           409:                 *
        !           410:                 * XXX will want to distribute interrupts across cpu's
        !           411:                 * eventually.  most likely, we'll want to vector each
        !           412:                 * interrupt to a specific CPU and load-balance across
        !           413:                 * cpu's.  but there's no point in doing that until after
        !           414:                 * most interrupts run without the kernel lock.
        !           415:                 */
        !           416:                redhi |= (ci->ci_apicid << IOAPIC_REDHI_DEST_SHIFT);
        !           417:
        !           418:                /* XXX derive this bit from BIOS info */
        !           419:                if (pp->ip_type == IST_LEVEL)
        !           420:                        redlo |= IOAPIC_REDLO_LEVEL;
        !           421:                else
        !           422:                        redlo &= ~IOAPIC_REDLO_LEVEL;
        !           423:                if (map != NULL && ((map->flags & 3) == MPS_INTPO_DEF)) {
        !           424:                        if (pp->ip_type == IST_LEVEL)
        !           425:                                redlo |= IOAPIC_REDLO_ACTLO;
        !           426:                        else
        !           427:                                redlo &= ~IOAPIC_REDLO_ACTLO;
        !           428:                }
        !           429:        }
        !           430:        /* Do atomic write */
        !           431:        ioapic_write(sc, IOAPIC_REDLO(pin), IOAPIC_REDLO_MASK);
        !           432:        ioapic_write(sc, IOAPIC_REDHI(pin), redhi);
        !           433:        ioapic_write(sc, IOAPIC_REDLO(pin), redlo);
        !           434:        if (mp_verbose)
        !           435:                ioapic_print_redir(sc, "int", pin);
        !           436: }
        !           437:
        !           438: /*
        !           439:  * Throw the switch and enable interrupts..
        !           440:  */
        !           441:
        !           442: void
        !           443: ioapic_enable(void)
        !           444: {
        !           445:        int p;
        !           446:        struct ioapic_softc *sc;
        !           447:        struct ioapic_pin *ip;
        !           448:
        !           449:        ioapic_cold = 0;
        !           450:
        !           451:        if (ioapics == NULL)
        !           452:                return;
        !           453:
        !           454:        if (ioapics->sc_flags & IOAPIC_PICMODE) {
        !           455:                printf("%s: writing to IMCR to disable pics\n",
        !           456:                    ioapics->sc_pic.pic_dev.dv_xname);
        !           457:                outb(IMCR_ADDR, IMCR_REGISTER);
        !           458:                outb(IMCR_DATA, IMCR_APIC);
        !           459:        }
        !           460:
        !           461:        for (sc = ioapics; sc != NULL; sc = sc->sc_next) {
        !           462:                if (mp_verbose)
        !           463:                        printf("%s: enabling\n", sc->sc_pic.pic_dev.dv_xname);
        !           464:
        !           465:                for (p = 0; p < sc->sc_apic_sz; p++) {
        !           466:                        ip = &sc->sc_pins[p];
        !           467:                        if (ip->ip_type != IST_NONE)
        !           468:                                apic_set_redir(sc, p, ip->ip_vector,
        !           469:                                    ip->ip_cpu);
        !           470:                }
        !           471:        }
        !           472: }
        !           473:
        !           474: void
        !           475: ioapic_hwmask(struct pic *pic, int pin)
        !           476: {
        !           477:        u_int32_t redlo;
        !           478:        struct ioapic_softc *sc = (struct ioapic_softc *)pic;
        !           479:        u_long flags;
        !           480:
        !           481:        if (ioapic_cold)
        !           482:                return;
        !           483:        flags = ioapic_lock(sc);
        !           484:        redlo = ioapic_read_ul(sc, IOAPIC_REDLO(pin));
        !           485:        redlo |= IOAPIC_REDLO_MASK;
        !           486:        ioapic_write_ul(sc, IOAPIC_REDLO(pin), redlo);
        !           487:        ioapic_unlock(sc, flags);
        !           488: }
        !           489:
        !           490: void
        !           491: ioapic_hwunmask(struct pic *pic, int pin)
        !           492: {
        !           493:        u_int32_t redlo;
        !           494:        struct ioapic_softc *sc = (struct ioapic_softc *)pic;
        !           495:        u_long flags;
        !           496:
        !           497:        if (ioapic_cold) {
        !           498:                return;
        !           499:        }
        !           500:        flags = ioapic_lock(sc);
        !           501:        redlo = ioapic_read_ul(sc, IOAPIC_REDLO(pin));
        !           502:        redlo &= ~IOAPIC_REDLO_MASK;
        !           503:        ioapic_write_ul(sc, IOAPIC_REDLO(pin), redlo);
        !           504:        ioapic_unlock(sc, flags);
        !           505: }
        !           506:
        !           507: void
        !           508: ioapic_addroute(struct pic *pic, struct cpu_info *ci, int pin,
        !           509:     int idtvec, int type)
        !           510: {
        !           511:        struct ioapic_softc *sc = (struct ioapic_softc *)pic;
        !           512:        struct ioapic_pin *pp;
        !           513:
        !           514:        pp = &sc->sc_pins[pin];
        !           515:        pp->ip_type = type;
        !           516:        pp->ip_vector = idtvec;
        !           517:        pp->ip_cpu = ci;
        !           518:        if (ioapic_cold)
        !           519:                return;
        !           520:        apic_set_redir(sc, pin, idtvec, ci);
        !           521: }
        !           522:
        !           523: void
        !           524: ioapic_delroute(struct pic *pic, struct cpu_info *ci, int pin,
        !           525:     int idtvec, int type)
        !           526: {
        !           527:        struct ioapic_softc *sc = (struct ioapic_softc *)pic;
        !           528:        struct ioapic_pin *pp;
        !           529:
        !           530:        if (ioapic_cold) {
        !           531:                pp = &sc->sc_pins[pin];
        !           532:                pp->ip_type = IST_NONE;
        !           533:                return;
        !           534:        }
        !           535:        ioapic_hwmask(pic, pin);
        !           536: }
        !           537:
        !           538: #ifdef DDB
        !           539: void ioapic_dump(void);
        !           540:
        !           541: void
        !           542: ioapic_dump(void)
        !           543: {
        !           544:        struct ioapic_softc *sc;
        !           545:        struct ioapic_pin *ip;
        !           546:        int p;
        !           547:
        !           548:        for (sc = ioapics; sc != NULL; sc = sc->sc_next) {
        !           549:                for (p = 0; p < sc->sc_apic_sz; p++) {
        !           550:                        ip = &sc->sc_pins[p];
        !           551:                        if (ip->ip_type != IST_NONE)
        !           552:                                ioapic_print_redir(sc, "dump", p);
        !           553:                }
        !           554:        }
        !           555: }
        !           556: #endif

CVSweb