i386 - Get completely rid of APIC_IO apic_io
authorMichael Neumann <mneumann@kvmdragon.ntecs.de>
Wed, 6 Oct 2010 18:00:44 +0000 (20:00 +0200)
committerMichael Neumann <mneumann@kvmdragon.ntecs.de>
Wed, 6 Oct 2010 18:00:44 +0000 (20:00 +0200)
For SMP kernels compile time APIC_IO option has been superseeded
by loader tunable hw.apic_io_enable which defaults to APIC I/O
enabled.

20 files changed:
sys/platform/pc32/acpica5/acpi_machdep.c
sys/platform/pc32/apic/apic_abi.c
sys/platform/pc32/apic/apic_ipl.h
sys/platform/pc32/apic/apic_ipl.s
sys/platform/pc32/apic/apic_vector.s
sys/platform/pc32/apic/mpapic.c
sys/platform/pc32/apic/mpapic.h
sys/platform/pc32/conf/files
sys/platform/pc32/conf/options
sys/platform/pc32/i386/autoconf.c
sys/platform/pc32/i386/machdep.c
sys/platform/pc32/i386/mp_machdep.c
sys/platform/pc32/i386/nexus.c
sys/platform/pc32/icu/icu_abi.c
sys/platform/pc32/icu/icu_ipl.s
sys/platform/pc32/icu/icu_vector.s
sys/platform/pc32/include/clock.h
sys/platform/pc32/include/smp.h
sys/platform/pc32/isa/clock.c
sys/platform/pc32/isa/intr_machdep.c

index 6985f1d..c0c06d1 100644 (file)
@@ -51,15 +51,20 @@ static device_t     acpi_dev;
 #include <machine/apm_bios.h>
 #include <machine/pc/bios.h>
 #include <machine_base/apm/apm.h>
+#include <machine/smp.h>
 
 uint32_t acpi_reset_video = 1;
 TUNABLE_INT("hw.acpi.reset_video", &acpi_reset_video);
 
-#ifdef APIC_IO
-static int intr_model = ACPI_INTR_APIC;
+/*
+ * -1 == unset. Use acpi_GetDefaultIntrModel()
+ */
+#ifdef SMP /* APIC-IO */
+static int intr_model = -1;
 #else
 static int intr_model = ACPI_INTR_PIC;
 #endif
+
 static struct apm_softc        apm_softc;
 
 static d_open_t apmopen;
@@ -327,6 +332,25 @@ acpi_capm_init(struct acpi_softc *sc)
        kprintf("Warning: ACPI is disabling APM's device.  You can't run both\n");
 }
 
