x86_64: Allow UP kernel to use LAPIC timer and I/O APIC
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 3 Jun 2011 09:10:10 +0000 (17:10 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Fri, 3 Jun 2011 09:11:46 +0000 (17:11 +0800)
16 files changed:
sys/bus/pci/pci_pci.c
sys/platform/pc64/acpica5/acpi_machdep.c
sys/platform/pc64/apic/apic_vector.s
sys/platform/pc64/apic/ioapic_abi.c
sys/platform/pc64/apic/lapic.c
sys/platform/pc64/apic/lapic.h
sys/platform/pc64/conf/files
sys/platform/pc64/icu/icu.c
sys/platform/pc64/icu/icu_abi.c
sys/platform/pc64/icu/icu_var.h
sys/platform/pc64/include/acpica_machdep.h
sys/platform/pc64/include/intr_machdep.h
sys/platform/pc64/isa/clock.c
sys/platform/pc64/x86_64/ipl.s
sys/platform/pc64/x86_64/machdep.c
sys/platform/pc64/x86_64/nexus.c

index cd273c4..81659cc 100644 (file)
@@ -126,12 +126,16 @@ 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__) || defined(__x86_64__)
+#if defined(__i386__)
 #ifdef SMP
        /* PCIBIOS PCI-PCI bridge is -2000 */
        if (ioapic_enable)
                return (-1000);
 #endif
+#elif defined(__x86_64__)
+       /* PCIBIOS PCI-PCI bridge is -2000 */
+       if (ioapic_enable)
+               return (-1000);
 #endif
        return (-10000);
     }
index 3d3943f..701b93c 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);
@@ -370,7 +343,12 @@ acpi_machdep_init(device_t dev)
 
        acpi_install_wakeup_handler(sc);
 
-       if (acpi_GetDefaultIntrModel() != ACPI_INTR_PIC)
+       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,
@@ -380,10 +358,3 @@ acpi_machdep_init(device_t dev)
 
        return (0);
 }
-
-void
-acpi_SetDefaultIntrModel(int model)
-{
-
-       intr_model = model;
-}
index c12a03a..5e662b9 100644 (file)
@@ -175,6 +175,7 @@ Xspuriousint:
 
        jmp     doreti_iret
 
+#ifdef SMP
 
 /*
  * Handle TLB shootdowns.
@@ -297,6 +298,8 @@ Xipiq:
        APIC_POP_FRAME
        jmp     doreti_iret
 
+#endif /* SMP */
+
        .text
        SUPERALIGN_TEXT
        .globl Xtimer
index 05153ef..da0059c 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 8089d6a..d5d10f6 100644 (file)
@@ -123,6 +123,11 @@ lapic_init(boolean_t bsp)
                setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
                    SDT_SYSIGT, SEL_KPL, 0);
 
+               /* Install a timer vector */
+               setidt(XTIMER_OFFSET, Xtimer,
+                   SDT_SYSIGT, SEL_KPL, 0);
+
+#ifdef SMP
                /* Install an inter-CPU IPI for TLB invalidation */
                setidt(XINVLTLB_OFFSET, Xinvltlb,
                    SDT_SYSIGT, SEL_KPL, 0);
@@ -131,13 +136,10 @@ lapic_init(boolean_t bsp)
                setidt(XIPIQ_OFFSET, Xipiq,
                    SDT_SYSIGT, SEL_KPL, 0);
 
-               /* Install a timer vector */
-               setidt(XTIMER_OFFSET, Xtimer,
-                   SDT_SYSIGT, SEL_KPL, 0);
-
                /* Install an inter-CPU IPI for CPU stop/restart */
                setidt(XCPUSTOP_OFFSET, Xcpustop,
                    SDT_SYSIGT, SEL_KPL, 0);
+#endif
        }
 
        /*
@@ -477,14 +479,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
 }
 
 
@@ -499,6 +509,8 @@ apic_dump(char* str)
                lapic->lvt_lint0, lapic->lvt_lint1, lapic->tpr, lapic->svr);
 }
 
+#ifdef SMP
+
 /*
  * Inter Processor Interrupt functions.
  */
@@ -625,6 +637,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 d198617..74d1433 100644 (file)
@@ -59,10 +59,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 *);
@@ -71,6 +67,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
  */
@@ -82,8 +89,6 @@ all_but_self_ipi(int vector)
        return apic_ipi(APIC_DEST_ALLESELF, vector, APIC_DELMODE_FIXED);
 }
 
-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 18ac7d0..54d935f 100644 (file)
@@ -167,11 +167,11 @@ platform/pc64/x86_64/identcpu.c           standard
 platform/pc64/x86_64/amd64_mem.c       standard
 platform/pc64/x86_64/cpufreq_machdep.c    standard
 
