Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
[sfrench/cifs-2.6.git] / arch / x86 / kernel / cpu / proc.c
1 #include <linux/smp.h>
2 #include <linux/timex.h>
3 #include <linux/string.h>
4 #include <asm/semaphore.h>
5 #include <linux/seq_file.h>
6 #include <linux/cpufreq.h>
7
8 /*
9  *      Get CPU information for use by the procfs.
10  */
11 static int show_cpuinfo(struct seq_file *m, void *v)
12 {
13         struct cpuinfo_x86 *c = v;
14         int i, n = 0;
15         int fpu_exception;
16
17 #ifdef CONFIG_SMP
18         n = c->cpu_index;
19 #endif
20         seq_printf(m, "processor\t: %d\n"
21                 "vendor_id\t: %s\n"
22                 "cpu family\t: %d\n"
23                 "model\t\t: %d\n"
24                 "model name\t: %s\n",
25                 n,
26                 c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
27                 c->x86,
28                 c->x86_model,
29                 c->x86_model_id[0] ? c->x86_model_id : "unknown");
30
31         if (c->x86_mask || c->cpuid_level >= 0)
32                 seq_printf(m, "stepping\t: %d\n", c->x86_mask);
33         else
34                 seq_printf(m, "stepping\t: unknown\n");
35
36         if ( cpu_has(c, X86_FEATURE_TSC) ) {
37                 unsigned int freq = cpufreq_quick_get(n);
38                 if (!freq)
39                         freq = cpu_khz;
40                 seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
41                         freq / 1000, (freq % 1000));
42         }
43
44         /* Cache size */
45         if (c->x86_cache_size >= 0)
46                 seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
47 #ifdef CONFIG_X86_HT
48         if (c->x86_max_cores * smp_num_siblings > 1) {
49                 seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
50                 seq_printf(m, "siblings\t: %d\n",
51                                 cpus_weight(per_cpu(cpu_core_map, n)));
52                 seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
53                 seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
54         }
55 #endif
56         
57         /* We use exception 16 if we have hardware math and we've either seen it or the CPU claims it is internal */
58         fpu_exception = c->hard_math && (ignore_fpu_irq || cpu_has_fpu);
59         seq_printf(m, "fdiv_bug\t: %s\n"
60                         "hlt_bug\t\t: %s\n"
61                         "f00f_bug\t: %s\n"
62                         "coma_bug\t: %s\n"
63                         "fpu\t\t: %s\n"
64                         "fpu_exception\t: %s\n"
65                         "cpuid level\t: %d\n"
66                         "wp\t\t: %s\n"
67                         "flags\t\t:",
68                      c->fdiv_bug ? "yes" : "no",
69                      c->hlt_works_ok ? "no" : "yes",
70                      c->f00f_bug ? "yes" : "no",
71                      c->coma_bug ? "yes" : "no",
72                      c->hard_math ? "yes" : "no",
73                      fpu_exception ? "yes" : "no",
74                      c->cpuid_level,
75                      c->wp_works_ok ? "yes" : "no");
76
77         for ( i = 0 ; i < 32*NCAPINTS ; i++ )
78                 if ( test_bit(i, c->x86_capability) &&
79                      x86_cap_flags[i] != NULL )
80                         seq_printf(m, " %s", x86_cap_flags[i]);
81
82         for (i = 0; i < 32; i++)
83                 if (c->x86_power & (1 << i)) {
84                         if (i < ARRAY_SIZE(x86_power_flags) &&
85                             x86_power_flags[i])
86                                 seq_printf(m, "%s%s",
87                                            x86_power_flags[i][0]?" ":"",
88                                            x86_power_flags[i]);
89                         else
90                                 seq_printf(m, " [%d]", i);
91                 }
92
93         seq_printf(m, "\nbogomips\t: %lu.%02lu\n",
94                      c->loops_per_jiffy/(500000/HZ),
95                      (c->loops_per_jiffy/(5000/HZ)) % 100);
96         seq_printf(m, "clflush size\t: %u\n\n", c->x86_clflush_size);
97
98         return 0;
99 }
100
101 static void *c_start(struct seq_file *m, loff_t *pos)
102 {
103         if (*pos == 0)  /* just in case, cpu 0 is not the first */
104                 *pos = first_cpu(cpu_online_map);
105         if ((*pos) < NR_CPUS && cpu_online(*pos))
106                 return &cpu_data(*pos);
107         return NULL;
108 }
109 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
110 {
111         *pos = next_cpu(*pos, cpu_online_map);
112         return c_start(m, pos);
113 }
114 static void c_stop(struct seq_file *m, void *v)
115 {
116 }
117 const struct seq_operations cpuinfo_op = {
118         .start  = c_start,
119         .next   = c_next,
120         .stop   = c_stop,
121         .show   = show_cpuinfo,
122 };