diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/kernel/apic_32.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/apic_64.c | 26 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/Makefile | 4 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/amd.c | 42 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/amd_64.c | 211 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/bugs_64.c (renamed from arch/x86/kernel/bugs_64.c) | 0 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/centaur_64.c | 43 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/cpu.h | 5 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel_64.c | 103 | ||||
-rw-r--r-- | arch/x86/kernel/mmconf-fam10h_64.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/process.c | 190 | ||||
-rw-r--r-- | arch/x86/kernel/process_32.c | 61 | ||||
-rw-r--r-- | arch/x86/kernel/process_64.c | 35 | ||||
-rw-r--r-- | arch/x86/kernel/setup_64.c | 450 | ||||
-rw-r--r-- | arch/x86/kernel/vmlinux_64.lds.S | 1 | ||||
-rw-r--r-- | arch/x86/pci/Makefile_32 | 1 | ||||
-rw-r--r-- | arch/x86/pci/Makefile_64 | 2 | ||||
-rw-r--r-- | arch/x86/pci/amd_bus.c (renamed from arch/x86/pci/k8-bus_64.c) | 32 | ||||
-rw-r--r-- | arch/x86/pci/direct.c | 25 | ||||
-rw-r--r-- | arch/x86/pci/pci.h | 1 |
21 files changed, 666 insertions, 573 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 77807d4769c9..3a2a54c950ff 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -25,7 +25,6 @@ obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o setup64.o | |||
25 | obj-y += bootflag.o e820_$(BITS).o | 25 | obj-y += bootflag.o e820_$(BITS).o |
26 | obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o | 26 | obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o |
27 | obj-y += alternative.o i8253.o pci-nommu.o | 27 | obj-y += alternative.o i8253.o pci-nommu.o |
28 | obj-$(CONFIG_X86_64) += bugs_64.o | ||
29 | obj-y += tsc_$(BITS).o io_delay.o rtc.o | 28 | obj-y += tsc_$(BITS).o io_delay.o rtc.o |
30 | 29 | ||
31 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o | 30 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o |
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c index 4b99b1bdeb6c..c44206e731d4 100644 --- a/arch/x86/kernel/apic_32.c +++ b/arch/x86/kernel/apic_32.c | |||
@@ -64,9 +64,8 @@ static int enable_local_apic __initdata; | |||
64 | 64 | ||
65 | /* Local APIC timer verification ok */ | 65 | /* Local APIC timer verification ok */ |
66 | static int local_apic_timer_verify_ok; | 66 | static int local_apic_timer_verify_ok; |
67 | /* Disable local APIC timer from the kernel commandline or via dmi quirk | 67 | /* Disable local APIC timer from the kernel commandline or via dmi quirk */ |
68 | or using CPU MSR check */ | 68 | static int local_apic_timer_disabled; |
69 | int local_apic_timer_disabled; | ||
70 | /* Local APIC timer works in C2 */ | 69 | /* Local APIC timer works in C2 */ |
71 | int local_apic_timer_c2_ok; | 70 | int local_apic_timer_c2_ok; |
72 | EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); | 71 | EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); |
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c index 0633cfd0dc29..a5cc8447cf4d 100644 --- a/arch/x86/kernel/apic_64.c +++ b/arch/x86/kernel/apic_64.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include <mach_ipi.h> | 43 | #include <mach_ipi.h> |
44 | #include <mach_apic.h> | 44 | #include <mach_apic.h> |
45 | 45 | ||
46 | int disable_apic_timer __cpuinitdata; | 46 | static int disable_apic_timer __cpuinitdata; |
47 | static int apic_calibrate_pmtmr __initdata; | 47 | static int apic_calibrate_pmtmr __initdata; |
48 | int disable_apic; | 48 | int disable_apic; |
49 | 49 | ||
@@ -422,32 +422,8 @@ void __init setup_boot_APIC_clock(void) | |||
422 | setup_APIC_timer(); | 422 | setup_APIC_timer(); |
423 | } | 423 | } |
424 | 424 | ||
425 | /* | ||
426 | * AMD C1E enabled CPUs have a real nasty problem: Some BIOSes set the | ||
427 | * C1E flag only in the secondary CPU, so when we detect the wreckage | ||
428 | * we already have enabled the boot CPU local apic timer. Check, if | ||
429 | * disable_apic_timer is set and the DUMMY flag is cleared. If yes, | ||
430 | * set the DUMMY flag again and force the broadcast mode in the | ||
431 | * clockevents layer. | ||
432 | */ | ||
433 | static void __cpuinit check_boot_apic_timer_broadcast(void) | ||
434 | { | ||
435 | if (!disable_apic_timer || | ||
436 | (lapic_clockevent.features & CLOCK_EVT_FEAT_DUMMY)) | ||
437 | return; | ||
438 | |||
439 | printk(KERN_INFO "AMD C1E detected late. Force timer broadcast.\n"); | ||
440 | lapic_clockevent.features |= CLOCK_EVT_FEAT_DUMMY; | ||
441 | |||
442 | local_irq_enable(); | ||
443 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, | ||
444 | &boot_cpu_physical_apicid); | ||
445 | local_irq_disable(); | ||
446 | } | ||
447 | |||
448 | void __cpuinit setup_secondary_APIC_clock(void) | 425 | void __cpuinit setup_secondary_APIC_clock(void) |
449 | { | 426 | { |
450 | check_boot_apic_timer_broadcast(); | ||
451 | setup_APIC_timer(); | 427 | setup_APIC_timer(); |
452 | } | 428 | } |
453 | 429 | ||
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index a0c6f8190887..65b1be5fe9ce 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile | |||
@@ -6,11 +6,15 @@ obj-y := intel_cacheinfo.o addon_cpuid_features.o | |||
6 | obj-y += proc.o feature_names.o | 6 | obj-y += proc.o feature_names.o |
7 | 7 | ||
8 | obj-$(CONFIG_X86_32) += common.o bugs.o | 8 | obj-$(CONFIG_X86_32) += common.o bugs.o |
9 | obj-$(CONFIG_X86_64) += bugs_64.o | ||
9 | obj-$(CONFIG_X86_32) += amd.o | 10 | obj-$(CONFIG_X86_32) += amd.o |
11 | obj-$(CONFIG_X86_64) += amd_64.o | ||
10 | obj-$(CONFIG_X86_32) += cyrix.o | 12 | obj-$(CONFIG_X86_32) += cyrix.o |
11 | obj-$(CONFIG_X86_32) += centaur.o | 13 | obj-$(CONFIG_X86_32) += centaur.o |
14 | obj-$(CONFIG_X86_64) += centaur_64.o | ||
12 | obj-$(CONFIG_X86_32) += transmeta.o | 15 | obj-$(CONFIG_X86_32) += transmeta.o |
13 | obj-$(CONFIG_X86_32) += intel.o | 16 | obj-$(CONFIG_X86_32) += intel.o |
17 | obj-$(CONFIG_X86_64) += intel_64.o | ||
14 | obj-$(CONFIG_X86_32) += umc.o | 18 | obj-$(CONFIG_X86_32) += umc.o |
15 | 19 | ||
16 | obj-$(CONFIG_X86_MCE) += mcheck/ | 20 | obj-$(CONFIG_X86_MCE) += mcheck/ |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 245866828294..81a07ca65d44 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -24,43 +24,6 @@ | |||
24 | extern void vide(void); | 24 | extern void vide(void); |
25 | __asm__(".align 4\nvide: ret"); | 25 | __asm__(".align 4\nvide: ret"); |
26 | 26 | ||
27 | #ifdef CONFIG_X86_LOCAL_APIC | ||
28 | #define ENABLE_C1E_MASK 0x18000000 | ||
29 | #define CPUID_PROCESSOR_SIGNATURE 1 | ||
30 | #define CPUID_XFAM 0x0ff00000 | ||
31 | #define CPUID_XFAM_K8 0x00000000 | ||
32 | #define CPUID_XFAM_10H 0x00100000 | ||
33 | #define CPUID_XFAM_11H 0x00200000 | ||
34 | #define CPUID_XMOD 0x000f0000 | ||
35 | #define CPUID_XMOD_REV_F 0x00040000 | ||
36 | |||
37 | /* AMD systems with C1E don't have a working lAPIC timer. Check for that. */ | ||
38 | static __cpuinit int amd_apic_timer_broken(void) | ||
39 | { | ||
40 | u32 lo, hi; | ||
41 | u32 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); | ||
42 | switch (eax & CPUID_XFAM) { | ||
43 | case CPUID_XFAM_K8: | ||
44 | if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F) | ||
45 | break; | ||
46 | case CPUID_XFAM_10H: | ||
47 | case CPUID_XFAM_11H: | ||
48 | rdmsr(MSR_K8_ENABLE_C1E, lo, hi); | ||
49 | if (lo & ENABLE_C1E_MASK) { | ||
50 | if (smp_processor_id() != boot_cpu_physical_apicid) | ||
51 | printk(KERN_INFO "AMD C1E detected late. " | ||
52 | " Force timer broadcast.\n"); | ||
53 | return 1; | ||
54 | } | ||
55 | break; | ||
56 | default: | ||
57 | /* err on the side of caution */ | ||
58 | return 1; | ||
59 | } | ||
60 | return 0; | ||
61 | } | ||
62 | #endif | ||
63 | |||
64 | int force_mwait __cpuinitdata; | 27 | int force_mwait __cpuinitdata; |
65 | 28 | ||
66 | static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) | 29 | static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) |
@@ -297,11 +260,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
297 | num_cache_leaves = 3; | 260 | num_cache_leaves = 3; |
298 | } | 261 | } |
299 | 262 | ||
300 | #ifdef CONFIG_X86_LOCAL_APIC | ||
301 | if (amd_apic_timer_broken()) | ||
302 | local_apic_timer_disabled = 1; | ||
303 | #endif | ||
304 | |||
305 | /* K6s reports MCEs but don't actually have all the MSRs */ | 263 | /* K6s reports MCEs but don't actually have all the MSRs */ |
306 | if (c->x86 < 6) | 264 | if (c->x86 < 6) |
307 | clear_cpu_cap(c, X86_FEATURE_MCE); | 265 | clear_cpu_cap(c, X86_FEATURE_MCE); |
diff --git a/arch/x86/kernel/cpu/amd_64.c b/arch/x86/kernel/cpu/amd_64.c new file mode 100644 index 000000000000..30b7557c9641 --- /dev/null +++ b/arch/x86/kernel/cpu/amd_64.c | |||
@@ -0,0 +1,211 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/mm.h> | ||
3 | |||
4 | #include <asm/numa_64.h> | ||
5 | #include <asm/mmconfig.h> | ||
6 | #include <asm/cacheflush.h> | ||
7 | |||
8 | #include <mach_apic.h> | ||
9 | |||
10 | #include "cpu.h" | ||
11 | |||
12 | int force_mwait __cpuinitdata; | ||
13 | |||
14 | #ifdef CONFIG_NUMA | ||
15 | static int __cpuinit nearby_node(int apicid) | ||
16 | { | ||
17 | int i, node; | ||
18 | |||
19 | for (i = apicid - 1; i >= 0; i--) { | ||
20 | node = apicid_to_node[i]; | ||
21 | if (node != NUMA_NO_NODE && node_online(node)) | ||
22 | return node; | ||
23 | } | ||
24 | for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) { | ||
25 | node = apicid_to_node[i]; | ||
26 | if (node != NUMA_NO_NODE && node_online(node)) | ||
27 | return node; | ||
28 | } | ||
29 | return first_node(node_online_map); /* Shouldn't happen */ | ||
30 | } | ||
31 | #endif | ||
32 | |||
33 | /* | ||
34 | * On a AMD dual core setup the lower bits of the APIC id distingush the cores. | ||
35 | * Assumes number of cores is a power of two. | ||
36 | */ | ||
37 | static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c) | ||
38 | { | ||
39 | #ifdef CONFIG_SMP | ||
40 | unsigned bits; | ||
41 | #ifdef CONFIG_NUMA | ||
42 | int cpu = smp_processor_id(); | ||
43 | int node = 0; | ||
44 | unsigned apicid = hard_smp_processor_id(); | ||
45 | #endif | ||
46 | bits = c->x86_coreid_bits; | ||
47 | |||
48 | /* Low order bits define the core id (index of core in socket) */ | ||
49 | c->cpu_core_id = c->initial_apicid & ((1 << bits)-1); | ||
50 | /* Convert the initial APIC ID into the socket ID */ | ||
51 | c->phys_proc_id = c->initial_apicid >> bits; | ||
52 | |||
53 | #ifdef CONFIG_NUMA | ||
54 | node = c->phys_proc_id; | ||
55 | if (apicid_to_node[apicid] != NUMA_NO_NODE) | ||
56 | node = apicid_to_node[apicid]; | ||
57 | if (!node_online(node)) { | ||
58 | /* Two possibilities here: | ||
59 | - The CPU is missing memory and no node was created. | ||
60 | In that case try picking one from a nearby CPU | ||
61 | - The APIC IDs differ from the HyperTransport node IDs | ||
62 | which the K8 northbridge parsing fills in. | ||
63 | Assume they are all increased by a constant offset, | ||
64 | but in the same order as the HT nodeids. | ||
65 | If that doesn't result in a usable node fall back to the | ||
66 | path for the previous case. */ | ||
67 | |||
68 | int ht_nodeid = c->initial_apicid; | ||
69 | |||
70 | if (ht_nodeid >= 0 && | ||
71 | apicid_to_node[ht_nodeid] != NUMA_NO_NODE) | ||
72 | node = apicid_to_node[ht_nodeid]; | ||
73 | /* Pick a nearby node */ | ||
74 | if (!node_online(node)) | ||
75 | node = nearby_node(apicid); | ||
76 | } | ||
77 | numa_set_node(cpu, node); | ||
78 | |||
79 | printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); | ||
80 | #endif | ||
81 | #endif | ||
82 | } | ||
83 | |||
84 | static void __cpuinit early_init_amd_mc(struct cpuinfo_x86 *c) | ||
85 | { | ||
86 | #ifdef CONFIG_SMP | ||
87 | unsigned bits, ecx; | ||
88 | |||
89 | /* Multi core CPU? */ | ||
90 | if (c->extended_cpuid_level < 0x80000008) | ||
91 | return; | ||
92 | |||
93 | ecx = cpuid_ecx(0x80000008); | ||
94 | |||
95 | c->x86_max_cores = (ecx & 0xff) + 1; | ||
96 | |||
97 | /* CPU telling us the core id bits shift? */ | ||
98 | bits = (ecx >> 12) & 0xF; | ||
99 | |||
100 | /* Otherwise recompute */ | ||
101 | if (bits == 0) { | ||
102 | while ((1 << bits) < c->x86_max_cores) | ||
103 | bits++; | ||
104 | } | ||
105 | |||
106 | c->x86_coreid_bits = bits; | ||
107 | |||
108 | #endif | ||
109 | } | ||
110 | |||
111 | static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) | ||
112 | { | ||
113 | early_init_amd_mc(c); | ||
114 | |||
115 | /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */ | ||
116 | if (c->x86_power & (1<<8)) | ||
117 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | ||
118 | } | ||
119 | |||
120 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) | ||
121 | { | ||
122 | unsigned level; | ||
123 | |||
124 | #ifdef CONFIG_SMP | ||
125 | unsigned long value; | ||
126 | |||
127 | /* | ||
128 | * Disable TLB flush filter by setting HWCR.FFDIS on K8 | ||
129 | * bit 6 of msr C001_0015 | ||
130 | * | ||
131 | * Errata 63 for SH-B3 steppings | ||
132 | * Errata 122 for all steppings (F+ have it disabled by default) | ||
133 | */ | ||
134 | if (c->x86 == 15) { | ||
135 | rdmsrl(MSR_K8_HWCR, value); | ||
136 | value |= 1 << 6; | ||
137 | wrmsrl(MSR_K8_HWCR, value); | ||
138 | } | ||
139 | #endif | ||
140 | |||
141 | /* Bit 31 in normal CPUID used for nonstandard 3DNow ID; | ||
142 | 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */ | ||
143 | clear_cpu_cap(c, 0*32+31); | ||
144 | |||
145 | /* On C+ stepping K8 rep microcode works well for copy/memset */ | ||
146 | level = cpuid_eax(1); | ||
147 | if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || | ||
148 | level >= 0x0f58)) | ||
149 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | ||
150 | if (c->x86 == 0x10 || c->x86 == 0x11) | ||
151 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | ||
152 | |||
153 | /* Enable workaround for FXSAVE leak */ | ||
154 | if (c->x86 >= 6) | ||
155 | set_cpu_cap(c, X86_FEATURE_FXSAVE_LEAK); | ||
156 | |||
157 | level = get_model_name(c); | ||
158 | if (!level) { | ||
159 | switch (c->x86) { | ||
160 | case 15: | ||
161 | /* Should distinguish Models here, but this is only | ||
162 | a fallback anyways. */ | ||
163 | strcpy(c->x86_model_id, "Hammer"); | ||
164 | break; | ||
165 | } | ||
166 | } | ||
167 | display_cacheinfo(c); | ||
168 | |||
169 | /* Multi core CPU? */ | ||
170 | if (c->extended_cpuid_level >= 0x80000008) | ||
171 | amd_detect_cmp(c); | ||
172 | |||
173 | if (c->extended_cpuid_level >= 0x80000006 && | ||
174 | (cpuid_edx(0x80000006) & 0xf000)) | ||
175 | num_cache_leaves = 4; | ||
176 | else | ||
177 | num_cache_leaves = 3; | ||
178 | |||
179 | if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x11) | ||
180 | set_cpu_cap(c, X86_FEATURE_K8); | ||
181 | |||
182 | /* MFENCE stops RDTSC speculation */ | ||
183 | set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC); | ||
184 | |||
185 | if (c->x86 == 0x10) | ||
186 | fam10h_check_enable_mmcfg(); | ||
187 | |||
188 | if (c == &boot_cpu_data && c->x86 >= 0xf && c->x86 <= 0x11) { | ||
189 | unsigned long long tseg; | ||
190 | |||
191 | /* | ||
192 | * Split up direct mapping around the TSEG SMM area. | ||
193 | * Don't do it for gbpages because there seems very little | ||
194 | * benefit in doing so. | ||
195 | */ | ||
196 | if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg) && | ||
197 | (tseg >> PMD_SHIFT) < | ||
198 | (max_pfn_mapped >> (PMD_SHIFT-PAGE_SHIFT))) | ||
199 | set_memory_4k((unsigned long)__va(tseg), 1); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | static struct cpu_dev amd_cpu_dev __cpuinitdata = { | ||
204 | .c_vendor = "AMD", | ||
205 | .c_ident = { "AuthenticAMD" }, | ||
206 | .c_early_init = early_init_amd, | ||
207 | .c_init = init_amd, | ||
208 | }; | ||
209 | |||
210 | cpu_vendor_dev_register(X86_VENDOR_AMD, &amd_cpu_dev); | ||
211 | |||
diff --git a/arch/x86/kernel/bugs_64.c b/arch/x86/kernel/cpu/bugs_64.c index 9a3ed0649d4e..9a3ed0649d4e 100644 --- a/arch/x86/kernel/bugs_64.c +++ b/arch/x86/kernel/cpu/bugs_64.c | |||
diff --git a/arch/x86/kernel/cpu/centaur_64.c b/arch/x86/kernel/cpu/centaur_64.c new file mode 100644 index 000000000000..13526fd5cce1 --- /dev/null +++ b/arch/x86/kernel/cpu/centaur_64.c | |||
@@ -0,0 +1,43 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/smp.h> | ||
3 | |||
4 | #include <asm/cpufeature.h> | ||
5 | #include <asm/processor.h> | ||
6 | |||
7 | #include "cpu.h" | ||
8 | |||
9 | static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c) | ||
10 | { | ||
11 | if (c->x86 == 0x6 && c->x86_model >= 0xf) | ||
12 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | ||
13 | } | ||
14 | |||
15 | static void __cpuinit init_centaur(struct cpuinfo_x86 *c) | ||
16 | { | ||
17 | /* Cache sizes */ | ||
18 | unsigned n; | ||
19 | |||
20 | n = c->extended_cpuid_level; | ||
21 | if (n >= 0x80000008) { | ||
22 | unsigned eax = cpuid_eax(0x80000008); | ||
23 | c->x86_virt_bits = (eax >> 8) & 0xff; | ||
24 | c->x86_phys_bits = eax & 0xff; | ||
25 | } | ||
26 | |||
27 | if (c->x86 == 0x6 && c->x86_model >= 0xf) { | ||
28 | c->x86_cache_alignment = c->x86_clflush_size * 2; | ||
29 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | ||
30 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | ||
31 | } | ||
32 | set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); | ||
33 | } | ||
34 | |||
35 | static struct cpu_dev centaur_cpu_dev __cpuinitdata = { | ||
36 | .c_vendor = "Centaur", | ||
37 | .c_ident = { "CentaurHauls" }, | ||
38 | .c_early_init = early_init_centaur, | ||
39 | .c_init = init_centaur, | ||
40 | }; | ||
41 | |||
42 | cpu_vendor_dev_register(X86_VENDOR_CENTAUR, ¢aur_cpu_dev); | ||
43 | |||
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 783691b2a738..4d894e8565fe 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h | |||
@@ -1,3 +1,6 @@ | |||
1 | #ifndef ARCH_X86_CPU_H | ||
2 | |||
3 | #define ARCH_X86_CPU_H | ||
1 | 4 | ||
2 | struct cpu_model_info { | 5 | struct cpu_model_info { |
3 | int vendor; | 6 | int vendor; |
@@ -36,3 +39,5 @@ extern struct cpu_vendor_dev __x86cpuvendor_start[], __x86cpuvendor_end[]; | |||
36 | 39 | ||
37 | extern int get_model_name(struct cpuinfo_x86 *c); | 40 | extern int get_model_name(struct cpuinfo_x86 *c); |
38 | extern void display_cacheinfo(struct cpuinfo_x86 *c); | 41 | extern void display_cacheinfo(struct cpuinfo_x86 *c); |
42 | |||
43 | #endif | ||
diff --git a/arch/x86/kernel/cpu/intel_64.c b/arch/x86/kernel/cpu/intel_64.c new file mode 100644 index 000000000000..fcb1cc9d75ca --- /dev/null +++ b/arch/x86/kernel/cpu/intel_64.c | |||
@@ -0,0 +1,103 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/smp.h> | ||
3 | #include <asm/processor.h> | ||
4 | #include <asm/ptrace.h> | ||
5 | #include <asm/topology.h> | ||
6 | #include <asm/numa_64.h> | ||
7 | |||
8 | #include "cpu.h" | ||
9 | |||
10 | static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) | ||
11 | { | ||
12 | if ((c->x86 == 0xf && c->x86_model >= 0x03) || | ||
13 | (c->x86 == 0x6 && c->x86_model >= 0x0e)) | ||
14 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | ||
15 | } | ||
16 | |||
17 | /* | ||
18 | * find out the number of processor cores on the die | ||
19 | */ | ||
20 | static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c) | ||
21 | { | ||
22 | unsigned int eax, t; | ||
23 | |||
24 | if (c->cpuid_level < 4) | ||
25 | return 1; | ||
26 | |||
27 | cpuid_count(4, 0, &eax, &t, &t, &t); | ||
28 | |||
29 | if (eax & 0x1f) | ||
30 | return ((eax >> 26) + 1); | ||
31 | else | ||
32 | return 1; | ||
33 | } | ||
34 | |||
35 | static void __cpuinit srat_detect_node(void) | ||
36 | { | ||
37 | #ifdef CONFIG_NUMA | ||
38 | unsigned node; | ||
39 | int cpu = smp_processor_id(); | ||
40 | int apicid = hard_smp_processor_id(); | ||
41 | |||
42 | /* Don't do the funky fallback heuristics the AMD version employs | ||
43 | for now. */ | ||
44 | node = apicid_to_node[apicid]; | ||
45 | if (node == NUMA_NO_NODE || !node_online(node)) | ||
46 | node = first_node(node_online_map); | ||
47 | numa_set_node(cpu, node); | ||
48 | |||
49 | printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); | ||
50 | #endif | ||
51 | } | ||
52 | |||
53 | static void __cpuinit init_intel(struct cpuinfo_x86 *c) | ||
54 | { | ||
55 | /* Cache sizes */ | ||
56 | unsigned n; | ||
57 | |||
58 | init_intel_cacheinfo(c); | ||
59 | if (c->cpuid_level > 9) { | ||
60 | unsigned eax = cpuid_eax(10); | ||
61 | /* Check for version and the number of counters */ | ||
62 | if ((eax & 0xff) && (((eax>>8) & 0xff) > 1)) | ||
63 | set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON); | ||
64 | } | ||
65 | |||
66 | if (cpu_has_ds) { | ||
67 | unsigned int l1, l2; | ||
68 | rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); | ||
69 | if (!(l1 & (1<<11))) | ||
70 | set_cpu_cap(c, X86_FEATURE_BTS); | ||
71 | if (!(l1 & (1<<12))) | ||
72 | set_cpu_cap(c, X86_FEATURE_PEBS); | ||
73 | } | ||
74 | |||
75 | |||
76 | if (cpu_has_bts) | ||
77 | ds_init_intel(c); | ||
78 | |||
79 | n = c->extended_cpuid_level; | ||
80 | if (n >= 0x80000008) { | ||
81 | unsigned eax = cpuid_eax(0x80000008); | ||
82 | c->x86_virt_bits = (eax >> 8) & 0xff; | ||
83 | c->x86_phys_bits = eax & 0xff; | ||
84 | } | ||
85 | |||
86 | if (c->x86 == 15) | ||
87 | c->x86_cache_alignment = c->x86_clflush_size * 2; | ||
88 | if (c->x86 == 6) | ||
89 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | ||
90 | set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); | ||
91 | c->x86_max_cores = intel_num_cpu_cores(c); | ||
92 | |||
93 | srat_detect_node(); | ||
94 | } | ||
95 | |||
96 | static struct cpu_dev intel_cpu_dev __cpuinitdata = { | ||
97 | .c_vendor = "Intel", | ||
98 | .c_ident = { "GenuineIntel" }, | ||
99 | .c_early_init = early_init_intel, | ||
100 | .c_init = init_intel, | ||
101 | }; | ||
102 | cpu_vendor_dev_register(X86_VENDOR_INTEL, &intel_cpu_dev); | ||
103 | |||
diff --git a/arch/x86/kernel/mmconf-fam10h_64.c b/arch/x86/kernel/mmconf-fam10h_64.c index edc5fbfe85c0..fdfdc550b366 100644 --- a/arch/x86/kernel/mmconf-fam10h_64.c +++ b/arch/x86/kernel/mmconf-fam10h_64.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <asm/io.h> | 12 | #include <asm/io.h> |
13 | #include <asm/msr.h> | 13 | #include <asm/msr.h> |
14 | #include <asm/acpi.h> | 14 | #include <asm/acpi.h> |
15 | #include <asm/mmconfig.h> | ||
15 | 16 | ||
16 | #include "../pci/pci.h" | 17 | #include "../pci/pci.h" |
17 | 18 | ||
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index ba370dc8685b..4061d63aabe7 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/sched.h> | 6 | #include <linux/sched.h> |
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/pm.h> | 8 | #include <linux/pm.h> |
9 | #include <linux/clockchips.h> | ||
9 | 10 | ||
10 | struct kmem_cache *task_xstate_cachep; | 11 | struct kmem_cache *task_xstate_cachep; |
11 | 12 | ||
@@ -45,6 +46,76 @@ void arch_task_cache_init(void) | |||
45 | SLAB_PANIC, NULL); | 46 | SLAB_PANIC, NULL); |
46 | } | 47 | } |
47 | 48 | ||
49 | /* | ||
50 | * Idle related variables and functions | ||
51 | */ | ||
52 | unsigned long boot_option_idle_override = 0; | ||
53 | EXPORT_SYMBOL(boot_option_idle_override); | ||
54 | |||
55 | /* | ||
56 | * Powermanagement idle function, if any.. | ||
57 | */ | ||
58 | void (*pm_idle)(void); | ||
59 | EXPORT_SYMBOL(pm_idle); | ||
60 | |||
61 | #ifdef CONFIG_X86_32 | ||
62 | /* | ||
63 | * This halt magic was a workaround for ancient floppy DMA | ||
64 | * wreckage. It should be safe to remove. | ||
65 | */ | ||
66 | static int hlt_counter; | ||
67 | void disable_hlt(void) | ||
68 | { | ||
69 | hlt_counter++; | ||
70 | } | ||
71 | EXPORT_SYMBOL(disable_hlt); | ||
72 | |||
73 | void enable_hlt(void) | ||
74 | { | ||
75 | hlt_counter--; | ||
76 | } | ||
77 | EXPORT_SYMBOL(enable_hlt); | ||
78 | |||
79 | static inline int hlt_use_halt(void) | ||
80 | { | ||
81 | return (!hlt_counter && boot_cpu_data.hlt_works_ok); | ||
82 | } | ||
83 | #else | ||
84 | static inline int hlt_use_halt(void) | ||
85 | { | ||
86 | return 1; | ||
87 | } | ||
88 | #endif | ||
89 | |||
90 | /* | ||
91 | * We use this if we don't have any better | ||
92 | * idle routine.. | ||
93 | */ | ||
94 | void default_idle(void) | ||
95 | { | ||
96 | if (hlt_use_halt()) { | ||
97 | current_thread_info()->status &= ~TS_POLLING; | ||
98 | /* | ||
99 | * TS_POLLING-cleared state must be visible before we | ||
100 | * test NEED_RESCHED: | ||
101 | */ | ||
102 | smp_mb(); | ||
103 | |||
104 | if (!need_resched()) | ||
105 | safe_halt(); /* enables interrupts racelessly */ | ||
106 | else | ||
107 | local_irq_enable(); | ||
108 | current_thread_info()->status |= TS_POLLING; | ||
109 | } else { | ||
110 | local_irq_enable(); | ||
111 | /* loop is done by the caller */ | ||
112 | cpu_relax(); | ||
113 | } | ||
114 | } | ||
115 | #ifdef CONFIG_APM_MODULE | ||
116 | EXPORT_SYMBOL(default_idle); | ||
117 | #endif | ||
118 | |||
48 | static void do_nothing(void *unused) | 119 | static void do_nothing(void *unused) |
49 | { | 120 | { |
50 | } | 121 | } |
@@ -122,44 +193,129 @@ static void poll_idle(void) | |||
122 | * | 193 | * |
123 | * idle=mwait overrides this decision and forces the usage of mwait. | 194 | * idle=mwait overrides this decision and forces the usage of mwait. |
124 | */ | 195 | */ |
196 | |||
197 | #define MWAIT_INFO 0x05 | ||
198 | #define MWAIT_ECX_EXTENDED_INFO 0x01 | ||
199 | #define MWAIT_EDX_C1 0xf0 | ||
200 | |||
125 | static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c) | 201 | static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c) |
126 | { | 202 | { |
203 | u32 eax, ebx, ecx, edx; | ||
204 | |||
127 | if (force_mwait) | 205 | if (force_mwait) |
128 | return 1; | 206 | return 1; |
129 | 207 | ||
130 | if (c->x86_vendor == X86_VENDOR_AMD) { | 208 | if (c->cpuid_level < MWAIT_INFO) |
131 | switch(c->x86) { | 209 | return 0; |
132 | case 0x10: | 210 | |
133 | case 0x11: | 211 | cpuid(MWAIT_INFO, &eax, &ebx, &ecx, &edx); |
134 | return 0; | 212 | /* Check, whether EDX has extended info about MWAIT */ |
135 | } | 213 | if (!(ecx & MWAIT_ECX_EXTENDED_INFO)) |
136 | } | 214 | return 1; |
215 | |||
216 | /* | ||
217 | * edx enumeratios MONITOR/MWAIT extensions. Check, whether | ||
218 | * C1 supports MWAIT | ||
219 | */ | ||
220 | return (edx & MWAIT_EDX_C1); | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * Check for AMD CPUs, which have potentially C1E support | ||
225 | */ | ||
226 | static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c) | ||
227 | { | ||
228 | if (c->x86_vendor != X86_VENDOR_AMD) | ||
229 | return 0; | ||
230 | |||
231 | if (c->x86 < 0x0F) | ||
232 | return 0; | ||
233 | |||
234 | /* Family 0x0f models < rev F do not have C1E */ | ||
235 | if (c->x86 == 0x0f && c->x86_model < 0x40) | ||
236 | return 0; | ||
237 | |||
137 | return 1; | 238 | return 1; |
138 | } | 239 | } |
139 | 240 | ||
140 | void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) | 241 | /* |
242 | * C1E aware idle routine. We check for C1E active in the interrupt | ||
243 | * pending message MSR. If we detect C1E, then we handle it the same | ||
244 | * way as C3 power states (local apic timer and TSC stop) | ||
245 | */ | ||
246 | static void c1e_idle(void) | ||
141 | { | 247 | { |
142 | static int selected; | 248 | static cpumask_t c1e_mask = CPU_MASK_NONE; |
249 | static int c1e_detected; | ||
143 | 250 | ||
144 | if (selected) | 251 | if (need_resched()) |
145 | return; | 252 | return; |
253 | |||
254 | if (!c1e_detected) { | ||
255 | u32 lo, hi; | ||
256 | |||
257 | rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi); | ||
258 | if (lo & K8_INTP_C1E_ACTIVE_MASK) { | ||
259 | c1e_detected = 1; | ||
260 | mark_tsc_unstable("TSC halt in C1E"); | ||
261 | printk(KERN_INFO "System has C1E enabled\n"); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | if (c1e_detected) { | ||
266 | int cpu = smp_processor_id(); | ||
267 | |||
268 | if (!cpu_isset(cpu, c1e_mask)) { | ||
269 | cpu_set(cpu, c1e_mask); | ||
270 | /* | ||
271 | * Force broadcast so ACPI can not interfere. Needs | ||
272 | * to run with interrupts enabled as it uses | ||
273 | * smp_function_call. | ||
274 | */ | ||
275 | local_irq_enable(); | ||
276 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_FORCE, | ||
277 | &cpu); | ||
278 | printk(KERN_INFO "Switch to broadcast mode on CPU%d\n", | ||
279 | cpu); | ||
280 | local_irq_disable(); | ||
281 | } | ||
282 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); | ||
283 | |||
284 | default_idle(); | ||
285 | |||
286 | /* | ||
287 | * The switch back from broadcast mode needs to be | ||
288 | * called with interrupts disabled. | ||
289 | */ | ||
290 | local_irq_disable(); | ||
291 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); | ||
292 | local_irq_enable(); | ||
293 | } else | ||
294 | default_idle(); | ||
295 | } | ||
296 | |||
297 | void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) | ||
298 | { | ||
146 | #ifdef CONFIG_X86_SMP | 299 | #ifdef CONFIG_X86_SMP |
147 | if (pm_idle == poll_idle && smp_num_siblings > 1) { | 300 | if (pm_idle == poll_idle && smp_num_siblings > 1) { |
148 | printk(KERN_WARNING "WARNING: polling idle and HT enabled," | 301 | printk(KERN_WARNING "WARNING: polling idle and HT enabled," |
149 | " performance may degrade.\n"); | 302 | " performance may degrade.\n"); |
150 | } | 303 | } |
151 | #endif | 304 | #endif |
305 | if (pm_idle) | ||
306 | return; | ||
307 | |||
152 | if (cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)) { | 308 | if (cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)) { |
153 | /* | 309 | /* |
154 | * Skip, if setup has overridden idle. | ||
155 | * One CPU supports mwait => All CPUs supports mwait | 310 | * One CPU supports mwait => All CPUs supports mwait |
156 | */ | 311 | */ |
157 | if (!pm_idle) { | 312 | printk(KERN_INFO "using mwait in idle threads.\n"); |
158 | printk(KERN_INFO "using mwait in idle threads.\n"); | 313 | pm_idle = mwait_idle; |
159 | pm_idle = mwait_idle; | 314 | } else if (check_c1e_idle(c)) { |
160 | } | 315 | printk(KERN_INFO "using C1E aware idle routine\n"); |
161 | } | 316 | pm_idle = c1e_idle; |
162 | selected = 1; | 317 | } else |
318 | pm_idle = default_idle; | ||
163 | } | 319 | } |
164 | 320 | ||
165 | static int __init idle_setup(char *str) | 321 | static int __init idle_setup(char *str) |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index e2db9ac5c61c..c2a11d77b1b5 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -58,11 +58,6 @@ | |||
58 | 58 | ||
59 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 59 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
60 | 60 | ||
61 | static int hlt_counter; | ||
62 | |||
63 | unsigned long boot_option_idle_override = 0; | ||
64 | EXPORT_SYMBOL(boot_option_idle_override); | ||
65 | |||
66 | DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; | 61 | DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; |
67 | EXPORT_PER_CPU_SYMBOL(current_task); | 62 | EXPORT_PER_CPU_SYMBOL(current_task); |
68 | 63 | ||
@@ -77,55 +72,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk) | |||
77 | return ((unsigned long *)tsk->thread.sp)[3]; | 72 | return ((unsigned long *)tsk->thread.sp)[3]; |
78 | } | 73 | } |
79 | 74 | ||
80 | /* | ||
81 | * Powermanagement idle function, if any.. | ||
82 | */ | ||
83 | void (*pm_idle)(void); | ||
84 | EXPORT_SYMBOL(pm_idle); | ||
85 | |||
86 | void disable_hlt(void) | ||
87 | { | ||
88 | hlt_counter++; | ||
89 | } | ||
90 | |||
91 | EXPORT_SYMBOL(disable_hlt); | ||
92 | |||
93 | void enable_hlt(void) | ||
94 | { | ||
95 | hlt_counter--; | ||
96 | } | ||
97 | |||
98 | EXPORT_SYMBOL(enable_hlt); | ||
99 | |||
100 | /* | ||
101 | * We use this if we don't have any better | ||
102 | * idle routine.. | ||
103 | */ | ||
104 | void default_idle(void) | ||
105 | { | ||
106 | if (!hlt_counter && boot_cpu_data.hlt_works_ok) { | ||
107 | current_thread_info()->status &= ~TS_POLLING; | ||
108 | /* | ||
109 | * TS_POLLING-cleared state must be visible before we | ||
110 | * test NEED_RESCHED: | ||
111 | */ | ||
112 | smp_mb(); | ||
113 | |||
114 | if (!need_resched()) | ||
115 | safe_halt(); /* enables interrupts racelessly */ | ||
116 | else | ||
117 | local_irq_enable(); | ||
118 | current_thread_info()->status |= TS_POLLING; | ||
119 | } else { | ||
120 | local_irq_enable(); | ||
121 | /* loop is done by the caller */ | ||
122 | cpu_relax(); | ||
123 | } | ||
124 | } | ||
125 | #ifdef CONFIG_APM_MODULE | ||
126 | EXPORT_SYMBOL(default_idle); | ||
127 | #endif | ||
128 | |||
129 | #ifdef CONFIG_HOTPLUG_CPU | 75 | #ifdef CONFIG_HOTPLUG_CPU |
130 | #include <asm/nmi.h> | 76 | #include <asm/nmi.h> |
131 | /* We don't actually take CPU down, just spin without interrupts. */ | 77 | /* We don't actually take CPU down, just spin without interrupts. */ |
@@ -168,24 +114,19 @@ void cpu_idle(void) | |||
168 | while (1) { | 114 | while (1) { |
169 | tick_nohz_stop_sched_tick(); | 115 | tick_nohz_stop_sched_tick(); |
170 | while (!need_resched()) { | 116 | while (!need_resched()) { |
171 | void (*idle)(void); | ||
172 | 117 | ||
173 | check_pgt_cache(); | 118 | check_pgt_cache(); |
174 | rmb(); | 119 | rmb(); |
175 | idle = pm_idle; | ||
176 | 120 | ||
177 | if (rcu_pending(cpu)) | 121 | if (rcu_pending(cpu)) |
178 | rcu_check_callbacks(cpu, 0); | 122 | rcu_check_callbacks(cpu, 0); |
179 | 123 | ||
180 | if (!idle) | ||
181 | idle = default_idle; | ||
182 | |||
183 | if (cpu_is_offline(cpu)) | 124 | if (cpu_is_offline(cpu)) |
184 | play_dead(); | 125 | play_dead(); |
185 | 126 | ||
186 | local_irq_disable(); | 127 | local_irq_disable(); |
187 | __get_cpu_var(irq_stat).idle_timestamp = jiffies; | 128 | __get_cpu_var(irq_stat).idle_timestamp = jiffies; |
188 | idle(); | 129 | pm_idle(); |
189 | } | 130 | } |
190 | tick_nohz_restart_sched_tick(); | 131 | tick_nohz_restart_sched_tick(); |
191 | preempt_enable_no_resched(); | 132 | preempt_enable_no_resched(); |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index c6eb5c91e5f6..290183e9731a 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -56,15 +56,6 @@ asmlinkage extern void ret_from_fork(void); | |||
56 | 56 | ||
57 | unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; | 57 | unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; |
58 | 58 | ||
59 | unsigned long boot_option_idle_override = 0; | ||
60 | EXPORT_SYMBOL(boot_option_idle_override); | ||
61 | |||
62 | /* | ||
63 | * Powermanagement idle function, if any.. | ||
64 | */ | ||
65 | void (*pm_idle)(void); | ||
66 | EXPORT_SYMBOL(pm_idle); | ||
67 | |||
68 | static ATOMIC_NOTIFIER_HEAD(idle_notifier); | 59 | static ATOMIC_NOTIFIER_HEAD(idle_notifier); |
69 | 60 | ||
70 | void idle_notifier_register(struct notifier_block *n) | 61 | void idle_notifier_register(struct notifier_block *n) |
@@ -94,25 +85,6 @@ void exit_idle(void) | |||
94 | __exit_idle(); | 85 | __exit_idle(); |
95 | } | 86 | } |
96 | 87 | ||
97 | /* | ||
98 | * We use this if we don't have any better | ||
99 | * idle routine.. | ||
100 | */ | ||
101 | void default_idle(void) | ||
102 | { | ||
103 | current_thread_info()->status &= ~TS_POLLING; | ||
104 | /* | ||
105 | * TS_POLLING-cleared state must be visible before we | ||
106 | * test NEED_RESCHED: | ||
107 | */ | ||
108 | smp_mb(); | ||
109 | if (!need_resched()) | ||
110 | safe_halt(); /* enables interrupts racelessly */ | ||
111 | else | ||
112 | local_irq_enable(); | ||
113 | current_thread_info()->status |= TS_POLLING; | ||
114 | } | ||
115 | |||
116 | #ifdef CONFIG_HOTPLUG_CPU | 88 | #ifdef CONFIG_HOTPLUG_CPU |
117 | DECLARE_PER_CPU(int, cpu_state); | 89 | DECLARE_PER_CPU(int, cpu_state); |
118 | 90 | ||
@@ -150,12 +122,9 @@ void cpu_idle(void) | |||
150 | while (1) { | 122 | while (1) { |
151 | tick_nohz_stop_sched_tick(); | 123 | tick_nohz_stop_sched_tick(); |
152 | while (!need_resched()) { | 124 | while (!need_resched()) { |
153 | void (*idle)(void); | ||
154 | 125 | ||
155 | rmb(); | 126 | rmb(); |
156 | idle = pm_idle; | 127 | |
157 | if (!idle) | ||
158 | idle = default_idle; | ||
159 | if (cpu_is_offline(smp_processor_id())) | 128 | if (cpu_is_offline(smp_processor_id())) |
160 | play_dead(); | 129 | play_dead(); |
161 | /* | 130 | /* |
@@ -165,7 +134,7 @@ void cpu_idle(void) | |||
165 | */ | 134 | */ |
166 | local_irq_disable(); | 135 | local_irq_disable(); |
167 | enter_idle(); | 136 | enter_idle(); |
168 | idle(); | 137 | pm_idle(); |
169 | /* In many cases the interrupt that ended idle | 138 | /* In many cases the interrupt that ended idle |
170 | has already called exit_idle. But some idle | 139 | has already called exit_idle. But some idle |
171 | loops can be woken up without interrupt. */ | 140 | loops can be woken up without interrupt. */ |
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index 6dff1286ad8a..b789ec599923 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c | |||
@@ -71,6 +71,7 @@ | |||
71 | #include <asm/topology.h> | 71 | #include <asm/topology.h> |
72 | #include <asm/trampoline.h> | 72 | #include <asm/trampoline.h> |
73 | #include <asm/pat.h> | 73 | #include <asm/pat.h> |
74 | #include <asm/mmconfig.h> | ||
74 | 75 | ||
75 | #include <mach_apic.h> | 76 | #include <mach_apic.h> |
76 | #ifdef CONFIG_PARAVIRT | 77 | #ifdef CONFIG_PARAVIRT |
@@ -79,6 +80,8 @@ | |||
79 | #define ARCH_SETUP | 80 | #define ARCH_SETUP |
80 | #endif | 81 | #endif |
81 | 82 | ||
83 | #include "cpu/cpu.h" | ||
84 | |||
82 | /* | 85 | /* |
83 | * Machine setup.. | 86 | * Machine setup.. |
84 | */ | 87 | */ |
@@ -95,8 +98,6 @@ int bootloader_type; | |||
95 | 98 | ||
96 | unsigned long saved_video_mode; | 99 | unsigned long saved_video_mode; |
97 | 100 | ||
98 | int force_mwait __cpuinitdata; | ||
99 | |||
100 | /* | 101 | /* |
101 | * Early DMI memory | 102 | * Early DMI memory |
102 | */ | 103 | */ |
@@ -164,6 +165,7 @@ static struct resource bss_resource = { | |||
164 | .flags = IORESOURCE_RAM, | 165 | .flags = IORESOURCE_RAM, |
165 | }; | 166 | }; |
166 | 167 | ||
168 | static void __init early_cpu_init(void); | ||
167 | static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c); | 169 | static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c); |
168 | 170 | ||
169 | #ifdef CONFIG_PROC_VMCORE | 171 | #ifdef CONFIG_PROC_VMCORE |
@@ -293,18 +295,6 @@ static void __init parse_setup_data(void) | |||
293 | } | 295 | } |
294 | } | 296 | } |
295 | 297 | ||
296 | #ifdef CONFIG_PCI_MMCONFIG | ||
297 | extern void __cpuinit fam10h_check_enable_mmcfg(void); | ||
298 | extern void __init check_enable_amd_mmconf_dmi(void); | ||
299 | #else | ||
300 | void __cpuinit fam10h_check_enable_mmcfg(void) | ||
301 | { | ||
302 | } | ||
303 | void __init check_enable_amd_mmconf_dmi(void) | ||
304 | { | ||
305 | } | ||
306 | #endif | ||
307 | |||
308 | /* | 298 | /* |
309 | * setup_arch - architecture-specific boot-time initializations | 299 | * setup_arch - architecture-specific boot-time initializations |
310 | * | 300 | * |
@@ -352,6 +342,7 @@ void __init setup_arch(char **cmdline_p) | |||
352 | bss_resource.start = virt_to_phys(&__bss_start); | 342 | bss_resource.start = virt_to_phys(&__bss_start); |
353 | bss_resource.end = virt_to_phys(&__bss_stop)-1; | 343 | bss_resource.end = virt_to_phys(&__bss_stop)-1; |
354 | 344 | ||
345 | early_cpu_init(); | ||
355 | early_identify_cpu(&boot_cpu_data); | 346 | early_identify_cpu(&boot_cpu_data); |
356 | 347 | ||
357 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); | 348 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); |
@@ -537,7 +528,20 @@ void __init setup_arch(char **cmdline_p) | |||
537 | check_enable_amd_mmconf_dmi(); | 528 | check_enable_amd_mmconf_dmi(); |
538 | } | 529 | } |
539 | 530 | ||
540 | static int __cpuinit get_model_name(struct cpuinfo_x86 *c) | 531 | struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {}; |
532 | |||
533 | static void __cpuinit default_init(struct cpuinfo_x86 *c) | ||
534 | { | ||
535 | display_cacheinfo(c); | ||
536 | } | ||
537 | |||
538 | static struct cpu_dev __cpuinitdata default_cpu = { | ||
539 | .c_init = default_init, | ||
540 | .c_vendor = "Unknown", | ||
541 | }; | ||
542 | static struct cpu_dev *this_cpu __cpuinitdata = &default_cpu; | ||
543 | |||
544 | int __cpuinit get_model_name(struct cpuinfo_x86 *c) | ||
541 | { | 545 | { |
542 | unsigned int *v; | 546 | unsigned int *v; |
543 | 547 | ||
@@ -553,7 +557,7 @@ static int __cpuinit get_model_name(struct cpuinfo_x86 *c) | |||
553 | } | 557 | } |
554 | 558 | ||
555 | 559 | ||
556 | static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) | 560 | void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) |
557 | { | 561 | { |
558 | unsigned int n, dummy, eax, ebx, ecx, edx; | 562 | unsigned int n, dummy, eax, ebx, ecx, edx; |
559 | 563 | ||
@@ -585,228 +589,6 @@ static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) | |||
585 | } | 589 | } |
586 | } | 590 | } |
587 | 591 | ||
588 | #ifdef CONFIG_NUMA | ||
589 | static int __cpuinit nearby_node(int apicid) | ||
590 | { | ||
591 | int i, node; | ||
592 | |||
593 | for (i = apicid - 1; i >= 0; i--) { | ||
594 | node = apicid_to_node[i]; | ||
595 | if (node != NUMA_NO_NODE && node_online(node)) | ||
596 | return node; | ||
597 | } | ||
598 | for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) { | ||
599 | node = apicid_to_node[i]; | ||
600 | if (node != NUMA_NO_NODE && node_online(node)) | ||
601 | return node; | ||
602 | } | ||
603 | return first_node(node_online_map); /* Shouldn't happen */ | ||
604 | } | ||
605 | #endif | ||
606 | |||
607 | /* | ||
608 | * On a AMD dual core setup the lower bits of the APIC id distingush the cores. | ||
609 | * Assumes number of cores is a power of two. | ||
610 | */ | ||
611 | static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c) | ||
612 | { | ||
613 | #ifdef CONFIG_SMP | ||
614 | unsigned bits; | ||
615 | #ifdef CONFIG_NUMA | ||
616 | int cpu = smp_processor_id(); | ||
617 | int node = 0; | ||
618 | unsigned apicid = hard_smp_processor_id(); | ||
619 | #endif | ||
620 | bits = c->x86_coreid_bits; | ||
621 | |||
622 | /* Low order bits define the core id (index of core in socket) */ | ||
623 | c->cpu_core_id = c->initial_apicid & ((1 << bits)-1); | ||
624 | /* Convert the initial APIC ID into the socket ID */ | ||
625 | c->phys_proc_id = c->initial_apicid >> bits; | ||
626 | |||
627 | #ifdef CONFIG_NUMA | ||
628 | node = c->phys_proc_id; | ||
629 | if (apicid_to_node[apicid] != NUMA_NO_NODE) | ||
630 | node = apicid_to_node[apicid]; | ||
631 | if (!node_online(node)) { | ||
632 | /* Two possibilities here: | ||
633 | - The CPU is missing memory and no node was created. | ||
634 | In that case try picking one from a nearby CPU | ||
635 | - The APIC IDs differ from the HyperTransport node IDs | ||
636 | which the K8 northbridge parsing fills in. | ||
637 | Assume they are all increased by a constant offset, | ||
638 | but in the same order as the HT nodeids. | ||
639 | If that doesn't result in a usable node fall back to the | ||
640 | path for the previous case. */ | ||
641 | |||
642 | int ht_nodeid = c->initial_apicid; | ||
643 | |||
644 | if (ht_nodeid >= 0 && | ||
645 | apicid_to_node[ht_nodeid] != NUMA_NO_NODE) | ||
646 | node = apicid_to_node[ht_nodeid]; | ||
647 | /* Pick a nearby node */ | ||
648 | if (!node_online(node)) | ||
649 | node = nearby_node(apicid); | ||
650 | } | ||
651 | numa_set_node(cpu, node); | ||
652 | |||
653 | printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); | ||
654 | #endif | ||
655 | #endif | ||
656 | } | ||
657 | |||
658 | static void __cpuinit early_init_amd_mc(struct cpuinfo_x86 *c) | ||
659 | { | ||
660 | #ifdef CONFIG_SMP | ||
661 | unsigned bits, ecx; | ||
662 | |||
663 | /* Multi core CPU? */ | ||
664 | if (c->extended_cpuid_level < 0x80000008) | ||
665 | return; | ||
666 | |||
667 | ecx = cpuid_ecx(0x80000008); | ||
668 | |||
669 | c->x86_max_cores = (ecx & 0xff) + 1; | ||
670 | |||
671 | /* CPU telling us the core id bits shift? */ | ||
672 | bits = (ecx >> 12) & 0xF; | ||
673 | |||
674 | /* Otherwise recompute */ | ||
675 | if (bits == 0) { | ||
676 | while ((1 << bits) < c->x86_max_cores) | ||
677 | bits++; | ||
678 | } | ||
679 | |||
680 | c->x86_coreid_bits = bits; | ||
681 | |||
682 | #endif | ||
683 | } | ||
684 | |||
685 | #define ENABLE_C1E_MASK 0x18000000 | ||
686 | #define CPUID_PROCESSOR_SIGNATURE 1 | ||
687 | #define CPUID_XFAM 0x0ff00000 | ||
688 | #define CPUID_XFAM_K8 0x00000000 | ||
689 | #define CPUID_XFAM_10H 0x00100000 | ||
690 | #define CPUID_XFAM_11H 0x00200000 | ||
691 | #define CPUID_XMOD 0x000f0000 | ||
692 | #define CPUID_XMOD_REV_F 0x00040000 | ||
693 | |||
694 | /* AMD systems with C1E don't have a working lAPIC timer. Check for that. */ | ||
695 | static __cpuinit int amd_apic_timer_broken(void) | ||
696 | { | ||
697 | u32 lo, hi, eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); | ||
698 | |||
699 | switch (eax & CPUID_XFAM) { | ||
700 | case CPUID_XFAM_K8: | ||
701 | if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F) | ||
702 | break; | ||
703 | case CPUID_XFAM_10H: | ||
704 | case CPUID_XFAM_11H: | ||
705 | rdmsr(MSR_K8_ENABLE_C1E, lo, hi); | ||
706 | if (lo & ENABLE_C1E_MASK) | ||
707 | return 1; | ||
708 | break; | ||
709 | default: | ||
710 | /* err on the side of caution */ | ||
711 | return 1; | ||
712 | } | ||
713 | return 0; | ||
714 | } | ||
715 | |||
716 | static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) | ||
717 | { | ||
718 | early_init_amd_mc(c); | ||
719 | |||
720 | /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */ | ||
721 | if (c->x86_power & (1<<8)) | ||
722 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | ||
723 | } | ||
724 | |||
725 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) | ||
726 | { | ||
727 | unsigned level; | ||
728 | |||
729 | #ifdef CONFIG_SMP | ||
730 | unsigned long value; | ||
731 | |||
732 | /* | ||
733 | * Disable TLB flush filter by setting HWCR.FFDIS on K8 | ||
734 | * bit 6 of msr C001_0015 | ||
735 | * | ||
736 | * Errata 63 for SH-B3 steppings | ||
737 | * Errata 122 for all steppings (F+ have it disabled by default) | ||
738 | */ | ||
739 | if (c->x86 == 15) { | ||
740 | rdmsrl(MSR_K8_HWCR, value); | ||
741 | value |= 1 << 6; | ||
742 | wrmsrl(MSR_K8_HWCR, value); | ||
743 | } | ||
744 | #endif | ||
745 | |||
746 | /* Bit 31 in normal CPUID used for nonstandard 3DNow ID; | ||
747 | 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */ | ||
748 | clear_cpu_cap(c, 0*32+31); | ||
749 | |||
750 | /* On C+ stepping K8 rep microcode works well for copy/memset */ | ||
751 | level = cpuid_eax(1); | ||
752 | if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || | ||
753 | level >= 0x0f58)) | ||
754 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | ||
755 | if (c->x86 == 0x10 || c->x86 == 0x11) | ||
756 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | ||
757 | |||
758 | /* Enable workaround for FXSAVE leak */ | ||
759 | if (c->x86 >= 6) | ||
760 | set_cpu_cap(c, X86_FEATURE_FXSAVE_LEAK); | ||
761 | |||
762 | level = get_model_name(c); | ||
763 | if (!level) { | ||
764 | switch (c->x86) { | ||
765 | case 15: | ||
766 | /* Should distinguish Models here, but this is only | ||
767 | a fallback anyways. */ | ||
768 | strcpy(c->x86_model_id, "Hammer"); | ||
769 | break; | ||
770 | } | ||
771 | } | ||
772 | display_cacheinfo(c); | ||
773 | |||
774 | /* Multi core CPU? */ | ||
775 | if (c->extended_cpuid_level >= 0x80000008) | ||
776 | amd_detect_cmp(c); | ||
777 | |||
778 | if (c->extended_cpuid_level >= 0x80000006 && | ||
779 | (cpuid_edx(0x80000006) & 0xf000)) | ||
780 | num_cache_leaves = 4; | ||
781 | else | ||
782 | num_cache_leaves = 3; | ||
783 | |||
784 | if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x11) | ||
785 | set_cpu_cap(c, X86_FEATURE_K8); | ||
786 | |||
787 | /* MFENCE stops RDTSC speculation */ | ||
788 | set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC); | ||
789 | |||
790 | if (c->x86 == 0x10) | ||
791 | fam10h_check_enable_mmcfg(); | ||
792 | |||
793 | if (amd_apic_timer_broken()) | ||
794 | disable_apic_timer = 1; | ||
795 | |||
796 | if (c == &boot_cpu_data && c->x86 >= 0xf && c->x86 <= 0x11) { | ||
797 | unsigned long long tseg; | ||
798 | |||
799 | /* | ||
800 | * Split up direct mapping around the TSEG SMM area. | ||
801 | * Don't do it for gbpages because there seems very little | ||
802 | * benefit in doing so. | ||
803 | */ | ||
804 | if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg) && | ||
805 | (tseg >> PMD_SHIFT) < (max_pfn_mapped >> (PMD_SHIFT-PAGE_SHIFT))) | ||
806 | set_memory_4k((unsigned long)__va(tseg), 1); | ||
807 | } | ||
808 | } | ||
809 | |||
810 | void __cpuinit detect_ht(struct cpuinfo_x86 *c) | 592 | void __cpuinit detect_ht(struct cpuinfo_x86 *c) |
811 | { | 593 | { |
812 | #ifdef CONFIG_SMP | 594 | #ifdef CONFIG_SMP |
@@ -857,135 +639,59 @@ out: | |||
857 | #endif | 639 | #endif |
858 | } | 640 | } |
859 | 641 | ||
860 | /* | 642 | static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) |
861 | * find out the number of processor cores on the die | ||
862 | */ | ||
863 | static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c) | ||
864 | { | ||
865 | unsigned int eax, t; | ||
866 | |||
867 | if (c->cpuid_level < 4) | ||
868 | return 1; | ||
869 | |||
870 | cpuid_count(4, 0, &eax, &t, &t, &t); | ||
871 | |||
872 | if (eax & 0x1f) | ||
873 | return ((eax >> 26) + 1); | ||
874 | else | ||
875 | return 1; | ||
876 | } | ||
877 | |||
878 | static void __cpuinit srat_detect_node(void) | ||
879 | { | ||
880 | #ifdef CONFIG_NUMA | ||
881 | unsigned node; | ||
882 | int cpu = smp_processor_id(); | ||
883 | int apicid = hard_smp_processor_id(); | ||
884 | |||
885 | /* Don't do the funky fallback heuristics the AMD version employs | ||
886 | for now. */ | ||
887 | node = apicid_to_node[apicid]; | ||
888 | if (node == NUMA_NO_NODE || !node_online(node)) | ||
889 | node = first_node(node_online_map); | ||
890 | numa_set_node(cpu, node); | ||
891 | |||
892 | printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); | ||
893 | #endif | ||
894 | } | ||
895 | |||
896 | static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) | ||
897 | { | ||
898 | if ((c->x86 == 0xf && c->x86_model >= 0x03) || | ||
899 | (c->x86 == 0x6 && c->x86_model >= 0x0e)) | ||
900 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | ||
901 | } | ||
902 | |||
903 | static void __cpuinit init_intel(struct cpuinfo_x86 *c) | ||
904 | { | 643 | { |
905 | /* Cache sizes */ | 644 | char *v = c->x86_vendor_id; |
906 | unsigned n; | 645 | int i; |
907 | 646 | static int printed; | |
908 | init_intel_cacheinfo(c); | 647 | |
909 | if (c->cpuid_level > 9) { | 648 | for (i = 0; i < X86_VENDOR_NUM; i++) { |
910 | unsigned eax = cpuid_eax(10); | 649 | if (cpu_devs[i]) { |
911 | /* Check for version and the number of counters */ | 650 | if (!strcmp(v, cpu_devs[i]->c_ident[0]) || |
912 | if ((eax & 0xff) && (((eax>>8) & 0xff) > 1)) | 651 | (cpu_devs[i]->c_ident[1] && |
913 | set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON); | 652 | !strcmp(v, cpu_devs[i]->c_ident[1]))) { |
653 | c->x86_vendor = i; | ||
654 | this_cpu = cpu_devs[i]; | ||
655 | return; | ||
656 | } | ||
657 | } | ||
914 | } | 658 | } |
915 | 659 | if (!printed) { | |
916 | if (cpu_has_ds) { | 660 | printed++; |
917 | unsigned int l1, l2; | 661 | printk(KERN_ERR "CPU: Vendor unknown, using generic init.\n"); |
918 | rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); | 662 | printk(KERN_ERR "CPU: Your system may be unstable.\n"); |
919 | if (!(l1 & (1<<11))) | ||
920 | set_cpu_cap(c, X86_FEATURE_BTS); | ||
921 | if (!(l1 & (1<<12))) | ||
922 | set_cpu_cap(c, X86_FEATURE_PEBS); | ||
923 | } | 663 | } |
924 | 664 | c->x86_vendor = X86_VENDOR_UNKNOWN; | |
925 | |||
926 | if (cpu_has_bts) | ||
927 | ds_init_intel(c); | ||
928 | |||
929 | n = c->extended_cpuid_level; | ||
930 | if (n >= 0x80000008) { | ||
931 | unsigned eax = cpuid_eax(0x80000008); | ||
932 | c->x86_virt_bits = (eax >> 8) & 0xff; | ||
933 | c->x86_phys_bits = eax & 0xff; | ||
934 | /* CPUID workaround for Intel 0F34 CPU */ | ||
935 | if (c->x86_vendor == X86_VENDOR_INTEL && | ||
936 | c->x86 == 0xF && c->x86_model == 0x3 && | ||
937 | c->x86_mask == 0x4) | ||
938 | c->x86_phys_bits = 36; | ||
939 | } | ||
940 | |||
941 | if (c->x86 == 15) | ||
942 | c->x86_cache_alignment = c->x86_clflush_size * 2; | ||
943 | if (c->x86 == 6) | ||
944 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | ||
945 | set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); | ||
946 | c->x86_max_cores = intel_num_cpu_cores(c); | ||
947 | |||
948 | srat_detect_node(); | ||
949 | } | ||
950 | |||
951 | static void __cpuinit early_init_centaur(struct cpuinfo_x86 *c) | ||
952 | { | ||
953 | if (c->x86 == 0x6 && c->x86_model >= 0xf) | ||
954 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | ||
955 | } | 665 | } |
956 | 666 | ||
957 | static void __cpuinit init_centaur(struct cpuinfo_x86 *c) | 667 | static void __init early_cpu_support_print(void) |
958 | { | 668 | { |
959 | /* Cache sizes */ | 669 | int i,j; |
960 | unsigned n; | 670 | struct cpu_dev *cpu_devx; |
961 | 671 | ||
962 | n = c->extended_cpuid_level; | 672 | printk("KERNEL supported cpus:\n"); |
963 | if (n >= 0x80000008) { | 673 | for (i = 0; i < X86_VENDOR_NUM; i++) { |
964 | unsigned eax = cpuid_eax(0x80000008); | 674 | cpu_devx = cpu_devs[i]; |
965 | c->x86_virt_bits = (eax >> 8) & 0xff; | 675 | if (!cpu_devx) |
966 | c->x86_phys_bits = eax & 0xff; | 676 | continue; |
967 | } | 677 | for (j = 0; j < 2; j++) { |
968 | 678 | if (!cpu_devx->c_ident[j]) | |
969 | if (c->x86 == 0x6 && c->x86_model >= 0xf) { | 679 | continue; |
970 | c->x86_cache_alignment = c->x86_clflush_size * 2; | 680 | printk(" %s %s\n", cpu_devx->c_vendor, |
971 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | 681 | cpu_devx->c_ident[j]); |
972 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | 682 | } |
973 | } | 683 | } |
974 | set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); | ||
975 | } | 684 | } |
976 | 685 | ||
977 | static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) | 686 | static void __init early_cpu_init(void) |
978 | { | 687 | { |
979 | char *v = c->x86_vendor_id; | 688 | struct cpu_vendor_dev *cvdev; |
980 | 689 | ||
981 | if (!strcmp(v, "AuthenticAMD")) | 690 | for (cvdev = __x86cpuvendor_start ; |
982 | c->x86_vendor = X86_VENDOR_AMD; | 691 | cvdev < __x86cpuvendor_end ; |
983 | else if (!strcmp(v, "GenuineIntel")) | 692 | cvdev++) |
984 | c->x86_vendor = X86_VENDOR_INTEL; | 693 | cpu_devs[cvdev->vendor] = cvdev->cpu_dev; |
985 | else if (!strcmp(v, "CentaurHauls")) | 694 | early_cpu_support_print(); |
986 | c->x86_vendor = X86_VENDOR_CENTAUR; | ||
987 | else | ||
988 | c->x86_vendor = X86_VENDOR_UNKNOWN; | ||
989 | } | 695 | } |
990 | 696 | ||
991 | /* Do some early cpuid on the boot CPU to get some parameter that are | 697 | /* Do some early cpuid on the boot CPU to get some parameter that are |
@@ -1066,17 +772,9 @@ static void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) | |||
1066 | if (c->extended_cpuid_level >= 0x80000007) | 772 | if (c->extended_cpuid_level >= 0x80000007) |
1067 | c->x86_power = cpuid_edx(0x80000007); | 773 | c->x86_power = cpuid_edx(0x80000007); |
1068 | 774 | ||
1069 | switch (c->x86_vendor) { | 775 | if (c->x86_vendor != X86_VENDOR_UNKNOWN && |
1070 | case X86_VENDOR_AMD: | 776 | cpu_devs[c->x86_vendor]->c_early_init) |
1071 | early_init_amd(c); | 777 | cpu_devs[c->x86_vendor]->c_early_init(c); |
1072 | break; | ||
1073 | case X86_VENDOR_INTEL: | ||
1074 | early_init_intel(c); | ||
1075 | break; | ||
1076 | case X86_VENDOR_CENTAUR: | ||
1077 | early_init_centaur(c); | ||
1078 | break; | ||
1079 | } | ||
1080 | 778 | ||
1081 | validate_pat_support(c); | 779 | validate_pat_support(c); |
1082 | } | 780 | } |
@@ -1104,24 +802,8 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
1104 | * At the end of this section, c->x86_capability better | 802 | * At the end of this section, c->x86_capability better |
1105 | * indicate the features this CPU genuinely supports! | 803 | * indicate the features this CPU genuinely supports! |
1106 | */ | 804 | */ |
1107 | switch (c->x86_vendor) { | 805 | if (this_cpu->c_init) |
1108 | case X86_VENDOR_AMD: | 806 | this_cpu->c_init(c); |
1109 | init_amd(c); | ||
1110 | break; | ||
1111 | |||
1112 | case X86_VENDOR_INTEL: | ||
1113 | init_intel(c); | ||
1114 | break; | ||
1115 | |||
1116 | case X86_VENDOR_CENTAUR: | ||
1117 | init_centaur(c); | ||
1118 | break; | ||
1119 | |||
1120 | case X86_VENDOR_UNKNOWN: | ||
1121 | default: | ||
1122 | display_cacheinfo(c); | ||
1123 | break; | ||
1124 | } | ||
1125 | 807 | ||
1126 | detect_ht(c); | 808 | detect_ht(c); |
1127 | 809 | ||
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S index fad3674b06a5..b29f63bdff5e 100644 --- a/arch/x86/kernel/vmlinux_64.lds.S +++ b/arch/x86/kernel/vmlinux_64.lds.S | |||
@@ -177,6 +177,7 @@ SECTIONS | |||
177 | *(.con_initcall.init) | 177 | *(.con_initcall.init) |
178 | } | 178 | } |
179 | __con_initcall_end = .; | 179 | __con_initcall_end = .; |
180 | . = ALIGN(16); | ||
180 | __x86cpuvendor_start = .; | 181 | __x86cpuvendor_start = .; |
181 | .x86cpuvendor.init : AT(ADDR(.x86cpuvendor.init) - LOAD_OFFSET) { | 182 | .x86cpuvendor.init : AT(ADDR(.x86cpuvendor.init) - LOAD_OFFSET) { |
182 | *(.x86cpuvendor.init) | 183 | *(.x86cpuvendor.init) |
diff --git a/arch/x86/pci/Makefile_32 b/arch/x86/pci/Makefile_32 index 89ec35d00efd..f647e7e56da4 100644 --- a/arch/x86/pci/Makefile_32 +++ b/arch/x86/pci/Makefile_32 | |||
@@ -22,3 +22,4 @@ pci-$(CONFIG_X86_NUMAQ) := numa.o irq.o | |||
22 | pci-$(CONFIG_NUMA) += mp_bus_to_node.o | 22 | pci-$(CONFIG_NUMA) += mp_bus_to_node.o |
23 | 23 | ||
24 | obj-y += $(pci-y) common.o early.o | 24 | obj-y += $(pci-y) common.o early.o |
25 | obj-y += amd_bus.o | ||
diff --git a/arch/x86/pci/Makefile_64 b/arch/x86/pci/Makefile_64 index 8fbd19832cf6..fd47068c95de 100644 --- a/arch/x86/pci/Makefile_64 +++ b/arch/x86/pci/Makefile_64 | |||
@@ -13,5 +13,5 @@ obj-y += legacy.o irq.o common.o early.o | |||
13 | # mmconfig has a 64bit special | 13 | # mmconfig has a 64bit special |
14 | obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o | 14 | obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o |
15 | 15 | ||
16 | obj-y += k8-bus_64.o | 16 | obj-y += amd_bus.o |
17 | 17 | ||
diff --git a/arch/x86/pci/k8-bus_64.c b/arch/x86/pci/amd_bus.c index 5c2799c20e47..15f505d3a78e 100644 --- a/arch/x86/pci/k8-bus_64.c +++ b/arch/x86/pci/amd_bus.c | |||
@@ -1,5 +1,9 @@ | |||
1 | #include <linux/init.h> | 1 | #include <linux/init.h> |
2 | #include <linux/pci.h> | 2 | #include <linux/pci.h> |
3 | #include "pci.h" | ||
4 | |||
5 | #ifdef CONFIG_X86_64 | ||
6 | |||
3 | #include <asm/pci-direct.h> | 7 | #include <asm/pci-direct.h> |
4 | #include <asm/mpspec.h> | 8 | #include <asm/mpspec.h> |
5 | #include <linux/cpumask.h> | 9 | #include <linux/cpumask.h> |
@@ -526,3 +530,31 @@ static int __init early_fill_mp_bus_info(void) | |||
526 | } | 530 | } |
527 | 531 | ||
528 | postcore_initcall(early_fill_mp_bus_info); | 532 | postcore_initcall(early_fill_mp_bus_info); |
533 | |||
534 | #endif | ||
535 | |||
536 | /* common 32/64 bit code */ | ||
537 | |||
538 | #define ENABLE_CF8_EXT_CFG (1ULL << 46) | ||
539 | |||
540 | static void enable_pci_io_ecs_per_cpu(void *unused) | ||
541 | { | ||
542 | u64 reg; | ||
543 | rdmsrl(MSR_AMD64_NB_CFG, reg); | ||
544 | if (!(reg & ENABLE_CF8_EXT_CFG)) { | ||
545 | reg |= ENABLE_CF8_EXT_CFG; | ||
546 | wrmsrl(MSR_AMD64_NB_CFG, reg); | ||
547 | } | ||
548 | } | ||
549 | |||
550 | static int __init enable_pci_io_ecs(void) | ||
551 | { | ||
552 | /* assume all cpus from fam10h have IO ECS */ | ||
553 | if (boot_cpu_data.x86 < 0x10) | ||
554 | return 0; | ||
555 | on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1, 1); | ||
556 | pci_probe |= PCI_HAS_IO_ECS; | ||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | postcore_initcall(enable_pci_io_ecs); | ||
diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c index 21d1e0e0d535..9915293500fb 100644 --- a/arch/x86/pci/direct.c +++ b/arch/x86/pci/direct.c | |||
@@ -8,18 +8,21 @@ | |||
8 | #include "pci.h" | 8 | #include "pci.h" |
9 | 9 | ||
10 | /* | 10 | /* |
11 | * Functions for accessing PCI configuration space with type 1 accesses | 11 | * Functions for accessing PCI base (first 256 bytes) and extended |
12 | * (4096 bytes per PCI function) configuration space with type 1 | ||
13 | * accesses. | ||
12 | */ | 14 | */ |
13 | 15 | ||
14 | #define PCI_CONF1_ADDRESS(bus, devfn, reg) \ | 16 | #define PCI_CONF1_ADDRESS(bus, devfn, reg) \ |
15 | (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) | 17 | (0x80000000 | ((reg & 0xF00) << 16) | (bus << 16) \ |
18 | | (devfn << 8) | (reg & 0xFC)) | ||
16 | 19 | ||
17 | static int pci_conf1_read(unsigned int seg, unsigned int bus, | 20 | static int pci_conf1_read(unsigned int seg, unsigned int bus, |
18 | unsigned int devfn, int reg, int len, u32 *value) | 21 | unsigned int devfn, int reg, int len, u32 *value) |
19 | { | 22 | { |
20 | unsigned long flags; | 23 | unsigned long flags; |
21 | 24 | ||
22 | if ((bus > 255) || (devfn > 255) || (reg > 255)) { | 25 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) { |
23 | *value = -1; | 26 | *value = -1; |
24 | return -EINVAL; | 27 | return -EINVAL; |
25 | } | 28 | } |
@@ -50,7 +53,7 @@ static int pci_conf1_write(unsigned int seg, unsigned int bus, | |||
50 | { | 53 | { |
51 | unsigned long flags; | 54 | unsigned long flags; |
52 | 55 | ||
53 | if ((bus > 255) || (devfn > 255) || (reg > 255)) | 56 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) |
54 | return -EINVAL; | 57 | return -EINVAL; |
55 | 58 | ||
56 | spin_lock_irqsave(&pci_config_lock, flags); | 59 | spin_lock_irqsave(&pci_config_lock, flags); |
@@ -260,10 +263,18 @@ void __init pci_direct_init(int type) | |||
260 | return; | 263 | return; |
261 | printk(KERN_INFO "PCI: Using configuration type %d for base access\n", | 264 | printk(KERN_INFO "PCI: Using configuration type %d for base access\n", |
262 | type); | 265 | type); |
263 | if (type == 1) | 266 | if (type == 1) { |
264 | raw_pci_ops = &pci_direct_conf1; | 267 | raw_pci_ops = &pci_direct_conf1; |
265 | else | 268 | if (raw_pci_ext_ops) |
266 | raw_pci_ops = &pci_direct_conf2; | 269 | return; |
270 | if (!(pci_probe & PCI_HAS_IO_ECS)) | ||
271 | return; | ||
272 | printk(KERN_INFO "PCI: Using configuration type 1 " | ||
273 | "for extended access\n"); | ||
274 | raw_pci_ext_ops = &pci_direct_conf1; | ||
275 | return; | ||
276 | } | ||
277 | raw_pci_ops = &pci_direct_conf2; | ||
267 | } | 278 | } |
268 | 279 | ||
269 | int __init pci_direct_probe(void) | 280 | int __init pci_direct_probe(void) |
diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h index 720c4c554534..ba263e626a68 100644 --- a/arch/x86/pci/pci.h +++ b/arch/x86/pci/pci.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #define PCI_CAN_SKIP_ISA_ALIGN 0x8000 | 27 | #define PCI_CAN_SKIP_ISA_ALIGN 0x8000 |
28 | #define PCI_USE__CRS 0x10000 | 28 | #define PCI_USE__CRS 0x10000 |
29 | #define PCI_CHECK_ENABLE_AMD_MMCONF 0x20000 | 29 | #define PCI_CHECK_ENABLE_AMD_MMCONF 0x20000 |
30 | #define PCI_HAS_IO_ECS 0x40000 | ||
30 | 31 | ||
31 | extern unsigned int pci_probe; | 32 | extern unsigned int pci_probe; |
32 | extern unsigned long pirq_table_addr; | 33 | extern unsigned long pirq_table_addr; |