aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-09-04 23:09:13 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-05 03:40:56 -0400
commit102bbe3ab83c7ac04461d277df23cd5acdb49892 (patch)
tree50204d2cd9a2ef86ad0e08522c5cc48149b0a295 /arch
parentb89d3b3e2caeab3d895301d1aee3cd2a91eddb79 (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.c89
-rw-r--r--arch/x86/kernel/cpu/common_64.c116
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. */
115static 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
135static int __init x86_fxsr_setup(char *s) 107static 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
172static 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 */
201static inline int have_cpuid_p(void) 177static inline int have_cpuid_p(void)
202{ 178{
203 return 1; 179 return 1;
204} 180}
181static 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. */
194static 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
702void __init identify_boot_cpu(void) 729void __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
709void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) 738void __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. */
114static 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
134static int __init x86_fxsr_setup(char *s) 106static 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
171static 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 */
200static inline int have_cpuid_p(void) 176static inline int have_cpuid_p(void)
201{ 177{
202 return 1; 178 return 1;
203} 179}
180static 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. */
193static 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)
682void __init identify_boot_cpu(void) 733void __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
687void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) 742void __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