x86: L3 cache index disable for 2.6.26, cleanups
[linux-2.6.git] / arch / x86 / kernel / cpu / intel_cacheinfo.c
1 /*
2  *      Routines to indentify caches on Intel CPU.
3  *
4  *      Changes:
5  *      Venkatesh Pallipadi     : Adding cache identification through cpuid(4)
6  *              Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
7  *      Andi Kleen / Andreas Herrmann   : CPUID4 emulation on AMD.
8  */
9
10 #include <linux/init.h>
11 #include <linux/slab.h>
12 #include <linux/device.h>
13 #include <linux/compiler.h>
14 #include <linux/cpu.h>
15 #include <linux/sched.h>
16
17 #include <asm/processor.h>
18 #include <asm/smp.h>
19 #include <asm/k8.h>
20
21 #define LVL_1_INST      1
22 #define LVL_1_DATA      2
23 #define LVL_2           3
24 #define LVL_3           4
25 #define LVL_TRACE       5
26
27 struct _cache_table
28 {
29         unsigned char descriptor;
30         char cache_type;
31         short size;
32 };
33
34 /* all the cache descriptor types we care about (no TLB or trace cache entries) */
35 static struct _cache_table cache_table[] __cpuinitdata =
36 {
37         { 0x06, LVL_1_INST, 8 },        /* 4-way set assoc, 32 byte line size */
38         { 0x08, LVL_1_INST, 16 },       /* 4-way set assoc, 32 byte line size */
39         { 0x0a, LVL_1_DATA, 8 },        /* 2 way set assoc, 32 byte line size */
40         { 0x0c, LVL_1_DATA, 16 },       /* 4-way set assoc, 32 byte line size */
41         { 0x22, LVL_3,      512 },      /* 4-way set assoc, sectored cache, 64 byte line size */
42         { 0x23, LVL_3,      1024 },     /* 8-way set assoc, sectored cache, 64 byte line size */
43         { 0x25, LVL_3,      2048 },     /* 8-way set assoc, sectored cache, 64 byte line size */
44         { 0x29, LVL_3,      4096 },     /* 8-way set assoc, sectored cache, 64 byte line size */
45         { 0x2c, LVL_1_DATA, 32 },       /* 8-way set assoc, 64 byte line size */
46         { 0x30, LVL_1_INST, 32 },       /* 8-way set assoc, 64 byte line size */
47         { 0x39, LVL_2,      128 },      /* 4-way set assoc, sectored cache, 64 byte line size */
48         { 0x3a, LVL_2,      192 },      /* 6-way set assoc, sectored cache, 64 byte line size */
49         { 0x3b, LVL_2,      128 },      /* 2-way set assoc, sectored cache, 64 byte line size */
50         { 0x3c, LVL_2,      256 },      /* 4-way set assoc, sectored cache, 64 byte line size */
51         { 0x3d, LVL_2,      384 },      /* 6-way set assoc, sectored cache, 64 byte line size */
52         { 0x3e, LVL_2,      512 },      /* 4-way set assoc, sectored cache, 64 byte line size */
53         { 0x3f, LVL_2,      256 },      /* 2-way set assoc, 64 byte line size */
54         { 0x41, LVL_2,      128 },      /* 4-way set assoc, 32 byte line size */
55         { 0x42, LVL_2,      256 },      /* 4-way set assoc, 32 byte line size */
56         { 0x43, LVL_2,      512 },      /* 4-way set assoc, 32 byte line size */
57         { 0x44, LVL_2,      1024 },     /* 4-way set assoc, 32 byte line size */
58         { 0x45, LVL_2,      2048 },     /* 4-way set assoc, 32 byte line size */
59         { 0x46, LVL_3,      4096 },     /* 4-way set assoc, 64 byte line size */
60         { 0x47, LVL_3,      8192 },     /* 8-way set assoc, 64 byte line size */
61         { 0x49, LVL_3,      4096 },     /* 16-way set assoc, 64 byte line size */
62         { 0x4a, LVL_3,      6144 },     /* 12-way set assoc, 64 byte line size */
63         { 0x4b, LVL_3,      8192 },     /* 16-way set assoc, 64 byte line size */
64         { 0x4c, LVL_3,     12288 },     /* 12-way set assoc, 64 byte line size */
65         { 0x4d, LVL_3,     16384 },     /* 16-way set assoc, 64 byte line size */
66         { 0x4e, LVL_2,      6144 },     /* 24-way set assoc, 64 byte line size */
67         { 0x60, LVL_1_DATA, 16 },       /* 8-way set assoc, sectored cache, 64 byte line size */
68         { 0x66, LVL_1_DATA, 8 },        /* 4-way set assoc, sectored cache, 64 byte line size */
69         { 0x67, LVL_1_DATA, 16 },       /* 4-way set assoc, sectored cache, 64 byte line size */
70         { 0x68, LVL_1_DATA, 32 },       /* 4-way set assoc, sectored cache, 64 byte line size */
71         { 0x70, LVL_TRACE,  12 },       /* 8-way set assoc */
72         { 0x71, LVL_TRACE,  16 },       /* 8-way set assoc */
73         { 0x72, LVL_TRACE,  32 },       /* 8-way set assoc */
74         { 0x73, LVL_TRACE,  64 },       /* 8-way set assoc */
75         { 0x78, LVL_2,    1024 },       /* 4-way set assoc, 64 byte line size */
76         { 0x79, LVL_2,     128 },       /* 8-way set assoc, sectored cache, 64 byte line size */
77         { 0x7a, LVL_2,     256 },       /* 8-way set assoc, sectored cache, 64 byte line size */
78         { 0x7b, LVL_2,     512 },       /* 8-way set assoc, sectored cache, 64 byte line size */
79         { 0x7c, LVL_2,    1024 },       /* 8-way set assoc, sectored cache, 64 byte line size */
80         { 0x7d, LVL_2,    2048 },       /* 8-way set assoc, 64 byte line size */
81         { 0x7f, LVL_2,     512 },       /* 2-way set assoc, 64 byte line size */
82         { 0x82, LVL_2,     256 },       /* 8-way set assoc, 32 byte line size */
83         { 0x83, LVL_2,     512 },       /* 8-way set assoc, 32 byte line size */
84         { 0x84, LVL_2,    1024 },       /* 8-way set assoc, 32 byte line size */
85         { 0x85, LVL_2,    2048 },       /* 8-way set assoc, 32 byte line size */
86         { 0x86, LVL_2,     512 },       /* 4-way set assoc, 64 byte line size */
87         { 0x87, LVL_2,    1024 },       /* 8-way set assoc, 64 byte line size */
88         { 0x00, 0, 0}
89 };
90
91
92 enum _cache_type
93 {
94         CACHE_TYPE_NULL = 0,
95         CACHE_TYPE_DATA = 1,
96         CACHE_TYPE_INST = 2,
97         CACHE_TYPE_UNIFIED = 3
98 };
99
100 union _cpuid4_leaf_eax {
101         struct {
102                 enum _cache_type        type:5;
103                 unsigned int            level:3;
104                 unsigned int            is_self_initializing:1;
105                 unsigned int            is_fully_associative:1;
106                 unsigned int            reserved:4;
107                 unsigned int            num_threads_sharing:12;
108                 unsigned int            num_cores_on_die:6;
109         } split;
110         u32 full;
111 };
112
113 union _cpuid4_leaf_ebx {
114         struct {
115                 unsigned int            coherency_line_size:12;
116                 unsigned int            physical_line_partition:10;
117                 unsigned int            ways_of_associativity:10;
118         } split;
119         u32 full;
120 };
121
122 union _cpuid4_leaf_ecx {
123         struct {
124                 unsigned int            number_of_sets:32;
125         } split;
126         u32 full;
127 };
128
129 struct _cpuid4_info {
130         union _cpuid4_leaf_eax eax;
131         union _cpuid4_leaf_ebx ebx;
132         union _cpuid4_leaf_ecx ecx;
133         unsigned long size;
134         unsigned long can_disable;
135         cpumask_t shared_cpu_map;       /* future?: only cpus/node is needed */
136 };
137
138 unsigned short                  num_cache_leaves;
139
140 /* AMD doesn't have CPUID4. Emulate it here to report the same
141    information to the user.  This makes some assumptions about the machine:
142    L2 not shared, no SMT etc. that is currently true on AMD CPUs.
143
144    In theory the TLBs could be reported as fake type (they are in "dummy").
145    Maybe later */
146 union l1_cache {
147         struct {
148                 unsigned line_size : 8;
149                 unsigned lines_per_tag : 8;
150                 unsigned assoc : 8;
151                 unsigned size_in_kb : 8;
152         };
153         unsigned val;
154 };
155
156 union l2_cache {
157         struct {
158                 unsigned line_size : 8;
159                 unsigned lines_per_tag : 4;
160                 unsigned assoc : 4;
161                 unsigned size_in_kb : 16;
162         };
163         unsigned val;
164 };
165
166 union l3_cache {
167         struct {
168                 unsigned line_size : 8;
169                 unsigned lines_per_tag : 4;
170                 unsigned assoc : 4;
171                 unsigned res : 2;
172                 unsigned size_encoded : 14;
173         };
174         unsigned val;
175 };
176
177 static unsigned short assocs[] __cpuinitdata = {
178         [1] = 1, [2] = 2, [4] = 4, [6] = 8,
179         [8] = 16, [0xa] = 32, [0xb] = 48,
180         [0xc] = 64,
181         [0xf] = 0xffff // ??
182 };
183
184 static unsigned char levels[] __cpuinitdata = { 1, 1, 2, 3 };
185 static unsigned char types[] __cpuinitdata = { 1, 2, 3, 3 };
186
187 static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
188                        union _cpuid4_leaf_ebx *ebx,
189                        union _cpuid4_leaf_ecx *ecx)
190 {
191         unsigned dummy;
192         unsigned line_size, lines_per_tag, assoc, size_in_kb;
193         union l1_cache l1i, l1d;
194         union l2_cache l2;
195         union l3_cache l3;
196         union l1_cache *l1 = &l1d;
197
198         eax->full = 0;
199         ebx->full = 0;
200         ecx->full = 0;
201
202         cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
203         cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
204
205         switch (leaf) {
206         case 1:
207                 l1 = &l1i;
208         case 0:
209                 if (!l1->val)
210                         return;
211                 assoc = l1->assoc;
212                 line_size = l1->line_size;
213                 lines_per_tag = l1->lines_per_tag;
214                 size_in_kb = l1->size_in_kb;
215                 break;
216         case 2:
217                 if (!l2.val)
218                         return;
219                 assoc = l2.assoc;
220                 line_size = l2.line_size;
221                 lines_per_tag = l2.lines_per_tag;
222                 /* cpu_data has errata corrections for K7 applied */
223                 size_in_kb = current_cpu_data.x86_cache_size;
224                 break;
225         case 3:
226                 if (!l3.val)
227                         return;
228                 assoc = l3.assoc;
229                 line_size = l3.line_size;
230                 lines_per_tag = l3.lines_per_tag;
231                 size_in_kb = l3.size_encoded * 512;
232                 break;
233         default:
234                 return;
235         }
236
237         eax->split.is_self_initializing = 1;
238         eax->split.type = types[leaf];
239         eax->split.level = levels[leaf];
240         if (leaf == 3)
241                 eax->split.num_threads_sharing = current_cpu_data.x86_max_cores - 1;
242         else
243                 eax->split.num_threads_sharing = 0;
244         eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
245
246
247         if (assoc == 0xf)
248                 eax->split.is_fully_associative = 1;
249         ebx->split.coherency_line_size = line_size - 1;
250         ebx->split.ways_of_associativity = assocs[assoc] - 1;
251         ebx->split.physical_line_partition = lines_per_tag - 1;
252         ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
253                 (ebx->split.ways_of_associativity + 1) - 1;
254 }
255
256 static void __cpuinit
257 amd_check_l3_disable(int index, struct _cpuid4_info *this_leaf)
258 {
259         if (index < 3)
260                 return;
261         this_leaf->can_disable = 1;     
262 }
263
264 static int
265 __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
266 {
267         union _cpuid4_leaf_eax  eax;
268         union _cpuid4_leaf_ebx  ebx;
269         union _cpuid4_leaf_ecx  ecx;
270         unsigned                edx;
271
272         if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
273                 amd_cpuid4(index, &eax, &ebx, &ecx);
274                 if (boot_cpu_data.x86 >= 0x10)
275                         amd_check_l3_disable(index, this_leaf);
276         } else {
277                 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
278         }
279
280         if (eax.split.type == CACHE_TYPE_NULL)
281                 return -EIO; /* better error ? */
282
283         this_leaf->eax = eax;
284         this_leaf->ebx = ebx;
285         this_leaf->ecx = ecx;
286         this_leaf->size = (ecx.split.number_of_sets          + 1) *
287                           (ebx.split.coherency_line_size     + 1) *
288                           (ebx.split.physical_line_partition + 1) *
289                           (ebx.split.ways_of_associativity   + 1);
290         return 0;
291 }
292
293 static int __cpuinit find_num_cache_leaves(void)
294 {
295         unsigned int            eax, ebx, ecx, edx;
296         union _cpuid4_leaf_eax  cache_eax;
297         int                     i = -1;
298
299         do {
300                 ++i;
301                 /* Do cpuid(4) loop to find out num_cache_leaves */
302                 cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
303                 cache_eax.full = eax;
304         } while (cache_eax.split.type != CACHE_TYPE_NULL);
305         return i;
306 }
307
308 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
309 {
310         unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
311         unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
312         unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
313         unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
314 #ifdef CONFIG_X86_HT
315         unsigned int cpu = c->cpu_index;
316 #endif
317
318         if (c->cpuid_level > 3) {
319                 static int is_initialized;
320
321                 if (is_initialized == 0) {
322                         /* Init num_cache_leaves from boot CPU */
323                         num_cache_leaves = find_num_cache_leaves();
324                         is_initialized++;
325                 }
326
327                 /*
328                  * Whenever possible use cpuid(4), deterministic cache
329                  * parameters cpuid leaf to find the cache details
330                  */
331                 for (i = 0; i < num_cache_leaves; i++) {
332                         struct _cpuid4_info this_leaf;
333
334                         int retval;
335
336                         retval = cpuid4_cache_lookup(i, &this_leaf);
337                         if (retval >= 0) {
338                                 switch(this_leaf.eax.split.level) {
339                                     case 1:
340                                         if (this_leaf.eax.split.type ==
341                                                         CACHE_TYPE_DATA)
342                                                 new_l1d = this_leaf.size/1024;
343                                         else if (this_leaf.eax.split.type ==
344                                                         CACHE_TYPE_INST)
345                                                 new_l1i = this_leaf.size/1024;
346                                         break;
347                                     case 2:
348                                         new_l2 = this_leaf.size/1024;
349                                         num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
350                                         index_msb = get_count_order(num_threads_sharing);
351                                         l2_id = c->apicid >> index_msb;
352                                         break;
353                                     case 3:
354                                         new_l3 = this_leaf.size/1024;
355                                         num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
356                                         index_msb = get_count_order(num_threads_sharing);
357                                         l3_id = c->apicid >> index_msb;
358                                         break;
359                                     default:
360                                         break;
361                                 }
362                         }
363                 }
364         }
365         /*
366          * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
367          * trace cache
368          */
369         if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
370                 /* supports eax=2  call */
371                 int j, n;
372                 unsigned int regs[4];
373                 unsigned char *dp = (unsigned char *)regs;
374                 int only_trace = 0;
375
376                 if (num_cache_leaves != 0 && c->x86 == 15)
377                         only_trace = 1;
378
379                 /* Number of times to iterate */
380                 n = cpuid_eax(2) & 0xFF;
381
382                 for ( i = 0 ; i < n ; i++ ) {
383                         cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
384
385                         /* If bit 31 is set, this is an unknown format */
386                         for ( j = 0 ; j < 3 ; j++ ) {
387                                 if (regs[j] & (1 << 31)) regs[j] = 0;
388                         }
389
390                         /* Byte 0 is level count, not a descriptor */
391                         for ( j = 1 ; j < 16 ; j++ ) {
392                                 unsigned char des = dp[j];
393                                 unsigned char k = 0;
394
395                                 /* look up this descriptor in the table */
396                                 while (cache_table[k].descriptor != 0)
397                                 {
398                                         if (cache_table[k].descriptor == des) {
399                                                 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
400                                                         break;
401                                                 switch (cache_table[k].cache_type) {
402                                                 case LVL_1_INST:
403                                                         l1i += cache_table[k].size;
404                                                         break;
405                                                 case LVL_1_DATA:
406                                                         l1d += cache_table[k].size;
407                                                         break;
408                                                 case LVL_2:
409                                                         l2 += cache_table[k].size;
410                                                         break;
411                                                 case LVL_3:
412                                                         l3 += cache_table[k].size;
413                                                         break;
414                                                 case LVL_TRACE:
415                                                         trace += cache_table[k].size;
416                                                         break;
417                                                 }
418
419                                                 break;
420                                         }
421
422                                         k++;
423                                 }
424                         }
425                 }
426         }
427
428         if (new_l1d)
429                 l1d = new_l1d;
430
431         if (new_l1i)
432                 l1i = new_l1i;
433
434         if (new_l2) {
435                 l2 = new_l2;
436 #ifdef CONFIG_X86_HT
437                 per_cpu(cpu_llc_id, cpu) = l2_id;
438 #endif
439         }
440
441         if (new_l3) {
442                 l3 = new_l3;
443 #ifdef CONFIG_X86_HT
444                 per_cpu(cpu_llc_id, cpu) = l3_id;
445 #endif
446         }
447
448         if (trace)
449                 printk (KERN_INFO "CPU: Trace cache: %dK uops", trace);
450         else if ( l1i )
451                 printk (KERN_INFO "CPU: L1 I cache: %dK", l1i);
452
453         if (l1d)
454                 printk(", L1 D cache: %dK\n", l1d);
455         else
456                 printk("\n");
457
458         if (l2)
459                 printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
460
461         if (l3)
462                 printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
463
464         c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
465
466         return l2;
467 }
468
469 /* pointer to _cpuid4_info array (for each cache leaf) */
470 static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info);
471 #define CPUID4_INFO_IDX(x, y)    (&((per_cpu(cpuid4_info, x))[y]))
472
473 #ifdef CONFIG_SMP
474 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
475 {
476         struct _cpuid4_info     *this_leaf, *sibling_leaf;
477         unsigned long num_threads_sharing;
478         int index_msb, i;
479         struct cpuinfo_x86 *c = &cpu_data(cpu);
480
481         this_leaf = CPUID4_INFO_IDX(cpu, index);
482         num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
483
484         if (num_threads_sharing == 1)
485                 cpu_set(cpu, this_leaf->shared_cpu_map);
486         else {
487                 index_msb = get_count_order(num_threads_sharing);
488
489                 for_each_online_cpu(i) {
490                         if (cpu_data(i).apicid >> index_msb ==
491                             c->apicid >> index_msb) {
492                                 cpu_set(i, this_leaf->shared_cpu_map);
493                                 if (i != cpu && per_cpu(cpuid4_info, i))  {
494                                         sibling_leaf = CPUID4_INFO_IDX(i, index);
495                                         cpu_set(cpu, sibling_leaf->shared_cpu_map);
496                                 }
497                         }
498                 }
499         }
500 }
501 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
502 {
503         struct _cpuid4_info     *this_leaf, *sibling_leaf;
504         int sibling;
505
506         this_leaf = CPUID4_INFO_IDX(cpu, index);
507         for_each_cpu_mask(sibling, this_leaf->shared_cpu_map) {
508                 sibling_leaf = CPUID4_INFO_IDX(sibling, index); 
509                 cpu_clear(cpu, sibling_leaf->shared_cpu_map);
510         }
511 }
512 #else
513 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
514 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
515 #endif
516
517 static void __cpuinit free_cache_attributes(unsigned int cpu)
518 {
519         int i;
520
521         for (i = 0; i < num_cache_leaves; i++)
522                 cache_remove_shared_cpu_map(cpu, i);
523
524         kfree(per_cpu(cpuid4_info, cpu));
525         per_cpu(cpuid4_info, cpu) = NULL;
526 }
527
528 static int __cpuinit detect_cache_attributes(unsigned int cpu)
529 {
530         struct _cpuid4_info     *this_leaf;
531         unsigned long           j;
532         int                     retval;
533         cpumask_t               oldmask;
534
535         if (num_cache_leaves == 0)
536                 return -ENOENT;
537
538         per_cpu(cpuid4_info, cpu) = kzalloc(
539             sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
540         if (per_cpu(cpuid4_info, cpu) == NULL)
541                 return -ENOMEM;
542
543         oldmask = current->cpus_allowed;
544         retval = set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
545         if (retval)
546                 goto out;
547
548         /* Do cpuid and store the results */
549         for (j = 0; j < num_cache_leaves; j++) {
550                 this_leaf = CPUID4_INFO_IDX(cpu, j);
551                 retval = cpuid4_cache_lookup(j, this_leaf);
552                 if (unlikely(retval < 0)) {
553                         int i;
554
555                         for (i = 0; i < j; i++)
556                                 cache_remove_shared_cpu_map(cpu, i);
557                         break;
558                 }
559                 cache_shared_cpu_map_setup(cpu, j);
560         }
561         set_cpus_allowed_ptr(current, &oldmask);
562
563 out:
564         if (retval) {
565                 kfree(per_cpu(cpuid4_info, cpu));
566                 per_cpu(cpuid4_info, cpu) = NULL;
567         }
568
569         return retval;
570 }
571
572 #ifdef CONFIG_SYSFS
573
574 #include <linux/kobject.h>
575 #include <linux/sysfs.h>
576
577 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
578
579 /* pointer to kobject for cpuX/cache */
580 static DEFINE_PER_CPU(struct kobject *, cache_kobject);
581
582 struct _index_kobject {
583         struct kobject kobj;
584         unsigned int cpu;
585         unsigned short index;
586 };
587
588 /* pointer to array of kobjects for cpuX/cache/indexY */
589 static DEFINE_PER_CPU(struct _index_kobject *, index_kobject);
590 #define INDEX_KOBJECT_PTR(x, y)    (&((per_cpu(index_kobject, x))[y]))
591
592 #define show_one_plus(file_name, object, val)                           \
593 static ssize_t show_##file_name                                         \
594                         (struct _cpuid4_info *this_leaf, char *buf)     \
595 {                                                                       \
596         return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \
597 }
598
599 show_one_plus(level, eax.split.level, 0);
600 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
601 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
602 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
603 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
604
605 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
606 {
607         return sprintf (buf, "%luK\n", this_leaf->size / 1024);
608 }
609
610 static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
611                                         int type, char *buf)
612 {
613         ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
614         int n = 0;
615
616         if (len > 1) {
617                 cpumask_t *mask = &this_leaf->shared_cpu_map;
618
619                 n = type?
620                         cpulist_scnprintf(buf, len-2, *mask):
621                         cpumask_scnprintf(buf, len-2, *mask);
622                 buf[n++] = '\n';
623                 buf[n] = '\0';
624         }
625         return n;
626 }
627
628 static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf)
629 {
630         return show_shared_cpu_map_func(leaf, 0, buf);
631 }
632
633 static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf)
634 {
635         return show_shared_cpu_map_func(leaf, 1, buf);
636 }
637
638 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf) {
639         switch(this_leaf->eax.split.type) {
640             case CACHE_TYPE_DATA:
641                 return sprintf(buf, "Data\n");
642                 break;
643             case CACHE_TYPE_INST:
644                 return sprintf(buf, "Instruction\n");
645                 break;
646             case CACHE_TYPE_UNIFIED:
647                 return sprintf(buf, "Unified\n");
648                 break;
649             default:
650                 return sprintf(buf, "Unknown\n");
651                 break;
652         }
653 }
654
655 #define to_object(k)    container_of(k, struct _index_kobject, kobj)
656 #define to_attr(a)      container_of(a, struct _cache_attr, attr)
657
658 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf)
659 {
660         int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map));
661         struct pci_dev *dev = k8_northbridges[node];
662         ssize_t ret = 0;
663         int i;
664
665         if (!this_leaf->can_disable)
666                 return sprintf(buf, "Feature not enabled\n");
667
668         for (i = 0; i < 2; i++) {
669                 unsigned int reg;
670
671                 pci_read_config_dword(dev, 0x1BC + i * 4, &reg);
672
673                 ret += sprintf(buf, "%sEntry: %d\n", buf, i);
674                 ret += sprintf(buf, "%sReads:  %s\tNew Entries: %s\n",  
675                         buf,
676                         reg & 0x80000000 ? "Disabled" : "Allowed",
677                         reg & 0x40000000 ? "Disabled" : "Allowed");
678                 ret += sprintf(buf, "%sSubCache: %x\tIndex: %x\n",
679                         buf, (reg & 0x30000) >> 16, reg & 0xfff);
680         }
681         return ret;
682 }
683
684 static ssize_t
685 store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf,
686                     size_t count)
687 {
688         int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map));
689         struct pci_dev *dev = k8_northbridges[node];
690         unsigned int ret, index, val;
691
692         if (!this_leaf->can_disable)
693                 return 0;
694
695         /* write the MSR value */
696
697         if (strlen(buf) > 15)
698                 return -EINVAL;
699
700         ret = sscanf(buf, "%x %x", &index, &val);
701         if (ret != 2)
702                 return -EINVAL;
703         if (index > 1)
704                 return -EINVAL;
705
706         val |= 0xc0000000;
707         pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000);
708         wbinvd();
709         pci_write_config_dword(dev, 0x1BC + index * 4, val);
710
711         return 1;
712 }
713
714 struct _cache_attr {
715         struct attribute attr;
716         ssize_t (*show)(struct _cpuid4_info *, char *);
717         ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
718 };
719
720 #define define_one_ro(_name) \
721 static struct _cache_attr _name = \
722         __ATTR(_name, 0444, show_##_name, NULL)
723
724 define_one_ro(level);
725 define_one_ro(type);
726 define_one_ro(coherency_line_size);
727 define_one_ro(physical_line_partition);
728 define_one_ro(ways_of_associativity);
729 define_one_ro(number_of_sets);
730 define_one_ro(size);
731 define_one_ro(shared_cpu_map);
732 define_one_ro(shared_cpu_list);
733
734 static struct _cache_attr cache_disable = __ATTR(cache_disable, 0644, show_cache_disable, store_cache_disable);
735
736 static struct attribute * default_attrs[] = {
737         &type.attr,
738         &level.attr,
739         &coherency_line_size.attr,
740         &physical_line_partition.attr,
741         &ways_of_associativity.attr,
742         &number_of_sets.attr,
743         &size.attr,
744         &shared_cpu_map.attr,
745         &shared_cpu_list.attr,
746         &cache_disable.attr,
747         NULL
748 };
749
750 static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf)
751 {
752         struct _cache_attr *fattr = to_attr(attr);
753         struct _index_kobject *this_leaf = to_object(kobj);
754         ssize_t ret;
755
756         ret = fattr->show ?
757                 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
758                         buf) :
759                 0;
760         return ret;
761 }
762
763 static ssize_t store(struct kobject * kobj, struct attribute * attr,
764                      const char * buf, size_t count)
765 {
766         struct _cache_attr *fattr = to_attr(attr);
767         struct _index_kobject *this_leaf = to_object(kobj);
768         ssize_t ret;
769
770         ret = fattr->store ?
771                 fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
772                         buf, count) :
773                 0;
774         return ret;
775 }
776
777 static struct sysfs_ops sysfs_ops = {
778         .show   = show,
779         .store  = store,
780 };
781
782 static struct kobj_type ktype_cache = {
783         .sysfs_ops      = &sysfs_ops,
784         .default_attrs  = default_attrs,
785 };
786
787 static struct kobj_type ktype_percpu_entry = {
788         .sysfs_ops      = &sysfs_ops,
789 };
790
791 static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
792 {
793         kfree(per_cpu(cache_kobject, cpu));
794         kfree(per_cpu(index_kobject, cpu));
795         per_cpu(cache_kobject, cpu) = NULL;
796         per_cpu(index_kobject, cpu) = NULL;
797         free_cache_attributes(cpu);
798 }
799
800 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
801 {
802         int err;
803
804         if (num_cache_leaves == 0)
805                 return -ENOENT;
806
807         err = detect_cache_attributes(cpu);
808         if (err)
809                 return err;
810
811         /* Allocate all required memory */
812         per_cpu(cache_kobject, cpu) =
813                 kzalloc(sizeof(struct kobject), GFP_KERNEL);
814         if (unlikely(per_cpu(cache_kobject, cpu) == NULL))
815                 goto err_out;
816
817         per_cpu(index_kobject, cpu) = kzalloc(
818             sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL);
819         if (unlikely(per_cpu(index_kobject, cpu) == NULL))
820                 goto err_out;
821
822         return 0;
823
824 err_out:
825         cpuid4_cache_sysfs_exit(cpu);
826         return -ENOMEM;
827 }
828
829 static cpumask_t cache_dev_map = CPU_MASK_NONE;
830
831 /* Add/Remove cache interface for CPU device */
832 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
833 {
834         unsigned int cpu = sys_dev->id;
835         unsigned long i, j;
836         struct _index_kobject *this_object;
837         int retval;
838
839         retval = cpuid4_cache_sysfs_init(cpu);
840         if (unlikely(retval < 0))
841                 return retval;
842
843         retval = kobject_init_and_add(per_cpu(cache_kobject, cpu),
844                                       &ktype_percpu_entry,
845                                       &sys_dev->kobj, "%s", "cache");
846         if (retval < 0) {
847                 cpuid4_cache_sysfs_exit(cpu);
848                 return retval;
849         }
850
851         for (i = 0; i < num_cache_leaves; i++) {
852                 this_object = INDEX_KOBJECT_PTR(cpu,i);
853                 this_object->cpu = cpu;
854                 this_object->index = i;
855                 retval = kobject_init_and_add(&(this_object->kobj),
856                                               &ktype_cache,
857                                               per_cpu(cache_kobject, cpu),
858                                               "index%1lu", i);
859                 if (unlikely(retval)) {
860                         for (j = 0; j < i; j++) {
861                                 kobject_put(&(INDEX_KOBJECT_PTR(cpu,j)->kobj));
862                         }
863                         kobject_put(per_cpu(cache_kobject, cpu));
864                         cpuid4_cache_sysfs_exit(cpu);
865                         return retval;
866                 }
867                 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
868         }
869         cpu_set(cpu, cache_dev_map);
870
871         kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
872         return 0;
873 }
874
875 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
876 {
877         unsigned int cpu = sys_dev->id;
878         unsigned long i;
879
880         if (per_cpu(cpuid4_info, cpu) == NULL)
881                 return;
882         if (!cpu_isset(cpu, cache_dev_map))
883                 return;
884         cpu_clear(cpu, cache_dev_map);
885
886         for (i = 0; i < num_cache_leaves; i++)
887                 kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
888         kobject_put(per_cpu(cache_kobject, cpu));
889         cpuid4_cache_sysfs_exit(cpu);
890 }
891
892 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
893                                         unsigned long action, void *hcpu)
894 {
895         unsigned int cpu = (unsigned long)hcpu;
896         struct sys_device *sys_dev;
897
898         sys_dev = get_cpu_sysdev(cpu);
899         switch (action) {
900         case CPU_ONLINE:
901         case CPU_ONLINE_FROZEN:
902                 cache_add_dev(sys_dev);
903                 break;
904         case CPU_DEAD:
905         case CPU_DEAD_FROZEN:
906                 cache_remove_dev(sys_dev);
907                 break;
908         }
909         return NOTIFY_OK;
910 }
911
912 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier =
913 {
914         .notifier_call = cacheinfo_cpu_callback,
915 };
916
917 static int __cpuinit cache_sysfs_init(void)
918 {
919         int i;
920
921         if (num_cache_leaves == 0)
922                 return 0;
923
924         for_each_online_cpu(i) {
925                 int err;
926                 struct sys_device *sys_dev = get_cpu_sysdev(i);
927
928                 err = cache_add_dev(sys_dev);
929                 if (err)
930                         return err;
931         }
932         register_hotcpu_notifier(&cacheinfo_cpu_notifier);
933         return 0;
934 }
935
936 device_initcall(cache_sysfs_init);
937
938 #endif