i386: Allow UP kernel to use LAPIC timer and I/O APIC
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Mon, 6 Jun 2011 11:38:24 +0000 (19:38 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Mon, 6 Jun 2011 11:38:24 +0000 (19:38 +0800)
17 files changed:
sys/bus/pci/pci_pci.c
sys/platform/pc32/acpica5/acpi_machdep.c
sys/platform/pc32/apic/apic_vector.s
sys/platform/pc32/apic/ioapic_abi.c
sys/platform/pc32/apic/ioapic_abi.h
sys/platform/pc32/apic/ioapic_ipl.h
sys/platform/pc32/apic/lapic.c
sys/platform/pc32/apic/lapic.h
sys/platform/pc32/conf/files
sys/platform/pc32/i386/ipl.s
sys/platform/pc32/i386/machdep.c
sys/platform/pc32/i386/nexus.c
sys/platform/pc32/icu/icu.c
sys/platform/pc32/icu/icu_abi.c
sys/platform/pc32/icu/icu_var.h
sys/platform/pc32/include/intr_machdep.h
sys/platform/pc32/isa/clock.c

index 81659cc..4847f3a 100644 (file)
@@ -126,13 +126,7 @@ pcib_probe(device_t dev)
     if ((pci_get_class(dev) == PCIC_BRIDGE) &&
        (pci_get_subclass(dev) == PCIS_BRIDGE_PCI)) {
        device_set_desc(dev, "PCI-PCI bridge");
-#if defined(__i386__)
-#ifdef SMP
-       /* PCIBIOS PCI-PCI bridge is -2000 */
-       if (ioapic_enable)
-               return (-1000);
-#endif
-#elif defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__)
        /* PCIBIOS PCI-PCI bridge is -2000 */
        if (ioapic_enable)
                return (-1000);
index 176bff9..cd6e060 100644 (file)
@@ -56,15 +56,6 @@ static device_t      acpi_dev;
 uint32_t acpi_reset_video = 1;
 TUNABLE_INT("hw.acpi.reset_video", &acpi_reset_video);
 
-/*
- * -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;
@@ -331,29 +322,11 @@ 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
-               if (ioapic_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)
 {
        struct  acpi_softc *sc;
+       int intr_model;
 
        acpi_dev = dev;
        sc = device_get_softc(acpi_dev);
@@ -368,8 +341,13 @@ acpi_machdep_init(device_t dev)
 
        acpi_install_wakeup_handler(sc);
 
-       if (acpi_GetDefaultIntrModel() != ACPI_INTR_PIC)
-               acpi_SetIntrModel(acpi_GetDefaultIntrModel());
+       if (ioapic_enable)
+               intr_model = ACPI_INTR_APIC;
+       else
+               intr_model = ACPI_INTR_PIC;
+
+       if (intr_model != ACPI_INTR_PIC)
+               acpi_SetIntrModel(intr_model);
 
        SYSCTL_ADD_UINT(&sc->acpi_sysctl_ctx,
            SYSCTL_CHILDREN(sc->acpi_sysctl_tree), OID_AUTO,
@@ -378,10 +356,3 @@ acpi_machdep_init(device_t dev)
 
        return (0);
 }
-
-void
-acpi_SetDefaultIntrModel(int model)
-{
-
-       intr_model = model;
-}
index 07c42a8..1f4f297 100644 (file)
@@ -183,6 +183,7 @@ Xspuriousint:
 
        iret
 
+#ifdef SMP
 
 /*
  * Handle TLB shootdowns.
@@ -323,6 +324,8 @@ Xipiq:
        MEXITCOUNT
        jmp     doreti_syscall_ret
 
+#endif /* SMP */
+
        .text
        SUPERALIGN_TEXT
        .globl Xtimer
index 9f32fbe..1f3bf2d 100644 (file)
@@ -60,6 +60,7 @@
 #include <machine_base/apic/ioapic.h>
 #include <machine_base/apic/ioapic_abi.h>
 #include <machine_base/apic/ioapic_ipl.h>
+#include <machine_base/apic/apicreg.h>
 
 extern inthand_t
        IDTVEC(ioapic_intr0),
index ea69162..c8ba181 100644 (file)
@@ -66,8 +66,6 @@ struct apic_intmapinfo {
 
 extern struct apic_intmapinfo  int_to_apicintpin[];
 
-#ifdef SMP     /* APIC_IO */
-
 extern struct machintr_abi MachIntrABI_IOAPIC;
 
 int    ioapic_abi_extint_irqmap(int);
@@ -77,6 +75,4 @@ void  ioapic_abi_fixup_irqmap(void);
 int    ioapic_abi_find_gsi(int, enum intr_trigger, enum intr_polarity);
 int    ioapic_abi_find_irq(int, enum intr_trigger, enum intr_polarity);
 
-#endif /* SMP */
-
 #endif /* !_ARCH_APIC_IOAPIC_ABI_H_ */
index 01ce1ca..fcdd88f 100644 (file)
 #ifndef _ARCH_APIC_IOAPIC_IPL_H_
 #define        _ARCH_APIC_IOAPIC_IPL_H_
 
-#ifdef SMP /* APIC-IO */
-
 #define IOAPIC_HWI_VECTORS 192
 
-#endif
-
 #ifdef LOCORE
 
 /*
index 2af9ca8..fe60743 100644 (file)
@@ -113,6 +113,11 @@ lapic_init(boolean_t bsp)
                setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
                    SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
 
+               /* Install a timer vector */
+               setidt(XTIMER_OFFSET, Xtimer,
+                   SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+
+#ifdef SMP
                /* Install an inter-CPU IPI for TLB invalidation */
                setidt(XINVLTLB_OFFSET, Xinvltlb,
                    SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
@@ -121,13 +126,10 @@ lapic_init(boolean_t bsp)
                setidt(XIPIQ_OFFSET, Xipiq,
                    SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
 
-               /* Install a timer vector */
-               setidt(XTIMER_OFFSET, Xtimer,
-                   SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
-               
                /* Install an inter-CPU IPI for CPU stop/restart */
                setidt(XCPUSTOP_OFFSET, Xcpustop,
                    SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+#endif
        }
 
        /*
@@ -409,14 +411,22 @@ lapic_timer_restart_handler(void *dummy __unused)
 static void
 lapic_timer_intr_pmfixup(struct cputimer_intr *cti __unused)
 {
+#ifdef SMP
        lwkt_send_ipiq_mask(smp_active_mask,
                            lapic_timer_fixup_handler, NULL);
+#else
+       lapic_timer_fixup_handler(NULL);
+#endif
 }
 
 static void
 lapic_timer_intr_restart(struct cputimer_intr *cti __unused)
 {
+#ifdef SMP
        lwkt_send_ipiq_mask(smp_active_mask, lapic_timer_restart_handler, NULL);
+#else
+       lapic_timer_restart_handler(NULL);
+#endif
 }
 
 
@@ -431,6 +441,8 @@ apic_dump(char* str)
                lapic->lvt_lint0, lapic->lvt_lint1, lapic->tpr, lapic->svr);
 }
 
+#ifdef SMP
+
 /*
  * Inter Processor Interrupt functions.
  */
@@ -557,6 +569,8 @@ selected_apic_ipi(cpumask_t target, int vector, int delivery_mode)
        crit_exit();
 }
 
+#endif /* SMP */
+
 /*
  * Timer code, in development...
  *  - suggested by rgrimes@gndrsh.aac.dev.com
index 759caa2..385e3a1 100644 (file)
@@ -51,8 +51,6 @@ struct lapic_enumerator {
 #define LAPIC_ENUM_PRIO_MPTABLE                20
 #define LAPIC_ENUM_PRIO_MADT           40
 
-#ifdef SMP
-
 extern volatile lapic_t                *lapic;
 extern int                     cpu_id_to_apic_id[];
 extern int                     apic_id_to_cpu_id[];
@@ -60,10 +58,6 @@ extern int                   lapic_enable;
 
 void   apic_dump(char*);
 void   lapic_init(boolean_t);
-int    apic_ipi(int, int, int);
-void   selected_apic_ipi(cpumask_t, int, int);
-void   single_apic_ipi(int, int, int);
-int    single_apic_ipi_passive(int, int, int);
 void   lapic_set_cpuid(int, int);
 int    lapic_config(void);
 void   lapic_enumerator_register(struct lapic_enumerator *);
@@ -72,6 +66,17 @@ int  get_apic_timer_frequency(void);
 int    read_apic_timer(void);
 void   u_sleep(int);
 
+void   lapic_map(vm_offset_t /* XXX should be vm_paddr_t */);
+int    lapic_unused_apic_id(int);
+void   lapic_fixup_noioapic(void);
+
+#ifdef SMP
+
+int    apic_ipi(int, int, int);
+void   selected_apic_ipi(cpumask_t, int, int);
+void   single_apic_ipi(int, int, int);
+int    single_apic_ipi_passive(int, int, int);
+
 /*
  * Send an IPI INTerrupt containing 'vector' to all CPUs EXCEPT myself
  */
@@ -83,10 +88,6 @@ all_but_self_ipi(int vector)
        return apic_ipi(APIC_DEST_ALLESELF, vector, APIC_DELMODE_FIXED);
 }
 
-#endif
-
-void   lapic_map(vm_offset_t /* XXX should be vm_paddr_t */);
-int    lapic_unused_apic_id(int);
-void   lapic_fixup_noioapic(void);
+#endif /* SMP */
 
 #endif /* _ARCH_APIC_LAPIC_H_ */
index a948f15..60c864b 100644 (file)
@@ -193,19 +193,17 @@ platform/pc32/icu/icu_abi.c               standard
 platform/pc32/icu/icu_ipl.s            standard
 platform/pc32/icu/icu_vector.s         standard
 platform/pc32/icu/elcr.c               standard
-platform/pc32/apic/lapic.c             optional        smp
-platform/pc32/apic/ioapic.c            optional        smp
-platform/pc32/apic/ioapic_abi.c                optional        smp
-platform/pc32/apic/ioapic_ipl.s                optional        smp
-platform/pc32/apic/apic_vector.s       optional        smp
+platform/pc32/apic/lapic.c             standard
+platform/pc32/apic/ioapic.c            standard
+platform/pc32/apic/ioapic_abi.c                standard
+platform/pc32/apic/ioapic_ipl.s                standard
+platform/pc32/apic/apic_vector.s       standard
 platform/pc32/i386/est.c               optional        cpu_enable_est
 # temporarily not in build until we get the 'apic' option working on UP
-#arch/i386/i386/io_apic.c              optional        smp
-#arch/i386/i386/local_apic.c           optional        smp
 platform/pc32/i386/mpboot.s            optional        smp
 platform/pc32/i386/mp_clock.c          optional        smp
 platform/pc32/i386/mp_machdep.c                optional        smp
-platform/pc32/i386/mptable.c           optional        smp
+platform/pc32/i386/mptable.c           standard
 platform/pc32/i386/nexus.c             standard
 platform/pc32/i386/p4tcc.c             optional        cpu_enable_tcc
 platform/pc32/i386/perfmon.c           optional        perfmon
@@ -227,7 +225,7 @@ platform/pc32/i386/vm_machdep.c             standard
 platform/pc32/i386/cpufreq_machdep.c   standard
 platform/pc32/acpica5/acpi_sdt.c       standard
 platform/pc32/acpica5/acpi_fadt.c      standard
-platform/pc32/acpica5/acpi_madt.c      optional        smp
+platform/pc32/acpica5/acpi_madt.c      standard
 platform/pc32/isa/asc.c                        optional        asc
 platform/pc32/isa/clock.c              standard nowerror
 dev/video/ctx/ctx.c                    optional        ctx
@@ -255,7 +253,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
+bus/pci/i386/mptable_pci.c             optional        pci
 platform/pc32/isa/pmtimer.c            optional        pmtimer acpi
 # XXX drhodus
 platform/pc32/isa/prof_machdep.c       optional        profiling-routine
index b01dfa5..6c6d06d 100644 (file)
@@ -119,9 +119,9 @@ doreti_next:
 #ifdef SMP
        testl   $RQF_IPIQ,PCPU(reqflags)
        jnz     doreti_ipiq
+#endif
        testl   $RQF_TIMER,PCPU(reqflags)
        jnz     doreti_timer
-#endif
        /*
         * check for an unmasked int (6 groups)
         */
@@ -318,6 +318,7 @@ doreti_ipiq:
        decl    PCPU(intr_nesting_level)
        movl    %esi,%eax               /* restore cpl for loop */
        jmp     doreti_next
+#endif
 
 doreti_timer:
        movl    %eax,%esi               /* save cpl (can't use stack) */
@@ -332,8 +333,6 @@ doreti_timer:
        movl    %esi,%eax               /* restore cpl for loop */
        jmp     doreti_next
 
-#endif
-
        /*
         * SPLZ() a C callable procedure to dispatch any unmasked pending
         *        interrupts regardless of critical section nesting.  ASTs
@@ -358,9 +357,10 @@ splz_next:
 #ifdef SMP
        testl   $RQF_IPIQ,PCPU(reqflags)
        jnz     splz_ipiq
+#endif
        testl   $RQF_TIMER,PCPU(reqflags)
        jnz     splz_timer
-#endif
+
        /*
         * check for an unmasked int (6 groups)
         */
@@ -460,6 +460,7 @@ splz_ipiq:
        call    lwkt_process_ipiq
        popl    %eax
        jmp     splz_next
+#endif
 
 splz_timer:
        andl    $~RQF_TIMER,PCPU(reqflags)
@@ -468,7 +469,6 @@ splz_timer:
        call    lapic_timer_process
        popl    %eax
        jmp     splz_next
-#endif
 
        /*
         * dofastunpend(%ecx:intr)
index 8d3046b..7871118 100644 (file)
@@ -1948,11 +1948,10 @@ init386(int first)
         * Default MachIntrABI to ICU
         */
        MachIntrABI = MachIntrABI_ICU;
-#ifdef SMP
+
        TUNABLE_INT_FETCH("hw.apic_io_enable", &ioapic_enable); /* for compat */
        TUNABLE_INT_FETCH("hw.ioapic_enable", &ioapic_enable);
        TUNABLE_INT_FETCH("hw.lapic_enable", &lapic_enable);
-#endif
 
        /*
         * start with one cpu.  Note: with one cpu, ncpus2_shift, ncpus2_mask,
index c83b9dd..d2a83f0 100644 (file)
@@ -164,23 +164,20 @@ nexus_probe(device_t dev)
        irq_rman.rm_type = RMAN_ARRAY;
        irq_rman.rm_descr = "Interrupt request lines";
 
-#if SMP
-if (ioapic_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 {
-#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
-}
-#endif
+       if (ioapic_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 {
+               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");
+       }
+
        /*
         * 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
index e9bf35e..58932d3 100644 (file)
@@ -70,10 +70,8 @@ icu_init(void)
        int auto_eoi = 0;               /* 8086 mode */
 #endif
 
-#ifdef SMP
        if (ioapic_enable)
                auto_eoi = 2;           /* auto EOI, 8086 mode */
-#endif
 
        /*
         * Program master
@@ -183,8 +181,6 @@ icu_ioapic_extint(int irq, int vec)
        return 0;
 }
 
-#ifdef SMP
-
 void
 icu_reinit_noioapic(void)
 {
@@ -209,5 +205,3 @@ icu_reinit_noioapic(void)
        MachIntrABI.cleanup();
        crit_exit();
 }
-
-#endif
index e25760b..09680b5 100644 (file)
@@ -167,8 +167,6 @@ static void
 icu_finalize(void)
 {
        KKASSERT(MachIntrABI.type == MACHINTR_ICU);
-
-#ifdef SMP
        KKASSERT(!ioapic_enable);
 
        /*
@@ -184,7 +182,6 @@ icu_finalize(void)
                outb(0x22, 0x70);
                outb(0x23, 0x01);
        }
-#endif /* SMP */
 }
 
 static int
index 47e046c..7d04411 100644 (file)
@@ -40,9 +40,7 @@
 
 void           icu_definit(void);
 void           icu_reinit(void);
-#ifdef SMP
 void           icu_reinit_noioapic(void);
-#endif
 
 intrmask_t     icu_irq_pending(void);
 
index c350242..1a13b77 100644 (file)
@@ -53,8 +53,6 @@
 #define IDT_OFFSET_SYSCALL     0x80
 #define IDT_OFFSET_IPI         0xe0
 
-#if defined(SMP)
-
 /*
  * Local APIC TPR priority vector levels:
  *
 /* NOTE: this vector MUST be xxxx1111 */
 #define XSPURIOUSINT_OFFSET    (IDT_OFFSET_IPIG2 + 15)
 
-#endif /* SMP */
-
 #ifndef        LOCORE
 
 /*
@@ -142,14 +138,16 @@ typedef void inthand_t(u_int cs, u_int ef, u_int esp, u_int ss);
 
 #define        IDTVEC(name)    __CONCAT(X,name)
 
-#if defined(SMP)
 inthand_t
-       Xinvltlb,       /* TLB shootdowns */
-       Xcpustop,       /* CPU stops & waits for another CPU to restart it */
        Xspuriousint,   /* handle APIC "spurious INTs" */
-       Xtimer,         /* handle LAPIC timer INT */
+       Xtimer;         /* handle LAPIC timer INT */
+
+#ifdef SMP
+inthand_t
+       Xcpustop,       /* CPU stops & waits for another CPU to restart it */
+       Xinvltlb,       /* TLB shootdowns */
        Xipiq;          /* handle lwkt_send_ipiq() requests */
-#endif /* SMP */
+#endif
 
 #endif /* LOCORE */
 
index 6fde329..a44c9d0 100644 (file)
 #include <machine/smp.h>
 #include <machine/specialreg.h>
 
-#ifdef SMP
 #include <machine_base/apic/ioapic.h>
 #include <machine_base/apic/ioapic_abi.h>
-#endif
 #include <machine_base/icu/icu.h>
 #include <bus/isa/isa.h>
 #include <bus/isa/rtc.h>
@@ -1001,8 +999,6 @@ resettodr(void)
        crit_exit();
 }
 
-#ifdef SMP
-
 static int
 i8254_ioapic_trial(int irq, struct cputimer_intr *cti)
 {
@@ -1034,8 +1030,6 @@ i8254_ioapic_trial(int irq, struct cputimer_intr *cti)
        return 0;
 }
 
-#endif /* SMP */
-
 /*
  * Start both clocks running.  DragonFly note: the stat clock is no longer
  * used.  Instead, 8254 based systimers are used for all major clock
@@ -1044,10 +1038,8 @@ i8254_ioapic_trial(int irq, struct cputimer_intr *cti)
 static void
 i8254_intr_initclock(struct cputimer_intr *cti, boolean_t selected)
 {
-#ifdef SMP /* APIC-IO */
        void *clkdesc = NULL;
        int irq = 0, mixed_mode = 0, error;
-#endif
 
        callout_init(&sysbeepstop_ch);
 
@@ -1063,7 +1055,6 @@ i8254_intr_initclock(struct cputimer_intr *cti, boolean_t selected)
        rtc_statusb = RTCSB_24HR;
 
        /* Finish initializing 8253 timer 0. */
-#ifdef SMP
        if (ioapic_enable) {
                irq = ioapic_abi_find_irq(0, INTR_TRIGGER_EDGE,
                        INTR_POLARITY_HIGH);
@@ -1096,21 +1087,17 @@ mixed_mode_setup:
                                       INTR_NOENTROPY);
                machintr_intren(irq);
        } else {
-#endif
-       register_int(0, clkintr, NULL, "clk", NULL,
-                    INTR_EXCL | INTR_CLOCK |
-                    INTR_NOPOLL | INTR_MPSAFE |
-                    INTR_NOENTROPY);
-       machintr_intren(0);
-#ifdef SMP
+               register_int(0, clkintr, NULL, "clk", NULL,
+                            INTR_EXCL | INTR_CLOCK |
+                            INTR_NOPOLL | INTR_MPSAFE |
+                            INTR_NOENTROPY);
+               machintr_intren(0);
        }
-#endif
 
        /* Initialize RTC. */
        writertc(RTC_STATUSA, rtc_statusa);
        writertc(RTC_STATUSB, RTCSB_24HR);
 
-#ifdef SMP
        if (ioapic_enable) {
                error = i8254_ioapic_trial(irq, cti);
                if (error) {
@@ -1133,7 +1120,6 @@ mixed_mode_setup:
                        }
                }
        }
-#endif
        return;
 
 nointr: