x86_64 - Get completely rid of APIC_IO
authorMichael Neumann <mneumann@ntecs.de>
Sun, 7 Nov 2010 20:32:27 +0000 (21:32 +0100)
committerMichael Neumann <mneumann@ntecs.de>
Sun, 7 Nov 2010 20:32:27 +0000 (21:32 +0100)
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.

19 files changed:
sys/platform/pc64/apic/apic_abi.c
sys/platform/pc64/apic/apic_ipl.h
sys/platform/pc64/apic/apic_ipl.s
sys/platform/pc64/apic/apic_vector.s
sys/platform/pc64/apic/mpapic.c
sys/platform/pc64/apic/mpapic.h
sys/platform/pc64/conf/files
sys/platform/pc64/conf/options
sys/platform/pc64/icu/icu_abi.c
sys/platform/pc64/icu/icu_ipl.s
sys/platform/pc64/icu/icu_vector.s
sys/platform/pc64/include/clock.h
sys/platform/pc64/include/smp.h
sys/platform/pc64/isa/clock.c
sys/platform/pc64/isa/intr_machdep.c
sys/platform/pc64/x86_64/autoconf.c
sys/platform/pc64/x86_64/machdep.c
sys/platform/pc64/x86_64/mp_machdep.c
sys/platform/pc64/x86_64/nexus.c

index b179655..44768ec 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);
@@ -101,7 +101,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 6073714..91976c7 100644 (file)
@@ -30,7 +30,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 c395948..a3d79df 100644 (file)
@@ -71,7 +71,7 @@
 #include "apic_ipl.h"
 #include "assym.s"
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 
        .text
        SUPERALIGN_TEXT
index 37ca171..93f2d62 100644 (file)
        APIC_IMASK_UNLOCK ;                                             \
 8: ;                                                                   \
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 
 /*
  * Fast interrupt call handlers run in the following sequence:
@@ -355,7 +355,7 @@ Xtimer:
        APIC_POP_FRAME
        iretq
 
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
 
 MCOUNT_LABEL(bintr)
        FAST_INTR(0,apic_fastintr0)
index da927e0..cb1c887 100644 (file)
@@ -160,14 +160,17 @@ 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
+        * 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;
 
        /* 
@@ -406,7 +409,7 @@ apic_dump(char* str)
 }
 
 
-#if defined(APIC_IO)
+#ifdef SMP /* APIC-IO */
 
 /*
  * IO APIC code,
@@ -820,7 +823,7 @@ imen_dump(void)
  * Inter Processor Interrupt functions.
  */
 
-#endif /* APIC_IO */
+#endif /* SMP APIC-IO */
 
 /*
  * Send APIC IPI 'vector' to 'destType' via 'deliveryMode'.
index 681b396..47a5677 100644 (file)
@@ -59,7 +59,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 3d4c6ad..db83dda 100644 (file)
@@ -181,7 +181,7 @@ platform/pc64/icu/icu_vector.s          standard
 bus/pci/x86_64/legacy.c                        optional        pci
 bus/pci/x86_64/pci_bus.c                       optional        pci
 bus/pci/x86_64/pci_cfgreg.c            optional        pci
-bus/pci/x86_64/mptable_pci.c           optional        pci smp apic_io
+bus/pci/x86_64/mptable_pci.c           optional        pci smp
 # notyet (BIOS struct and functions)
 #bus/pci/x86_64/pci_pir.c                      optional        pci
 
index 1aa512d..b7e26e1 100644 (file)
@@ -12,7 +12,6 @@ I586_PMC_GUPROF               opt_i586_guprof.h
 BROKEN_KEYBOARD_RESET  opt_reset.h
 
 # x86_64 SMP options
-APIC_IO                        opt_global.h
 
 # The cpu type
 #
index 95ead43..8c41929 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,
@@ -211,5 +209,3 @@ icu_vectorctl(int op, int intr, int flags)
     write_rflags(ef);
     return (error);
 }
-
-#endif
index 16c3005..d4fa942 100644 (file)
@@ -84,8 +84,6 @@
  * WARNING!  SMP builds can use the ICU now so this code must be MP safe.
  */
 
-#ifndef APIC_IO
-
        .data
        ALIGN_DATA
 
@@ -130,5 +128,3 @@ ENTRY(ICU_INTREN)
        outb    %al,$IO_ICU2+ICU_IMR_OFFSET
        ICU_IMASK_UNLOCK
        ret
