]> err.no Git - linux-2.6/commitdiff
Use a new CPU feature word to cover features that are spread around
authorVenki Pallipadi <venkatesh.pallipadi@intel.com>
Wed, 11 Jul 2007 19:18:32 +0000 (12:18 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Thu, 12 Jul 2007 17:55:54 +0000 (10:55 -0700)
Some Intel features are spread around in different CPUID leafs like 0x5,
0x6 and 0xA.  Make this feature detection code common across i386 and
x86_64.

Display Intel Dynamic Acceleration feature in /proc/cpuinfo. This feature
will be enabled automatically by current acpi-cpufreq driver.

Refer to Intel Software Developer's Manual for more details about the feature.

Thanks to hpa (H Peter Anvin) for the making the actual code detecting the
scattered features data-driven.

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/i386/kernel/cpu/Makefile
arch/i386/kernel/cpu/addon_cpuid_features.c [new file with mode: 0644]
arch/i386/kernel/cpu/common.c
arch/i386/kernel/cpu/proc.c
arch/x86_64/kernel/Makefile
arch/x86_64/kernel/setup.c
include/asm-i386/cpufeature.h
include/asm-i386/processor.h
include/asm-i386/required-features.h
include/asm-x86_64/processor.h
include/asm-x86_64/required-features.h

index 74f27a463db088dbccce3293a9904d7c1c646f55..0b6a8551e9e222167c44fbb8e6bd63bd0d10141c 100644 (file)
@@ -8,7 +8,7 @@ obj-y   +=      amd.o
 obj-y  +=      cyrix.o
 obj-y  +=      centaur.o
 obj-y  +=      transmeta.o
-obj-y  +=      intel.o intel_cacheinfo.o
+obj-y  +=      intel.o intel_cacheinfo.o addon_cpuid_features.o
 obj-y  +=      rise.o
 obj-y  +=      nexgen.o
 obj-y  +=      umc.o
diff --git a/arch/i386/kernel/cpu/addon_cpuid_features.c b/arch/i386/kernel/cpu/addon_cpuid_features.c
new file mode 100644 (file)
index 0000000..3e91d3e
--- /dev/null
@@ -0,0 +1,50 @@
+
+/*
+ *     Routines to indentify additional cpu features that are scattered in
+ *     cpuid space.
+ */
+
+#include <linux/cpu.h>
+
+#include <asm/processor.h>
+
+struct cpuid_bit {
+       u16 feature;
+       u8 reg;
+       u8 bit;
+       u32 level;
+};
+
+enum cpuid_regs {
+       CR_EAX = 0,
+       CR_ECX,
+       CR_EDX,
+       CR_EBX
+};
+
+void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
+{
+       u32 max_level;
+       u32 regs[4];
+       const struct cpuid_bit *cb;
+
+       static const struct cpuid_bit cpuid_bits[] = {
+               { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
+               { 0, 0, 0, 0 }
+       };
+
+       for (cb = cpuid_bits; cb->feature; cb++) {
+
+               /* Verify that the level is valid */
+               max_level = cpuid_eax(cb->level & 0xffff0000);
+               if (max_level < cb->level ||
+                   max_level > (cb->level | 0xffff))
+                       continue;
+
+               cpuid(cb->level, &regs[CR_EAX], &regs[CR_EBX],
+                       &regs[CR_ECX], &regs[CR_EDX]);
+
+               if (regs[cb->reg] & (1 << cb->bit))
+                       set_bit(cb->feature, c->x86_capability);
+       }
+}
index 794d593c47eb078acf6cf435023aabbbfef65ce1..e5419a9dec885e1d1135f1f46279e3388039a71f 100644 (file)
@@ -353,6 +353,8 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
                        if ( xlvl >= 0x80000004 )
                                get_model_name(c); /* Default name */
                }
+
+               init_scattered_cpuid_features(c);
        }
 
        early_intel_workaround(c);
