diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-09-04 23:09:13 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-09-05 03:40:56 -0400 |
commit | 102bbe3ab83c7ac04461d277df23cd5acdb49892 (patch) | |
tree | 50204d2cd9a2ef86ad0e08522c5cc48149b0a295 /arch | |
parent | b89d3b3e2caeab3d895301d1aee3cd2a91eddb79 (diff) |
x86: cpu/common*.c, merge identify_cpu()
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 89 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common_64.c | 116 |
2 files changed, 147 insertions, 58 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index f35baa7f3036..eef868c97b89 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -104,34 +104,6 @@ static int __init cachesize_setup(char *str) | |||
104 | } | 104 | } |
105 | __setup("cachesize=", cachesize_setup); | 105 | __setup("cachesize=", cachesize_setup); |
106 | 106 | ||
107 | /* | ||
108 | * Naming convention should be: <Name> [(<Codename>)] | ||
109 | * This table only is used unless init_<vendor>() below doesn't set it; | ||
110 | * in particular, if CPUID levels 0x80000002..4 are supported, this isn't used | ||
111 | * | ||
112 | */ | ||
113 | |||
114 | /* Look up CPU names by table lookup. */ | ||
115 | static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c) | ||
116 | { | ||
117 | struct cpu_model_info *info; | ||
118 | |||
119 | if (c->x86_model >= 16) | ||
120 | return NULL; /* Range check */ | ||
121 | |||
122 | if (!this_cpu) | ||
123 | return NULL; | ||
124 | |||
125 | info = this_cpu->c_models; | ||
126 | |||
127 | while (info && info->family) { | ||
128 | if (info->family == c->x86) | ||
129 | return info->model_names[c->x86_model]; | ||
130 | info++; | ||
131 | } | ||
132 | return NULL; /* Not found */ | ||
133 | } | ||
134 | |||
135 | static int __init x86_fxsr_setup(char *s) | 107 | static int __init x86_fxsr_setup(char *s) |
136 | { | 108 | { |
137 | setup_clear_cpu_cap(X86_FEATURE_FXSR); | 109 | setup_clear_cpu_cap(X86_FEATURE_FXSR); |
@@ -197,13 +169,48 @@ static int __init x86_serial_nr_setup(char *s) | |||
197 | } | 169 | } |
198 | __setup("serialnumber", x86_serial_nr_setup); | 170 | __setup("serialnumber", x86_serial_nr_setup); |
199 | #else | 171 | #else |
172 | static inline int flag_is_changeable_p(u32 flag) | ||
173 | { | ||
174 | return 1; | ||
175 | } | ||
200 | /* Probe for the CPUID instruction */ | 176 | /* Probe for the CPUID instruction */ |
201 | static inline int have_cpuid_p(void) | 177 | static inline int have_cpuid_p(void) |
202 | { | 178 | { |
203 | return 1; | 179 | return 1; |
204 | } | 180 | } |
181 | static inline void squash_the_stupid_serial_number(struct cpuinfo_x86 *c) | ||
182 | { | ||
183 | } | ||
205 | #endif | 184 | #endif |
206 | 185 | ||
186 | /* | ||
187 | * Naming convention should be: <Name> [(<Codename>)] | ||
188 | * This table only is used unless init_<vendor>() below doesn't set it; | ||
189 | * in particular, if CPUID levels 0x80000002..4 are supported, this isn't used | ||
190 | * | ||
191 | */ | ||
192 | |||
193 | /* Look up CPU names by table lookup. */ | ||
194 | static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c) | ||
195 | { | ||
196 | struct cpu_model_info *info; | ||
197 | |||
198 | if (c->x86_model >= 16) | ||
199 | return NULL; /* Range check */ | ||
200 | |||
201 | if (!this_cpu) | ||
202 | return NULL; | ||
203 | |||
204 | info = this_cpu->c_models; | ||
205 | |||
206 | while (info && info->family) { | ||
207 | if (info->family == c->x86) | ||
208 | return info->model_names[c->x86_model]; | ||
209 | info++; | ||
210 | } | ||
211 | return NULL; /* Not found */ | ||
212 | } | ||
213 | |||
207 | __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata; | 214 | __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata; |
208 | 215 | ||
209 | /* Current gdt points %fs at the "master" per-cpu area: after this, | 216 | /* Current gdt points %fs at the "master" per-cpu area: after this, |
@@ -620,12 +627,18 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
620 | c->loops_per_jiffy = loops_per_jiffy; | 627 | c->loops_per_jiffy = loops_per_jiffy; |
621 | c->x86_cache_size = -1; | 628 | c->x86_cache_size = -1; |
622 | c->x86_vendor = X86_VENDOR_UNKNOWN; | 629 | c->x86_vendor = X86_VENDOR_UNKNOWN; |
623 | c->cpuid_level = -1; /* CPUID not detected */ | ||
624 | c->x86_model = c->x86_mask = 0; /* So far unknown... */ | 630 | c->x86_model = c->x86_mask = 0; /* So far unknown... */ |
625 | c->x86_vendor_id[0] = '\0'; /* Unset */ | 631 | c->x86_vendor_id[0] = '\0'; /* Unset */ |
626 | c->x86_model_id[0] = '\0'; /* Unset */ | 632 | c->x86_model_id[0] = '\0'; /* Unset */ |
627 | c->x86_max_cores = 1; | 633 | c->x86_max_cores = 1; |
634 | #ifdef CONFIG_X86_64 | ||
635 | c->x86_coreid_bits = 0; | ||
636 | c->x86_clflush_size = 64; | ||
637 | #else | ||
638 | c->cpuid_level = -1; /* CPUID not detected */ | ||
628 | c->x86_clflush_size = 32; | 639 | c->x86_clflush_size = 32; |
640 | #endif | ||
641 | c->x86_cache_alignment = c->x86_clflush_size; | ||
629 | memset(&c->x86_capability, 0, sizeof c->x86_capability); | 642 | memset(&c->x86_capability, 0, sizeof c->x86_capability); |
630 | 643 | ||
631 | if (!have_cpuid_p()) { | 644 | if (!have_cpuid_p()) { |
@@ -644,6 +657,10 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
644 | if (this_cpu->c_identify) | 657 | if (this_cpu->c_identify) |
645 | this_cpu->c_identify(c); | 658 | this_cpu->c_identify(c); |
646 | 659 | ||
660 | #ifdef CONFIG_X86_64 | ||
661 | c->apicid = phys_pkg_id(0); | ||
662 | #endif | ||
663 | |||
647 | /* | 664 | /* |
648 | * Vendor-specific initialization. In this section we | 665 | * Vendor-specific initialization. In this section we |
649 | * canonicalize the feature flags, meaning if there are | 666 | * canonicalize the feature flags, meaning if there are |
@@ -677,6 +694,10 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
677 | c->x86, c->x86_model); | 694 | c->x86, c->x86_model); |
678 | } | 695 | } |
679 | 696 | ||
697 | #ifdef CONFIG_X86_64 | ||
698 | detect_ht(c); | ||
699 | #endif | ||
700 | |||
680 | /* | 701 | /* |
681 | * On SMP, boot_cpu_data holds the common feature set between | 702 | * On SMP, boot_cpu_data holds the common feature set between |
682 | * all CPUs; so make sure that we indicate which features are | 703 | * all CPUs; so make sure that we indicate which features are |
@@ -693,24 +714,34 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
693 | for (i = 0; i < NCAPINTS; i++) | 714 | for (i = 0; i < NCAPINTS; i++) |
694 | c->x86_capability[i] &= ~cleared_cpu_caps[i]; | 715 | c->x86_capability[i] &= ~cleared_cpu_caps[i]; |
695 | 716 | ||
717 | #ifdef CONFIG_X86_MCE | ||
696 | /* Init Machine Check Exception if available. */ | 718 | /* Init Machine Check Exception if available. */ |
697 | mcheck_init(c); | 719 | mcheck_init(c); |
720 | #endif | ||
698 | 721 | ||
699 | select_idle_routine(c); | 722 | select_idle_routine(c); |
723 | |||
724 | #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) | ||
725 | numa_add_cpu(smp_processor_id()); | ||
726 | #endif | ||
700 | } | 727 | } |
701 | 728 | ||
702 | void __init identify_boot_cpu(void) | 729 | void __init identify_boot_cpu(void) |
703 | { | 730 | { |
704 | identify_cpu(&boot_cpu_data); | 731 | identify_cpu(&boot_cpu_data); |
732 | #ifdef CONFIG_X86_32 | ||
705 | sysenter_setup(); | 733 | sysenter_setup(); |
706 | enable_sep_cpu(); | 734 | enable_sep_cpu(); |
735 | #endif | ||
707 | } | 736 | } |
708 | 737 | ||
709 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) | 738 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) |
710 | { | 739 | { |
711 | BUG_ON(c == &boot_cpu_data); | 740 | BUG_ON(c == &boot_cpu_data); |
712 | identify_cpu(c); | 741 | identify_cpu(c); |
742 | #ifdef CONFIG_X86_32 | ||
713 | enable_sep_cpu(); | 743 | enable_sep_cpu(); |
744 | #endif | ||
714 | mtrr_ap_init(); | 745 | mtrr_ap_init(); |
715 | } | 746 | } |
716 | 747 | ||
diff --git a/arch/x86/kernel/cpu/common_64.c b/arch/x86/kernel/cpu/common_64.c index 869a6ff9f7dc..6a42371a609f 100644 --- a/arch/x86/kernel/cpu/common_64.c +++ b/arch/x86/kernel/cpu/common_64.c | |||
@@ -103,34 +103,6 @@ static int __init cachesize_setup(char *str) | |||
103 | } | 103 | } |
104 | __setup("cachesize=", cachesize_setup); | 104 | __setup("cachesize=", cachesize_setup); |
105 | 105 | ||
106 | /* | ||
107 | * Naming convention should be: <Name> [(<Codename>)] | ||
108 | * This table only is used unless init_<vendor>() below doesn't set it; | ||
109 | * in particular, if CPUID levels 0x80000002..4 are supported, this isn't used | ||
110 | * | ||
111 | */ | ||
112 | |||
113 | /* Look up CPU names by table lookup. */ | ||
114 | static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c) | ||
115 | { | ||
116 | struct cpu_model_info *info; | ||
117 | |||
118 | if (c->x86_model >= 16) | ||
119 | return NULL; /* Range check */ | ||
120 | |||
121 | if (!this_cpu) | ||
122 | return NULL; | ||
123 | |||
124 | info = this_cpu->c_models; | ||
125 | |||
126 | while (info && info->family) { | ||
127 | if (info->family == c->x86) | ||
128 | return info->model_names[c->x86_model]; | ||
129 | info++; | ||
130 | } | ||
131 | return NULL; /* Not found */ | ||
132 | } | ||
133 | |||
134 | static int __init x86_fxsr_setup(char *s) | 106 | static int __init x86_fxsr_setup(char *s) |
135 | { | 107 | { |
136 | setup_clear_cpu_cap(X86_FEATURE_FXSR); | 108 | setup_clear_cpu_cap(X86_FEATURE_FXSR); |
@@ -196,13 +168,48 @@ static int __init x86_serial_nr_setup(char *s) | |||
196 | } | 168 | } |
197 | __setup("serialnumber", x86_serial_nr_setup); | 169 | __setup("serialnumber", x86_serial_nr_setup); |
198 | #else | 170 | #else |
171 | static inline int flag_is_changeable_p(u32 flag) | ||
172 | { | ||
173 | return 1; | ||
174 | } | ||
199 | /* Probe for the CPUID instruction */ | 175 | /* Probe for the CPUID instruction */ |
200 | static inline int have_cpuid_p(void) | 176 | static inline int have_cpuid_p(void) |
201 | { | 177 | { |
202 | return 1; | 178 | return 1; |
203 | } | 179 | } |
180 | static inline void squash_the_stupid_serial_number(struct cpuinfo_x86 *c) | ||
181 | { | ||
182 | } | ||
204 | #endif | 183 | #endif |
205 | 184 | ||
185 | /* | ||
186 | * Naming convention should be: <Name> [(<Codename>)] | ||
187 | * This table only is used unless init_<vendor>() below doesn't set it; | ||
188 | * in particular, if CPUID levels 0x80000002..4 are supported, this isn't used | ||
189 | * | ||
190 | */ | ||
191 | |||
192 | /* Look up CPU names by table lookup. */ | ||
193 | static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c) | ||
194 | { | ||
195 | struct cpu_model_info *info; | ||
196 | |||
197 | if (c->x86_model >= 16) | ||
198 | return NULL; /* Range check */ | ||
199 | |||
200 | if (!this_cpu) | ||
201 | return NULL; | ||
202 | |||
203 | info = this_cpu->c_models; | ||
204 | |||
205 | while (info && info->family) { | ||
206 | if (info->family == c->x86) | ||
207 | return info->model_names[c->x86_model]; | ||
208 | info++; | ||
209 | } | ||
210 | return NULL; /* Not found */ | ||
211 | } | ||
212 | |||
206 | __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata; | 213 | __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata; |
207 | 214 | ||
208 | /* Current gdt points %fs at the "master" per-cpu area: after this, | 215 | /* Current gdt points %fs at the "master" per-cpu area: after this, |
@@ -628,14 +635,35 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
628 | c->x86_vendor_id[0] = '\0'; /* Unset */ | 635 | c->x86_vendor_id[0] = '\0'; /* Unset */ |
629 | c->x86_model_id[0] = '\0'; /* Unset */ | 636 | c->x86_model_id[0] = '\0'; /* Unset */ |
630 | c->x86_max_cores = 1; | 637 | c->x86_max_cores = 1; |
638 | #ifdef CONFIG_X86_64 | ||
631 | c->x86_coreid_bits = 0; | 639 | c->x86_coreid_bits = 0; |
632 | c->x86_clflush_size = 64; | 640 | c->x86_clflush_size = 64; |
641 | #else | ||
642 | c->cpuid_level = -1; /* CPUID not detected */ | ||
643 | c->x86_clflush_size = 32; | ||
644 | #endif | ||
633 | c->x86_cache_alignment = c->x86_clflush_size; | 645 | c->x86_cache_alignment = c->x86_clflush_size; |
634 | memset(&c->x86_capability, 0, sizeof c->x86_capability); | 646 | memset(&c->x86_capability, 0, sizeof c->x86_capability); |
635 | 647 | ||
648 | if (!have_cpuid_p()) { | ||
649 | /* | ||
650 | * First of all, decide if this is a 486 or higher | ||
651 | * It's a 486 if we can modify the AC flag | ||
652 | */ | ||
653 | if (flag_is_changeable_p(X86_EFLAGS_AC)) | ||
654 | c->x86 = 4; | ||
655 | else | ||
656 | c->x86 = 3; | ||
657 | } | ||
658 | |||
636 | generic_identify(c); | 659 | generic_identify(c); |
637 | 660 | ||
661 | if (this_cpu->c_identify) | ||
662 | this_cpu->c_identify(c); | ||
663 | |||
664 | #ifdef CONFIG_X86_64 | ||
638 | c->apicid = phys_pkg_id(0); | 665 | c->apicid = phys_pkg_id(0); |
666 | #endif | ||
639 | 667 | ||
640 | /* | 668 | /* |
641 | * Vendor-specific initialization. In this section we | 669 | * Vendor-specific initialization. In this section we |
@@ -650,7 +678,29 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
650 | if (this_cpu->c_init) | 678 | if (this_cpu->c_init) |
651 | this_cpu->c_init(c); | 679 | this_cpu->c_init(c); |
652 | 680 | ||
681 | /* Disable the PN if appropriate */ | ||
682 | squash_the_stupid_serial_number(c); | ||
683 | |||
684 | /* | ||
685 | * The vendor-specific functions might have changed features. Now | ||
686 | * we do "generic changes." | ||
687 | */ | ||
688 | |||
689 | /* If the model name is still unset, do table lookup. */ | ||
690 | if (!c->x86_model_id[0]) { | ||
691 | char *p; | ||
692 | p = table_lookup_model(c); | ||
693 | if (p) | ||
694 | strcpy(c->x86_model_id, p); | ||
695 | else | ||
696 | /* Last resort... */ | ||
697 | sprintf(c->x86_model_id, "%02x/%02x", | ||
698 | c->x86, c->x86_model); | ||
699 | } | ||
700 | |||
701 | #ifdef CONFIG_X86_64 | ||
653 | detect_ht(c); | 702 | detect_ht(c); |
703 | #endif | ||
654 | 704 | ||
655 | /* | 705 | /* |
656 | * On SMP, boot_cpu_data holds the common feature set between | 706 | * On SMP, boot_cpu_data holds the common feature set between |
@@ -669,11 +719,12 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
669 | c->x86_capability[i] &= ~cleared_cpu_caps[i]; | 719 | c->x86_capability[i] &= ~cleared_cpu_caps[i]; |
670 | 720 | ||
671 | #ifdef CONFIG_X86_MCE | 721 | #ifdef CONFIG_X86_MCE |
722 | /* Init Machine Check Exception if available. */ | ||
672 | mcheck_init(c); | 723 | mcheck_init(c); |
673 | #endif | 724 | #endif |
674 | select_idle_routine(c); | 725 | select_idle_routine(c); |
675 | 726 | ||
676 | #ifdef CONFIG_NUMA | 727 | #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) |
677 | numa_add_cpu(smp_processor_id()); | 728 | numa_add_cpu(smp_processor_id()); |
678 | #endif | 729 | #endif |
679 | 730 | ||
@@ -682,12 +733,19 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
682 | void __init identify_boot_cpu(void) | 733 | void __init identify_boot_cpu(void) |
683 | { | 734 | { |
684 | identify_cpu(&boot_cpu_data); | 735 | identify_cpu(&boot_cpu_data); |
736 | #ifdef CONFIG_X86_32 | ||
737 | sysenter_setup(); | ||
738 | enable_sep_cpu(); | ||
739 | #endif | ||
685 | } | 740 | } |
686 | 741 | ||
687 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) | 742 | void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) |
688 | { | 743 | { |
689 | BUG_ON(c == &boot_cpu_data); | 744 | BUG_ON(c == &boot_cpu_data); |
690 | identify_cpu(c); | 745 | identify_cpu(c); |
746 | #ifdef CONFIG_X86_32 | ||
747 | enable_sep_cpu(); | ||
748 | #endif | ||
691 | mtrr_ap_init(); | 749 | mtrr_ap_init(); |
692 | } | 750 | } |
693 | 751 | ||