x86: L3 cache index disable for 2.6.26
[safe/jmp/linux-2.6] / 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 amd_check_l3_disable(int index, struct _cpuid4_info *this_leaf)
257 {
258         if (index < 3)
259                 return;
260         this_leaf->can_disable = 1;     
261 }
262
263 static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
264 {
265         union _cpuid4_leaf_eax  eax;
266         union _cpuid4_leaf_ebx  ebx;
267         union _cpuid4_leaf_ecx  ecx;
268         unsigned                edx;
269
270         if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
271                 amd_cpuid4(index, &eax, &ebx, &ecx);
272                 if (boot_cpu_data.x86 >= 0x10)
273                         amd_check_l3_disable(index, this_leaf);
274                         
275         } else
276                 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full,  &edx);
277         if (eax.split.type == CACHE_TYPE_NULL)
278                 return -EIO; /* better error ? */
279
280         this_leaf->eax = eax;
281         this_leaf->ebx = ebx;
282         this_leaf->ecx = ecx;
283         this_leaf->size = (ecx.split.number_of_sets + 1) *
284                 (ebx.split.coherency_line_size + 1) *
285                 (ebx.split.physical_line_partition + 1) *
286                 (ebx.split.ways_of_associativity + 1);
287         return 0;
288 }
289
290 static int __cpuinit find_num_cache_leaves(void)
291 {
292         unsigned int            eax, ebx, ecx, edx;
293         union _cpuid4_leaf_eax  cache_eax;
294         int                     i = -1;
295
296         do {
297                 ++i;
298                 /* Do cpuid(4) loop to find out num_cache_leaves */
299                 cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
300                 cache_eax.full = eax;
301         } while (cache_eax.split.type != CACHE_TYPE_NULL);
302         return i;
303 }
304
305 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
306 {
307         unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
308         unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
309         unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
310         unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
311 #ifdef CONFIG_X86_HT
312         unsigned int cpu = c->cpu_index;
313 #endif
314
315         if (c->cpuid_level > 3) {
316                 static int is_initialized;
317
318                 if (is_initialized == 0) {
319                         /* Init num_cache_leaves from boot CPU */
320                         num_cache_leaves = find_num_cache_leaves();
321                         is_initialized++;
322                 }
323
324                 /*
325                  * Whenever possible use cpuid(4), deterministic cache
326                  * parameters cpuid leaf to find the cache details
327                  */
328                 for (i = 0; i < num_cache_leaves; i++) {
329                         struct _cpuid4_info this_leaf;
330
331                         int retval;
332
333                         retval = cpuid4_cache_lookup(i, &this_leaf);
334                         if (retval >= 0) {
335                                 switch(this_leaf.eax.split.level) {
336                                     case 1:
337                                         if (this_leaf.eax.split.type ==
338                                                         CACHE_TYPE_DATA)
339                                                 new_l1d = this_leaf.size/1024;
340                                         else if (this_leaf.eax.split.type ==
341                                                         CACHE_TYPE_INST)
342                                                 new_l1i = this_leaf.size/1024;
343                                         break;
344                                     case 2:
345                                         new_l2 = this_leaf.size/1024;
346                                         num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
347                                         index_msb = get_count_order(num_threads_sharing);
348                                         l2_id = c->apicid >> index_msb;
349                                         break;
350                                     case 3:
351                                         new_l3 = this_leaf.size/1024;
352                                         num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
353                                         index_msb = get_count_order(num_threads_sharing);
354                                         l3_id = c->apicid >> index_msb;
355                                         break;
356                                     default:
357                                         break;
358                                 }
359                         }
360                 }
361         }
362         /*
363          * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
364          * trace cache
365          */
366         if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
367                 /* supports eax=2  call */
368                 int j, n;
369                 unsigned int regs[4];
370                 unsigned char *dp = (unsigned char *)regs;
371                 int only_trace = 0;
372
373                 if (num_cache_leaves != 0 && c->x86 == 15)
374                         only_trace = 1;
375
376                 /* Number of times to iterate */
377                 n = cpuid_eax(2) & 0xFF;
378
379                 for ( i = 0 ; i < n ; i++ ) {
380                         cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
381
382                         /* If bit 31 is set, this is an unknown format */
383                         for ( j = 0 ; j < 3 ; j++ ) {
384                                 if (regs[j] & (1 << 31)) regs[j] = 0;
385                         }
386
387                         /* Byte 0 is level count, not a descriptor */
388                         for ( j = 1 ; j < 16 ; j++ ) {
389                                 unsigned char des = dp[j];
390                                 unsigned char k = 0;
391
392                                 /* look up this descriptor in the table */
393                                 while (cache_table[k].descriptor != 0)
394                                 {
395                                         if (cache_table[k].descriptor == des) {
396                                                 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
397                                                         break;
398                                                 switch (cache_table[k].cache_type) {
399                                                 case LVL_1_INST:
400                                                         l1i += cache_table[k].size;
401                                                         break;
402                                                 case LVL_1_DATA:
403                                                         l1d += cache_table[k].size;
404                                                         break;
405                                                 case LVL_2:
406                                                         l2 += cache_table[k].size;
407                                                         break;
408                                                 case LVL_3:
409                                                         l3 += cache_table[k].size;
410                                                         break;
411                                                 case LVL_TRACE:
412                                                         trace += cache_table[k].size;
413                                                         break;
414                                                 }
415
416                                                 break;
417                                         }
418
419                                         k++;
420                                 }
421                         }
422                 }
423         }
424
425         if (new_l1d)
426                 l1d = new_l1d;
427
428         if (new_l1i)
429                 l1i = new_l1i;
430
431         if (new_l2) {
432                 l2 = new_l2;
433 #ifdef CONFIG_X86_HT
434                 per_cpu(cpu_llc_id, cpu) = l2_id;
435 #endif
436         }
437
438         if (new_l3) {
439                 l3 = new_l3;
440 #ifdef CONFIG_X86_HT
441                 per_cpu(cpu_llc_id, cpu) = l3_id;
442 #endif
443         }
444
445         if (trace)
446                 printk (KERN_INFO "CPU: Trace cache: %dK uops", trace);
447         else if ( l1i )
448                 printk (KERN_INFO "CPU: L1 I cache: %dK", l1i);
449
450         if (l1d)
451                 printk(", L1 D cache: %dK\n", l1d);
452         else
453                 printk("\n");
454
455         if (l2)
456                 printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
457
458         if (l3)
459                 printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
460
461         c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
462
463         return l2;
464 }
465
466 /* pointer to _cpuid4_info array (for each cache leaf) */
467 static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info);
468 #define CPUID4_INFO_IDX(x, y)    (&((per_cpu(cpuid4_info, x))[y]))
469
470 #ifdef CONFIG_SMP
471 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
472 {
473         struct _cpuid4_info     *this_leaf, *sibling_leaf;
474         unsigned long num_threads_sharing;
475         int index_msb, i;
476         struct cpuinfo_x86 *c = &cpu_data(cpu);
477
478         this_leaf = CPUID4_INFO_IDX(cpu, index);
479         num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
480
481         if (num_threads_sharing == 1)
482                 cpu_set(cpu, this_leaf->shared_cpu_map);
483         else {
484                 index_msb = get_count_order(num_threads_sharing);
485
486                 for_each_online_cpu(i) {
487                         if (cpu_data(i).apicid >> index_msb ==
488                             c->apicid >> index_msb) {
489                                 cpu_set(i, this_leaf->shared_cpu_map);
490                                 if (i != cpu && per_cpu(cpuid4_info, i))  {
491                                         sibling_leaf = CPUID4_INFO_IDX(i, index);
492                                         cpu_set(cpu, sibling_leaf->shared_cpu_map);
493                                 }
494                         }
495                 }
496         }
497 }
498 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
499 {
500         struct _cpuid4_info     *this_leaf, *sibling_leaf;
501         int sibling;
502
503         this_leaf = CPUID4_INFO_IDX(cpu, index);
504         for_each_cpu_mask(sibling, this_leaf->shared_cpu_map) {
505                 sibling_leaf = CPUID4_INFO_IDX(sibling, index); 
506                 cpu_clear(cpu, sibling_leaf->shared_cpu_map);
507         }
508 }
509 #else
510 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
511 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
512 #endif
513
514 static void __cpuinit free_cache_attributes(unsigned int cpu)
515 {
516         int i;
517
518         for (i = 0; i < num_cache_leaves; i++)
519                 cache_remove_shared_cpu_map(cpu, i);
520
521         kfree(per_cpu(cpuid4_info, cpu));
522         per_cpu(cpuid4_info, cpu) = NULL;
523 }
524
525 static int __cpuinit detect_cache_attributes(unsigned int cpu)
526 {
527         struct _cpuid4_info     *this_leaf;
528         unsigned long           j;
529         int                     retval;
530         cpumask_t               oldmask;
531
532         if (num_cache_leaves == 0)
533                 return -ENOENT;
534
535         per_cpu(cpuid4_info, cpu) = kzalloc(
536             sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
537         if (per_cpu(cpuid4_info, cpu) == NULL)
538                 return -ENOMEM;
539
540         oldmask = current->cpus_allowed;
541         retval = set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu));
542         if (retval)
543                 goto out;
544
545         /* Do cpuid and store the results */
546         for (j = 0; j < num_cache_leaves; j++) {
547                 this_leaf = CPUID4_INFO_IDX(cpu, j);
548                 retval = cpuid4_cache_lookup(j, this_leaf);
549                 if (unlikely(retval < 0)) {
550                         int i;
551
552                         for (i = 0; i < j; i++)
553                                 cache_remove_shared_cpu_map(cpu, i);
554                         break;
555                 }
556                 cache_shared_cpu_map_setup(cpu, j);
557         }
558         set_cpus_allowed_ptr(current, &oldmask);
559
560 out:
561         if (retval) {
562                 kfree(per_cpu(cpuid4_info, cpu));
563                 per_cpu(cpuid4_info, cpu) = NULL;
564         }
565
566         return retval;
567 }
568
569 #ifdef CONFIG_SYSFS
570
571 #include <linux/kobject.h>
572 #include <linux/sysfs.h>
573
574 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
575
576 /* pointer to kobject for cpuX/cache */
577 static DEFINE_PER_CPU(struct kobject *, cache_kobject);
578
579 struct _index_kobject {
580         struct kobject kobj;
581         unsigned int cpu;
582         unsigned short index;
583 };
584
585 /* pointer to array of kobjects for cpuX/cache/indexY */
586 static DEFINE_PER_CPU(struct _index_kobject *, index_kobject);
587 #define INDEX_KOBJECT_PTR(x, y)    (&((per_cpu(index_kobject, x))[y]))
588
589 #define show_one_plus(file_name, object, val)                           \
590 static ssize_t show_##file_name                                         \
591                         (struct _cpuid4_info *this_leaf, char *buf)     \
592 {                                                                       \
593         return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \
594 }
595
596 show_one_plus(level, eax.split.level, 0);
597 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
598 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
599 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
600 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
601
602 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
603 {
604         return sprintf (buf, "%luK\n", this_leaf->size / 1024);
605 }
606
607 static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
608                                         int type, char *buf)
609 {
610         ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
611         int n = 0;
612
613         if (len > 1) {
614                 cpumask_t *mask = &this_leaf->shared_cpu_map;
615
616                 n = type?
617                         cpulist_scnprintf(buf, len-2, *mask):
618                         cpumask_scnprintf(buf, len-2, *mask);
619                 buf[n++] = '\n';
620                 buf[n] = '\0';
621         }
622         return n;
623 }
624
625 static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf)
626 {
627         return show_shared_cpu_map_func(leaf, 0, buf);
628 }
629
630 static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf)
631 {
632         return show_shared_cpu_map_func(leaf, 1, buf);
633 }
634
635 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf) {
636         switch(this_leaf->eax.split.type) {
637             case CACHE_TYPE_DATA:
638                 return sprintf(buf, "Data\n");
639                 break;
640             case CACHE_TYPE_INST:
641                 return sprintf(buf, "Instruction\n");
642                 break;
643             case CACHE_TYPE_UNIFIED:
644                 return sprintf(buf, "Unified\n");
645                 break;
646             default:
647                 return sprintf(buf, "Unknown\n");
648                 break;
649         }
650 }
651
652 #define to_object(k) container_of(k, struct _index_kobject, kobj)
653 #define to_attr(a) container_of(a, struct _cache_attr, attr)
654
655 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf)
656 {
657         struct pci_dev *dev;
658         if (this_leaf->can_disable) {
659                 int i;
660                 ssize_t ret = 0;
661                 int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map));
662                 dev = k8_northbridges[node];
663
664                 for (i = 0; i < 2; i++) {
665                         unsigned int reg;
666                         pci_read_config_dword(dev, 0x1BC + i * 4, &reg);
667                         ret += sprintf(buf, "%sEntry: %d\n", buf, i);
668                         ret += sprintf(buf, "%sReads:  %s\tNew Entries: %s\n",  
669                                 buf,
670                                 reg & 0x80000000 ? "Disabled" : "Allowed",
671                                 reg & 0x40000000 ? "Disabled" : "Allowed");
672                         ret += sprintf(buf, "%sSubCache: %x\tIndex: %x\n", buf,
673                                 (reg & 0x30000) >> 16, reg & 0xfff);
674
675                 }
676                 return ret;
677         }
678         return sprintf(buf, "Feature not enabled\n");
679 }
680
681 static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf, size_t count)
682 {
683         struct pci_dev *dev;
684         if (this_leaf->can_disable) {
685                 /* write the MSR value */
686                 unsigned int ret;
687                 unsigned int index, val;
688                 int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map));
689                 dev = k8_northbridges[node];
690
691                 if (strlen(buf) > 15)
692                         return -EINVAL;
693                 ret = sscanf(buf, "%x %x", &index, &val);
694                 if (ret != 2)
695                         return -EINVAL;
696                 if (index > 1)
697                         return -EINVAL;
698                 val |= 0xc0000000;
699                 pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000);
700                 wbinvd();
701                 pci_write_config_dword(dev, 0x1BC + index * 4, val);
702                 return 1;
703         }
704         return 0;
705 }
706
707 struct _cache_attr {
708         struct attribute attr;
709         ssize_t (*show)(struct _cpuid4_info *, char *);
710         ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
711 };
712
713 #define define_one_ro(_name) \
714 static struct _cache_attr _name = \
715         __ATTR(_name, 0444, show_##_name, NULL)
716
717 define_one_ro(level);
718 define_one_ro(type);
719 define_one_ro(coherency_line_size);
720 define_one_ro(physical_line_partition);
721 define_one_ro(ways_of_associativity);
722 define_one_ro(number_of_sets);
723 define_one_ro(size);
724 define_one_ro(shared_cpu_map);
725 define_one_ro(shared_cpu_list);
726
727 static struct _cache_attr cache_disable = __ATTR(cache_disable, 0644, show_cache_disable, store_cache_disable);
728
729 static struct attribute * default_attrs[] = {
730         &type.attr,
731         &level.attr,
732         &coherency_line_size.attr,
733         &physical_line_partition.attr,
734         &ways_of_associativity.attr,
735         &number_of_sets.attr,
736         &size.attr,
737         &shared_cpu_map.attr,
738         &shared_cpu_list.attr,
739         &cache_disable.attr,
740         NULL
741 };
742
743 static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf)
744 {
745         struct _cache_attr *fattr = to_attr(attr);
746         struct _index_kobject *this_leaf = to_object(kobj);
747         ssize_t ret;
748
749         ret = fattr->show ?
750                 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
751                         buf) :
752                 0;
753         return ret;
754 }
755
756 static ssize_t store(struct kobject * kobj, struct attribute * attr,
757                      const char * buf, size_t count)
758 {
759         struct _cache_attr *fattr = to_attr(attr);
760         struct _index_kobject *this_leaf = to_object(kobj);
761         ssize_t ret;
762
763         ret = fattr->store ?
764                 fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
765                         buf, count) :
766                 0;
767         return ret;
768 }
769
770 static struct sysfs_ops sysfs_ops = {
771         .show   = show,
772         .store  = store,
773 };
774
775 static struct kobj_type ktype_cache = {
776         .sysfs_ops      = &sysfs_ops,
777         .default_attrs  = default_attrs,
778 };
779
780 static struct kobj_type ktype_percpu_entry = {
781         .sysfs_ops      = &sysfs_ops,
782 };
783
784 static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
785 {
786         kfree(per_cpu(cache_kobject, cpu));
787         kfree(per_cpu(index_kobject, cpu));
788         per_cpu(cache_kobject, cpu) = NULL;
789         per_cpu(index_kobject, cpu) = NULL;
790         free_cache_attributes(cpu);
791 }
792
793 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
794 {
795         int err;
796
797         if (num_cache_leaves == 0)
798                 return -ENOENT;
799
800         err = detect_cache_attributes(cpu);
801         if (err)
802                 return err;
803
804         /* Allocate all required memory */
805         per_cpu(cache_kobject, cpu) =
806                 kzalloc(sizeof(struct kobject), GFP_KERNEL);
807         if (unlikely(per_cpu(cache_kobject, cpu) == NULL))
808                 goto err_out;
809
810         per_cpu(index_kobject, cpu) = kzalloc(
811             sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL);
812         if (unlikely(per_cpu(index_kobject, cpu) == NULL))
813                 goto err_out;
814
815         return 0;
816
817 err_out:
818         cpuid4_cache_sysfs_exit(cpu);
819         return -ENOMEM;
820 }
821
822 static cpumask_t cache_dev_map = CPU_MASK_NONE;
823
824 /* Add/Remove cache interface for CPU device */
825 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
826 {
827         unsigned int cpu = sys_dev->id;
828         unsigned long i, j;
829         struct _index_kobject *this_object;
830         int retval;
831
832         retval = cpuid4_cache_sysfs_init(cpu);
833         if (unlikely(retval < 0))
834                 return retval;
835
836         retval = kobject_init_and_add(per_cpu(cache_kobject, cpu),
837                                       &ktype_percpu_entry,
838                                       &sys_dev->kobj, "%s", "cache");
839         if (retval < 0) {
840                 cpuid4_cache_sysfs_exit(cpu);
841                 return retval;
842         }
843
844         for (i = 0; i < num_cache_leaves; i++) {
845                 this_object = INDEX_KOBJECT_PTR(cpu,i);
846                 this_object->cpu = cpu;
847                 this_object->index = i;
848                 retval = kobject_init_and_add(&(this_object->kobj),
849                                               &ktype_cache,
850                                               per_cpu(cache_kobject, cpu),
851                                               "index%1lu", i);
852                 if (unlikely(retval)) {
853                         for (j = 0; j < i; j++) {
854                                 kobject_put(&(INDEX_KOBJECT_PTR(cpu,j)->kobj));
855                         }
856                         kobject_put(per_cpu(cache_kobject, cpu));
857                         cpuid4_cache_sysfs_exit(cpu);
858                         return retval;
859                 }
860                 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
861         }
862         cpu_set(cpu, cache_dev_map);
863
864         kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
865         return 0;
866 }
867
868 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
869 {
870         unsigned int cpu = sys_dev->id;
871         unsigned long i;
872
873         if (per_cpu(cpuid4_info, cpu) == NULL)
874                 return;
875         if (!cpu_isset(cpu, cache_dev_map))
876                 return;
877         cpu_clear(cpu, cache_dev_map);
878
879         for (i = 0; i < num_cache_leaves; i++)
880                 kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
881         kobject_put(per_cpu(cache_kobject, cpu));
882         cpuid4_cache_sysfs_exit(cpu);
883 }
884
885 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
886                                         unsigned long action, void *hcpu)
887 {
888         unsigned int cpu = (unsigned long)hcpu;
889         struct sys_device *sys_dev;
890
891         sys_dev = get_cpu_sysdev(cpu);
892         switch (action) {
893         case CPU_ONLINE:
894         case CPU_ONLINE_FROZEN:
895                 cache_add_dev(sys_dev);
896                 break;
897         case CPU_DEAD:
898         case CPU_DEAD_FROZEN:
899                 cache_remove_dev(sys_dev);
900                 break;
901         }
902         return NOTIFY_OK;
903 }
904
905 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier =
906 {
907         .notifier_call = cacheinfo_cpu_callback,
908 };
909
910 static int __cpuinit cache_sysfs_init(void)
911 {
912         int i;
913
914         if (num_cache_leaves == 0)
915                 return 0;
916
917         for_each_online_cpu(i) {
918                 int err;
919                 struct sys_device *sys_dev = get_cpu_sysdev(i);
920
921                 err = cache_add_dev(sys_dev);
922                 if (err)
923                         return err;
924         }
925         register_hotcpu_notifier(&cacheinfo_cpu_notifier);
926         return 0;
927 }
928
929 device_initcall(cache_sysfs_init);
930
931 #endif