diff options
author | Dave Jones <davej@redhat.com> | 2008-05-22 18:48:32 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-05-30 18:46:29 -0400 |
commit | 4d285878564bb46cf64e54be18eeffe33ca583a0 (patch) | |
tree | e2705f008ef505ee550bd85e82546ef6d2dc7246 /arch/x86 | |
parent | d364319b989967b74e57fef5c8017fd56a16c392 (diff) |
x86: Move the AMD64 specific parts out of setup_64.c
Create a separate amd_64.c file in the cpu/ dir for
the useful parts to live in.
Signed-off-by: Dave Jones <davej@redhat.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/cpu/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/amd_64.c | 235 | ||||
-rw-r--r-- | arch/x86/kernel/setup_64.c | 232 |
3 files changed, 242 insertions, 226 deletions
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index a0c6f8190887..ef065c1a2e1a 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile | |||
@@ -7,6 +7,7 @@ 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_32) += amd.o | 9 | obj-$(CONFIG_X86_32) += amd.o |
10 | obj-$(CONFIG_X86_64) += amd_64.o | ||
10 | obj-$(CONFIG_X86_32) += cyrix.o | 11 | obj-$(CONFIG_X86_32) += cyrix.o |
11 | obj-$(CONFIG_X86_32) += centaur.o | 12 | obj-$(CONFIG_X86_32) += centaur.o |
12 | obj-$(CONFIG_X86_32) += transmeta.o | 13 | obj-$(CONFIG_X86_32) += transmeta.o |
diff --git a/arch/x86/kernel/cpu/amd_64.c b/arch/x86/kernel/cpu/amd_64.c new file mode 100644 index 000000000000..1746f6f95726 --- /dev/null +++ b/arch/x86/kernel/cpu/amd_64.c | |||
@@ -0,0 +1,235 @@ | |||
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 | extern int __cpuinit get_model_name(struct cpuinfo_x86 *c); | ||
11 | extern void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c); | ||
12 | |||
13 | int force_mwait __cpuinitdata; | ||
14 | |||
15 | #ifdef CONFIG_NUMA | ||
16 | static int __cpuinit nearby_node(int apicid) | ||
17 | { | ||
18 | int i, node; | ||
19 | |||
20 | for (i = apicid - 1; i >= 0; i--) { | ||
21 | node = apicid_to_node[i]; | ||
22 | if (node != NUMA_NO_NODE && node_online(node)) | ||
23 | return node; | ||
24 | } | ||
25 | for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) { | ||
26 | node = apicid_to_node[i]; | ||
27 | if (node != NUMA_NO_NODE && node_online(node)) | ||
28 | return node; | ||
29 | } | ||
30 | return first_node(node_online_map); /* Shouldn't happen */ | ||
31 | } | ||
32 | #endif | ||
33 | |||
34 | /* | ||
35 | * On a AMD dual core setup the lower bits of the APIC id distingush the cores. | ||
36 | * Assumes number of cores is a power of two. | ||
37 | */ | ||
38 | static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c) | ||
39 | { | ||
40 | #ifdef CONFIG_SMP | ||
41 | unsigned bits; | ||
42 | #ifdef CONFIG_NUMA | ||
43 | int cpu = smp_processor_id(); | ||
44 | int node = 0; | ||
45 | unsigned apicid = hard_smp_processor_id(); | ||
46 | #endif | ||
47 | bits = c->x86_coreid_bits; | ||
48 | |||
49 | /* Low order bits define the core id (index of core in socket) */ | ||
50 | c->cpu_core_id = c->initial_apicid & ((1 << bits)-1); | ||
51 | /* Convert the initial APIC ID into the socket ID */ | ||
52 | c->phys_proc_id = c->initial_apicid >> bits; | ||
53 | |||
54 | #ifdef CONFIG_NUMA | ||
55 | node = c->phys_proc_id; | ||
56 | if (apicid_to_node[apicid] != NUMA_NO_NODE) | ||
57 | node = apicid_to_node[apicid]; | ||
58 | if (!node_online(node)) { | ||
59 | /* Two possibilities here: | ||
60 | - The CPU is missing memory and no node was created. | ||
61 | In that case try picking one from a nearby CPU | ||
62 | - The APIC IDs differ from the HyperTransport node IDs | ||
63 | which the K8 northbridge parsing fills in. | ||
64 | Assume they are all increased by a constant offset, | ||
65 | but in the same order as the HT nodeids. | ||
66 | If that doesn't result in a usable node fall back to the | ||
67 | path for the previous case. */ | ||
68 | |||
69 | int ht_nodeid = c->initial_apicid; | ||
70 | |||
71 | if (ht_nodeid >= 0 && | ||
72 | apicid_to_node[ht_nodeid] != NUMA_NO_NODE) | ||
73 | node = apicid_to_node[ht_nodeid]; | ||
74 | /* Pick a nearby node */ | ||
75 | if (!node_online(node)) | ||
76 | node = nearby_node(apicid); | ||
77 | } | ||
78 | numa_set_node(cpu, node); | ||
79 | |||
80 | printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); | ||
81 | #endif | ||
82 | #endif | ||
83 | } | ||
84 | |||
85 | static void __cpuinit early_init_amd_mc(struct cpuinfo_x86 *c) | ||
86 | { | ||
87 | #ifdef CONFIG_SMP | ||
88 | unsigned bits, ecx; | ||
89 | |||
90 | /* Multi core CPU? */ | ||
91 | if (c->extended_cpuid_level < 0x80000008) | ||
92 | return; | ||
93 | |||
94 | ecx = cpuid_ecx(0x80000008); | ||
95 | |||
96 | c->x86_max_cores = (ecx & 0xff) + 1; | ||
97 | |||
98 | /* CPU telling us the core id bits shift? */ | ||
99 | bits = (ecx >> 12) & 0xF; | ||
100 | |||
101 | /* Otherwise recompute */ | ||
102 | if (bits == 0) { | ||
103 | while ((1 << bits) < c->x86_max_cores) | ||
104 | bits++; | ||
105 | } | ||
106 | |||
107 | c->x86_coreid_bits = bits; | ||
108 | |||
109 | #endif | ||
110 | } | ||
111 | |||
112 | #define ENABLE_C1E_MASK 0x18000000 | ||
113 | #define CPUID_PROCESSOR_SIGNATURE 1 | ||
114 | #define CPUID_XFAM 0x0ff00000 | ||
115 | #define CPUID_XFAM_K8 0x00000000 | ||
116 | #define CPUID_XFAM_10H 0x00100000 | ||
117 | #define CPUID_XFAM_11H 0x00200000 | ||
118 | #define CPUID_XMOD 0x000f0000 | ||
119 | #define CPUID_XMOD_REV_F 0x00040000 | ||
120 | |||
121 | /* AMD systems with C1E don't have a working lAPIC timer. Check for that. */ | ||
122 | static __cpuinit int amd_apic_timer_broken(void) | ||
123 | { | ||
124 | u32 lo, hi, eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); | ||
125 | |||
126 | switch (eax & CPUID_XFAM) { | ||
127 | case CPUID_XFAM_K8: | ||
128 | if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F) | ||
129 | break; | ||
130 | case CPUID_XFAM_10H: | ||
131 | case CPUID_XFAM_11H: | ||
132 | rdmsr(MSR_K8_ENABLE_C1E, lo, hi); | ||
133 | if (lo & ENABLE_C1E_MASK) | ||
134 | return 1; | ||
135 | break; | ||
136 | default: | ||
137 | /* err on the side of caution */ | ||
138 | return 1; | ||
139 | } | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | void __cpuinit early_init_amd(struct cpuinfo_x86 *c) | ||
144 | { | ||
145 | early_init_amd_mc(c); | ||
146 | |||
147 | /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */ | ||
148 | if (c->x86_power & (1<<8)) | ||
149 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | ||
150 | } | ||
151 | |||
152 | void __cpuinit init_amd(struct cpuinfo_x86 *c) | ||
153 | { | ||
154 | unsigned level; | ||
155 | |||
156 | #ifdef CONFIG_SMP | ||
157 | unsigned long value; | ||
158 | |||
159 | /* | ||
160 | * Disable TLB flush filter by setting HWCR.FFDIS on K8 | ||
161 | * bit 6 of msr C001_0015 | ||
162 | * | ||
163 | * Errata 63 for SH-B3 steppings | ||
164 | * Errata 122 for all steppings (F+ have it disabled by default) | ||
165 | */ | ||
166 | if (c->x86 == 15) { | ||
167 | rdmsrl(MSR_K8_HWCR, value); | ||
168 | value |= 1 << 6; | ||
169 | wrmsrl(MSR_K8_HWCR, value); | ||
170 | } | ||
171 | #endif | ||
172 | |||
173 | /* Bit 31 in normal CPUID used for nonstandard 3DNow ID; | ||
174 | 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */ | ||
175 | clear_cpu_cap(c, 0*32+31); | ||
176 | |||
177 | /* On C+ stepping K8 rep microcode works well for copy/memset */ | ||
178 | level = cpuid_eax(1); | ||
179 | if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || | ||
180 | level >= 0x0f58)) | ||
181 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | ||
182 | if (c->x86 == 0x10 || c->x86 == 0x11) | ||
183 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | ||
184 | |||
185 | /* Enable workaround for FXSAVE leak */ | ||
186 | if (c->x86 >= 6) | ||
187 | set_cpu_cap(c, X86_FEATURE_FXSAVE_LEAK); | ||
188 | |||
189 | level = get_model_name(c); | ||
190 | if (!level) { | ||
191 | switch (c->x86) { | ||
192 | case 15: | ||
193 | /* Should distinguish Models here, but this is only | ||
194 | a fallback anyways. */ | ||
195 | strcpy(c->x86_model_id, "Hammer"); | ||
196 | break; | ||
197 | } | ||
198 | } | ||
199 | display_cacheinfo(c); | ||
200 | |||
201 | /* Multi core CPU? */ | ||
202 | if (c->extended_cpuid_level >= 0x80000008) | ||
203 | amd_detect_cmp(c); | ||
204 | |||
205 | if (c->extended_cpuid_level >= 0x80000006 && | ||
206 | (cpuid_edx(0x80000006) & 0xf000)) | ||
207 | num_cache_leaves = 4; | ||
208 | else | ||
209 | num_cache_leaves = 3; | ||
210 | |||
211 | if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x11) | ||
212 | set_cpu_cap(c, X86_FEATURE_K8); | ||
213 | |||
214 | /* MFENCE stops RDTSC speculation */ | ||
215 | set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC); | ||
216 | |||
217 | if (c->x86 == 0x10) | ||
218 | fam10h_check_enable_mmcfg(); | ||
219 | |||
220 | if (amd_apic_timer_broken()) | ||
221 | disable_apic_timer = 1; | ||
222 | |||
223 | if (c == &boot_cpu_data && c->x86 >= 0xf && c->x86 <= 0x11) { | ||
224 | unsigned long long tseg; | ||
225 | |||
226 | /* | ||
227 | * Split up direct mapping around the TSEG SMM area. | ||
228 | * Don't do it for gbpages because there seems very little | ||
229 | * benefit in doing so. | ||
230 | */ | ||
231 | if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg) && | ||
232 | (tseg >> PMD_SHIFT) < (max_pfn_mapped >> (PMD_SHIFT-PAGE_SHIFT))) | ||
233 | set_memory_4k((unsigned long)__va(tseg), 1); | ||
234 | } | ||
235 | } | ||
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index 341230db74e1..b07b1997ed97 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c | |||
@@ -96,8 +96,6 @@ int bootloader_type; | |||
96 | 96 | ||
97 | unsigned long saved_video_mode; | 97 | unsigned long saved_video_mode; |
98 | 98 | ||
99 | int force_mwait __cpuinitdata; | ||
100 | |||
101 | /* | 99 | /* |
102 | * Early DMI memory | 100 | * Early DMI memory |
103 | */ | 101 | */ |
@@ -526,7 +524,7 @@ void __init setup_arch(char **cmdline_p) | |||
526 | check_enable_amd_mmconf_dmi(); | 524 | check_enable_amd_mmconf_dmi(); |
527 | } | 525 | } |
528 | 526 | ||
529 | static int __cpuinit get_model_name(struct cpuinfo_x86 *c) | 527 | int __cpuinit get_model_name(struct cpuinfo_x86 *c) |
530 | { | 528 | { |
531 | unsigned int *v; | 529 | unsigned int *v; |
532 | 530 | ||
@@ -542,7 +540,7 @@ static int __cpuinit get_model_name(struct cpuinfo_x86 *c) | |||
542 | } | 540 | } |
543 | 541 | ||
544 | 542 | ||
545 | static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) | 543 | void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) |
546 | { | 544 | { |
547 | unsigned int n, dummy, eax, ebx, ecx, edx; | 545 | unsigned int n, dummy, eax, ebx, ecx, edx; |
548 | 546 | ||
@@ -574,228 +572,6 @@ static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) | |||
574 | } | 572 | } |
575 | } | 573 | } |
576 | 574 | ||
577 | #ifdef CONFIG_NUMA | ||
578 | static int __cpuinit nearby_node(int apicid) | ||
579 | { | ||
580 | int i, node; | ||
581 | |||
582 | for (i = apicid - 1; i >= 0; i--) { | ||
583 | node = apicid_to_node[i]; | ||
584 | if (node != NUMA_NO_NODE && node_online(node)) | ||
585 | return node; | ||
586 | } | ||
587 | for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) { | ||
588 | node = apicid_to_node[i]; | ||
589 | if (node != NUMA_NO_NODE && node_online(node)) | ||
590 | return node; | ||
591 | } | ||
592 | return first_node(node_online_map); /* Shouldn't happen */ | ||
593 | } | ||
594 | #endif | ||
595 | |||
596 | /* | ||
597 | * On a AMD dual core setup the lower bits of the APIC id distingush the cores. | ||
598 | * Assumes number of cores is a power of two. | ||
599 | */ | ||
600 | static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c) | ||
601 | { | ||
602 | #ifdef CONFIG_SMP | ||
603 | unsigned bits; | ||
604 | #ifdef CONFIG_NUMA | ||
605 | int cpu = smp_processor_id(); | ||
606 | int node = 0; | ||
607 | unsigned apicid = hard_smp_processor_id(); | ||
608 | #endif | ||
609 | bits = c->x86_coreid_bits; | ||
610 | |||
611 | /* Low order bits define the core id (index of core in socket) */ | ||
612 | c->cpu_core_id = c->initial_apicid & ((1 << bits)-1); | ||
613 | /* Convert the initial APIC ID into the socket ID */ | ||
614 | c->phys_proc_id = c->initial_apicid >> bits; | ||
615 | |||
616 | #ifdef CONFIG_NUMA | ||
617 | node = c->phys_proc_id; | ||
618 | if (apicid_to_node[apicid] != NUMA_NO_NODE) | ||
619 | node = apicid_to_node[apicid]; | ||
620 | if (!node_online(node)) { | ||
621 | /* Two possibilities here: | ||
622 | - The CPU is missing memory and no node was created. | ||
623 | In that case try picking one from a nearby CPU | ||
624 | - The APIC IDs differ from the HyperTransport node IDs | ||
625 | which the K8 northbridge parsing fills in. | ||
626 | Assume they are all increased by a constant offset, | ||
627 | but in the same order as the HT nodeids. | ||
628 | If that doesn't result in a usable node fall back to the | ||
629 | path for the previous case. */ | ||
630 | |||
631 | int ht_nodeid = c->initial_apicid; | ||
632 | |||
633 | if (ht_nodeid >= 0 && | ||
634 | apicid_to_node[ht_nodeid] != NUMA_NO_NODE) | ||
635 | node = apicid_to_node[ht_nodeid]; | ||
636 | /* Pick a nearby node */ | ||
637 | if (!node_online(node)) | ||
638 | node = nearby_node(apicid); | ||
639 | } | ||
640 | numa_set_node(cpu, node); | ||
641 | |||
642 | printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); | ||
643 | #endif | ||
644 | #endif | ||
645 | } | ||
646 | |||
647 | static void __cpuinit early_init_amd_mc(struct cpuinfo_x86 *c) | ||
648 | { | ||
649 | #ifdef CONFIG_SMP | ||
650 | unsigned bits, ecx; | ||
651 | |||
652 | /* Multi core CPU? */ | ||
653 | if (c->extended_cpuid_level < 0x80000008) | ||
654 | return; | ||
655 | |||
656 | ecx = cpuid_ecx(0x80000008); | ||
657 | |||
658 | c->x86_max_cores = (ecx & 0xff) + 1; | ||
659 | |||
660 | /* CPU telling us the core id bits shift? */ | ||
661 | bits = (ecx >> 12) & 0xF; | ||
662 | |||
663 | /* Otherwise recompute */ | ||
664 | if (bits == 0) { | ||
665 | while ((1 << bits) < c->x86_max_cores) | ||
666 | bits++; | ||
667 | } | ||
668 | |||
669 | c->x86_coreid_bits = bits; | ||
670 | |||
671 | #endif | ||
672 | } | ||
673 | |||
674 | #define ENABLE_C1E_MASK 0x18000000 | ||
675 | #define CPUID_PROCESSOR_SIGNATURE 1 | ||
676 | #define CPUID_XFAM 0x0ff00000 | ||
677 | #define CPUID_XFAM_K8 0x00000000 | ||
678 | #define CPUID_XFAM_10H 0x00100000 | ||
679 | #define CPUID_XFAM_11H 0x00200000 | ||
680 | #define CPUID_XMOD 0x000f0000 | ||
681 | #define CPUID_XMOD_REV_F 0x00040000 | ||
682 | |||
683 | /* AMD systems with C1E don't have a working lAPIC timer. Check for that. */ | ||
684 | static __cpuinit int amd_apic_timer_broken(void) | ||
685 | { | ||
686 | u32 lo, hi, eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); | ||
687 | |||
688 | switch (eax & CPUID_XFAM) { | ||
689 | case CPUID_XFAM_K8: | ||
690 | if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F) | ||
691 | break; | ||
692 | case CPUID_XFAM_10H: | ||
693 | case CPUID_XFAM_11H: | ||
694 | rdmsr(MSR_K8_ENABLE_C1E, lo, hi); | ||
695 | if (lo & ENABLE_C1E_MASK) | ||
696 | return 1; | ||
697 | break; | ||
698 | default: | ||
699 | /* err on the side of caution */ | ||
700 | return 1; | ||
701 | } | ||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | static void __cpuinit early_init_amd(struct cpuinfo_x86 *c) | ||
706 | { | ||
707 | early_init_amd_mc(c); | ||
708 | |||
709 | /* c->x86_power is 8000_0007 edx. Bit 8 is constant TSC */ | ||
710 | if (c->x86_power & (1<<8)) | ||
711 | set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | ||
712 | } | ||
713 | |||
714 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) | ||
715 | { | ||
716 | unsigned level; | ||
717 | |||
718 | #ifdef CONFIG_SMP | ||
719 | unsigned long value; | ||
720 | |||
721 | /* | ||
722 | * Disable TLB flush filter by setting HWCR.FFDIS on K8 | ||
723 | * bit 6 of msr C001_0015 | ||
724 | * | ||
725 | * Errata 63 for SH-B3 steppings | ||
726 | * Errata 122 for all steppings (F+ have it disabled by default) | ||
727 | */ | ||
728 | if (c->x86 == 15) { | ||
729 | rdmsrl(MSR_K8_HWCR, value); | ||
730 | value |= 1 << 6; | ||
731 | wrmsrl(MSR_K8_HWCR, value); | ||
732 | } | ||
733 | #endif | ||
734 | |||
735 | /* Bit 31 in normal CPUID used for nonstandard 3DNow ID; | ||
736 | 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */ | ||
737 | clear_cpu_cap(c, 0*32+31); | ||
738 | |||
739 | /* On C+ stepping K8 rep microcode works well for copy/memset */ | ||
740 | level = cpuid_eax(1); | ||
741 | if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || | ||
742 | level >= 0x0f58)) | ||
743 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | ||
744 | if (c->x86 == 0x10 || c->x86 == 0x11) | ||
745 | set_cpu_cap(c, X86_FEATURE_REP_GOOD); | ||
746 | |||
747 | /* Enable workaround for FXSAVE leak */ | ||
748 | if (c->x86 >= 6) | ||
749 | set_cpu_cap(c, X86_FEATURE_FXSAVE_LEAK); | ||
750 | |||
751 | level = get_model_name(c); | ||
752 | if (!level) { | ||
753 | switch (c->x86) { | ||
754 | case 15: | ||
755 | /* Should distinguish Models here, but this is only | ||
756 | a fallback anyways. */ | ||
757 | strcpy(c->x86_model_id, "Hammer"); | ||
758 | break; | ||
759 | } | ||
760 | } | ||
761 | display_cacheinfo(c); | ||
762 | |||
763 | /* Multi core CPU? */ | ||
764 | if (c->extended_cpuid_level >= 0x80000008) | ||
765 | amd_detect_cmp(c); | ||
766 | |||
767 | if (c->extended_cpuid_level >= 0x80000006 && | ||
768 | (cpuid_edx(0x80000006) & 0xf000)) | ||
769 | num_cache_leaves = 4; | ||
770 | else | ||
771 | num_cache_leaves = 3; | ||
772 | |||
773 | if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x11) | ||
774 | set_cpu_cap(c, X86_FEATURE_K8); | ||
775 | |||
776 | /* MFENCE stops RDTSC speculation */ | ||
777 | set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC); | ||
778 | |||
779 | if (c->x86 == 0x10) | ||
780 | fam10h_check_enable_mmcfg(); | ||
781 | |||
782 | if (amd_apic_timer_broken()) | ||
783 | disable_apic_timer = 1; | ||
784 | |||
785 | if (c == &boot_cpu_data && c->x86 >= 0xf && c->x86 <= 0x11) { | ||
786 | unsigned long long tseg; | ||
787 | |||
788 | /* | ||
789 | * Split up direct mapping around the TSEG SMM area. | ||
790 | * Don't do it for gbpages because there seems very little | ||
791 | * benefit in doing so. | ||
792 | */ | ||
793 | if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg) && | ||
794 | (tseg >> PMD_SHIFT) < (max_pfn_mapped >> (PMD_SHIFT-PAGE_SHIFT))) | ||
795 | set_memory_4k((unsigned long)__va(tseg), 1); | ||
796 | } | ||
797 | } | ||
798 | |||
799 | void __cpuinit detect_ht(struct cpuinfo_x86 *c) | 575 | void __cpuinit detect_ht(struct cpuinfo_x86 *c) |
800 | { | 576 | { |
801 | #ifdef CONFIG_SMP | 577 | #ifdef CONFIG_SMP |
@@ -977,6 +753,10 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c) | |||
977 | c->x86_vendor = X86_VENDOR_UNKNOWN; | 753 | c->x86_vendor = X86_VENDOR_UNKNOWN; |
978 | } | 754 | } |
979 | 755 | ||
756 | // FIXME: Needs to use cpu_vendor_dev_register | ||
757 | extern void __cpuinit early_init_amd(struct cpuinfo_x86 *c); | ||
758 | extern void __cpuinit init_amd(struct cpuinfo_x86 *c); | ||
759 | |||
980 | /* Do some early cpuid on the boot CPU to get some parameter that are | 760 | /* Do some early cpuid on the boot CPU to get some parameter that are |
981 | needed before check_bugs. Everything advanced is in identify_cpu | 761 | needed before check_bugs. Everything advanced is in identify_cpu |
982 | below. */ | 762 | below. */ |