#ifdef SMP /* APIC-IO */
-extern void APIC_INTREN(int);
-extern void APIC_INTRDIS(int);
+extern void APIC_INTREN(int);
+extern void APIC_INTRDIS(int);
extern inthand_t
IDTVEC(apic_fastintr0), IDTVEC(apic_fastintr1),
IDTVEC(apic_fastintr20), IDTVEC(apic_fastintr21),
IDTVEC(apic_fastintr22), IDTVEC(apic_fastintr23);
-static int apic_setvar(int, const void *);
-static int apic_getvar(int, void *);
-static int apic_vectorctl(int, int, int);
-static void apic_finalize(void);
-static void apic_cleanup(void);
+static int apic_setvar(int, const void *);
+static int apic_getvar(int, void *);
+static int apic_vectorctl(int, int, int);
+static void apic_finalize(void);
+static void apic_cleanup(void);
static inthand_t *apic_fastintr[APIC_HWI_VECTORS] = {
&IDTVEC(apic_fastintr0), &IDTVEC(apic_fastintr1),
&IDTVEC(apic_fastintr22), &IDTVEC(apic_fastintr23)
};
-static int apic_imcr_present;
+static int apic_imcr_present;
struct machintr_abi MachIntrABI_APIC = {
MACHINTR_APIC,
- .intrdis = APIC_INTRDIS,
- .intren = APIC_INTREN,
- .vectorctl = apic_vectorctl,
- .setvar = apic_setvar,
- .getvar = apic_getvar,
- .finalize = apic_finalize,
- .cleanup = apic_cleanup
+ .intrdis = APIC_INTRDIS,
+ .intren = APIC_INTREN,
+ .vectorctl = apic_vectorctl,
+ .setvar = apic_setvar,
+ .getvar = apic_getvar,
+ .finalize = apic_finalize,
+ .cleanup = apic_cleanup
};
static int
apic_setvar(int varid, const void *buf)
{
- int error = 0;
-
- switch(varid) {
- case MACHINTR_VAR_IMCR_PRESENT:
- apic_imcr_present = *(const int *)buf;
- break;
- default:
- error = ENOENT;
- break;
- }
- return (error);
+ int error = 0;
+
+ switch(varid) {
+ case MACHINTR_VAR_IMCR_PRESENT:
+ apic_imcr_present = *(const int *)buf;
+ break;
+
+ default:
+ error = ENOENT;
+ break;
+ }
+ return error;
}
static int
apic_getvar(int varid, void *buf)
{
- int error = 0;
-
- switch(varid) {
- case MACHINTR_VAR_IMCR_PRESENT:
- *(int *)buf = apic_imcr_present;
- break;
- default:
- error = ENOENT;
- break;
- }
- return (error);
+ int error = 0;
+
+ switch(varid) {
+ case MACHINTR_VAR_IMCR_PRESENT:
+ *(int *)buf = apic_imcr_present;
+ break;
+
+ default:
+ error = ENOENT;
+ break;
+ }
+ return error;
}
/*
static void
apic_finalize(void)
{
- u_int32_t temp;
-
- /*
- * If an IMCR is present, program bit 0 to disconnect the 8259
- * from the BSP. The 8259 may still be connected to LINT0 on
- * the BSP's LAPIC.
- */
- if (apic_imcr_present) {
- outb(0x22, 0x70); /* select IMCR */
- outb(0x23, 0x01); /* disconnect 8259 */
- }
-
- /*
- * Setup lint0 (the 8259 'virtual wire' connection). We
- * mask the interrupt, completing the disconnection of the
- * 8259.
- */
- temp = lapic->lvt_lint0;
- temp |= APIC_LVT_MASKED;
- lapic->lvt_lint0 = temp;
-
- /*
- * setup lint1 to handle an NMI
- */
- temp = lapic->lvt_lint1;
- temp &= ~APIC_LVT_MASKED;
- lapic->lvt_lint1 = temp;
-
- if (bootverbose)
- apic_dump("bsp_apic_configure()");
+ uint32_t temp;
+
+ /*
+ * If an IMCR is present, program bit 0 to disconnect the 8259
+ * from the BSP. The 8259 may still be connected to LINT0 on
+ * the BSP's LAPIC.
+ */
+ if (apic_imcr_present) {
+ outb(0x22, 0x70); /* select IMCR */
+ outb(0x23, 0x01); /* disconnect 8259 */
+ }
+
+ /*
+ * Setup lint0 (the 8259 'virtual wire' connection). We
+ * mask the interrupt, completing the disconnection of the
+ * 8259.
+ */
+ temp = lapic->lvt_lint0;
+ temp |= APIC_LVT_MASKED;
+ lapic->lvt_lint0 = temp;
+
+ /*
+ * Setup lint1 to handle an NMI
+ */
+ temp = lapic->lvt_lint1;
+ temp &= ~APIC_LVT_MASKED;
+ lapic->lvt_lint1 = temp;
+
+ if (bootverbose)
+ apic_dump("bsp_apic_configure()");
}
/*
mdcpu->gd_fpending = 0;
}
-static
-int
+static int
apic_vectorctl(int op, int intr, int flags)
{
- int error;
- int vector;
- int select;
- u_int32_t value;
- u_long ef;
+ int error;
+ int vector;
+ int select;
+ uint32_t value;
+ u_long ef;
- if (intr < 0 || intr >= APIC_HWI_VECTORS)
- return (EINVAL);
+ if (intr < 0 || intr >= APIC_HWI_VECTORS)
+ return EINVAL;
- ef = read_rflags();
- cpu_disable_intr();
- error = 0;
+ ef = read_rflags();
+ cpu_disable_intr();
+ error = 0;
- switch(op) {
- case MACHINTR_VECTOR_SETUP:
- vector = IDT_OFFSET + intr;
- setidt(vector, apic_fastintr[intr], SDT_SYSIGT, SEL_KPL, 0);
+ switch(op) {
+ case MACHINTR_VECTOR_SETUP:
+ vector = IDT_OFFSET + intr;
+ setidt(vector, apic_fastintr[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.
- */
- if (int_to_apicintpin[intr].ioapic >= 0) {
- imen_lock();
- select = int_to_apicintpin[intr].redirindex;
- value = io_apic_read(int_to_apicintpin[intr].ioapic, select);
- value |= IOART_INTMSET;
- io_apic_write(int_to_apicintpin[intr].ioapic,
- select, (value & ~APIC_TRIGMOD_MASK));
- io_apic_write(int_to_apicintpin[intr].ioapic,
- 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, apic_fastintr[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.
+ */
+ if (int_to_apicintpin[intr].ioapic >= 0) {
+ imen_lock();
- /*
- * And then reprogram the IO APIC to point to the SLOW vector (it may
- * have previously been pointed to the FAST version of the vector).
- * This will allow us to keep track of spurious interrupts.
- *
- * 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.
- */
- if (int_to_apicintpin[intr].ioapic >= 0) {
- imen_lock();
- select = int_to_apicintpin[intr].redirindex;
- value = io_apic_read(int_to_apicintpin[intr].ioapic, select);
- io_apic_write(int_to_apicintpin[intr].ioapic,
- select, (value & ~APIC_TRIGMOD_MASK));
- io_apic_write(int_to_apicintpin[intr].ioapic,
- select, (value & ~IOART_INTVEC) | vector);
- imen_unlock();
+ select = int_to_apicintpin[intr].redirindex;
+ value = io_apic_read(int_to_apicintpin[intr].ioapic,
+ select);
+ value |= IOART_INTMSET;
+
+ io_apic_write(int_to_apicintpin[intr].ioapic,
+ select, (value & ~APIC_TRIGMOD_MASK));
+ io_apic_write(int_to_apicintpin[intr].ioapic,
+ 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, apic_fastintr[intr], SDT_SYSIGT, SEL_KPL, 0);
+
+ /*
+ * And then reprogram the IO APIC to point to the SLOW vector
+ * (it may have previously been pointed to the FAST version of
+ * the vector). This will allow us to keep track of spurious
+ * interrupts.
+ *
+ * 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.
+ */
+ if (int_to_apicintpin[intr].ioapic >= 0) {
+ imen_lock();
+
+ select = int_to_apicintpin[intr].redirindex;
+ value = io_apic_read(int_to_apicintpin[intr].ioapic,
+ select);
+
+ io_apic_write(int_to_apicintpin[intr].ioapic,
+ select, (value & ~APIC_TRIGMOD_MASK));
+ io_apic_write(int_to_apicintpin[intr].ioapic,
+ select, (value & ~IOART_INTVEC) | vector);
+
+ imen_unlock();
+ }
+ break;
+
+ case MACHINTR_VECTOR_SETDEFAULT:
+ /*
+ * This is a just-in-case an int pin is running through the 8259
+ * when we don't expect it to, or an IO APIC pin somehow wound
+ * up getting enabled without us specifically programming it in
+ * this ABI. Note that IO APIC pins are by default programmed
+ * to IDT_OFFSET + intr.
+ */
+ vector = IDT_OFFSET + intr;
+ setidt(vector, apic_fastintr[intr], SDT_SYSIGT, SEL_KPL, 0);
+ break;
+
+ default:
+ error = EOPNOTSUPP;
+ break;
}
- break;
- case MACHINTR_VECTOR_SETDEFAULT:
- /*
- * This is a just-in-case an int pin is running through the 8259
- * when we don't expect it to, or an IO APIC pin somehow wound
- * up getting enabled without us specifically programming it in
- * this ABI. Note that IO APIC pins are by default programmed
- * to IDT_OFFSET + intr.
- */
- vector = IDT_OFFSET + intr;
- setidt(vector, apic_fastintr[intr], SDT_SYSIGT, SEL_KPL, 0);
- break;
- default:
- error = EOPNOTSUPP;
- break;
- }
-
- write_rflags(ef);
- return (error);
-}
-#endif
+ write_rflags(ef);
+ return error;
+}
+#endif /* SMP */
#include "icu.h"
#include "icu_ipl.h"
-extern void ICU_INTREN(int);
-extern void ICU_INTRDIS(int);
+extern void ICU_INTREN(int);
+extern void ICU_INTRDIS(int);
extern inthand_t
IDTVEC(icu_fastintr0), IDTVEC(icu_fastintr1),
IDTVEC(icu_fastintr12), IDTVEC(icu_fastintr13),
IDTVEC(icu_fastintr14), IDTVEC(icu_fastintr15);
-static int icu_vectorctl(int, int, int);
-static int icu_setvar(int, const void *);
-static int icu_getvar(int, void *);
-static void icu_finalize(void);
-static void icu_cleanup(void);
+static int icu_vectorctl(int, int, int);
+static int icu_setvar(int, const void *);
+static int icu_getvar(int, void *);
+static void icu_finalize(void);
+static void icu_cleanup(void);
static inthand_t *icu_fastintr[ICU_HWI_VECTORS] = {
&IDTVEC(icu_fastintr0), &IDTVEC(icu_fastintr1),
};
struct machintr_abi MachIntrABI_ICU = {
- MACHINTR_ICU,
- .intrdis = ICU_INTRDIS,
- .intren = ICU_INTREN,
- .vectorctl =icu_vectorctl,
- .setvar = icu_setvar,
- .getvar = icu_getvar,
- .finalize = icu_finalize,
- .cleanup = icu_cleanup
+ MACHINTR_ICU,
+ .intrdis = ICU_INTRDIS,
+ .intren = ICU_INTREN,
+ .vectorctl = icu_vectorctl,
+ .setvar = icu_setvar,
+ .getvar = icu_getvar,
+ .finalize = icu_finalize,
+ .cleanup = icu_cleanup
};
-static int icu_imcr_present;
+static int icu_imcr_present;
/*
* WARNING! SMP builds can use the ICU now so this code must be MP safe.
*/
-static
-int
+static int
icu_setvar(int varid, const void *buf)
{
- int error = 0;
+ int error = 0;
- switch(varid) {
- case MACHINTR_VAR_IMCR_PRESENT:
- icu_imcr_present = *(const int *)buf;
- break;
- default:
- error = ENOENT;
- break;
- }
- return (error);
+ switch(varid) {
+ case MACHINTR_VAR_IMCR_PRESENT:
+ icu_imcr_present = *(const int *)buf;
+ break;
+
+ default:
+ error = ENOENT;
+ break;
+ }
+ return error;
}
-static
-int
+static int
icu_getvar(int varid, void *buf)
{
- int error = 0;
+ int error = 0;
- switch(varid) {
- case MACHINTR_VAR_IMCR_PRESENT:
- *(int *)buf = icu_imcr_present;
- break;
- default:
- error = ENOENT;
- break;
- }
- return (error);
+ switch(varid) {
+ case MACHINTR_VAR_IMCR_PRESENT:
+ *(int *)buf = icu_imcr_present;
+ break;
+
+ default:
+ error = ENOENT;
+ break;
+ }
+ return error;
}
/*
static void
icu_finalize(void)
{
- int intr;
-
- for (intr = 0; intr < ICU_HWI_VECTORS; ++intr) {
- machintr_intrdis(intr);
- }
- machintr_intren(ICU_IRQ_SLAVE);
-
- /*
- * If an IMCR is present, programming bit 0 disconnects the 8259
- * from the BSP. The 8259 may still be connected to LINT0 on the BSP's
- * LAPIC.
- *
- * If we are running SMP the LAPIC is active, try to use virtual wire
- * mode so we can use other interrupt sources within the LAPIC in
- * addition to the 8259.
- */
- if (icu_imcr_present) {
+ int intr;
+
+ for (intr = 0; intr < ICU_HWI_VECTORS; ++intr)
+ machintr_intrdis(intr);
+ machintr_intren(ICU_IRQ_SLAVE);
+
#if defined(SMP)
- outb(0x22, 0x70);
- outb(0x23, 0x01);
+ /*
+ * If an IMCR is present, programming bit 0 disconnects the 8259
+ * from the BSP. The 8259 may still be connected to LINT0 on the
+ * BSP's LAPIC.
+ *
+ * If we are running SMP the LAPIC is active, try to use virtual
+ * wire mode so we can use other interrupt sources within the LAPIC
+ * in addition to the 8259.
+ */
+ if (icu_imcr_present) {
+ outb(0x22, 0x70);
+ outb(0x23, 0x01);
+ }
#endif
- }
}
/*
* Called after interrupts physically enabled but before the
* critical section is released.
*/
-static
-void
+static void
icu_cleanup(void)
{
mdcpu->gd_fpending = 0;
}
-static
-int
+static int
icu_vectorctl(int op, int intr, int flags)
{
- int error;
- register_t ef;
-
- if (intr < 0 || intr >= ICU_HWI_VECTORS || intr == ICU_IRQ_SLAVE)
- return (EINVAL);
-
- ef = read_rflags();
- cpu_disable_intr();
- error = 0;
-
- switch(op) {
- case MACHINTR_VECTOR_SETUP:
- setidt(IDT_OFFSET + intr, icu_fastintr[intr], SDT_SYSIGT, SEL_KPL, 0);
- machintr_intren(intr);
- break;
- case MACHINTR_VECTOR_TEARDOWN:
- case MACHINTR_VECTOR_SETDEFAULT:
- setidt(IDT_OFFSET + intr, icu_fastintr[intr], SDT_SYSIGT, SEL_KPL, 0);
- machintr_intrdis(intr);
- break;
- default:
- error = EOPNOTSUPP;
- break;
- }
- write_rflags(ef);
- return (error);
+ int error;
+ register_t ef;
+
+ if (intr < 0 || intr >= ICU_HWI_VECTORS || intr == ICU_IRQ_SLAVE)
+ return EINVAL;
+
+ ef = read_rflags();
+ cpu_disable_intr();
+ error = 0;
+
+ switch(op) {
+ case MACHINTR_VECTOR_SETUP:
+ setidt(IDT_OFFSET + intr, icu_fastintr[intr], SDT_SYSIGT,
+ SEL_KPL, 0);
+ machintr_intren(intr);
+ break;
+
+ case MACHINTR_VECTOR_TEARDOWN:
+ case MACHINTR_VECTOR_SETDEFAULT:
+ setidt(IDT_OFFSET + intr, icu_fastintr[intr], SDT_SYSIGT,
+ SEL_KPL, 0);
+ machintr_intrdis(intr);
+ break;
+
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+ write_rflags(ef);
+ return error;
}