]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/x86/kernel/cpu/intel_cacheinfo.c
Merge branch 'linus' into x86/cpu
[linux-2.6-omap-h63xx.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_nr(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         cpumask_of_cpu_ptr(newmask, cpu);
542
543         if (num_cache_leaves == 0)
544                 return -ENOENT;
545
546         per_cpu(cpuid4_info, cpu) = kzalloc(
547             sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
548         if (per_cpu(cpuid4_info, cpu) == NULL)
549                 return -ENOMEM;
550
551         oldmask = current->cpus_allowed;
552         retval = set_cpus_allowed_ptr(current, newmask);
553         if (retval)
554                 goto out;
555
556         /* Do cpuid and store the results */
557         for (j = 0; j < num_cache_leaves; j++) {
558                 this_leaf = CPUID4_INFO_IDX(cpu, j);
559                 retval = cpuid4_cache_lookup(j, this_leaf);
560                 if (unlikely(retval < 0)) {
561                         int i;
562
563                         for (i = 0; i < j; i++)
564                                 cache_remove_shared_cpu_map(cpu, i);
565                         break;
566                 }
567                 cache_shared_cpu_map_setup(cpu, j);
568         }
569         set_cpus_allowed_ptr(current, &oldmask);
570
571 out:
572         if (retval) {
573                 kfree(per_cpu(cpuid4_info, cpu));
574                 per_cpu(cpuid4_info, cpu) = NULL;
575         }
576
577         return retval;
578 }
579
580 #ifdef CONFIG_SYSFS
581
582 #include <linux/kobject.h>
583 #include <linux/sysfs.h>
584
585 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
586
587 /* pointer to kobject for cpuX/cache */
588 static DEFINE_PER_CPU(struct kobject *, cache_kobject);
589
590 struct _index_kobject {
591         struct kobject kobj;
592         unsigned int cpu;
593         unsigned short index;
594 };
595
596 /* pointer to array of kobjects for cpuX/cache/indexY */
597 static DEFINE_PER_CPU(struct _index_kobject *, index_kobject);
598 #define INDEX_KOBJECT_PTR(x, y)         (&((per_cpu(index_kobject, x))[y]))
599
600 #define show_one_plus(file_name, object, val)                           \
601 static ssize_t show_##file_name                                         \
602                         (struct _cpuid4_info *this_leaf, char *buf)     \
603 {                                                                       \
604         return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \
605 }
606
607 show_one_plus(level, eax.split.level, 0);
608 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
609 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
610 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
611 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
612
613 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
614 {
615         return sprintf (buf, "%luK\n", this_leaf->size / 1024);
616 }
617
618 static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
619                                         int type, char *buf)
620 {
621         ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
622         int n = 0;
623
624         if (len > 1) {
625                 cpumask_t *mask = &this_leaf->shared_cpu_map;
626
627                 n = type?
628                         cpulist_scnprintf(buf, len-2, *mask):
629                         cpumask_scnprintf(buf, len-2, *mask);
630                 buf[n++] = '\n';
631                 buf[n] = '\0';
632         }
633         return n;
634 }
635
636 static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf)
637 {
638         return show_shared_cpu_map_func(leaf, 0, buf);
639 }
640
641 static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf)
642 {
643         return show_shared_cpu_map_func(leaf, 1, buf);
644 }
645
646 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf) {
647         switch(this_leaf->eax.split.type) {
648             case CACHE_TYPE_DATA:
649                 return sprintf(buf, "Data\n");
650                 break;
651             case CACHE_TYPE_INST:
652                 return sprintf(buf, "Instruction\n");
653                 break;
654             case CACHE_TYPE_UNIFIED:
655                 return sprintf(buf, "Unified\n");
656                 break;
657             default:
658                 return sprintf(buf, "Unknown\n");
659                 break;
660         }
661 }
662
663 #define to_object(k)    container_of(k, struct _index_kobject, kobj)
664 #define to_attr(a)      container_of(a, struct _cache_attr, attr)
665
666 static struct pci_dev *get_k8_northbridge(int node)
667 {
668         struct pci_dev *dev = NULL;
669         int i;
670
671         for (i = 0; i <= node; i++) {
672                 do {
673                         dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
674                         if (!dev)
675                                 break;
676                 } while (!pci_match_id(&k8_nb_id[0], dev));
677                 if (!dev)
678                         break;
679         }
680         return dev;
681 }
682
683 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf)
684 {
685         int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map));
686         struct pci_dev *dev = NULL;
687         ssize_t ret = 0;
688         int i;
689
690         if (!this_leaf->can_disable)
691                 return sprintf(buf, "Feature not enabled\n");
692
693         dev = get_k8_northbridge(node);
694         if (!dev) {
695                 printk(KERN_ERR "Attempting AMD northbridge operation on a system with no northbridge\n");
696                 return -EINVAL;
697         }
698
699         for (i = 0; i < 2; i++) {
700                 unsigned int reg;
701
702                 pci_read_config_dword(dev, 0x1BC + i * 4, &reg);
703
704                 ret += sprintf(buf, "%sEntry: %d\n", buf, i);
705                 ret += sprintf(buf, "%sReads:  %s\tNew Entries: %s\n",  
706                         buf,
707                         reg & 0x80000000 ? "Disabled" : "Allowed",
708                         reg & 0x40000000 ? "Disabled" : "Allowed");
709                 ret += sprintf(buf, "%sSubCache: %x\tIndex: %x\n",
710                         buf, (reg & 0x30000) >> 16, reg & 0xfff);
711         }
712         return ret;
713 }
714
715 static ssize_t
716 store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf,
717                     size_t count)
718 {
719         int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map));
720         struct pci_dev *dev = NULL;
721         unsigned int ret, index, val;
722
723         if (!this_leaf->can_disable)
724                 return 0;
725
726         if (strlen(buf) > 15)
727                 return -EINVAL;
728
729         ret = sscanf(buf, "%x %x", &index, &val);
730         if (ret != 2)
731                 return -EINVAL;
732         if (index > 1)
733                 return -EINVAL;
734
735         val |= 0xc0000000;
736         dev = get_k8_northbridge(node);
737         if (!dev) {
738                 printk(KERN_ERR "Attempting AMD northbridge operation on a system with no northbridge\n");
739                 return -EINVAL;
740         }
741
742         pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000);
743         wbinvd();
744         pci_write_config_dword(dev, 0x1BC + index * 4, val);
745
746         return 1;
747 }
748
749 struct _cache_attr {
750         struct attribute attr;
751         ssize_t (*show)(struct _cpuid4_info *, char *);
752         ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
753 };
754
755 #define define_one_ro(_name) \
756 static struct _cache_attr _name = \
757         __ATTR(_name, 0444, show_##_name, NULL)
758
759 define_one_ro(level);
760 define_one_ro(type);
761 define_one_ro(coherency_line_size);
762 define_one_ro(physical_line_partition);
763 define_one_ro(ways_of_associativity);
764 define_one_ro(number_of_sets);
765 define_one_ro(size);
766 define_one_ro(shared_cpu_map);
767 define_one_ro(shared_cpu_list);
768
769 static struct _cache_attr cache_disable = __ATTR(cache_disable, 0644, show_cache_disable, store_cache_disable);
770
771 static struct attribute * default_attrs[] = {
772         &type.attr,
773         &level.attr,
774         &coherency_line_size.attr,
775         &physical_line_partition.attr,
776         &ways_of_associativity.attr,
777         &number_of_sets.attr,
778         &size.attr,
779         &shared_cpu_map.attr,
780         &shared_cpu_list.attr,
781         &cache_disable.attr,
782         NULL
783 };
784
785 static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf)
786 {
787         struct _cache_attr *fattr = to_attr(attr);
788         struct _index_kobject *this_leaf = to_object(kobj);
789         ssize_t ret;
790
791         ret = fattr->show ?
792                 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
793                         buf) :
794                 0;
795         return ret;
796 }
797
798 static ssize_t store(struct kobject * kobj, struct attribute * attr,
799                      const char * buf, size_t count)
800 {
801         struct _cache_attr *fattr = to_attr(attr);
802         struct _index_kobject *this_leaf = to_object(kobj);
803         ssize_t ret;
804
805         ret = fattr->store ?
806                 fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
807                         buf, count) :
808                 0;
809         return ret;
810 }
811
812 static struct sysfs_ops sysfs_ops = {
813         .show   = show,
814         .store  = store,
815 };
816
817 static struct kobj_type ktype_cache = {
818         .sysfs_ops      = &sysfs_ops,
819         .default_attrs  = default_attrs,
820 };
821
822 static struct kobj_type ktype_percpu_entry = {
823         .sysfs_ops      = &sysfs_ops,
824 };
825
826 static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
827 {
828         kfree(per_cpu(cache_kobject, cpu));
829         kfree(per_cpu(index_kobject, cpu));
830         per_cpu(cache_kobject, cpu) = NULL;
831         per_cpu(index_kobject, cpu) = NULL;
832         free_cache_attributes(cpu);
833 }
834
835 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
836 {
837         int err;
838
839         if (num_cache_leaves == 0)
840                 return -ENOENT;
841
842         err = detect_cache_attributes(cpu);
843         if (err)
844                 return err;
845
846         /* Allocate all required memory */
847         per_cpu(cache_kobject, cpu) =
848                 kzalloc(sizeof(struct kobject), GFP_KERNEL);
849         if (unlikely(per_cpu(cache_kobject, cpu) == NULL))
850                 goto err_out;
851
852         per_cpu(index_kobject, cpu) = kzalloc(
853             sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL);
854         if (unlikely(per_cpu(index_kobject, cpu) == NULL))
855                 goto err_out;
856
857         return 0;
858
859 err_out:
860         cpuid4_cache_sysfs_exit(cpu);
861         return -ENOMEM;
862 }
863
864 static cpumask_t cache_dev_map = CPU_MASK_NONE;
865
866 /* Add/Remove cache interface for CPU device */
867 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
868 {
869         unsigned int cpu = sys_dev->id;
870         unsigned long i, j;
871         struct _index_kobject *this_object;
872         int retval;
873
874         retval = cpuid4_cache_sysfs_init(cpu);
875         if (unlikely(retval < 0))
876                 return retval;
877
878         retval = kobject_init_and_add(per_cpu(cache_kobject, cpu),
879                                       &ktype_percpu_entry,
880                                       &sys_dev->kobj, "%s", "cache");
881         if (retval < 0) {
882                 cpuid4_cache_sysfs_exit(cpu);
883                 return retval;
884         }
885
886         for (i = 0; i < num_cache_leaves; i++) {
887                 this_object = INDEX_KOBJECT_PTR(cpu,i);
888                 this_object->cpu = cpu;
889                 this_object->index = i;
890                 retval = kobject_init_and_add(&(this_object->kobj),
891                                               &ktype_cache,
892                                               per_cpu(cache_kobject, cpu),
893                                               "index%1lu", i);
894                 if (unlikely(retval)) {
895                         for (j = 0; j < i; j++) {
896                                 kobject_put(&(INDEX_KOBJECT_PTR(cpu,j)->kobj));
897                         }
898                         kobject_put(per_cpu(cache_kobject, cpu));
899                         cpuid4_cache_sysfs_exit(cpu);
900                         return retval;
901                 }
902                 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
903         }
904         cpu_set(cpu, cache_dev_map);
905
906         kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
907         return 0;
908 }
909
910 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
911 {
912         unsigned int cpu = sys_dev->id;
913         unsigned long i;
914
915         if (per_cpu(cpuid4_info, cpu) == NULL)
916                 return;
917         if (!cpu_isset(cpu, cache_dev_map))
918                 return;
919         cpu_clear(cpu, cache_dev_map);
920
921         for (i = 0; i < num_cache_leaves; i++)
922                 kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
923         kobject_put(per_cpu(cache_kobject, cpu));
924         cpuid4_cache_sysfs_exit(cpu);
925 }
926
927 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
928                                         unsigned long action, void *hcpu)
929 {
930         unsigned int cpu = (unsigned long)hcpu;
931         struct sys_device *sys_dev;
932
933         sys_dev = get_cpu_sysdev(cpu);
934         switch (action) {
935         case CPU_ONLINE:
936         case CPU_ONLINE_FROZEN:
937                 cache_add_dev(sys_dev);
938                 break;
939         case CPU_DEAD:
940         case CPU_DEAD_FROZEN:
941                 cache_remove_dev(sys_dev);
942                 break;
943         }
944         return NOTIFY_OK;
945 }
946
947 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier =
948 {
949         .notifier_call = cacheinfo_cpu_callback,
950 };
951
952 static int __cpuinit cache_sysfs_init(void)
953 {
954         int i;
955
956         if (num_cache_leaves == 0)
957                 return 0;
958
959         for_each_online_cpu(i) {
960                 int err;
961                 struct sys_device *sys_dev = get_cpu_sysdev(i);
962
963                 err = cache_add_dev(sys_dev);
964                 if (err)
965                         return err;
966         }
967         register_hotcpu_notifier(&cacheinfo_cpu_notifier);
968         return 0;
969 }
970
971 device_initcall(cache_sysfs_init);
972
973 #endif