-
-#endif
index 715b222..9b1612c 100644 (file)
@@ -50,8 +50,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 */
@@ -202,5 +200,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 2e799e8..f348dee 100644 (file)
@@ -65,6 +65,7 @@ u_int io_apic_read            (int, int);
 void   io_apic_write           (int, int, u_int);
 
 /* global data in mp_machdep.c */
+extern int                     apic_io_enable;
 extern int                     mp_naps;
 extern int                     mp_napics;
 extern vm_offset_t             io_apic_address[];
index ae7bbca..a726feb 100644 (file)
@@ -91,7 +91,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);
@@ -1020,10 +1020,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);
 
@@ -1048,8 +1048,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 ) {
@@ -1070,16 +1070,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);
@@ -1090,10 +1090,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 |
@@ -1103,7 +1105,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;
@@ -1171,10 +1174,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 f974349..efbb06a 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)
@@ -184,10 +176,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) */
index e5881a6..d98662a 100644 (file)
@@ -153,9 +153,10 @@ configure_final(void *dummy)
        cninit_finish();
 
        if (bootverbose) {
-#ifdef APIC_IO
+#ifdef SMP /* APIC-IO */
+       if (apic_io_enable)
                imen_dump();
-#endif /* APIC_IO */
+#endif
 
 #if JG
                /*
index 0039f8f..5085cb5 100644 (file)
 #include <sys/ptrace.h>
 #include <machine/sigframe.h>
 
+#include <sys/machintr.h>
+
 #define PHYSMAP_ENTRIES                10
 
 extern void init386(int first);
@@ -1611,6 +1613,15 @@ do_next:
                    off);
 }
 
+#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
@@ -1689,6 +1700,17 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
 #endif
 
        /*
+        * 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 2623202..e97773b 100644 (file)
@@ -228,11 +228,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
@@ -244,7 +242,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
 
@@ -253,7 +251,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];
@@ -303,7 +301,7 @@ static int  mptable_search(void);
 static int     mptable_check(vm_paddr_t);
 static long    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);
@@ -317,7 +315,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
@@ -562,15 +560,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 */
+}
 }
 
 /*
@@ -685,10 +683,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;
 
@@ -702,10 +698,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);
 
@@ -734,7 +730,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
@@ -818,8 +814,6 @@ typedef struct BUSTYPENAME {
        char    name[7];
 }       bus_type_name;
 
-#ifdef APIC_IO
-
 static bus_type_name bus_type_table[] =
 {
        {CBUS, "CBUS"},
@@ -863,17 +857,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)
@@ -1036,8 +1024,6 @@ mptable_pass2(struct mptable_pos *mpt)
                panic("mptable_iterate_entries(ioapic_pass2) failed\n");
 }
 
-#endif
-
 /*
  * Check if we should perform a hyperthreading "fix-up" to
  * enumerate any logical CPU's that aren't already listed
@@ -1203,8 +1189,6 @@ mptable_unmap(struct mptable_pos *mpt)
        }
 }
 
-#ifdef APIC_IO
-
 void
 assign_apic_irq(int apic, int intpin, int irq)
 {
@@ -1596,8 +1580,6 @@ setup_apic_irq_mapping(void)
        }
 }
 
-#endif
-
 void
 mp_set_cpuids(int cpu_id, int apic_id)
 {
@@ -1629,8 +1611,6 @@ processor_entry(const struct PROCENTRY *entry, int cpu)
        return 0;
 }
 
-#ifdef APIC_IO
-
 static int
 bus_entry(const struct BUSENTRY *entry, int bus)
 {
@@ -1865,8 +1845,6 @@ next_apic_irq(int irq)
 #undef INTAPIC
 #undef INTTYPE
 
-#endif
-
 /*
  * Reprogram the MB chipset to NOT redirect an ISA INTerrupt.
  *
@@ -1914,8 +1892,6 @@ undirect_pci_irq(int rirq)
 }
 
 
-#ifdef APIC_IO
-
 /*
  * given a bus ID, return:
  *  the bus type if found
@@ -2163,8 +2139,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 3ce6e76..fda7827 100644 (file)
@@ -154,18 +154,22 @@ 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
+#ifdef 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");
+#ifdef SMP /* APIC-IO */
+}
 #endif
 
        /*