index ed73091d3dd0158b1271e7d72738130aecae7c07..1e31b6caffb1651def36e96acf4cd06e4df48d4e 100644 (file)
@@ -65,6 +65,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                "osvw", "ibs", NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+               /* Auxiliary (Linux-defined) */
+               "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
        };
        static const char * const x86_power_flags[] = {
                "ts",   /* temperature sensor */
index de1de8a2fd84669e4643585e5119fa7d2e2db594..47f1dc30bf565625c86d96ff4862e685f2a72615 100644 (file)
@@ -44,6 +44,7 @@ obj-$(CONFIG_PCI)             += early-quirks.o
 
 obj-y                          += topology.o
 obj-y                          += intel_cacheinfo.o
+obj-y                          += addon_cpuid_features.o
 obj-y                          += pcspeaker.o
 
 CFLAGS_vsyscall.o              := $(PROFILING) -g0
@@ -55,6 +56,7 @@ cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  += ../../i386/kernel/cpuid.o
 topology-y                     += ../../i386/kernel/topology.o
 microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../i386/kernel/microcode.o
 intel_cacheinfo-y              += ../../i386/kernel/cpu/intel_cacheinfo.o
+addon_cpuid_features-y         += ../../i386/kernel/cpu/addon_cpuid_features.o
 quirks-y                       += ../../i386/kernel/quirks.o
 i8237-y                                += ../../i386/kernel/i8237.o
 msr-$(subst m,y,$(CONFIG_X86_MSR))  += ../../i386/kernel/msr.o
index dc7630d06460c425dd1a5c9edd7c103b88907fc5..33ef718f8cb5ee1e5cbf08c5644a25b592f685ea 100644 (file)
@@ -846,6 +846,8 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
                        c->x86_capability[2] = cpuid_edx(0x80860001);
        }
 
+       init_scattered_cpuid_features(c);
+
        c->apicid = phys_pkg_id(0);
 
        /*
@@ -973,6 +975,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                "osvw", "ibs", NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+               /* Auxiliary (Linux-defined) */
+               "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
        };
        static char *x86_power_flags[] = { 
                "ts",   /* temperature sensor */
index 7ea5f4a6706f032b25b8290bf405e85940572ac9..c961c03cf1e2c8b451a0a6d67f0420ec3ee3674e 100644 (file)
@@ -12,7 +12,7 @@
 #endif
 #include <asm/required-features.h>
 
-#define NCAPINTS       7       /* N 32-bit words worth of info */
+#define NCAPINTS       8       /* N 32-bit words worth of info */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
 #define X86_FEATURE_FPU                (0*32+ 0) /* Onboard FPU */
 #define X86_FEATURE_LAHF_LM    (6*32+ 0) /* LAHF/SAHF in long mode */
 #define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */
 
+/*
+ * Auxiliary flags: Linux defined - For features scattered in various
+ * CPUID levels like 0x6, 0xA etc
+ */
+#define X86_FEATURE_IDA                (7*32+ 0) /* Intel Dynamic Acceleration */
+
 #define cpu_has(c, bit)                                                        \
        (__builtin_constant_p(bit) &&                                   \
         ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) ||     \
           (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) ||     \
           (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) ||     \
           (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) ||     \
-          (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) )      \
+          (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) ||     \
+          (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) )      \
          ? 1 :                                                         \
          test_bit(bit, (c)->x86_capability))
 #define boot_cpu_has(bit)      cpu_has(&boot_cpu_data, bit)
index 338668bfb0a2a69ae0ebb3458b94ebddf1d9ae22..94e0c147c165333b853941f547460b4efe783371 100644 (file)
@@ -119,6 +119,7 @@ void __init cpu_detect(struct cpuinfo_x86 *c);
 extern void identify_boot_cpu(void);
 extern void identify_secondary_cpu(struct cpuinfo_x86 *);
 extern void print_cpu_info(struct cpuinfo_x86 *);
+extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern unsigned short num_cache_leaves;
 
index a9c3b1147bd05bafd76810e9750d51ec93a7e7d2..65848a007050911e3207b1d2e682ba4499c25ec9 100644 (file)
@@ -50,5 +50,6 @@
 #define REQUIRED_MASK4 0
 #define REQUIRED_MASK5 0
 #define REQUIRED_MASK6 0
+#define REQUIRED_MASK7 0
 
 #endif
index df6457248d62d5aef516e1a2e3aff17d74567ff1..efc87a5aff7f0f5febf0ff04f87b8f72c4a72c6f 100644 (file)
@@ -100,6 +100,7 @@ extern char ignore_irq13;
 
 extern void identify_cpu(struct cpuinfo_x86 *);
 extern void print_cpu_info(struct cpuinfo_x86 *);
+extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern unsigned short num_cache_leaves;
 
index 262f3159d032a7527a13a1aed4f4b74b0566178f..e80d5761b00a4caaf3931da74ad81ae3a7a2ffb9 100644 (file)
@@ -41,5 +41,6 @@
 #define REQUIRED_MASK4 0
 #define REQUIRED_MASK5 0
 #define REQUIRED_MASK6 0
+#define REQUIRED_MASK7 0
 
 #endif