0001
0002 #include <linux/smp.h>
0003 #include <linux/timex.h>
0004 #include <linux/string.h>
0005 #include <linux/seq_file.h>
0006 #include <linux/cpufreq.h>
0007
0008 #include "cpu.h"
0009
0010 #ifdef CONFIG_X86_VMX_FEATURE_NAMES
0011 extern const char * const x86_vmx_flags[NVMXINTS*32];
0012 #endif
0013
0014
0015
0016
0017 static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c,
0018 unsigned int cpu)
0019 {
0020 #ifdef CONFIG_SMP
0021 seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
0022 seq_printf(m, "siblings\t: %d\n",
0023 cpumask_weight(topology_core_cpumask(cpu)));
0024 seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
0025 seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
0026 seq_printf(m, "apicid\t\t: %d\n", c->apicid);
0027 seq_printf(m, "initial apicid\t: %d\n", c->initial_apicid);
0028 #endif
0029 }
0030
0031 #ifdef CONFIG_X86_32
0032 static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
0033 {
0034 seq_printf(m,
0035 "fdiv_bug\t: %s\n"
0036 "f00f_bug\t: %s\n"
0037 "coma_bug\t: %s\n"
0038 "fpu\t\t: %s\n"
0039 "fpu_exception\t: %s\n"
0040 "cpuid level\t: %d\n"
0041 "wp\t\t: yes\n",
0042 boot_cpu_has_bug(X86_BUG_FDIV) ? "yes" : "no",
0043 boot_cpu_has_bug(X86_BUG_F00F) ? "yes" : "no",
0044 boot_cpu_has_bug(X86_BUG_COMA) ? "yes" : "no",
0045 boot_cpu_has(X86_FEATURE_FPU) ? "yes" : "no",
0046 boot_cpu_has(X86_FEATURE_FPU) ? "yes" : "no",
0047 c->cpuid_level);
0048 }
0049 #else
0050 static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
0051 {
0052 seq_printf(m,
0053 "fpu\t\t: yes\n"
0054 "fpu_exception\t: yes\n"
0055 "cpuid level\t: %d\n"
0056 "wp\t\t: yes\n",
0057 c->cpuid_level);
0058 }
0059 #endif
0060
0061 static int show_cpuinfo(struct seq_file *m, void *v)
0062 {
0063 struct cpuinfo_x86 *c = v;
0064 unsigned int cpu;
0065 int i;
0066
0067 cpu = c->cpu_index;
0068 seq_printf(m, "processor\t: %u\n"
0069 "vendor_id\t: %s\n"
0070 "cpu family\t: %d\n"
0071 "model\t\t: %u\n"
0072 "model name\t: %s\n",
0073 cpu,
0074 c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
0075 c->x86,
0076 c->x86_model,
0077 c->x86_model_id[0] ? c->x86_model_id : "unknown");
0078
0079 if (c->x86_stepping || c->cpuid_level >= 0)
0080 seq_printf(m, "stepping\t: %d\n", c->x86_stepping);
0081 else
0082 seq_puts(m, "stepping\t: unknown\n");
0083 if (c->microcode)
0084 seq_printf(m, "microcode\t: 0x%x\n", c->microcode);
0085
0086 if (cpu_has(c, X86_FEATURE_TSC)) {
0087 unsigned int freq = arch_freq_get_on_cpu(cpu);
0088
0089 seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, (freq % 1000));
0090 }
0091
0092
0093 if (c->x86_cache_size)
0094 seq_printf(m, "cache size\t: %u KB\n", c->x86_cache_size);
0095
0096 show_cpuinfo_core(m, c, cpu);
0097 show_cpuinfo_misc(m, c);
0098
0099 seq_puts(m, "flags\t\t:");
0100 for (i = 0; i < 32*NCAPINTS; i++)
0101 if (cpu_has(c, i) && x86_cap_flags[i] != NULL)
0102 seq_printf(m, " %s", x86_cap_flags[i]);
0103
0104 #ifdef CONFIG_X86_VMX_FEATURE_NAMES
0105 if (cpu_has(c, X86_FEATURE_VMX) && c->vmx_capability[0]) {
0106 seq_puts(m, "\nvmx flags\t:");
0107 for (i = 0; i < 32*NVMXINTS; i++) {
0108 if (test_bit(i, (unsigned long *)c->vmx_capability) &&
0109 x86_vmx_flags[i] != NULL)
0110 seq_printf(m, " %s", x86_vmx_flags[i]);
0111 }
0112 }
0113 #endif
0114
0115 seq_puts(m, "\nbugs\t\t:");
0116 for (i = 0; i < 32*NBUGINTS; i++) {
0117 unsigned int bug_bit = 32*NCAPINTS + i;
0118
0119 if (cpu_has_bug(c, bug_bit) && x86_bug_flags[i])
0120 seq_printf(m, " %s", x86_bug_flags[i]);
0121 }
0122
0123 seq_printf(m, "\nbogomips\t: %lu.%02lu\n",
0124 c->loops_per_jiffy/(500000/HZ),
0125 (c->loops_per_jiffy/(5000/HZ)) % 100);
0126
0127 #ifdef CONFIG_X86_64
0128 if (c->x86_tlbsize > 0)
0129 seq_printf(m, "TLB size\t: %d 4K pages\n", c->x86_tlbsize);
0130 #endif
0131 seq_printf(m, "clflush size\t: %u\n", c->x86_clflush_size);
0132 seq_printf(m, "cache_alignment\t: %d\n", c->x86_cache_alignment);
0133 seq_printf(m, "address sizes\t: %u bits physical, %u bits virtual\n",
0134 c->x86_phys_bits, c->x86_virt_bits);
0135
0136 seq_puts(m, "power management:");
0137 for (i = 0; i < 32; i++) {
0138 if (c->x86_power & (1 << i)) {
0139 if (i < ARRAY_SIZE(x86_power_flags) &&
0140 x86_power_flags[i])
0141 seq_printf(m, "%s%s",
0142 x86_power_flags[i][0] ? " " : "",
0143 x86_power_flags[i]);
0144 else
0145 seq_printf(m, " [%d]", i);
0146 }
0147 }
0148
0149 seq_puts(m, "\n\n");
0150
0151 return 0;
0152 }
0153
0154 static void *c_start(struct seq_file *m, loff_t *pos)
0155 {
0156 *pos = cpumask_next(*pos - 1, cpu_online_mask);
0157 if ((*pos) < nr_cpu_ids)
0158 return &cpu_data(*pos);
0159 return NULL;
0160 }
0161
0162 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
0163 {
0164 (*pos)++;
0165 return c_start(m, pos);
0166 }
0167
0168 static void c_stop(struct seq_file *m, void *v)
0169 {
0170 }
0171
0172 const struct seq_operations cpuinfo_op = {
0173 .start = c_start,
0174 .next = c_next,
0175 .stop = c_stop,
0176 .show = show_cpuinfo,
0177 };