+/*
+ * Lazy initialize intr_model
+ */
+static int
+acpi_GetDefaultIntrModel(void)
+{
+       if (intr_model == -1) {
+#ifdef SMP /* APIC-IO */
+               if (apic_io_enable)
+                       intr_model = ACPI_INTR_APIC;
+               else
+                       intr_model = ACPI_INTR_PIC;
+#else
+               intr_model = ACPI_INTR_PIC;
+#endif
+       }
+       return intr_model;
+}
+
 int
 acpi_machdep_init(device_t dev)
 {
@@ -345,11 +369,11 @@ acpi_machdep_init(device_t dev)
 
        acpi_install_wakeup_handler(sc);
 
-       if (intr_model == ACPI_INTR_PIC)
+       if (acpi_GetDefaultIntrModel() == ACPI_INTR_PIC)
                BUS_CONFIG_INTR(dev, dev, AcpiGbl_FADT.SciInterrupt,
                    INTR_TRIGGER_LEVEL, INTR_POLARITY_LOW);
        else
-               acpi_SetIntrModel(intr_model);
+               acpi_SetIntrModel(acpi_GetDefaultIntrModel());
 
        SYSCTL_ADD_UINT(&sc->acpi_sysctl_ctx,
            SYSCTL_CHILDREN(sc->acpi_sysctl_tree), OID_AUTO,
index a6efefe..3a08bc9 100644 (file)
@@ -59,7 +59,7 @@
 
 #include "apic_ipl.h"
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 
 extern void APIC_INTREN(int);
 extern void APIC_INTRDIS(int);
@@ -109,7 +109,7 @@ static inthand_t *apic_fastintr[APIC_HWI_VECTORS] = {
 
 static int apic_imcr_present;
 
-struct machintr_abi MachIntrABI = {
+struct machintr_abi MachIntrABI_APIC = {
        MACHINTR_APIC,
        .intrdis =      APIC_INTRDIS,
        .intren =       APIC_INTREN,
index 7855e9f..3dcf040 100644 (file)
@@ -29,7 +29,7 @@
 #ifndef _ARCH_APIC_IPL_H_
 #define        _ARCH_APIC_IPL_H_
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 
 /* IDT vector base for regular (aka. slow) and fast interrupts */
 #define TPR_FAST_INTS  0x60
index f71d02c..077bc30 100644 (file)
@@ -69,7 +69,7 @@
 #include "apic_ipl.h"
 #include "assym.s"
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 
        .text
        SUPERALIGN_TEXT
index 99add4d..c506372 100644 (file)
        APIC_IMASK_UNLOCK ;                                             \
 8: ;                                                                   \
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 
 /*
  * Fast interrupt call handlers run in the following sequence:
@@ -349,7 +349,7 @@ Xtimer:
        POP_FRAME
        iret
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 
 MCOUNT_LABEL(bintr)
        FAST_INTR(0,apic_fastintr0)
index 4813912..1443044 100644 (file)
@@ -153,12 +153,16 @@ apic_initialize(boolean_t bsp)
         */
        temp = lapic.tpr;
        temp &= ~APIC_TPR_PRIO;         /* clear priority field */
-#ifndef APIC_IO
+#ifdef SMP /* APIC-IO */
+if (!apic_io_enable) {
+#endif
        /*
         * If we are NOT running the IO APICs, the LAPIC will only be used
         * for IPIs.  Set the TPR to prevent any unintentional interrupts.
         */
        temp |= TPR_IPI_ONLY;
+#ifdef SMP /* APIC-IO */
+}
 #endif
 
        lapic.tpr = temp;
@@ -399,7 +403,7 @@ apic_dump(char* str)
 }
 
 
-#if defined(APIC_IO)
+#ifdef SMP /* APIC-IO */
 
 /*
  * IO APIC code,
@@ -813,7 +817,7 @@ imen_dump(void)
  * Inter Processor Interrupt functions.
  */
 
-#endif /* APIC_IO */
+#endif /* SMP APIC-IO */
 
 /*
  * Send APIC IPI 'vector' to 'destType' via 'deliveryMode'.
index b6c1f0e..d31eeb0 100644 (file)
@@ -58,7 +58,7 @@ enum busTypes {
  */
 #define CPU_TO_ID(CPU) (cpu_num_to_apic_id[CPU])
 #define ID_TO_CPU(ID)  (apic_id_to_logical[ID])
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 #define IO_TO_ID(IO)   (io_num_to_apic_id[IO])
 #define ID_TO_IO(ID)   (apic_id_to_logical[ID])
 #endif
index 46741b8..4036f38 100644 (file)
@@ -240,7 +240,7 @@ bus/pci/i386/legacy.c                       optional        pci
 bus/pci/i386/pci_bus.c                 optional        pci
 bus/pci/i386/pci_cfgreg.c              optional        pci
 bus/pci/i386/pci_pir.c                 optional        pci
-bus/pci/i386/mptable_pci.c             optional        pci smp apic_io
+bus/pci/i386/mptable_pci.c             optional        pci smp
 platform/pc32/isa/pmtimer.c            optional        pmtimer acpi
 # XXX drhodus
 platform/pc32/isa/prof_machdep.c       optional        profiling-routine
index bf86de4..61d60e7 100644 (file)
@@ -24,7 +24,6 @@ COMPAT_LINUX          opt_dontuse.h
 LINPROCFS              opt_dontuse.h   #Linux compatible procfs
 
 # i386 SMP options
-APIC_IO                        opt_global.h
 
 # Change KVM size.  Changes things all over the kernel.
 KVA_PAGES              opt_global.h
index 2f59db9..9811335 100644 (file)
@@ -155,9 +155,10 @@ configure_final(void *dummy)
        cninit_finish();
 
        if (bootverbose) {
-#ifdef APIC_IO
-               imen_dump();
-#endif /* APIC_IO */
+#ifdef SMP /* APIC-IO */
+               if (apic_io_enable)
+                       imen_dump();
+#endif
 
                /*
                 * Print out the BIOS's idea of the disk geometries.
index 5c1394b..f545659 100644 (file)
 #include <sys/ptrace.h>
 #include <machine/sigframe.h>
 
+#include <sys/machintr.h>
+
 #define PHYSMAP_ENTRIES                10
 
 extern void init386(int first);
@@ -1841,6 +1843,15 @@ do_next:
        avail_end = phys_avail[pa_indx];
 }
 
+#ifdef SMP
+int apic_io_enable = 1; /* Enabled by default */
+TUNABLE_INT("hw.apic_io_enable", &apic_io_enable);
+extern struct machintr_abi MachIntrABI_APIC;
+#endif
+
+extern struct machintr_abi MachIntrABI_ICU;
+struct machintr_abi MachIntrABI;
+
 /*
  * IDT VECTORS:
  *     0       Divide by zero
@@ -1895,6 +1906,17 @@ init386(int first)
                kern_envp = (caddr_t)bootinfo.bi_envp + KERNBASE;
 
        /*
+        * Setup MachIntrABI
+        * XXX: Where is the correct place for it?
+        */
+       MachIntrABI = MachIntrABI_ICU;
+#ifdef SMP
+       TUNABLE_INT_FETCH("hw.apic_io_enable", &apic_io_enable);
+       if (apic_io_enable)
+               MachIntrABI = MachIntrABI_APIC;
+#endif
+
+       /*
         * start with one cpu.  Note: with one cpu, ncpus2_shift, ncpus2_mask,
         * and ncpus_fit_mask remain 0.
         */
index 9078ecd..179f9ab 100644 (file)
@@ -229,11 +229,9 @@ int        current_postcode;
 extern struct region_descriptor r_gdt, r_idt;
 
 int    mp_naps;                /* # of Applications processors */
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 static int     mp_nbusses;     /* # of busses */
 int    mp_napics;              /* # of IO APICs */
-#endif
-#ifdef APIC_IO
 vm_offset_t io_apic_address[NAPICID];  /* NAPICID is more than enough */
 u_int32_t *io_apic_versions;
 #endif
@@ -245,7 +243,7 @@ extern int64_t tsc_offsets[];
 
 extern u_long ebda_addr;
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 struct apic_intmapinfo int_to_apicintpin[APIC_INTMAPSIZE];
 #endif
 
@@ -254,7 +252,7 @@ struct apic_intmapinfo      int_to_apicintpin[APIC_INTMAPSIZE];
  * We oversize these to simplify boot-time config.
  */
 int     cpu_num_to_apic_id[NAPICID];
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 int     io_num_to_apic_id[NAPICID];
 #endif
 int     apic_id_to_logical[NAPICID];
@@ -306,7 +304,7 @@ static int  mptable_search(void);
 static int     mptable_check(vm_paddr_t);
 static int     mptable_search_sig(u_int32_t target, int count);
 static int     mptable_hyperthread_fixup(u_int, int);
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 static void    mptable_pass1(struct mptable_pos *);
 static void    mptable_pass2(struct mptable_pos *);
 static void    mptable_default(int type);
@@ -320,7 +318,7 @@ static int  mptable_lapic_probe(struct lapic_enumerator *);
 static void    mptable_lapic_enumerate(struct lapic_enumerator *);
 static void    mptable_lapic_default(void);
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 static void    setup_apic_irq_mapping(void);
 static int     apic_int_is_bus_type(int intr, int bus_type);
 #endif
@@ -559,15 +557,15 @@ mp_announce(void)
                kprintf(", version: 0x%08x\n", cpu_apic_versions[x]);
        }
 
-#if defined(APIC_IO)
+if (apic_io_enable) {
        for (x = 0; x < mp_napics; ++x) {
                kprintf(" io%d (APIC): apic id: %2d", x, IO_TO_ID(x));
                kprintf(", version: 0x%08x", io_apic_versions[x]);
                kprintf(", at 0x%08lx\n", io_apic_address[x]);
        }
-#else
+} else {
        kprintf(" Warning: APIC I/O disabled\n");
-#endif /* APIC_IO */
+}
 }
 
 /*
@@ -650,10 +648,8 @@ init_secondary(void)
 static void
 mp_enable(u_int boot_addr)
 {
-#if defined(APIC_IO)
        int     apic;
        u_int   ux;
-#endif /* APIC_IO */
        vm_paddr_t mpfps_paddr;
        struct mptable_pos mpt;
 
@@ -667,10 +663,10 @@ mp_enable(u_int boot_addr)
                mptable_imcr(&mpt);
                mptable_unmap(&mpt);
        }
-#if defined(APIC_IO)
+if (apic_io_enable) {
 
        if (!mpfps_paddr)
-               panic("no MP table, disable APIC_IO!\n");
+               panic("no MP table, disable APIC_IO! (set hw.apic_io_enable=0)\n");
 
        mptable_map(&mpt, mpfps_paddr);
 
@@ -699,7 +695,7 @@ mp_enable(u_int boot_addr)
                if (io_apic_setup(apic) < 0)
                        panic("IO APIC setup failure");
 
-#endif /* APIC_IO */
+}
 
        /*
         * These are required for SMP operation
@@ -783,8 +779,6 @@ typedef struct BUSTYPENAME {
        char    name[7];
 }       bus_type_name;
 
-#ifdef APIC_IO
-
 static bus_type_name bus_type_table[] =
 {
        {CBUS, "CBUS"},
@@ -828,17 +822,11 @@ static bus_datum *bus_data;
 static io_int  *io_apic_ints;
 static int nintrs;
 
-#endif
-
 static int processor_entry     (const struct PROCENTRY *entry, int cpu);
-#ifdef APIC_IO
 static int bus_entry           (const struct BUSENTRY *entry, int bus);
 static int io_apic_entry       (const struct IOAPICENTRY *entry, int apic);
 static int int_entry           (const struct INTENTRY *entry, int intr);
 static int lookup_bus_type     (char *name);
-#endif
-
-#ifdef APIC_IO
 
 static int
 mptable_ioapic_pass1_callback(void *xarg, const void *pos, int type)
@@ -1001,8 +989,6 @@ mptable_pass2(struct mptable_pos *mpt)
                panic("mptable_iterate_entries(ioapic_pass2) failed\n");
 }
 
-#endif /* APIC_IO */
-
 /*
  * Check if we should perform a hyperthreading "fix-up" to
  * enumerate any logical CPU's that aren't already listed
@@ -1168,8 +1154,6 @@ mptable_unmap(struct mptable_pos *mpt)
        }
 }
 
-#ifdef APIC_IO
-
 void
 assign_apic_irq(int apic, int intpin, int irq)
 {
@@ -1555,8 +1539,6 @@ setup_apic_irq_mapping(void)
        /* PCI interrupt assignment is deferred */
 }
 
-#endif
-
 void
 mp_set_cpuids(int cpu_id, int apic_id)
 {
@@ -1588,8 +1570,6 @@ processor_entry(const struct PROCENTRY *entry, int cpu)
        return 0;
 }
 
-#ifdef APIC_IO
-
 static int
 bus_entry(const struct BUSENTRY *entry, int bus)
 {
@@ -1823,8 +1803,6 @@ next_apic_irq(int irq)
 #undef INTAPIC
 #undef INTTYPE
 
-#endif
-
 /*
  * Reprogram the MB chipset to NOT redirect an ISA INTerrupt.
  *
@@ -1872,8 +1850,6 @@ undirect_pci_irq(int rirq)
 }
 
 
-#ifdef APIC_IO
-
 /*
  * given a bus ID, return:
  *  the bus type if found
@@ -2121,8 +2097,6 @@ mptable_default(int type)
                io_apic_ints[0].int_type = 3;   /* vectored 8259 */
 }
 
-#endif /* APIC_IO */
-
 /*
  * Map a physical memory address representing I/O into KVA.  The I/O
  * block is assumed not to cross a page boundary.
index dea7b58..e3fd50f 100644 (file)
@@ -161,20 +161,24 @@ nexus_probe(device_t dev)
        irq_rman.rm_start = 0;
        irq_rman.rm_type = RMAN_ARRAY;
        irq_rman.rm_descr = "Interrupt request lines";
-#ifdef APIC_IO
+
+#if SMP /* APIC-IO */
+if (apic_io_enable) {
        irq_rman.rm_end = APIC_INTMAPSIZE - 1;
        if (rman_init(&irq_rman)
            || rman_manage_region(&irq_rman,
                                  irq_rman.rm_start, irq_rman.rm_end))
                panic("nexus_probe irq_rman");
-#else
+} else {
+#endif
        irq_rman.rm_end = 15;
        if (rman_init(&irq_rman)
            || rman_manage_region(&irq_rman, irq_rman.rm_start, 1)
            || rman_manage_region(&irq_rman, 3, irq_rman.rm_end))
                panic("nexus_probe irq_rman");
+#if SMP /* APIC-IO */
+}
 #endif
-
        /*
         * ISA DMA on PCI systems is implemented in the ISA part of each
         * PCI->ISA bridge and the channels can be duplicated if there are
@@ -475,7 +479,8 @@ static int
 nexus_config_intr(device_t dev, device_t child, int irq, enum intr_trigger trig,
     enum intr_polarity pol)
 {
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
+if (apic_io_enable) {
        int line;
        int slot = pci_get_slot(child);
        int bus = pci_get_bus(child);
@@ -488,9 +493,9 @@ nexus_config_intr(device_t dev, device_t child, int irq, enum intr_trigger trig,
                return line;
 
        return PCI_INVALID_IRQ;
-#else
-       return irq;
+}
 #endif
+       return irq;
 }
 
 /*
index 32aaa47..2a0d09b 100644 (file)
@@ -56,8 +56,6 @@
 #include "icu.h"
 #include "icu_ipl.h"
 
-#ifndef APIC_IO
-
 extern void ICU_INTREN(int);
 extern void ICU_INTRDIS(int);
 
@@ -88,7 +86,7 @@ static inthand_t *icu_fastintr[ICU_HWI_VECTORS] = {
        &IDTVEC(icu_fastintr14), &IDTVEC(icu_fastintr15)
 };
 
-struct machintr_abi MachIntrABI = {
+struct machintr_abi MachIntrABI_ICU = {
     MACHINTR_ICU,
     .intrdis = ICU_INTRDIS,
     .intren =  ICU_INTREN,
@@ -213,5 +211,3 @@ icu_vectorctl(int op, int intr, int flags)
     write_eflags(ef);
     return (error);
 }
-
-#endif
index cb31c92..44dc734 100644 (file)
@@ -86,8 +86,6 @@
  * WARNING!  SMP builds can use the ICU now so this code must be MP safe.
  */
 
-#ifndef APIC_IO
-
        .data
        ALIGN_DATA
 
@@ -132,5 +130,3 @@ ENTRY(ICU_INTREN)
        outb    %al,$IO_ICU2+ICU_IMR_OFFSET
        ICU_IMASK_UNLOCK
        ret
-
-#endif
index d196f9e..2c573fe 100644 (file)
@@ -21,8 +21,6 @@
 #include "assym.s"
 #include "icu_ipl.h"
 
-#ifndef APIC_IO
-
 #define ICU_IMR_OFFSET         1       /* IO_ICU{1,2} + 1 */
 
 #define        ICU_EOI                 0x20    /* XXX - define elsewhere */
@@ -207,5 +205,3 @@ MCOUNT_LABEL(eintr)
        .data
 
        .text
-
-#endif
index 5142717..756cd84 100644 (file)
@@ -29,7 +29,7 @@ extern int    tsc_present;
 extern int64_t tsc_frequency;
 extern int     tsc_is_broken;
 extern int     wall_cmos_clock;
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 extern int     apic_8254_intr;
 #endif
 
index 028732d..fd9acb0 100644 (file)
@@ -147,6 +147,7 @@ int io_apic_get_id          (int);
 int    ext_int_setup           (int, int);
 void   lapic_config(void);
 void   lapic_enumerator_register(struct lapic_enumerator *);
+extern int apic_io_enable;
 
 #if defined(READY)
 void   clr_io_apic_mask24      (int, u_int32_t);
index c5acda6..99ca676 100644 (file)
@@ -88,7 +88,7 @@
 
 #include <machine_base/isa/intr_machdep.h>
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 /* The interrupt triggered by the 8254 (timer) chip */
 int apic_8254_intr;
 static void setup_8254_mixed_mode (void);
@@ -1017,10 +1017,10 @@ static void
 i8254_intr_initclock(struct cputimer_intr *cti, boolean_t selected)
 {
        int diag;
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
        int apic_8254_trial;
        void *clkdesc;
-#endif /* APIC_IO */
+#endif
 
        callout_init(&sysbeepstop_ch);
 
@@ -1045,8 +1045,8 @@ i8254_intr_initclock(struct cputimer_intr *cti, boolean_t selected)
         }
 
        /* Finish initializing 8253 timer 0. */
-#ifdef APIC_IO
-
+#ifdef SMP /* APIC-IO */
+if (apic_io_enable) {
        apic_8254_intr = isa_apic_irq(0);
        apic_8254_trial = 0;
        if (apic_8254_intr >= 0 ) {
@@ -1067,16 +1067,16 @@ i8254_intr_initclock(struct cputimer_intr *cti, boolean_t selected)
                               INTR_NOPOLL | INTR_MPSAFE | 
                               INTR_NOENTROPY);
        machintr_intren(apic_8254_intr);
-       
-#else /* APIC_IO */
-
+} else {
+#endif
        register_int(0, clkintr, NULL, "clk", NULL,
                     INTR_EXCL | INTR_CLOCK |
                     INTR_NOPOLL | INTR_MPSAFE |
                     INTR_NOENTROPY);
        machintr_intren(ICU_IRQ0);
-
-#endif /* APIC_IO */
+#ifdef SMP /* APIC-IO */
+}
+#endif
 
        /* Initialize RTC. */
        writertc(RTC_STATUSA, rtc_statusa);
@@ -1087,10 +1087,12 @@ i8254_intr_initclock(struct cputimer_intr *cti, boolean_t selected)
                if (diag != 0)
                        kprintf("RTC BIOS diagnostic error %b\n", diag, RTCDG_BITS);
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
+if (apic_io_enable) {
                if (isa_apic_irq(8) != 8)
                        panic("APIC RTC != 8");
-#endif /* APIC_IO */
+}
+#endif
 
                register_int(8, (inthand2_t *)rtcintr, NULL, "rtc", NULL,
                             INTR_EXCL | INTR_CLOCK | INTR_NOPOLL |
@@ -1100,7 +1102,8 @@ i8254_intr_initclock(struct cputimer_intr *cti, boolean_t selected)
                writertc(RTC_STATUSB, rtc_statusb);
        }
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
+if (apic_io_enable) {
        if (apic_8254_trial) {
                sysclock_t base;
                long lastcnt;
@@ -1168,10 +1171,11 @@ i8254_intr_initclock(struct cputimer_intr *cti, boolean_t selected)
                kprintf("APIC_IO: "
                       "routing 8254 via 8259 and IOAPIC #0 intpin 0\n");
        }
+}
 #endif
 }
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 
 static void 
 setup_8254_mixed_mode(void)
