[PATCH] i386: Allow to use GENERICARCH for UP kernels
authorAndi Kleen <ak@suse.de>
Tue, 26 Sep 2006 08:52:26 +0000 (10:52 +0200)
committerAndi Kleen <andi@basil.nowhere.org>
Tue, 26 Sep 2006 08:52:26 +0000 (10:52 +0200)
There are some machines around (large xSeries or Unisys ES7000) that
need physical IO-APIC destination mode to access all of their IO
devices. This currently doesn't work in UP kernels as used in
distribution installers.

This patch allows to compile even UP kernels as GENERICARCH which
allows to use physical or clustered APIC mode.

Signed-off-by: Andi Kleen <ak@suse.de>
arch/i386/Kconfig
arch/i386/kernel/io_apic.c
arch/i386/kernel/mpparse.c
arch/i386/mach-generic/bigsmp.c
arch/i386/mach-generic/es7000.c
arch/i386/mach-generic/probe.c
arch/i386/mach-generic/summit.c
include/asm-i386/genapic.h
include/asm-i386/mach-es7000/mach_apic.h
include/asm-i386/mach-summit/mach_apic.h
include/asm-i386/smp.h

index b2751eadbc56367cfff8b360be44f6cc27453353..c134a545b37eaeaa3f67435a0366b382ec89e3d9 100644 (file)
@@ -166,7 +166,6 @@ config X86_VISWS
 
 config X86_GENERICARCH
        bool "Generic architecture (Summit, bigsmp, ES7000, default)"
-       depends on SMP
        help
           This option compiles in the Summit, bigsmp, ES7000, default subarchitectures.
          It is intended for a generic binary kernel.
@@ -263,7 +262,7 @@ source "kernel/Kconfig.preempt"
 
 config X86_UP_APIC
        bool "Local APIC support on uniprocessors"
-       depends on !SMP && !(X86_VISWS || X86_VOYAGER)
+       depends on !SMP && !(X86_VISWS || X86_VOYAGER || X86_GENERICARCH)
        help
          A local APIC (Advanced Programmable Interrupt Controller) is an
          integrated interrupt controller in the CPU. If you have a single-CPU
@@ -288,12 +287,12 @@ config X86_UP_IOAPIC
 
 config X86_LOCAL_APIC
        bool
-       depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER)
+       depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) || X86_GENERICARCH
        default y
 
 config X86_IO_APIC
        bool
-       depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER))
+       depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) || X86_GENERICARCH
        default y
 
 config X86_VISWS_APIC
index 4fb32c551fe0b9bb62df93acab0cb80dd657d359..4eacd52eeb7428987f7d8168b79590e9bca75d20 100644 (file)
@@ -40,6 +40,7 @@
 #include <asm/nmi.h>
 
 #include <mach_apic.h>
+#include <mach_apicdef.h>
 
 #include "io_ports.h"
 
index a70b5fa0ef06fd3cf165349959d52f25fe151fed..8275696885626951772a5a7c1715f0f0b4fbdee5 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/io_apic.h>
 
 #include <mach_apic.h>
+#include <mach_apicdef.h>
 #include <mach_mpparse.h>
 #include <bios_ebda.h>
 
index ef7a6e6fcb9f0a834e67a9d4608707f98cd5e027..33d9f93557badd2d1a466ba5268cf81665904e67 100644 (file)
@@ -5,6 +5,7 @@
 #define APIC_DEFINITION 1
 #include <linux/threads.h>
 #include <linux/cpumask.h>
+#include <asm/smp.h>
 #include <asm/mpspec.h>
 #include <asm/genapic.h>
 #include <asm/fixmap.h>
index 845cdd0b359350f4c6e860f9287999038c7358f7..aa144d82334de969c921f70b04ca1fb41fc46fc5 100644 (file)
@@ -4,6 +4,7 @@
 #define APIC_DEFINITION 1
 #include <linux/threads.h>
 #include <linux/cpumask.h>
+#include <asm/smp.h>
 #include <asm/mpspec.h>
 #include <asm/genapic.h>
 #include <asm/fixmap.h>
index bcd1bcfaa7238e9ad546c7191d506e0329e8f578..793d1b473251053bed12fc24894e49f61709d7b6 100644 (file)
@@ -119,7 +119,9 @@ int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
        return 0;       
 }
 
