From: Sepherosa Ziehau Date: Mon, 12 Sep 2011 12:57:34 +0000 (+0800) Subject: MachIntrABI: Split vectorctl into intr_setup and intr_teardown X-Git-Tag: v2.12.0~53 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/f416026e53f931769a07626f8ca515570f570d01 MachIntrABI: Split vectorctl into intr_setup and intr_teardown --- diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index b803aa03ff..16550f9ccd 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -326,10 +326,8 @@ register_int(int intr, inthand2_t *handler, void *arg, const char *name, /* * Setup the machine level interrupt vector */ - if (intr < FIRST_SOFTINT && info->i_slow + info->i_fast == 1) { - if (machintr_vector_setup(intr, intr_flags)) - kprintf("machintr_vector_setup: failed on irq %d\n", intr); - } + if (intr < FIRST_SOFTINT && info->i_slow + info->i_fast == 1) + machintr_intr_setup(intr, intr_flags); int_moveto_origcpu(orig_cpuid, cpuid); @@ -379,7 +377,7 @@ unregister_int(void *id) else --info->i_slow; if (intr < FIRST_SOFTINT && info->i_fast + info->i_slow == 0) - machintr_vector_teardown(intr); + machintr_intr_teardown(intr); /* * Clear i_mplock_required if no handlers in the chain require the diff --git a/sys/platform/pc32/apic/ioapic_abi.c b/sys/platform/pc32/apic/ioapic_abi.c index edfdecdd7e..828005a360 100644 --- a/sys/platform/pc32/apic/ioapic_abi.c +++ b/sys/platform/pc32/apic/ioapic_abi.c @@ -476,7 +476,8 @@ extern void IOAPIC_INTRDIS(int); extern int imcr_present; -static int ioapic_vectorctl(int, int, int); +static void ioapic_abi_intr_setup(int, int); +static void ioapic_abi_intr_teardown(int); static void ioapic_finalize(void); static void ioapic_cleanup(void); static void ioapic_setdefault(void); @@ -490,7 +491,8 @@ struct machintr_abi MachIntrABI_IOAPIC = { MACHINTR_IOAPIC, .intrdis = ioapic_abi_intrdis, .intren = ioapic_abi_intren, - .vectorctl = ioapic_vectorctl, + .intr_setup = ioapic_abi_intr_setup, + .intr_teardown = ioapic_abi_intr_teardown, .finalize = ioapic_finalize, .cleanup = ioapic_cleanup, .setdefault = ioapic_setdefault, @@ -557,92 +559,92 @@ ioapic_stabilize(void) panic("ioapic_stabilize() is called\n"); } -static int -ioapic_vectorctl(int op, int intr, int flags) +static void +ioapic_abi_intr_setup(int intr, int flags) { - int error; - int vector; - int select; + int vector, select; uint32_t value; u_long ef; - if (intr < 0 || intr >= IOAPIC_HWI_VECTORS || - intr == IOAPIC_HWI_SYSCALL) - return EINVAL; + KKASSERT(intr >= 0 && intr < IOAPIC_HWI_VECTORS && + intr != IOAPIC_HWI_SYSCALL); + KKASSERT(ioapic_irqs[intr].io_addr != NULL); + + ef = read_eflags(); + cpu_disable_intr(); + + vector = IDT_OFFSET + intr; + setidt(vector, ioapic_intr[intr], SDT_SYS386IGT, + SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + + /* + * Now reprogram the vector in the IO APIC. In order to avoid + * losing an EOI for a level interrupt, which is vector based, + * make sure that the IO APIC is programmed for edge-triggering + * first, then reprogrammed with the new vector. This should + * clear the IRR bit. + */ + imen_lock(); + + select = ioapic_irqs[intr].io_idx; + value = ioapic_read(ioapic_irqs[intr].io_addr, select); + value |= IOART_INTMSET; + + ioapic_write(ioapic_irqs[intr].io_addr, select, + (value & ~APIC_TRIGMOD_MASK)); + ioapic_write(ioapic_irqs[intr].io_addr, select, + (value & ~IOART_INTVEC) | vector); + + imen_unlock(); + + machintr_intren(intr); + + write_eflags(ef); +} + +static void +ioapic_abi_intr_teardown(int intr) +{ + int vector, select; + uint32_t value; + u_long ef; - if (ioapic_irqs[intr].io_addr == NULL) - return EINVAL; + KKASSERT(intr >= 0 && intr < IOAPIC_HWI_VECTORS && + intr != IOAPIC_HWI_SYSCALL); + KKASSERT(ioapic_irqs[intr].io_addr != NULL); ef = read_eflags(); cpu_disable_intr(); - error = 0; - switch(op) { - case MACHINTR_VECTOR_SETUP: - vector = IDT_OFFSET + intr; - setidt(vector, ioapic_intr[intr], SDT_SYS386IGT, - SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + /* + * Teardown an interrupt vector. The vector should already be + * installed in the cpu's IDT, but make sure. + */ + machintr_intrdis(intr); - /* - * Now reprogram the vector in the IO APIC. In order to avoid - * losing an EOI for a level interrupt, which is vector based, - * make sure that the IO APIC is programmed for edge-triggering - * first, then reprogrammed with the new vector. This should - * clear the IRR bit. - */ - imen_lock(); - - select = ioapic_irqs[intr].io_idx; - value = ioapic_read(ioapic_irqs[intr].io_addr, select); - value |= IOART_INTMSET; - - ioapic_write(ioapic_irqs[intr].io_addr, select, - (value & ~APIC_TRIGMOD_MASK)); - ioapic_write(ioapic_irqs[intr].io_addr, select, - (value & ~IOART_INTVEC) | vector); - - imen_unlock(); - - machintr_intren(intr); - break; - - case MACHINTR_VECTOR_TEARDOWN: - /* - * Teardown an interrupt vector. The vector should already be - * installed in the cpu's IDT, but make sure. - */ - machintr_intrdis(intr); - - vector = IDT_OFFSET + intr; - setidt(vector, ioapic_intr[intr], SDT_SYS386IGT, SEL_KPL, - GSEL(GCODE_SEL, SEL_KPL)); - - /* - * In order to avoid losing an EOI for a level interrupt, which - * is vector based, make sure that the IO APIC is programmed for - * edge-triggering first, then reprogrammed with the new vector. - * This should clear the IRR bit. - */ - imen_lock(); - - select = ioapic_irqs[intr].io_idx; - value = ioapic_read(ioapic_irqs[intr].io_addr, select); - - ioapic_write(ioapic_irqs[intr].io_addr, select, - (value & ~APIC_TRIGMOD_MASK)); - ioapic_write(ioapic_irqs[intr].io_addr, select, - (value & ~IOART_INTVEC) | vector); - - imen_unlock(); - break; - - default: - error = EOPNOTSUPP; - break; - } + vector = IDT_OFFSET + intr; + setidt(vector, ioapic_intr[intr], SDT_SYS386IGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); + + /* + * In order to avoid losing an EOI for a level interrupt, which + * is vector based, make sure that the IO APIC is programmed for + * edge-triggering first, then reprogrammed with the new vector. + * This should clear the IRR bit. + */ + imen_lock(); + + select = ioapic_irqs[intr].io_idx; + value = ioapic_read(ioapic_irqs[intr].io_addr, select); + + ioapic_write(ioapic_irqs[intr].io_addr, select, + (value & ~APIC_TRIGMOD_MASK)); + ioapic_write(ioapic_irqs[intr].io_addr, select, + (value & ~IOART_INTVEC) | vector); + + imen_unlock(); write_eflags(ef); - return error; } static void diff --git a/sys/platform/pc32/icu/icu_abi.c b/sys/platform/pc32/icu/icu_abi.c index eccdd6e70d..3d61dfbb8f 100644 --- a/sys/platform/pc32/icu/icu_abi.c +++ b/sys/platform/pc32/icu/icu_abi.c @@ -96,7 +96,8 @@ extern void ICU_INTRDIS(int); extern int imcr_present; -static int icu_vectorctl(int, int, int); +static void icu_abi_intr_setup(int, int); +static void icu_abi_intr_teardown(int); static void icu_finalize(void); static void icu_cleanup(void); static void icu_setdefault(void); @@ -108,7 +109,8 @@ struct machintr_abi MachIntrABI_ICU = { MACHINTR_ICU, .intrdis = ICU_INTRDIS, .intren = ICU_INTREN, - .vectorctl = icu_vectorctl, + .intr_setup = icu_abi_intr_setup, + .intr_teardown = icu_abi_intr_teardown, .finalize = icu_finalize, .cleanup = icu_cleanup, .setdefault = icu_setdefault, @@ -169,38 +171,38 @@ icu_finalize(void) } } -static int -icu_vectorctl(int op, int intr, int flags) +static void +icu_abi_intr_setup(int intr, int flags __unused) { - int error; u_long ef; - if (intr < 0 || intr >= ICU_HWI_VECTORS || intr == ICU_IRQ_SLAVE) - return EINVAL; + KKASSERT(intr >= 0 && intr < ICU_HWI_VECTORS && intr != ICU_IRQ_SLAVE); ef = read_eflags(); cpu_disable_intr(); - error = 0; - switch (op) { - case MACHINTR_VECTOR_SETUP: - setidt(IDT_OFFSET + intr, icu_intr[intr], SDT_SYS386IGT, - SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); - machintr_intren(intr); - break; + setidt(IDT_OFFSET + intr, icu_intr[intr], SDT_SYS386IGT, + SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); + machintr_intren(intr); - case MACHINTR_VECTOR_TEARDOWN: - machintr_intrdis(intr); - setidt(IDT_OFFSET + intr, icu_intr[intr], SDT_SYS386IGT, - SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); - break; + write_eflags(ef); +} + +static void +icu_abi_intr_teardown(int intr) +{ + u_long ef; + + KKASSERT(intr >= 0 && intr < ICU_HWI_VECTORS && intr != ICU_IRQ_SLAVE); + + ef = read_eflags(); + cpu_disable_intr(); + + machintr_intrdis(intr); + setidt(IDT_OFFSET + intr, icu_intr[intr], SDT_SYS386IGT, + SEL_KPL, GSEL(GCODE_SEL, SEL_KPL)); - default: - error = EOPNOTSUPP; - break; - } write_eflags(ef); - return error; } static void diff --git a/sys/platform/pc64/apic/ioapic_abi.c b/sys/platform/pc64/apic/ioapic_abi.c index a4023647d3..286d3b9d4b 100644 --- a/sys/platform/pc64/apic/ioapic_abi.c +++ b/sys/platform/pc64/apic/ioapic_abi.c @@ -476,7 +476,8 @@ extern void IOAPIC_INTRDIS(int); extern int imcr_present; -static int ioapic_vectorctl(int, int, int); +static void ioapic_abi_intr_setup(int, int); +static void ioapic_abi_intr_teardown(int); static void ioapic_finalize(void); static void ioapic_cleanup(void); static void ioapic_setdefault(void); @@ -490,7 +491,8 @@ struct machintr_abi MachIntrABI_IOAPIC = { MACHINTR_IOAPIC, .intrdis = ioapic_abi_intrdis, .intren = ioapic_abi_intren, - .vectorctl = ioapic_vectorctl, + .intr_setup = ioapic_abi_intr_setup, + .intr_teardown = ioapic_abi_intr_teardown, .finalize = ioapic_finalize, .cleanup = ioapic_cleanup, .setdefault = ioapic_setdefault, @@ -557,91 +559,90 @@ ioapic_stabilize(void) panic("ioapic_stabilize is called\n"); } -static int -ioapic_vectorctl(int op, int intr, int flags) +static void +ioapic_abi_intr_setup(int intr, int flags) { - int error; - int vector; - int select; + int vector, select; uint32_t value; register_t ef; - if (intr < 0 || intr >= IOAPIC_HWI_VECTORS || - intr == IOAPIC_HWI_SYSCALL) - return EINVAL; + KKASSERT(intr >= 0 && intr < IOAPIC_HWI_VECTORS && + intr != IOAPIC_HWI_SYSCALL); + KKASSERT(ioapic_irqs[intr].io_addr != NULL); + + ef = read_rflags(); + cpu_disable_intr(); + + vector = IDT_OFFSET + intr; + setidt(vector, ioapic_intr[intr], SDT_SYSIGT, SEL_KPL, 0); + + /* + * Now reprogram the vector in the IO APIC. In order to avoid + * losing an EOI for a level interrupt, which is vector based, + * make sure that the IO APIC is programmed for edge-triggering + * first, then reprogrammed with the new vector. This should + * clear the IRR bit. + */ + imen_lock(); + + select = ioapic_irqs[intr].io_idx; + value = ioapic_read(ioapic_irqs[intr].io_addr, select); + value |= IOART_INTMSET; + + ioapic_write(ioapic_irqs[intr].io_addr, select, + (value & ~APIC_TRIGMOD_MASK)); + ioapic_write(ioapic_irqs[intr].io_addr, select, + (value & ~IOART_INTVEC) | vector); - if (ioapic_irqs[intr].io_addr == NULL) - return EINVAL; + imen_unlock(); + + machintr_intren(intr); + + write_rflags(ef); +} + +static void +ioapic_abi_intr_teardown(int intr) +{ + int vector, select; + uint32_t value; + register_t ef; + + KKASSERT(intr >= 0 && intr < IOAPIC_HWI_VECTORS && + intr != IOAPIC_HWI_SYSCALL); + KKASSERT(ioapic_irqs[intr].io_addr != NULL); ef = read_rflags(); cpu_disable_intr(); - error = 0; - - switch(op) { - case MACHINTR_VECTOR_SETUP: - vector = IDT_OFFSET + intr; - setidt(vector, ioapic_intr[intr], SDT_SYSIGT, SEL_KPL, 0); - - /* - * Now reprogram the vector in the IO APIC. In order to avoid - * losing an EOI for a level interrupt, which is vector based, - * make sure that the IO APIC is programmed for edge-triggering - * first, then reprogrammed with the new vector. This should - * clear the IRR bit. - */ - imen_lock(); - - select = ioapic_irqs[intr].io_idx; - value = ioapic_read(ioapic_irqs[intr].io_addr, select); - value |= IOART_INTMSET; - - ioapic_write(ioapic_irqs[intr].io_addr, select, - (value & ~APIC_TRIGMOD_MASK)); - ioapic_write(ioapic_irqs[intr].io_addr, select, - (value & ~IOART_INTVEC) | vector); - - imen_unlock(); - - machintr_intren(intr); - break; - - case MACHINTR_VECTOR_TEARDOWN: - /* - * Teardown an interrupt vector. The vector should already be - * installed in the cpu's IDT, but make sure. - */ - machintr_intrdis(intr); - - vector = IDT_OFFSET + intr; - setidt(vector, ioapic_intr[intr], SDT_SYSIGT, SEL_KPL, 0); - - /* - * In order to avoid losing an EOI for a level interrupt, which - * is vector based, make sure that the IO APIC is programmed for - * edge-triggering first, then reprogrammed with the new vector. - * This should clear the IRR bit. - */ - imen_lock(); - - select = ioapic_irqs[intr].io_idx; - value = ioapic_read(ioapic_irqs[intr].io_addr, select); - - ioapic_write(ioapic_irqs[intr].io_addr, select, - (value & ~APIC_TRIGMOD_MASK)); - ioapic_write(ioapic_irqs[intr].io_addr, select, - (value & ~IOART_INTVEC) | vector); - - imen_unlock(); - - break; - - default: - error = EOPNOTSUPP; - break; - } + + /* + * Teardown an interrupt vector. The vector should already be + * installed in the cpu's IDT, but make sure. + */ + machintr_intrdis(intr); + + vector = IDT_OFFSET + intr; + setidt(vector, ioapic_intr[intr], SDT_SYSIGT, SEL_KPL, 0); + + /* + * In order to avoid losing an EOI for a level interrupt, which + * is vector based, make sure that the IO APIC is programmed for + * edge-triggering first, then reprogrammed with the new vector. + * This should clear the IRR bit. + */ + imen_lock(); + + select = ioapic_irqs[intr].io_idx; + value = ioapic_read(ioapic_irqs[intr].io_addr, select); + + ioapic_write(ioapic_irqs[intr].io_addr, select, + (value & ~APIC_TRIGMOD_MASK)); + ioapic_write(ioapic_irqs[intr].io_addr, select, + (value & ~IOART_INTVEC) | vector); + + imen_unlock(); write_rflags(ef); - return error; } static void diff --git a/sys/platform/pc64/icu/icu_abi.c b/sys/platform/pc64/icu/icu_abi.c index a32fd22f9b..dea7db691a 100644 --- a/sys/platform/pc64/icu/icu_abi.c +++ b/sys/platform/pc64/icu/icu_abi.c @@ -96,7 +96,8 @@ extern void ICU_INTRDIS(int); extern int imcr_present; -static int icu_vectorctl(int, int, int); +static void icu_abi_intr_setup(int, int); +static void icu_abi_intr_teardown(int); static void icu_finalize(void); static void icu_cleanup(void); static void icu_setdefault(void); @@ -108,7 +109,8 @@ struct machintr_abi MachIntrABI_ICU = { MACHINTR_ICU, .intrdis = ICU_INTRDIS, .intren = ICU_INTREN, - .vectorctl = icu_vectorctl, + .intr_setup = icu_abi_intr_setup, + .intr_teardown = icu_abi_intr_teardown, .finalize = icu_finalize, .cleanup = icu_cleanup, .setdefault = icu_setdefault, @@ -169,38 +171,36 @@ icu_finalize(void) } } -static int -icu_vectorctl(int op, int intr, int flags) +static void +icu_abi_intr_setup(int intr, int flags) { - int error; register_t ef; - if (intr < 0 || intr >= ICU_HWI_VECTORS || intr == ICU_IRQ_SLAVE) - return EINVAL; + KKASSERT(intr >= 0 && intr < ICU_HWI_VECTORS && intr != ICU_IRQ_SLAVE); ef = read_rflags(); cpu_disable_intr(); - error = 0; - switch(op) { - case MACHINTR_VECTOR_SETUP: - setidt(IDT_OFFSET + intr, icu_intr[intr], SDT_SYSIGT, - SEL_KPL, 0); - machintr_intren(intr); - break; + setidt(IDT_OFFSET + intr, icu_intr[intr], SDT_SYSIGT, SEL_KPL, 0); + machintr_intren(intr); - case MACHINTR_VECTOR_TEARDOWN: - machintr_intrdis(intr); - setidt(IDT_OFFSET + intr, icu_intr[intr], SDT_SYSIGT, - SEL_KPL, 0); - break; + write_rflags(ef); +} + +static void +icu_abi_intr_teardown(int intr) +{ + register_t ef; + + KKASSERT(intr >= 0 && intr < ICU_HWI_VECTORS && intr != ICU_IRQ_SLAVE); + + ef = read_rflags(); + cpu_disable_intr(); + + machintr_intrdis(intr); + setidt(IDT_OFFSET + intr, icu_intr[intr], SDT_SYSIGT, SEL_KPL, 0); - default: - error = EOPNOTSUPP; - break; - } write_rflags(ef); - return error; } static void diff --git a/sys/platform/vkernel/platform/machintr.c b/sys/platform/vkernel/platform/machintr.c index 6149eda837..421c416d66 100644 --- a/sys/platform/vkernel/platform/machintr.c +++ b/sys/platform/vkernel/platform/machintr.c @@ -54,7 +54,8 @@ static void dummy_intrdis(int); static void dummy_intren(int); -static int dummy_vectorctl(int, int, int); +static void dummy_intr_setup(int, int); +static void dummy_intr_teardown(int); static void dummy_finalize(void); static void dummy_intrcleanup(void); static void dummy_stabilize(void); @@ -63,7 +64,8 @@ struct machintr_abi MachIntrABI = { MACHINTR_GENERIC, .intrdis = dummy_intrdis, .intren = dummy_intren, - .vectorctl = dummy_vectorctl, + .intr_setup = dummy_intr_setup, + .intr_teardown = dummy_intr_teardown, .finalize = dummy_finalize, .cleanup = dummy_intrcleanup, .stabilize = dummy_stabilize @@ -79,11 +81,14 @@ dummy_intren(int intr) { } -static int -dummy_vectorctl(int op, int intr, int flags) +static void +dummy_intr_setup(int intr, int flags) +{ +} + +static void +dummy_intr_teardown(int intr) { - return (0); - /* return (EOPNOTSUPP); */ } static void diff --git a/sys/platform/vkernel64/platform/machintr.c b/sys/platform/vkernel64/platform/machintr.c index 4a15917f4c..b87e91c315 100644 --- a/sys/platform/vkernel64/platform/machintr.c +++ b/sys/platform/vkernel64/platform/machintr.c @@ -54,7 +54,8 @@ static void dummy_intrdis(int); static void dummy_intren(int); -static int dummy_vectorctl(int, int, int); +static void dummy_intr_setup(int, int); +static void dummy_intr_teardown(int); static void dummy_finalize(void); static void dummy_intrcleanup(void); static void dummy_stabilize(void); @@ -63,7 +64,8 @@ struct machintr_abi MachIntrABI = { MACHINTR_GENERIC, .intrdis = dummy_intrdis, .intren = dummy_intren, - .vectorctl = dummy_vectorctl, + .intr_setup = dummy_intr_setup, + .intr_teardown = dummy_intr_teardown, .finalize = dummy_finalize, .cleanup = dummy_intrcleanup, .stabilize = dummy_stabilize @@ -79,11 +81,14 @@ dummy_intren(int intr) { } -static int -dummy_vectorctl(int op, int intr, int flags) +static void +dummy_intr_setup(int intr, int flags) +{ +} + +static void +dummy_intr_teardown(int intr) { - return (0); - /* return (EOPNOTSUPP); */ } static void diff --git a/sys/sys/machintr.h b/sys/sys/machintr.h index 69f4aa0fdd..bae3e87f8c 100644 --- a/sys/sys/machintr.h +++ b/sys/sys/machintr.h @@ -59,7 +59,8 @@ struct machintr_abi { enum machintr_type type; void (*intrdis)(int); /* hardware disable irq */ void (*intren)(int); /* hardware enable irq */ - int (*vectorctl)(int, int, int); /* hardware intr vector ctl */ + void (*intr_setup)(int, int); /* setup intr */ + void (*intr_teardown)(int); /* tear down intr */ void (*finalize)(void); /* final before ints enabled */ void (*cleanup)(void); /* cleanup */ void (*setdefault)(void); /* set default vectors */ @@ -71,10 +72,10 @@ struct machintr_abi { #define machintr_intren(intr) MachIntrABI.intren(intr) #define machintr_intrdis(intr) MachIntrABI.intrdis(intr) -#define machintr_vector_setup(intr, flags) \ - MachIntrABI.vectorctl(MACHINTR_VECTOR_SETUP, intr, flags) -#define machintr_vector_teardown(intr) \ - MachIntrABI.vectorctl(MACHINTR_VECTOR_TEARDOWN, intr, 0) +#define machintr_intr_setup(intr, flags) \ + MachIntrABI.intr_setup((intr), (flags)) +#define machintr_intr_teardown(intr) \ + MachIntrABI.intr_teardown((intr)) #define machintr_intr_config(intr, trig, pola) \ MachIntrABI.intr_config((intr), (trig), (pola))