index b53129d..aad0fcb 100644 (file)
 /* XXX should be in suitable include files */
 #define        ICU_IMR_OFFSET          1               /* IO_ICU{1,2} + 1 */
 
-#ifdef APIC_IO
-/*
- * This is to accommodate "mixed-mode" programming for 
- * motherboards that don't connect the 8254 to the IO APIC.
- */
-#define        AUTO_EOI_1      1
-#endif
-
 static void    init_i8259(void);
 
 #define NMI_PARITY (1 << 7)
@@ -183,10 +175,16 @@ init_i8259(void)
        outb(IO_ICU1+ICU_IMR_OFFSET, IDT_OFFSET);       /* starting at this vector index */
        outb(IO_ICU1+ICU_IMR_OFFSET, 1 << ICU_IRQ_SLAVE); /* slave on line 2 */
 #ifdef AUTO_EOI_1
-       outb(IO_ICU1+ICU_IMR_OFFSET, 2 | 1);            /* auto EOI, 8086 mode */
+       int auto_eoi = 2;                               /* auto EOI, 8086 mode */
 #else
-       outb(IO_ICU1+ICU_IMR_OFFSET, 1);                /* 8086 mode */
+       int auto_eoi = 0;                               /* 8086 mode */
 #endif
+#ifdef SMP
+       if (apic_io_enable)
+               auto_eoi = 2;                           /* auto EOI, 8086 mode */
+#endif
+       outb(IO_ICU1+ICU_IMR_OFFSET, auto_eoi | 1);
+
        outb(IO_ICU1+ICU_IMR_OFFSET, 0xff);             /* leave interrupts masked */
        outb(IO_ICU1, 0x0a);            /* default to IRR on read */
        outb(IO_ICU1, 0xc0 | (3 - 1));  /* pri order 3-7, 0-2 (com2 first) */