+#ifdef CONFIG_SMP
 int hard_smp_processor_id(void)
 {
        return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID));
 }
+#endif
index b73501ddd653a9fed0be28c112a1a1c351707de2..f7e5d66648dc1ee16d30981e49847ffc509077b6 100644 (file)
@@ -4,6 +4,7 @@
 #define APIC_DEFINITION 1
 #include <linux/threads.h>
 #include <linux/cpumask.h>
+#include <asm/smp.h>
 #include <asm/mpspec.h>
 #include <asm/genapic.h>
 #include <asm/fixmap.h>
index b3783a32abeec92e8632465031cbca1778855351..8ffbb0f0745760f7747d850faf89d884c4cd93eb 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef _ASM_GENAPIC_H
 #define _ASM_GENAPIC_H 1
 
+#include <asm/mpspec.h>
+
 /*
  * Generic APIC driver interface.
  *
@@ -63,14 +65,25 @@ struct genapic {
        unsigned (*get_apic_id)(unsigned long x);
        unsigned long apic_id_mask;
        unsigned int (*cpu_mask_to_apicid)(cpumask_t cpumask);
-       
+
+#ifdef CONFIG_SMP
        /* ipi */
        void (*send_IPI_mask)(cpumask_t mask, int vector);
        void (*send_IPI_allbutself)(int vector);
        void (*send_IPI_all)(int vector);
+#endif
 }; 
 
-#define APICFUNC(x) .x = x
+#define APICFUNC(x) .x = x,
+
+/* More functions could be probably marked IPIFUNC and save some space
+   in UP GENERICARCH kernels, but I don't have the nerve right now
+   to untangle this mess. -AK  */
+#ifdef CONFIG_SMP
+#define IPIFUNC(x) APICFUNC(x)
+#else
+#define IPIFUNC(x)
+#endif
 
 #define APIC_INIT(aname, aprobe) { \
        .name = aname, \
@@ -80,33 +93,33 @@ struct genapic {
        .no_balance_irq = NO_BALANCE_IRQ, \
        .ESR_DISABLE = esr_disable, \
        .apic_destination_logical = APIC_DEST_LOGICAL, \
-       APICFUNC(apic_id_registered), \
-       APICFUNC(target_cpus), \
-       APICFUNC(check_apicid_used), \
-       APICFUNC(check_apicid_present), \
-       APICFUNC(init_apic_ldr), \
-       APICFUNC(ioapic_phys_id_map), \
-       APICFUNC(clustered_apic_check), \
-       APICFUNC(multi_timer_check), \
-       APICFUNC(apicid_to_node), \
-       APICFUNC(cpu_to_logical_apicid), \
-       APICFUNC(cpu_present_to_apicid), \
-       APICFUNC(apicid_to_cpu_present), \
-       APICFUNC(mpc_apic_id), \
-       APICFUNC(setup_portio_remap), \
-       APICFUNC(check_phys_apicid_present), \
-       APICFUNC(mpc_oem_bus_info), \
-       APICFUNC(mpc_oem_pci_bus), \
-       APICFUNC(mps_oem_check), \
-       APICFUNC(get_apic_id), \
+       APICFUNC(apic_id_registered) \
+       APICFUNC(target_cpus) \
+       APICFUNC(check_apicid_used) \
+       APICFUNC(check_apicid_present) \
+       APICFUNC(init_apic_ldr) \
+       APICFUNC(ioapic_phys_id_map) \
+       APICFUNC(clustered_apic_check) \
+       APICFUNC(multi_timer_check) \
+       APICFUNC(apicid_to_node) \
+       APICFUNC(cpu_to_logical_apicid) \
+       APICFUNC(cpu_present_to_apicid) \
+       APICFUNC(apicid_to_cpu_present) \
+       APICFUNC(mpc_apic_id) \
+       APICFUNC(setup_portio_remap) \
+       APICFUNC(check_phys_apicid_present) \
+       APICFUNC(mpc_oem_bus_info) \
+       APICFUNC(mpc_oem_pci_bus) \
+       APICFUNC(mps_oem_check) \
+       APICFUNC(get_apic_id) \
        .apic_id_mask = APIC_ID_MASK, \
-       APICFUNC(cpu_mask_to_apicid), \
-       APICFUNC(acpi_madt_oem_check), \
-       APICFUNC(send_IPI_mask), \
-       APICFUNC(send_IPI_allbutself), \
-       APICFUNC(send_IPI_all), \
-       APICFUNC(enable_apic_mode), \
-       APICFUNC(phys_pkg_id), \
+       APICFUNC(cpu_mask_to_apicid) \
+       APICFUNC(acpi_madt_oem_check) \
+       IPIFUNC(send_IPI_mask) \
+       IPIFUNC(send_IPI_allbutself) \
+       IPIFUNC(send_IPI_all) \
+       APICFUNC(enable_apic_mode) \
+       APICFUNC(phys_pkg_id) \
        }
 
 extern struct genapic *genapic;
