diff options
author | peter <peter@FreeBSD.org> | 2004-08-16 23:12:30 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2004-08-16 23:12:30 +0000 |
commit | b23c8d6fe517aef9545060cf2b11c3b9173d38ab (patch) | |
tree | 1c0ae587900538ab8b4dd609cce70a297124e949 /sys/amd64/isa/atpic.c | |
parent | f1342b61c3097ca3acacf47c8da0d405db5eb32d (diff) | |
download | FreeBSD-src-b23c8d6fe517aef9545060cf2b11c3b9173d38ab.zip FreeBSD-src-b23c8d6fe517aef9545060cf2b11c3b9173d38ab.tar.gz |
Sync with i386 - Optimize intr_execute_handlers a bit etc.
Diffstat (limited to 'sys/amd64/isa/atpic.c')
-rw-r--r-- | sys/amd64/isa/atpic.c | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/sys/amd64/isa/atpic.c b/sys/amd64/isa/atpic.c index c1f0178..3719a9b 100644 --- a/sys/amd64/isa/atpic.c +++ b/sys/amd64/isa/atpic.c @@ -140,7 +140,7 @@ struct atpic_intsrc { }; static void atpic_enable_source(struct intsrc *isrc); -static void atpic_disable_source(struct intsrc *isrc); +static void atpic_disable_source(struct intsrc *isrc, int eoi); static void atpic_eoi_master(struct intsrc *isrc); static void atpic_eoi_slave(struct intsrc *isrc); static void atpic_enable_intr(struct intsrc *isrc); @@ -177,6 +177,35 @@ static struct atpic_intsrc atintrs[] = { CTASSERT(sizeof(atintrs) / sizeof(atintrs[0]) == NUM_ISA_IRQS); +static __inline void +_atpic_eoi_master(struct intsrc *isrc) +{ + + KASSERT(isrc->is_pic == &atpics[MASTER].at_pic, + ("%s: mismatched pic", __func__)); +#ifndef AUTO_EOI_1 + outb(atpics[MASTER].at_ioaddr, OCW2_EOI); +#endif +} + +/* + * The data sheet says no auto-EOI on slave, but it sometimes works. + * So, if AUTO_EOI_2 is enabled, we use it. + */ +static __inline void +_atpic_eoi_slave(struct intsrc *isrc) +{ + + KASSERT(isrc->is_pic == &atpics[SLAVE].at_pic, + ("%s: mismatched pic", __func__)); +#ifndef AUTO_EOI_2 + outb(atpics[SLAVE].at_ioaddr, OCW2_EOI); +#ifndef AUTO_EOI_1 + outb(atpics[MASTER].at_ioaddr, OCW2_EOI); +#endif +#endif +} + static void atpic_enable_source(struct intsrc *isrc) { @@ -192,48 +221,48 @@ atpic_enable_source(struct intsrc *isrc) } static void -atpic_disable_source(struct intsrc *isrc) +atpic_disable_source(struct intsrc *isrc, int eoi) { struct atpic_intsrc *ai = (struct atpic_intsrc *)isrc; struct atpic *ap = (struct atpic *)isrc->is_pic; - if (ai->at_trigger == INTR_TRIGGER_EDGE) - return; mtx_lock_spin(&icu_lock); - *ap->at_imen |= IMEN_MASK(ai); - outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen); + if (ai->at_trigger != INTR_TRIGGER_EDGE) { + *ap->at_imen |= IMEN_MASK(ai); + outb(ap->at_ioaddr + ICU_IMR_OFFSET, *ap->at_imen); + } + + /* + * Take care to call these functions directly instead of through + * a function pointer. All of the referenced variables should + * still be hot in the cache. + */ + if (eoi == PIC_EOI) { + if (isrc->is_pic == &atpics[MASTER].at_pic) + _atpic_eoi_master(isrc); + else + _atpic_eoi_slave(isrc); + } + mtx_unlock_spin(&icu_lock); } static void atpic_eoi_master(struct intsrc *isrc) { - - KASSERT(isrc->is_pic == &atpics[MASTER].at_pic, - ("%s: mismatched pic", __func__)); #ifndef AUTO_EOI_1 mtx_lock_spin(&icu_lock); - outb(atpics[MASTER].at_ioaddr, OCW2_EOI); + _atpic_eoi_master(isrc); mtx_unlock_spin(&icu_lock); #endif } -/* - * The data sheet says no auto-EOI on slave, but it sometimes works. - * So, if AUTO_EOI_2 is enabled, we use it. - */ static void atpic_eoi_slave(struct intsrc *isrc) { - - KASSERT(isrc->is_pic == &atpics[SLAVE].at_pic, - ("%s: mismatched pic", __func__)); #ifndef AUTO_EOI_2 mtx_lock_spin(&icu_lock); - outb(atpics[SLAVE].at_ioaddr, OCW2_EOI); -#ifndef AUTO_EOI_1 - outb(atpics[MASTER].at_ioaddr, OCW2_EOI); -#endif + _atpic_eoi_slave(isrc); mtx_unlock_spin(&icu_lock); #endif } |