diff options
author | Andi Kleen <ak@suse.de> | 2006-09-26 04:52:26 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-09-26 04:52:26 -0400 |
commit | 874c4fe389d1358f82c96dc9b5092fc5c7690604 (patch) | |
tree | 9d79c398041c8902cff3abb6c9495c3d63bf59f1 | |
parent | 9142e0c8396b25ed4cb549b5efa636065768ebe0 (diff) |
[PATCH] i386: Allow to use GENERICARCH for UP kernels
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>
-rw-r--r-- | arch/i386/Kconfig | 7 | ||||
-rw-r--r-- | arch/i386/kernel/io_apic.c | 1 | ||||
-rw-r--r-- | arch/i386/kernel/mpparse.c | 1 | ||||
-rw-r--r-- | arch/i386/mach-generic/bigsmp.c | 1 | ||||
-rw-r--r-- | arch/i386/mach-generic/es7000.c | 1 | ||||
-rw-r--r-- | arch/i386/mach-generic/probe.c | 2 | ||||
-rw-r--r-- | arch/i386/mach-generic/summit.c | 1 | ||||
-rw-r--r-- | include/asm-i386/genapic.h | 69 | ||||
-rw-r--r-- | include/asm-i386/mach-es7000/mach_apic.h | 4 | ||||
-rw-r--r-- | include/asm-i386/mach-summit/mach_apic.h | 11 | ||||
-rw-r--r-- | include/asm-i386/smp.h | 19 |
11 files changed, 76 insertions, 41 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index b2751eadbc56..c134a545b37e 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -166,7 +166,6 @@ config X86_VISWS | |||
166 | 166 | ||
167 | config X86_GENERICARCH | 167 | config X86_GENERICARCH |
168 | bool "Generic architecture (Summit, bigsmp, ES7000, default)" | 168 | bool "Generic architecture (Summit, bigsmp, ES7000, default)" |
169 | depends on SMP | ||
170 | help | 169 | help |
171 | This option compiles in the Summit, bigsmp, ES7000, default subarchitectures. | 170 | This option compiles in the Summit, bigsmp, ES7000, default subarchitectures. |
172 | It is intended for a generic binary kernel. | 171 | It is intended for a generic binary kernel. |
@@ -263,7 +262,7 @@ source "kernel/Kconfig.preempt" | |||
263 | 262 | ||
264 | config X86_UP_APIC | 263 | config X86_UP_APIC |
265 | bool "Local APIC support on uniprocessors" | 264 | bool "Local APIC support on uniprocessors" |
266 | depends on !SMP && !(X86_VISWS || X86_VOYAGER) | 265 | depends on !SMP && !(X86_VISWS || X86_VOYAGER || X86_GENERICARCH) |
267 | help | 266 | help |
268 | A local APIC (Advanced Programmable Interrupt Controller) is an | 267 | A local APIC (Advanced Programmable Interrupt Controller) is an |
269 | integrated interrupt controller in the CPU. If you have a single-CPU | 268 | integrated interrupt controller in the CPU. If you have a single-CPU |
@@ -288,12 +287,12 @@ config X86_UP_IOAPIC | |||
288 | 287 | ||
289 | config X86_LOCAL_APIC | 288 | config X86_LOCAL_APIC |
290 | bool | 289 | bool |
291 | depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) | 290 | depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) || X86_GENERICARCH |
292 | default y | 291 | default y |
293 | 292 | ||
294 | config X86_IO_APIC | 293 | config X86_IO_APIC |
295 | bool | 294 | bool |
296 | depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) | 295 | depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) || X86_GENERICARCH |
297 | default y | 296 | default y |
298 | 297 | ||
299 | config X86_VISWS_APIC | 298 | config X86_VISWS_APIC |
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 4fb32c551fe0..4eacd52eeb74 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <asm/nmi.h> | 40 | #include <asm/nmi.h> |
41 | 41 | ||
42 | #include <mach_apic.h> | 42 | #include <mach_apic.h> |
43 | #include <mach_apicdef.h> | ||
43 | 44 | ||
44 | #include "io_ports.h" | 45 | #include "io_ports.h" |
45 | 46 | ||
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index a70b5fa0ef06..827569688562 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/io_apic.h> | 30 | #include <asm/io_apic.h> |
31 | 31 | ||
32 | #include <mach_apic.h> | 32 | #include <mach_apic.h> |
33 | #include <mach_apicdef.h> | ||
33 | #include <mach_mpparse.h> | 34 | #include <mach_mpparse.h> |
34 | #include <bios_ebda.h> | 35 | #include <bios_ebda.h> |
35 | 36 | ||
diff --git a/arch/i386/mach-generic/bigsmp.c b/arch/i386/mach-generic/bigsmp.c index ef7a6e6fcb9f..33d9f93557ba 100644 --- a/arch/i386/mach-generic/bigsmp.c +++ b/arch/i386/mach-generic/bigsmp.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #define APIC_DEFINITION 1 | 5 | #define APIC_DEFINITION 1 |
6 | #include <linux/threads.h> | 6 | #include <linux/threads.h> |
7 | #include <linux/cpumask.h> | 7 | #include <linux/cpumask.h> |
8 | #include <asm/smp.h> | ||
8 | #include <asm/mpspec.h> | 9 | #include <asm/mpspec.h> |
9 | #include <asm/genapic.h> | 10 | #include <asm/genapic.h> |
10 | #include <asm/fixmap.h> | 11 | #include <asm/fixmap.h> |
diff --git a/arch/i386/mach-generic/es7000.c b/arch/i386/mach-generic/es7000.c index 845cdd0b3593..aa144d82334d 100644 --- a/arch/i386/mach-generic/es7000.c +++ b/arch/i386/mach-generic/es7000.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #define APIC_DEFINITION 1 | 4 | #define APIC_DEFINITION 1 |
5 | #include <linux/threads.h> | 5 | #include <linux/threads.h> |
6 | #include <linux/cpumask.h> | 6 | #include <linux/cpumask.h> |
7 | #include <asm/smp.h> | ||
7 | #include <asm/mpspec.h> | 8 | #include <asm/mpspec.h> |
8 | #include <asm/genapic.h> | 9 | #include <asm/genapic.h> |
9 | #include <asm/fixmap.h> | 10 | #include <asm/fixmap.h> |
diff --git a/arch/i386/mach-generic/probe.c b/arch/i386/mach-generic/probe.c index bcd1bcfaa723..793d1b473251 100644 --- a/arch/i386/mach-generic/probe.c +++ b/arch/i386/mach-generic/probe.c | |||
@@ -119,7 +119,9 @@ int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
121 | 121 | ||
122 | #ifdef CONFIG_SMP | ||
122 | int hard_smp_processor_id(void) | 123 | int hard_smp_processor_id(void) |
123 | { | 124 | { |
124 | return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID)); | 125 | return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID)); |
125 | } | 126 | } |
127 | #endif | ||
diff --git a/arch/i386/mach-generic/summit.c b/arch/i386/mach-generic/summit.c index b73501ddd653..f7e5d66648dc 100644 --- a/arch/i386/mach-generic/summit.c +++ b/arch/i386/mach-generic/summit.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #define APIC_DEFINITION 1 | 4 | #define APIC_DEFINITION 1 |
5 | #include <linux/threads.h> | 5 | #include <linux/threads.h> |
6 | #include <linux/cpumask.h> | 6 | #include <linux/cpumask.h> |
7 | #include <asm/smp.h> | ||
7 | #include <asm/mpspec.h> | 8 | #include <asm/mpspec.h> |
8 | #include <asm/genapic.h> | 9 | #include <asm/genapic.h> |
9 | #include <asm/fixmap.h> | 10 | #include <asm/fixmap.h> |
diff --git a/include/asm-i386/genapic.h b/include/asm-i386/genapic.h index b3783a32abee..8ffbb0f07457 100644 --- a/include/asm-i386/genapic.h +++ b/include/asm-i386/genapic.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef _ASM_GENAPIC_H | 1 | #ifndef _ASM_GENAPIC_H |
2 | #define _ASM_GENAPIC_H 1 | 2 | #define _ASM_GENAPIC_H 1 |
3 | 3 | ||
4 | #include <asm/mpspec.h> | ||
5 | |||
4 | /* | 6 | /* |
5 | * Generic APIC driver interface. | 7 | * Generic APIC driver interface. |
6 | * | 8 | * |
@@ -63,14 +65,25 @@ struct genapic { | |||
63 | unsigned (*get_apic_id)(unsigned long x); | 65 | unsigned (*get_apic_id)(unsigned long x); |
64 | unsigned long apic_id_mask; | 66 | unsigned long apic_id_mask; |
65 | unsigned int (*cpu_mask_to_apicid)(cpumask_t cpumask); | 67 | unsigned int (*cpu_mask_to_apicid)(cpumask_t cpumask); |
66 | 68 | ||
69 | #ifdef CONFIG_SMP | ||
67 | /* ipi */ | 70 | /* ipi */ |
68 | void (*send_IPI_mask)(cpumask_t mask, int vector); | 71 | void (*send_IPI_mask)(cpumask_t mask, int vector); |
69 | void (*send_IPI_allbutself)(int vector); | 72 | void (*send_IPI_allbutself)(int vector); |
70 | void (*send_IPI_all)(int vector); | 73 | void (*send_IPI_all)(int vector); |
74 | #endif | ||
71 | }; | 75 | }; |
72 | 76 | ||
73 | #define APICFUNC(x) .x = x | 77 | #define APICFUNC(x) .x = x, |
78 | |||
79 | /* More functions could be probably marked IPIFUNC and save some space | ||
80 | in UP GENERICARCH kernels, but I don't have the nerve right now | ||
81 | to untangle this mess. -AK */ | ||
82 | #ifdef CONFIG_SMP | ||
83 | #define IPIFUNC(x) APICFUNC(x) | ||
84 | #else | ||
85 | #define IPIFUNC(x) | ||
86 | #endif | ||
74 | 87 | ||
75 | #define APIC_INIT(aname, aprobe) { \ | 88 | #define APIC_INIT(aname, aprobe) { \ |
76 | .name = aname, \ | 89 | .name = aname, \ |
@@ -80,33 +93,33 @@ struct genapic { | |||
80 | .no_balance_irq = NO_BALANCE_IRQ, \ | 93 | .no_balance_irq = NO_BALANCE_IRQ, \ |
81 | .ESR_DISABLE = esr_disable, \ | 94 | .ESR_DISABLE = esr_disable, \ |
82 | .apic_destination_logical = APIC_DEST_LOGICAL, \ | 95 | .apic_destination_logical = APIC_DEST_LOGICAL, \ |
83 | APICFUNC(apic_id_registered), \ | 96 | APICFUNC(apic_id_registered) \ |
84 | APICFUNC(target_cpus), \ | 97 | APICFUNC(target_cpus) \ |
85 | APICFUNC(check_apicid_used), \ | 98 | APICFUNC(check_apicid_used) \ |
86 | APICFUNC(check_apicid_present), \ | 99 | APICFUNC(check_apicid_present) \ |
87 | APICFUNC(init_apic_ldr), \ | 100 | APICFUNC(init_apic_ldr) \ |
88 | APICFUNC(ioapic_phys_id_map), \ | 101 | APICFUNC(ioapic_phys_id_map) \ |
89 | APICFUNC(clustered_apic_check), \ | 102 | APICFUNC(clustered_apic_check) \ |
90 | APICFUNC(multi_timer_check), \ | 103 | APICFUNC(multi_timer_check) \ |
91 | APICFUNC(apicid_to_node), \ | 104 | APICFUNC(apicid_to_node) \ |
92 | APICFUNC(cpu_to_logical_apicid), \ | 105 | APICFUNC(cpu_to_logical_apicid) \ |
93 | APICFUNC(cpu_present_to_apicid), \ | 106 | APICFUNC(cpu_present_to_apicid) \ |
94 | APICFUNC(apicid_to_cpu_present), \ | 107 | APICFUNC(apicid_to_cpu_present) \ |
95 | APICFUNC(mpc_apic_id), \ | 108 | APICFUNC(mpc_apic_id) \ |
96 | APICFUNC(setup_portio_remap), \ | 109 | APICFUNC(setup_portio_remap) \ |
97 | APICFUNC(check_phys_apicid_present), \ | 110 | APICFUNC(check_phys_apicid_present) \ |
98 | APICFUNC(mpc_oem_bus_info), \ | 111 | APICFUNC(mpc_oem_bus_info) \ |
99 | APICFUNC(mpc_oem_pci_bus), \ | 112 | APICFUNC(mpc_oem_pci_bus) \ |
100 | APICFUNC(mps_oem_check), \ | 113 | APICFUNC(mps_oem_check) \ |
101 | APICFUNC(get_apic_id), \ | 114 | APICFUNC(get_apic_id) \ |
102 | .apic_id_mask = APIC_ID_MASK, \ | 115 | .apic_id_mask = APIC_ID_MASK, \ |
103 | APICFUNC(cpu_mask_to_apicid), \ | 116 | APICFUNC(cpu_mask_to_apicid) \ |
104 | APICFUNC(acpi_madt_oem_check), \ | 117 | APICFUNC(acpi_madt_oem_check) \ |
105 | APICFUNC(send_IPI_mask), \ | 118 | IPIFUNC(send_IPI_mask) \ |
106 | APICFUNC(send_IPI_allbutself), \ | 119 | IPIFUNC(send_IPI_allbutself) \ |
107 | APICFUNC(send_IPI_all), \ | 120 | IPIFUNC(send_IPI_all) \ |
108 | APICFUNC(enable_apic_mode), \ | 121 | APICFUNC(enable_apic_mode) \ |
109 | APICFUNC(phys_pkg_id), \ | 122 | APICFUNC(phys_pkg_id) \ |
110 | } | 123 | } |
111 | 124 | ||
112 | extern struct genapic *genapic; | 125 | extern struct genapic *genapic; |
diff --git a/include/asm-i386/mach-es7000/mach_apic.h b/include/asm-i386/mach-es7000/mach_apic.h index b5f3f0d0b2bc..26333685a7fb 100644 --- a/include/asm-i386/mach-es7000/mach_apic.h +++ b/include/asm-i386/mach-es7000/mach_apic.h | |||
@@ -123,9 +123,13 @@ extern u8 cpu_2_logical_apicid[]; | |||
123 | /* Mapping from cpu number to logical apicid */ | 123 | /* Mapping from cpu number to logical apicid */ |
124 | static inline int cpu_to_logical_apicid(int cpu) | 124 | static inline int cpu_to_logical_apicid(int cpu) |
125 | { | 125 | { |
126 | #ifdef CONFIG_SMP | ||
126 | if (cpu >= NR_CPUS) | 127 | if (cpu >= NR_CPUS) |
127 | return BAD_APICID; | 128 | return BAD_APICID; |
128 | return (int)cpu_2_logical_apicid[cpu]; | 129 | return (int)cpu_2_logical_apicid[cpu]; |
130 | #else | ||
131 | return logical_smp_processor_id(); | ||
132 | #endif | ||
129 | } | 133 | } |
130 | 134 | ||
131 | static inline int mpc_apic_id(struct mpc_config_processor *m, struct mpc_config_translation *unused) | 135 | static inline int mpc_apic_id(struct mpc_config_processor *m, struct mpc_config_translation *unused) |
diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h index 9fd073286289..a81b05961595 100644 --- a/include/asm-i386/mach-summit/mach_apic.h +++ b/include/asm-i386/mach-summit/mach_apic.h | |||
@@ -46,10 +46,12 @@ extern u8 cpu_2_logical_apicid[]; | |||
46 | static inline void init_apic_ldr(void) | 46 | static inline void init_apic_ldr(void) |
47 | { | 47 | { |
48 | unsigned long val, id; | 48 | unsigned long val, id; |
49 | int i, count; | 49 | int count = 0; |
50 | u8 lid; | ||
51 | u8 my_id = (u8)hard_smp_processor_id(); | 50 | u8 my_id = (u8)hard_smp_processor_id(); |
52 | u8 my_cluster = (u8)apicid_cluster(my_id); | 51 | u8 my_cluster = (u8)apicid_cluster(my_id); |
52 | #ifdef CONFIG_SMP | ||
53 | u8 lid; | ||
54 | int i; | ||
53 | 55 | ||
54 | /* Create logical APIC IDs by counting CPUs already in cluster. */ | 56 | /* Create logical APIC IDs by counting CPUs already in cluster. */ |
55 | for (count = 0, i = NR_CPUS; --i >= 0; ) { | 57 | for (count = 0, i = NR_CPUS; --i >= 0; ) { |
@@ -57,6 +59,7 @@ static inline void init_apic_ldr(void) | |||
57 | if (lid != BAD_APICID && apicid_cluster(lid) == my_cluster) | 59 | if (lid != BAD_APICID && apicid_cluster(lid) == my_cluster) |
58 | ++count; | 60 | ++count; |
59 | } | 61 | } |
62 | #endif | ||
60 | /* We only have a 4 wide bitmap in cluster mode. If a deranged | 63 | /* We only have a 4 wide bitmap in cluster mode. If a deranged |
61 | * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */ | 64 | * BIOS puts 5 CPUs in one APIC cluster, we're hosed. */ |
62 | BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT); | 65 | BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT); |
@@ -91,9 +94,13 @@ static inline int apicid_to_node(int logical_apicid) | |||
91 | /* Mapping from cpu number to logical apicid */ | 94 | /* Mapping from cpu number to logical apicid */ |
92 | static inline int cpu_to_logical_apicid(int cpu) | 95 | static inline int cpu_to_logical_apicid(int cpu) |
93 | { | 96 | { |
97 | #ifdef CONFIG_SMP | ||
94 | if (cpu >= NR_CPUS) | 98 | if (cpu >= NR_CPUS) |
95 | return BAD_APICID; | 99 | return BAD_APICID; |
96 | return (int)cpu_2_logical_apicid[cpu]; | 100 | return (int)cpu_2_logical_apicid[cpu]; |
101 | #else | ||
102 | return logical_smp_processor_id(); | ||
103 | #endif | ||
97 | } | 104 | } |
98 | 105 | ||
99 | static inline int cpu_present_to_apicid(int mps_cpu) | 106 | static inline int cpu_present_to_apicid(int mps_cpu) |
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index 142d10e34ade..f87826039a51 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h | |||
@@ -80,17 +80,11 @@ static inline int hard_smp_processor_id(void) | |||
80 | return GET_APIC_ID(*(unsigned long *)(APIC_BASE+APIC_ID)); | 80 | return GET_APIC_ID(*(unsigned long *)(APIC_BASE+APIC_ID)); |
81 | } | 81 | } |
82 | #endif | 82 | #endif |
83 | |||
84 | static __inline int logical_smp_processor_id(void) | ||
85 | { | ||
86 | /* we don't want to mark this access volatile - bad code generation */ | ||
87 | return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR)); | ||
88 | } | ||
89 | |||
90 | #endif | 83 | #endif |
91 | 84 | ||
92 | extern int __cpu_disable(void); | 85 | extern int __cpu_disable(void); |
93 | extern void __cpu_die(unsigned int cpu); | 86 | extern void __cpu_die(unsigned int cpu); |
87 | |||
94 | #endif /* !__ASSEMBLY__ */ | 88 | #endif /* !__ASSEMBLY__ */ |
95 | 89 | ||
96 | #else /* CONFIG_SMP */ | 90 | #else /* CONFIG_SMP */ |
@@ -100,4 +94,15 @@ extern void __cpu_die(unsigned int cpu); | |||
100 | #define NO_PROC_ID 0xFF /* No processor magic marker */ | 94 | #define NO_PROC_ID 0xFF /* No processor magic marker */ |
101 | 95 | ||
102 | #endif | 96 | #endif |
97 | |||
98 | #ifndef __ASSEMBLY__ | ||
99 | #ifdef CONFIG_X86_LOCAL_APIC | ||
100 | static __inline int logical_smp_processor_id(void) | ||
101 | { | ||
102 | /* we don't want to mark this access volatile - bad code generation */ | ||
103 | return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR)); | ||
104 | } | ||
105 | #endif | ||
106 | #endif | ||
107 | |||
103 | #endif | 108 | #endif |