index b5f3f0d0b2bcc1f4573e5652837ff2b7009f9040..26333685a7fbe50974475026bced9b4ae9c13ca8 100644 (file)
@@ -123,9 +123,13 @@ extern u8 cpu_2_logical_apicid[];
 /* Mapping from cpu number to logical apicid */
 static inline int cpu_to_logical_apicid(int cpu)
 {
+#ifdef CONFIG_SMP
        if (cpu >= NR_CPUS)
               return BAD_APICID;
        return (int)cpu_2_logical_apicid[cpu];
+#else
+       return logical_smp_processor_id();
+#endif
 }
 
 static inline int mpc_apic_id(struct mpc_config_processor *m, struct mpc_config_translation *unused)
index 9fd0732862895fc4bf002765655fe329aef53ff8..a81b0596159508618a3e2b2bfc11ea5b9d62fe47 100644 (file)
@@ -46,10 +46,12 @@ extern u8 cpu_2_logical_apicid[];
 static inline void init_apic_ldr(void)
 {
        unsigned long val, id;
-       int i, count;
-       u8 lid;
+       int count = 0;
        u8 my_id = (u8)hard_smp_processor_id();
        u8 my_cluster = (u8)apicid_cluster(my_id);
+#ifdef CONFIG_SMP
+       u8 lid;
+       int i;
 
        /* Create logical APIC IDs by counting CPUs already in cluster. */
        for (count = 0, i = NR_CPUS; --i >= 0; ) {
@@ -57,6 +59,7 @@ static inline void init_apic_ldr(void)
                if (lid != BAD_APICID && apicid_cluster(lid) == my_cluster)
                        ++count;
        }
+#endif
        /* We only have a 4 wide bitmap in cluster mode.  If a deranged
         * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
        BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
@@ -91,9 +94,13 @@ static inline int apicid_to_node(int logical_apicid)
 /* Mapping from cpu number to logical apicid */
 static inline int cpu_to_logical_apicid(int cpu)
 {
+#ifdef CONFIG_SMP
        if (cpu >= NR_CPUS)
               return BAD_APICID;
        return (int)cpu_2_logical_apicid[cpu];
+#else
+       return logical_smp_processor_id();
+#endif
 }
 
 static inline int cpu_present_to_apicid(int mps_cpu)
index 142d10e34adeac2c4960e90018575c2094c28a62..f87826039a5118eeef7e2c033295ef83f09657b0 100644 (file)
@@ -80,17 +80,11 @@ static inline int hard_smp_processor_id(void)
        return GET_APIC_ID(*(unsigned long *)(APIC_BASE+APIC_ID));
 }
 #endif
-
-static __inline int logical_smp_processor_id(void)
-{
-       /* we don't want to mark this access volatile - bad code generation */
-       return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR));
-}
-
 #endif
 
 extern int __cpu_disable(void);
 extern void __cpu_die(unsigned int cpu);
+
 #endif /* !__ASSEMBLY__ */
 
 #else /* CONFIG_SMP */
@@ -100,4 +94,15 @@ extern void __cpu_die(unsigned int cpu);
 #define NO_PROC_ID             0xFF            /* No processor magic marker */
 
 #endif
+
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_X86_LOCAL_APIC
+static __inline int logical_smp_processor_id(void)
+{
+       /* we don't want to mark this access volatile - bad code generation */
+       return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR));
+}
+#endif
+#endif
+
 #endif