-platform/pc64/apic/lapic.c             optional        smp
-platform/pc64/apic/ioapic.c            optional        smp
-platform/pc64/apic/ioapic_abi.c                optional        smp
-platform/pc64/apic/ioapic_ipl.s                optional        smp
-platform/pc64/apic/apic_vector.s       optional        smp
+platform/pc64/apic/lapic.c             standard
+platform/pc64/apic/ioapic.c            standard
+platform/pc64/apic/ioapic_abi.c                standard
+platform/pc64/apic/ioapic_ipl.s                standard
+platform/pc64/apic/apic_vector.s       standard
 
 bus/isa/x86_64/isa.c                   optional        isa
 bus/isa/x86_64/isa_dma.c                       optional        isa
@@ -187,7 +187,7 @@ platform/pc64/icu/elcr.c            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
+bus/pci/x86_64/mptable_pci.c           optional        pci
 # notyet (BIOS struct and functions)
 #bus/pci/x86_64/pci_pir.c                      optional        pci
 
@@ -201,10 +201,10 @@ platform/pc64/x86_64/console.c    standard
 platform/pc64/x86_64/ipl_funcs.c       standard
 kern/syscalls.c                        standard
 platform/pc64/x86_64/mp_machdep.c              optional        smp
-platform/pc64/x86_64/mptable.c         optional        smp
+platform/pc64/x86_64/mptable.c         standard
 platform/pc64/acpica5/acpi_sdt.c       standard
 platform/pc64/acpica5/acpi_fadt.c      standard
-platform/pc64/acpica5/acpi_madt.c      optional        smp
+platform/pc64/acpica5/acpi_madt.c      standard
 dev/misc/atkbd/atkbd_isa.c             optional        atkbd
 dev/misc/atkbdc_layer/atkbdc_isa.c     optional        atkbdc
 dev/misc/ppc/ppc.c                     optional        ppc
index 3792fe6..5c99ea0 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 239989e..837b788 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 11ba221..3ade026 100644 (file)
@@ -74,6 +74,4 @@ extern int    acpi_release_global_lock(uint32_t *lock);
 #define COMPILER_DEPENDENT_INT64       long
 #define COMPILER_DEPENDENT_UINT64      unsigned long
 
-void   acpi_SetDefaultIntrModel(int model);
-
 #endif /* _MACHINE_ACPICA_MACHDEP_H__ */
index 262cb98..113845a 100644 (file)
@@ -54,8 +54,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
 
 /*
@@ -146,14 +142,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
+       Xspuriousint,   /* handle APIC "spurious INTs" */
+       Xtimer;         /* handle LAPIC timer INT */
+
+#ifdef 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 */
        Xipiq;          /* handle lwkt_send_ipiq() requests */
-#endif /* SMP */
+#endif
 
 #endif /* LOCORE */
 
index 5059466..4403aa9 100644 (file)
 #include <machine/specialreg.h>
 #include <machine/intr_machdep.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>
@@ -1008,8 +1006,6 @@ resettodr(void)
        crit_exit();
 }
 
-#ifdef SMP
-
 static int
 i8254_ioapic_trial(int irq, struct cputimer_intr *cti)
 {
@@ -1041,8 +1037,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
@@ -1051,10 +1045,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);
 
@@ -1070,7 +1062,6 @@ i8254_intr_initclock(struct cputimer_intr *cti, boolean_t selected)
        rtc_statusb = RTCSB_24HR;
 
        /* Finish initializing 8254 timer 0. */
-#ifdef SMP
        if (ioapic_enable) {
                irq = ioapic_abi_find_irq(0, INTR_TRIGGER_EDGE,
                        INTR_POLARITY_HIGH);
@@ -1103,21 +1094,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 /* APIC-IO */
+               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) {
@@ -1140,7 +1127,6 @@ mixed_mode_setup:
                        }
                }
        }
-#endif
        return;
 
 nointr:
index a96f63e..ff8f428 100644 (file)
@@ -153,9 +153,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 (3 groups)
         */
@@ -323,6 +323,7 @@ doreti_ipiq:
        decl    PCPU(intr_nesting_level)
        movl    %r12d,%eax              /* restore cpl for loop */
        jmp     doreti_next
+#endif
 
 doreti_timer:
        movl    %eax,%r12d              /* save cpl (can't use stack) */
@@ -337,8 +338,6 @@ doreti_timer:
        movl    %r12d,%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
@@ -363,9 +362,9 @@ 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 (3 groups)
         */
@@ -453,6 +452,7 @@ splz_ipiq:
        call    lwkt_process_ipiq
        popq    %rax
        jmp     splz_next
+#endif
 
 splz_timer:
        andl    $~RQF_TIMER,PCPU(reqflags)
@@ -461,7 +461,6 @@ splz_timer:
        call    lapic_timer_process
        popq    %rax
        jmp     splz_next
-#endif
 
        /*
         * dofastunpend(%rcx:intr)
index ebed1a6..3d19c73 100644 (file)
@@ -1772,11 +1772,10 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
         * 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 305d58b..e5e0dfa 100644 (file)
@@ -159,23 +159,20 @@ nexus_probe(device_t dev)
        irq_rman.rm_start = 0;
        irq_rman.rm_type = RMAN_ARRAY;
        irq_rman.rm_descr = "Interrupt request lines";
-#ifdef 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");
-#ifdef 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