x86: intel_cacheinfo: fix compiler warning
[linux-2.6/x86.git] / arch / x86 / kernel / cpu / intel_cacheinfo.c
blob51b5dfd6716366329e4cb3f04ebe3987ba837026
1 /*
2 * Routines to indentify caches on Intel CPU.
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 */
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>
18 #include <asm/processor.h>
19 #include <asm/smp.h>
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
27 struct _cache_table
29 unsigned char descriptor;
30 char cache_type;
31 short size;
34 /* all the cache descriptor types we care about (no TLB or trace cache entries) */
35 static struct _cache_table cache_table[] __cpuinitdata =
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}
92 enum _cache_type
94 CACHE_TYPE_NULL = 0,
95 CACHE_TYPE_DATA = 1,
96 CACHE_TYPE_INST = 2,
97 CACHE_TYPE_UNIFIED = 3
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;
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;
122 union _cpuid4_leaf_ecx {
123 struct {
124 unsigned int number_of_sets:32;
125 } split;
126 u32 full;
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 DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
138 /* subset of above _cpuid4_info w/o shared_cpu_map */
139 struct _cpuid4_info_regs {
140 union _cpuid4_leaf_eax eax;
141 union _cpuid4_leaf_ebx ebx;
142 union _cpuid4_leaf_ecx ecx;
143 unsigned long size;
144 unsigned long can_disable;
147 #ifdef CONFIG_PCI
148 static struct pci_device_id k8_nb_id[] = {
149 { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) },
150 { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1203) },
153 #endif
155 unsigned short num_cache_leaves;
157 /* AMD doesn't have CPUID4. Emulate it here to report the same
158 information to the user. This makes some assumptions about the machine:
159 L2 not shared, no SMT etc. that is currently true on AMD CPUs.
161 In theory the TLBs could be reported as fake type (they are in "dummy").
162 Maybe later */
163 union l1_cache {
164 struct {
165 unsigned line_size : 8;
166 unsigned lines_per_tag : 8;
167 unsigned assoc : 8;
168 unsigned size_in_kb : 8;
170 unsigned val;
173 union l2_cache {
174 struct {
175 unsigned line_size : 8;
176 unsigned lines_per_tag : 4;
177 unsigned assoc : 4;
178 unsigned size_in_kb : 16;
180 unsigned val;
183 union l3_cache {
184 struct {
185 unsigned line_size : 8;
186 unsigned lines_per_tag : 4;
187 unsigned assoc : 4;
188 unsigned res : 2;
189 unsigned size_encoded : 14;
191 unsigned val;
194 static unsigned short assocs[] __cpuinitdata = {
195 [1] = 1, [2] = 2, [4] = 4, [6] = 8,
196 [8] = 16, [0xa] = 32, [0xb] = 48,
197 [0xc] = 64,
198 [0xf] = 0xffff // ??
201 static unsigned char levels[] __cpuinitdata = { 1, 1, 2, 3 };
202 static unsigned char types[] __cpuinitdata = { 1, 2, 3, 3 };
204 static void __cpuinit
205 amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
206 union _cpuid4_leaf_ebx *ebx,
207 union _cpuid4_leaf_ecx *ecx)
209 unsigned dummy;
210 unsigned line_size, lines_per_tag, assoc, size_in_kb;
211 union l1_cache l1i, l1d;
212 union l2_cache l2;
213 union l3_cache l3;
214 union l1_cache *l1 = &l1d;
216 eax->full = 0;
217 ebx->full = 0;
218 ecx->full = 0;
220 cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
221 cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
223 switch (leaf) {
224 case 1:
225 l1 = &l1i;
226 case 0:
227 if (!l1->val)
228 return;
229 assoc = l1->assoc;
230 line_size = l1->line_size;
231 lines_per_tag = l1->lines_per_tag;
232 size_in_kb = l1->size_in_kb;
233 break;
234 case 2:
235 if (!l2.val)
236 return;
237 assoc = l2.assoc;
238 line_size = l2.line_size;
239 lines_per_tag = l2.lines_per_tag;
240 /* cpu_data has errata corrections for K7 applied */
241 size_in_kb = current_cpu_data.x86_cache_size;
242 break;
243 case 3:
244 if (!l3.val)
245 return;
246 assoc = l3.assoc;
247 line_size = l3.line_size;
248 lines_per_tag = l3.lines_per_tag;
249 size_in_kb = l3.size_encoded * 512;
250 break;
251 default:
252 return;
255 eax->split.is_self_initializing = 1;
256 eax->split.type = types[leaf];
257 eax->split.level = levels[leaf];
258 if (leaf == 3)
259 eax->split.num_threads_sharing = current_cpu_data.x86_max_cores - 1;
260 else
261 eax->split.num_threads_sharing = 0;
262 eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
265 if (assoc == 0xf)
266 eax->split.is_fully_associative = 1;
267 ebx->split.coherency_line_size = line_size - 1;
268 ebx->split.ways_of_associativity = assocs[assoc] - 1;
269 ebx->split.physical_line_partition = lines_per_tag - 1;
270 ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
271 (ebx->split.ways_of_associativity + 1) - 1;
274 static void __cpuinit
275 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
277 if (index < 3)
278 return;
279 this_leaf->can_disable = 1;
282 static int
283 __cpuinit cpuid4_cache_lookup_regs(int index,
284 struct _cpuid4_info_regs *this_leaf)
286 union _cpuid4_leaf_eax eax;
287 union _cpuid4_leaf_ebx ebx;
288 union _cpuid4_leaf_ecx ecx;
289 unsigned edx;
291 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
292 amd_cpuid4(index, &eax, &ebx, &ecx);
293 if (boot_cpu_data.x86 >= 0x10)
294 amd_check_l3_disable(index, this_leaf);
295 } else {
296 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
299 if (eax.split.type == CACHE_TYPE_NULL)
300 return -EIO; /* better error ? */
302 this_leaf->eax = eax;
303 this_leaf->ebx = ebx;
304 this_leaf->ecx = ecx;
305 this_leaf->size = (ecx.split.number_of_sets + 1) *
306 (ebx.split.coherency_line_size + 1) *
307 (ebx.split.physical_line_partition + 1) *
308 (ebx.split.ways_of_associativity + 1);
309 return 0;
312 static int __cpuinit find_num_cache_leaves(void)
314 unsigned int eax, ebx, ecx, edx;
315 union _cpuid4_leaf_eax cache_eax;
316 int i = -1;
318 do {
319 ++i;
320 /* Do cpuid(4) loop to find out num_cache_leaves */
321 cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
322 cache_eax.full = eax;
323 } while (cache_eax.split.type != CACHE_TYPE_NULL);
324 return i;
327 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
329 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
330 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
331 unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
332 unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
333 #ifdef CONFIG_X86_HT
334 unsigned int cpu = c->cpu_index;
335 #endif
337 if (c->cpuid_level > 3) {
338 static int is_initialized;
340 if (is_initialized == 0) {
341 /* Init num_cache_leaves from boot CPU */
342 num_cache_leaves = find_num_cache_leaves();
343 is_initialized++;
347 * Whenever possible use cpuid(4), deterministic cache
348 * parameters cpuid leaf to find the cache details
350 for (i = 0; i < num_cache_leaves; i++) {
351 struct _cpuid4_info_regs this_leaf;
352 int retval;
354 retval = cpuid4_cache_lookup_regs(i, &this_leaf);
355 if (retval >= 0) {
356 switch(this_leaf.eax.split.level) {
357 case 1:
358 if (this_leaf.eax.split.type ==
359 CACHE_TYPE_DATA)
360 new_l1d = this_leaf.size/1024;
361 else if (this_leaf.eax.split.type ==
362 CACHE_TYPE_INST)
363 new_l1i = this_leaf.size/1024;
364 break;
365 case 2:
366 new_l2 = this_leaf.size/1024;
367 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
368 index_msb = get_count_order(num_threads_sharing);
369 l2_id = c->apicid >> index_msb;
370 break;
371 case 3:
372 new_l3 = this_leaf.size/1024;
373 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
374 index_msb = get_count_order(num_threads_sharing);
375 l3_id = c->apicid >> index_msb;
376 break;
377 default:
378 break;
384 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
385 * trace cache
387 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
388 /* supports eax=2 call */
389 int j, n;
390 unsigned int regs[4];
391 unsigned char *dp = (unsigned char *)regs;
392 int only_trace = 0;
394 if (num_cache_leaves != 0 && c->x86 == 15)
395 only_trace = 1;
397 /* Number of times to iterate */
398 n = cpuid_eax(2) & 0xFF;
400 for ( i = 0 ; i < n ; i++ ) {
401 cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
403 /* If bit 31 is set, this is an unknown format */
404 for ( j = 0 ; j < 3 ; j++ ) {
405 if (regs[j] & (1 << 31)) regs[j] = 0;
408 /* Byte 0 is level count, not a descriptor */
409 for ( j = 1 ; j < 16 ; j++ ) {
410 unsigned char des = dp[j];
411 unsigned char k = 0;
413 /* look up this descriptor in the table */
414 while (cache_table[k].descriptor != 0)
416 if (cache_table[k].descriptor == des) {
417 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
418 break;
419 switch (cache_table[k].cache_type) {
420 case LVL_1_INST:
421 l1i += cache_table[k].size;
422 break;
423 case LVL_1_DATA:
424 l1d += cache_table[k].size;
425 break;
426 case LVL_2:
427 l2 += cache_table[k].size;
428 break;
429 case LVL_3:
430 l3 += cache_table[k].size;
431 break;
432 case LVL_TRACE:
433 trace += cache_table[k].size;
434 break;
437 break;
440 k++;
446 if (new_l1d)
447 l1d = new_l1d;
449 if (new_l1i)
450 l1i = new_l1i;
452 if (new_l2) {
453 l2 = new_l2;
454 #ifdef CONFIG_X86_HT
455 per_cpu(cpu_llc_id, cpu) = l2_id;
456 #endif
459 if (new_l3) {
460 l3 = new_l3;
461 #ifdef CONFIG_X86_HT
462 per_cpu(cpu_llc_id, cpu) = l3_id;
463 #endif
466 if (trace)
467 printk (KERN_INFO "CPU: Trace cache: %dK uops", trace);
468 else if ( l1i )
469 printk (KERN_INFO "CPU: L1 I cache: %dK", l1i);
471 if (l1d)
472 printk(", L1 D cache: %dK\n", l1d);
473 else
474 printk("\n");
476 if (l2)
477 printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
479 if (l3)
480 printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
482 c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
484 return l2;
487 /* pointer to _cpuid4_info array (for each cache leaf) */
488 static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info);
489 #define CPUID4_INFO_IDX(x, y) (&((per_cpu(cpuid4_info, x))[y]))
491 #ifdef CONFIG_SMP
492 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
494 struct _cpuid4_info *this_leaf, *sibling_leaf;
495 unsigned long num_threads_sharing;
496 int index_msb, i;
497 struct cpuinfo_x86 *c = &cpu_data(cpu);
499 this_leaf = CPUID4_INFO_IDX(cpu, index);
500 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
502 if (num_threads_sharing == 1)
503 cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map));
504 else {
505 index_msb = get_count_order(num_threads_sharing);
507 for_each_online_cpu(i) {
508 if (cpu_data(i).apicid >> index_msb ==
509 c->apicid >> index_msb) {
510 cpumask_set_cpu(i,
511 to_cpumask(this_leaf->shared_cpu_map));
512 if (i != cpu && per_cpu(cpuid4_info, i)) {
513 sibling_leaf =
514 CPUID4_INFO_IDX(i, index);
515 cpumask_set_cpu(cpu, to_cpumask(
516 sibling_leaf->shared_cpu_map));
522 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
524 struct _cpuid4_info *this_leaf, *sibling_leaf;
525 int sibling;
527 this_leaf = CPUID4_INFO_IDX(cpu, index);
528 for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) {
529 sibling_leaf = CPUID4_INFO_IDX(sibling, index);
530 cpumask_clear_cpu(cpu,
531 to_cpumask(sibling_leaf->shared_cpu_map));
534 #else
535 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
536 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
537 #endif
539 static void __cpuinit free_cache_attributes(unsigned int cpu)
541 int i;
543 for (i = 0; i < num_cache_leaves; i++)
544 cache_remove_shared_cpu_map(cpu, i);
546 kfree(per_cpu(cpuid4_info, cpu));
547 per_cpu(cpuid4_info, cpu) = NULL;
550 static int
551 __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
553 struct _cpuid4_info_regs *leaf_regs =
554 (struct _cpuid4_info_regs *)this_leaf;
556 return cpuid4_cache_lookup_regs(index, leaf_regs);
559 static void __cpuinit get_cpu_leaves(void *_retval)
561 int j, *retval = _retval, cpu = smp_processor_id();
563 /* Do cpuid and store the results */
564 for (j = 0; j < num_cache_leaves; j++) {
565 struct _cpuid4_info *this_leaf;
566 this_leaf = CPUID4_INFO_IDX(cpu, j);
567 *retval = cpuid4_cache_lookup(j, this_leaf);
568 if (unlikely(*retval < 0)) {
569 int i;
571 for (i = 0; i < j; i++)
572 cache_remove_shared_cpu_map(cpu, i);
573 break;
575 cache_shared_cpu_map_setup(cpu, j);
579 static int __cpuinit detect_cache_attributes(unsigned int cpu)
581 int retval;
583 if (num_cache_leaves == 0)
584 return -ENOENT;
586 per_cpu(cpuid4_info, cpu) = kzalloc(
587 sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
588 if (per_cpu(cpuid4_info, cpu) == NULL)
589 return -ENOMEM;
591 smp_call_function_single(cpu, get_cpu_leaves, &retval, true);
592 if (retval) {
593 kfree(per_cpu(cpuid4_info, cpu));
594 per_cpu(cpuid4_info, cpu) = NULL;
597 return retval;
600 #ifdef CONFIG_SYSFS
602 #include <linux/kobject.h>
603 #include <linux/sysfs.h>
605 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
607 /* pointer to kobject for cpuX/cache */
608 static DEFINE_PER_CPU(struct kobject *, cache_kobject);
610 struct _index_kobject {
611 struct kobject kobj;
612 unsigned int cpu;
613 unsigned short index;
616 /* pointer to array of kobjects for cpuX/cache/indexY */
617 static DEFINE_PER_CPU(struct _index_kobject *, index_kobject);
618 #define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(index_kobject, x))[y]))
620 #define show_one_plus(file_name, object, val) \
621 static ssize_t show_##file_name \
622 (struct _cpuid4_info *this_leaf, char *buf) \
624 return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \
627 show_one_plus(level, eax.split.level, 0);
628 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
629 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
630 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
631 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
633 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
635 return sprintf (buf, "%luK\n", this_leaf->size / 1024);
638 static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
639 int type, char *buf)
641 ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
642 int n = 0;
644 if (len > 1) {
645 const struct cpumask *mask;
647 mask = to_cpumask(this_leaf->shared_cpu_map);
648 n = type?
649 cpulist_scnprintf(buf, len-2, mask) :
650 cpumask_scnprintf(buf, len-2, mask);
651 buf[n++] = '\n';
652 buf[n] = '\0';
654 return n;
657 static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf)
659 return show_shared_cpu_map_func(leaf, 0, buf);
662 static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf)
664 return show_shared_cpu_map_func(leaf, 1, buf);
667 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf)
669 switch (this_leaf->eax.split.type) {
670 case CACHE_TYPE_DATA:
671 return sprintf(buf, "Data\n");
672 case CACHE_TYPE_INST:
673 return sprintf(buf, "Instruction\n");
674 case CACHE_TYPE_UNIFIED:
675 return sprintf(buf, "Unified\n");
676 default:
677 return sprintf(buf, "Unknown\n");
681 #define to_object(k) container_of(k, struct _index_kobject, kobj)
682 #define to_attr(a) container_of(a, struct _cache_attr, attr)
684 #ifdef CONFIG_PCI
685 static struct pci_dev *get_k8_northbridge(int node)
687 struct pci_dev *dev = NULL;
688 int i;
690 for (i = 0; i <= node; i++) {
691 do {
692 dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
693 if (!dev)
694 break;
695 } while (!pci_match_id(&k8_nb_id[0], dev));
696 if (!dev)
697 break;
699 return dev;
701 #else
702 static struct pci_dev *get_k8_northbridge(int node)
704 return NULL;
706 #endif
708 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf)
710 const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map);
711 int node = cpu_to_node(cpumask_first(mask));
712 struct pci_dev *dev = NULL;
713 ssize_t ret = 0;
714 int i;
716 if (!this_leaf->can_disable)
717 return sprintf(buf, "Feature not enabled\n");
719 dev = get_k8_northbridge(node);
720 if (!dev) {
721 printk(KERN_ERR "Attempting AMD northbridge operation on a system with no northbridge\n");
722 return -EINVAL;
725 for (i = 0; i < 2; i++) {
726 unsigned int reg;
728 pci_read_config_dword(dev, 0x1BC + i * 4, &reg);
730 ret += sprintf(buf, "%sEntry: %d\n", buf, i);
731 ret += sprintf(buf, "%sReads: %s\tNew Entries: %s\n",
732 buf,
733 reg & 0x80000000 ? "Disabled" : "Allowed",
734 reg & 0x40000000 ? "Disabled" : "Allowed");
735 ret += sprintf(buf, "%sSubCache: %x\tIndex: %x\n",
736 buf, (reg & 0x30000) >> 16, reg & 0xfff);
738 return ret;
741 static ssize_t
742 store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf,
743 size_t count)
745 const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map);
746 int node = cpu_to_node(cpumask_first(mask));
747 struct pci_dev *dev = NULL;
748 unsigned int ret, index, val;
750 if (!this_leaf->can_disable)
751 return 0;
753 if (strlen(buf) > 15)
754 return -EINVAL;
756 ret = sscanf(buf, "%x %x", &index, &val);
757 if (ret != 2)
758 return -EINVAL;
759 if (index > 1)
760 return -EINVAL;
762 val |= 0xc0000000;
763 dev = get_k8_northbridge(node);
764 if (!dev) {
765 printk(KERN_ERR "Attempting AMD northbridge operation on a system with no northbridge\n");
766 return -EINVAL;
769 pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000);
770 wbinvd();
771 pci_write_config_dword(dev, 0x1BC + index * 4, val);
773 return 1;
776 struct _cache_attr {
777 struct attribute attr;
778 ssize_t (*show)(struct _cpuid4_info *, char *);
779 ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
782 #define define_one_ro(_name) \
783 static struct _cache_attr _name = \
784 __ATTR(_name, 0444, show_##_name, NULL)
786 define_one_ro(level);
787 define_one_ro(type);
788 define_one_ro(coherency_line_size);
789 define_one_ro(physical_line_partition);
790 define_one_ro(ways_of_associativity);
791 define_one_ro(number_of_sets);
792 define_one_ro(size);
793 define_one_ro(shared_cpu_map);
794 define_one_ro(shared_cpu_list);
796 static struct _cache_attr cache_disable = __ATTR(cache_disable, 0644, show_cache_disable, store_cache_disable);
798 static struct attribute * default_attrs[] = {
799 &type.attr,
800 &level.attr,
801 &coherency_line_size.attr,
802 &physical_line_partition.attr,
803 &ways_of_associativity.attr,
804 &number_of_sets.attr,
805 &size.attr,
806 &shared_cpu_map.attr,
807 &shared_cpu_list.attr,
808 &cache_disable.attr,
809 NULL
812 static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf)
814 struct _cache_attr *fattr = to_attr(attr);
815 struct _index_kobject *this_leaf = to_object(kobj);
816 ssize_t ret;
818 ret = fattr->show ?
819 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
820 buf) :
822 return ret;
825 static ssize_t store(struct kobject * kobj, struct attribute * attr,
826 const char * buf, size_t count)
828 struct _cache_attr *fattr = to_attr(attr);
829 struct _index_kobject *this_leaf = to_object(kobj);
830 ssize_t ret;
832 ret = fattr->store ?
833 fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
834 buf, count) :
836 return ret;
839 static struct sysfs_ops sysfs_ops = {
840 .show = show,
841 .store = store,
844 static struct kobj_type ktype_cache = {
845 .sysfs_ops = &sysfs_ops,
846 .default_attrs = default_attrs,
849 static struct kobj_type ktype_percpu_entry = {
850 .sysfs_ops = &sysfs_ops,
853 static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
855 kfree(per_cpu(cache_kobject, cpu));
856 kfree(per_cpu(index_kobject, cpu));
857 per_cpu(cache_kobject, cpu) = NULL;
858 per_cpu(index_kobject, cpu) = NULL;
859 free_cache_attributes(cpu);
862 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
864 int err;
866 if (num_cache_leaves == 0)
867 return -ENOENT;
869 err = detect_cache_attributes(cpu);
870 if (err)
871 return err;
873 /* Allocate all required memory */
874 per_cpu(cache_kobject, cpu) =
875 kzalloc(sizeof(struct kobject), GFP_KERNEL);
876 if (unlikely(per_cpu(cache_kobject, cpu) == NULL))
877 goto err_out;
879 per_cpu(index_kobject, cpu) = kzalloc(
880 sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL);
881 if (unlikely(per_cpu(index_kobject, cpu) == NULL))
882 goto err_out;
884 return 0;
886 err_out:
887 cpuid4_cache_sysfs_exit(cpu);
888 return -ENOMEM;
891 static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
893 /* Add/Remove cache interface for CPU device */
894 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
896 unsigned int cpu = sys_dev->id;
897 unsigned long i, j;
898 struct _index_kobject *this_object;
899 int retval;
901 retval = cpuid4_cache_sysfs_init(cpu);
902 if (unlikely(retval < 0))
903 return retval;
905 retval = kobject_init_and_add(per_cpu(cache_kobject, cpu),
906 &ktype_percpu_entry,
907 &sys_dev->kobj, "%s", "cache");
908 if (retval < 0) {
909 cpuid4_cache_sysfs_exit(cpu);
910 return retval;
913 for (i = 0; i < num_cache_leaves; i++) {
914 this_object = INDEX_KOBJECT_PTR(cpu,i);
915 this_object->cpu = cpu;
916 this_object->index = i;
917 retval = kobject_init_and_add(&(this_object->kobj),
918 &ktype_cache,
919 per_cpu(cache_kobject, cpu),
920 "index%1lu", i);
921 if (unlikely(retval)) {
922 for (j = 0; j < i; j++) {
923 kobject_put(&(INDEX_KOBJECT_PTR(cpu,j)->kobj));
925 kobject_put(per_cpu(cache_kobject, cpu));
926 cpuid4_cache_sysfs_exit(cpu);
927 return retval;
929 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
931 cpumask_set_cpu(cpu, to_cpumask(cache_dev_map));
933 kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
934 return 0;
937 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
939 unsigned int cpu = sys_dev->id;
940 unsigned long i;
942 if (per_cpu(cpuid4_info, cpu) == NULL)
943 return;
944 if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map)))
945 return;
946 cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
948 for (i = 0; i < num_cache_leaves; i++)
949 kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
950 kobject_put(per_cpu(cache_kobject, cpu));
951 cpuid4_cache_sysfs_exit(cpu);
954 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
955 unsigned long action, void *hcpu)
957 unsigned int cpu = (unsigned long)hcpu;
958 struct sys_device *sys_dev;
960 sys_dev = get_cpu_sysdev(cpu);
961 switch (action) {
962 case CPU_ONLINE:
963 case CPU_ONLINE_FROZEN:
964 cache_add_dev(sys_dev);
965 break;
966 case CPU_DEAD:
967 case CPU_DEAD_FROZEN:
968 cache_remove_dev(sys_dev);
969 break;
971 return NOTIFY_OK;
974 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier =
976 .notifier_call = cacheinfo_cpu_callback,
979 static int __cpuinit cache_sysfs_init(void)
981 int i;
983 if (num_cache_leaves == 0)
984 return 0;
986 for_each_online_cpu(i) {
987 int err;
988 struct sys_device *sys_dev = get_cpu_sysdev(i);
990 err = cache_add_dev(sys_dev);
991 if (err)
992 return err;
994 register_hotcpu_notifier(&cacheinfo_cpu_notifier);
995 return 0;
998 device_initcall(cache_sysfs_init);
1000 #endif