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