2 * Routines to indentify caches on Intel CPU.
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.
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 <linux/smp.h>
30 unsigned char descriptor;
35 /* All the cache descriptor types we care about (no TLB or
36 trace cache entries) */
38 static const struct _cache_table __cpuinitconst cache_table[] =
40 { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
41 { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */
42 { 0x09, LVL_1_INST, 32 }, /* 4-way set assoc, 64 byte line size */
43 { 0x0a, LVL_1_DATA, 8 }, /* 2 way set assoc, 32 byte line size */
44 { 0x0c, LVL_1_DATA, 16 }, /* 4-way set assoc, 32 byte line size */
45 { 0x0d, LVL_1_DATA, 16 }, /* 4-way set assoc, 64 byte line size */
46 { 0x21, LVL_2, 256 }, /* 8-way set assoc, 64 byte line size */
47 { 0x22, LVL_3, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
48 { 0x23, LVL_3, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */
49 { 0x25, LVL_3, 2048 }, /* 8-way set assoc, sectored cache, 64 byte line size */
50 { 0x29, LVL_3, 4096 }, /* 8-way set assoc, sectored cache, 64 byte line size */
51 { 0x2c, LVL_1_DATA, 32 }, /* 8-way set assoc, 64 byte line size */
52 { 0x30, LVL_1_INST, 32 }, /* 8-way set assoc, 64 byte line size */
53 { 0x39, LVL_2, 128 }, /* 4-way set assoc, sectored cache, 64 byte line size */
54 { 0x3a, LVL_2, 192 }, /* 6-way set assoc, sectored cache, 64 byte line size */
55 { 0x3b, LVL_2, 128 }, /* 2-way set assoc, sectored cache, 64 byte line size */
56 { 0x3c, LVL_2, 256 }, /* 4-way set assoc, sectored cache, 64 byte line size */
57 { 0x3d, LVL_2, 384 }, /* 6-way set assoc, sectored cache, 64 byte line size */
58 { 0x3e, LVL_2, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
59 { 0x3f, LVL_2, 256 }, /* 2-way set assoc, 64 byte line size */
60 { 0x41, LVL_2, 128 }, /* 4-way set assoc, 32 byte line size */
61 { 0x42, LVL_2, 256 }, /* 4-way set assoc, 32 byte line size */
62 { 0x43, LVL_2, 512 }, /* 4-way set assoc, 32 byte line size */
63 { 0x44, LVL_2, 1024 }, /* 4-way set assoc, 32 byte line size */
64 { 0x45, LVL_2, 2048 }, /* 4-way set assoc, 32 byte line size */
65 { 0x46, LVL_3, 4096 }, /* 4-way set assoc, 64 byte line size */
66 { 0x47, LVL_3, 8192 }, /* 8-way set assoc, 64 byte line size */
67 { 0x49, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */
68 { 0x4a, LVL_3, 6144 }, /* 12-way set assoc, 64 byte line size */
69 { 0x4b, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */
70 { 0x4c, LVL_3, 12288 }, /* 12-way set assoc, 64 byte line size */
71 { 0x4d, LVL_3, 16384 }, /* 16-way set assoc, 64 byte line size */
72 { 0x4e, LVL_2, 6144 }, /* 24-way set assoc, 64 byte line size */
73 { 0x60, LVL_1_DATA, 16 }, /* 8-way set assoc, sectored cache, 64 byte line size */
74 { 0x66, LVL_1_DATA, 8 }, /* 4-way set assoc, sectored cache, 64 byte line size */
75 { 0x67, LVL_1_DATA, 16 }, /* 4-way set assoc, sectored cache, 64 byte line size */
76 { 0x68, LVL_1_DATA, 32 }, /* 4-way set assoc, sectored cache, 64 byte line size */
77 { 0x70, LVL_TRACE, 12 }, /* 8-way set assoc */
78 { 0x71, LVL_TRACE, 16 }, /* 8-way set assoc */
79 { 0x72, LVL_TRACE, 32 }, /* 8-way set assoc */
80 { 0x73, LVL_TRACE, 64 }, /* 8-way set assoc */
81 { 0x78, LVL_2, 1024 }, /* 4-way set assoc, 64 byte line size */
82 { 0x79, LVL_2, 128 }, /* 8-way set assoc, sectored cache, 64 byte line size */
83 { 0x7a, LVL_2, 256 }, /* 8-way set assoc, sectored cache, 64 byte line size */
84 { 0x7b, LVL_2, 512 }, /* 8-way set assoc, sectored cache, 64 byte line size */
85 { 0x7c, LVL_2, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */
86 { 0x7d, LVL_2, 2048 }, /* 8-way set assoc, 64 byte line size */
87 { 0x7f, LVL_2, 512 }, /* 2-way set assoc, 64 byte line size */
88 { 0x82, LVL_2, 256 }, /* 8-way set assoc, 32 byte line size */
89 { 0x83, LVL_2, 512 }, /* 8-way set assoc, 32 byte line size */
90 { 0x84, LVL_2, 1024 }, /* 8-way set assoc, 32 byte line size */
91 { 0x85, LVL_2, 2048 }, /* 8-way set assoc, 32 byte line size */
92 { 0x86, LVL_2, 512 }, /* 4-way set assoc, 64 byte line size */
93 { 0x87, LVL_2, 1024 }, /* 8-way set assoc, 64 byte line size */
94 { 0xd0, LVL_3, 512 }, /* 4-way set assoc, 64 byte line size */
95 { 0xd1, LVL_3, 1024 }, /* 4-way set assoc, 64 byte line size */
96 { 0xd2, LVL_3, 2048 }, /* 4-way set assoc, 64 byte line size */
97 { 0xd6, LVL_3, 1024 }, /* 8-way set assoc, 64 byte line size */
98 { 0xd7, LVL_3, 2048 }, /* 8-way set assoc, 64 byte line size */
99 { 0xd8, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */
100 { 0xdc, LVL_3, 2048 }, /* 12-way set assoc, 64 byte line size */
101 { 0xdd, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */
102 { 0xde, LVL_3, 8192 }, /* 12-way set assoc, 64 byte line size */
103 { 0xe2, LVL_3, 2048 }, /* 16-way set assoc, 64 byte line size */
104 { 0xe3, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */
105 { 0xe4, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */
106 { 0xea, LVL_3, 12288 }, /* 24-way set assoc, 64 byte line size */
107 { 0xeb, LVL_3, 18432 }, /* 24-way set assoc, 64 byte line size */
108 { 0xec, LVL_3, 24576 }, /* 24-way set assoc, 64 byte line size */
117 CACHE_TYPE_UNIFIED = 3
120 union _cpuid4_leaf_eax {
122 enum _cache_type type:5;
123 unsigned int level:3;
124 unsigned int is_self_initializing:1;
125 unsigned int is_fully_associative:1;
126 unsigned int reserved:4;
127 unsigned int num_threads_sharing:12;
128 unsigned int num_cores_on_die:6;
133 union _cpuid4_leaf_ebx {
135 unsigned int coherency_line_size:12;
136 unsigned int physical_line_partition:10;
137 unsigned int ways_of_associativity:10;
142 union _cpuid4_leaf_ecx {
144 unsigned int number_of_sets:32;
149 struct _cpuid4_info {
150 union _cpuid4_leaf_eax eax;
151 union _cpuid4_leaf_ebx ebx;
152 union _cpuid4_leaf_ecx ecx;
154 unsigned long can_disable;
155 DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
158 /* subset of above _cpuid4_info w/o shared_cpu_map */
159 struct _cpuid4_info_regs {
160 union _cpuid4_leaf_eax eax;
161 union _cpuid4_leaf_ebx ebx;
162 union _cpuid4_leaf_ecx ecx;
164 unsigned long can_disable;
167 unsigned short num_cache_leaves;
169 /* AMD doesn't have CPUID4. Emulate it here to report the same
170 information to the user. This makes some assumptions about the machine:
171 L2 not shared, no SMT etc. that is currently true on AMD CPUs.
173 In theory the TLBs could be reported as fake type (they are in "dummy").
177 unsigned line_size:8;
178 unsigned lines_per_tag:8;
180 unsigned size_in_kb:8;
187 unsigned line_size:8;
188 unsigned lines_per_tag:4;
190 unsigned size_in_kb:16;
197 unsigned line_size:8;
198 unsigned lines_per_tag:4;
201 unsigned size_encoded:14;
206 static const unsigned short __cpuinitconst assocs[] = {
217 [0xf] = 0xffff /* fully associative - no way to show this currently */
220 static const unsigned char __cpuinitconst levels[] = { 1, 1, 2, 3 };
221 static const unsigned char __cpuinitconst types[] = { 1, 2, 3, 3 };
223 static void __cpuinit
224 amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
225 union _cpuid4_leaf_ebx *ebx,
226 union _cpuid4_leaf_ecx *ecx)
229 unsigned line_size, lines_per_tag, assoc, size_in_kb;
230 union l1_cache l1i, l1d;
233 union l1_cache *l1 = &l1d;
239 cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
240 cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
248 assoc = assocs[l1->assoc];
249 line_size = l1->line_size;
250 lines_per_tag = l1->lines_per_tag;
251 size_in_kb = l1->size_in_kb;
256 assoc = assocs[l2.assoc];
257 line_size = l2.line_size;
258 lines_per_tag = l2.lines_per_tag;
259 /* cpu_data has errata corrections for K7 applied */
260 size_in_kb = current_cpu_data.x86_cache_size;
265 assoc = assocs[l3.assoc];
266 line_size = l3.line_size;
267 lines_per_tag = l3.lines_per_tag;
268 size_in_kb = l3.size_encoded * 512;
269 if (boot_cpu_has(X86_FEATURE_AMD_DCM)) {
270 size_in_kb = size_in_kb >> 1;
278 eax->split.is_self_initializing = 1;
279 eax->split.type = types[leaf];
280 eax->split.level = levels[leaf];
281 eax->split.num_threads_sharing = 0;
282 eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
286 eax->split.is_fully_associative = 1;
287 ebx->split.coherency_line_size = line_size - 1;
288 ebx->split.ways_of_associativity = assoc - 1;
289 ebx->split.physical_line_partition = lines_per_tag - 1;
290 ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
291 (ebx->split.ways_of_associativity + 1) - 1;
294 static void __cpuinit
295 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
300 if (boot_cpu_data.x86 == 0x11)
303 /* see errata #382 and #388 */
304 if ((boot_cpu_data.x86 == 0x10) &&
305 ((boot_cpu_data.x86_model < 0x9) ||
306 (boot_cpu_data.x86_mask < 0x1)))
309 this_leaf->can_disable = 1;
313 __cpuinit cpuid4_cache_lookup_regs(int index,
314 struct _cpuid4_info_regs *this_leaf)
316 union _cpuid4_leaf_eax eax;
317 union _cpuid4_leaf_ebx ebx;
318 union _cpuid4_leaf_ecx ecx;
321 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
322 amd_cpuid4(index, &eax, &ebx, &ecx);
323 if (boot_cpu_data.x86 >= 0x10)
324 amd_check_l3_disable(index, this_leaf);
326 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
329 if (eax.split.type == CACHE_TYPE_NULL)
330 return -EIO; /* better error ? */
332 this_leaf->eax = eax;
333 this_leaf->ebx = ebx;
334 this_leaf->ecx = ecx;
335 this_leaf->size = (ecx.split.number_of_sets + 1) *
336 (ebx.split.coherency_line_size + 1) *
337 (ebx.split.physical_line_partition + 1) *
338 (ebx.split.ways_of_associativity + 1);
342 static int __cpuinit find_num_cache_leaves(void)
344 unsigned int eax, ebx, ecx, edx;
345 union _cpuid4_leaf_eax cache_eax;
350 /* Do cpuid(4) loop to find out num_cache_leaves */
351 cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
352 cache_eax.full = eax;
353 } while (cache_eax.split.type != CACHE_TYPE_NULL);
357 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
360 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0;
361 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
362 unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
363 unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
365 unsigned int cpu = c->cpu_index;
368 if (c->cpuid_level > 3) {
369 static int is_initialized;
371 if (is_initialized == 0) {
372 /* Init num_cache_leaves from boot CPU */
373 num_cache_leaves = find_num_cache_leaves();
378 * Whenever possible use cpuid(4), deterministic cache
379 * parameters cpuid leaf to find the cache details
381 for (i = 0; i < num_cache_leaves; i++) {
382 struct _cpuid4_info_regs this_leaf;
385 retval = cpuid4_cache_lookup_regs(i, &this_leaf);
387 switch (this_leaf.eax.split.level) {
389 if (this_leaf.eax.split.type ==
391 new_l1d = this_leaf.size/1024;
392 else if (this_leaf.eax.split.type ==
394 new_l1i = this_leaf.size/1024;
397 new_l2 = this_leaf.size/1024;
398 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
399 index_msb = get_count_order(num_threads_sharing);
400 l2_id = c->apicid >> index_msb;
403 new_l3 = this_leaf.size/1024;
404 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
405 index_msb = get_count_order(
406 num_threads_sharing);
407 l3_id = c->apicid >> index_msb;
416 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
419 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
420 /* supports eax=2 call */
422 unsigned int regs[4];
423 unsigned char *dp = (unsigned char *)regs;
426 if (num_cache_leaves != 0 && c->x86 == 15)
429 /* Number of times to iterate */
430 n = cpuid_eax(2) & 0xFF;
432 for (i = 0 ; i < n ; i++) {
433 cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]);
435 /* If bit 31 is set, this is an unknown format */
436 for (j = 0 ; j < 3 ; j++)
437 if (regs[j] & (1 << 31))
440 /* Byte 0 is level count, not a descriptor */
441 for (j = 1 ; j < 16 ; j++) {
442 unsigned char des = dp[j];
445 /* look up this descriptor in the table */
446 while (cache_table[k].descriptor != 0) {
447 if (cache_table[k].descriptor == des) {
448 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
450 switch (cache_table[k].cache_type) {
452 l1i += cache_table[k].size;
455 l1d += cache_table[k].size;
458 l2 += cache_table[k].size;
461 l3 += cache_table[k].size;
464 trace += cache_table[k].size;
486 per_cpu(cpu_llc_id, cpu) = l2_id;
493 per_cpu(cpu_llc_id, cpu) = l3_id;
497 c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
504 /* pointer to _cpuid4_info array (for each cache leaf) */
505 static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);
506 #define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y]))
509 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
511 struct _cpuid4_info *this_leaf, *sibling_leaf;
512 unsigned long num_threads_sharing;
513 int index_msb, i, sibling;
514 struct cpuinfo_x86 *c = &cpu_data(cpu);
516 if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
517 for_each_cpu(i, c->llc_shared_map) {
518 if (!per_cpu(ici_cpuid4_info, i))
520 this_leaf = CPUID4_INFO_IDX(i, index);
521 for_each_cpu(sibling, c->llc_shared_map) {
522 if (!cpu_online(sibling))
524 set_bit(sibling, this_leaf->shared_cpu_map);
529 this_leaf = CPUID4_INFO_IDX(cpu, index);
530 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
532 if (num_threads_sharing == 1)
533 cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map));
535 index_msb = get_count_order(num_threads_sharing);
537 for_each_online_cpu(i) {
538 if (cpu_data(i).apicid >> index_msb ==
539 c->apicid >> index_msb) {
541 to_cpumask(this_leaf->shared_cpu_map));
542 if (i != cpu && per_cpu(ici_cpuid4_info, i)) {
544 CPUID4_INFO_IDX(i, index);
545 cpumask_set_cpu(cpu, to_cpumask(
546 sibling_leaf->shared_cpu_map));
552 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
554 struct _cpuid4_info *this_leaf, *sibling_leaf;
557 this_leaf = CPUID4_INFO_IDX(cpu, index);
558 for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) {
559 sibling_leaf = CPUID4_INFO_IDX(sibling, index);
560 cpumask_clear_cpu(cpu,
561 to_cpumask(sibling_leaf->shared_cpu_map));
565 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
569 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
574 static void __cpuinit free_cache_attributes(unsigned int cpu)
578 for (i = 0; i < num_cache_leaves; i++)
579 cache_remove_shared_cpu_map(cpu, i);
581 kfree(per_cpu(ici_cpuid4_info, cpu));
582 per_cpu(ici_cpuid4_info, cpu) = NULL;
586 __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
588 struct _cpuid4_info_regs *leaf_regs =
589 (struct _cpuid4_info_regs *)this_leaf;
591 return cpuid4_cache_lookup_regs(index, leaf_regs);
594 static void __cpuinit get_cpu_leaves(void *_retval)
596 int j, *retval = _retval, cpu = smp_processor_id();
598 /* Do cpuid and store the results */
599 for (j = 0; j < num_cache_leaves; j++) {
600 struct _cpuid4_info *this_leaf;
601 this_leaf = CPUID4_INFO_IDX(cpu, j);
602 *retval = cpuid4_cache_lookup(j, this_leaf);
603 if (unlikely(*retval < 0)) {
606 for (i = 0; i < j; i++)
607 cache_remove_shared_cpu_map(cpu, i);
610 cache_shared_cpu_map_setup(cpu, j);
614 static int __cpuinit detect_cache_attributes(unsigned int cpu)
618 if (num_cache_leaves == 0)
621 per_cpu(ici_cpuid4_info, cpu) = kzalloc(
622 sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
623 if (per_cpu(ici_cpuid4_info, cpu) == NULL)
626 smp_call_function_single(cpu, get_cpu_leaves, &retval, true);
628 kfree(per_cpu(ici_cpuid4_info, cpu));
629 per_cpu(ici_cpuid4_info, cpu) = NULL;
635 #include <linux/kobject.h>
636 #include <linux/sysfs.h>
638 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
640 /* pointer to kobject for cpuX/cache */
641 static DEFINE_PER_CPU(struct kobject *, ici_cache_kobject);
643 struct _index_kobject {
646 unsigned short index;
649 /* pointer to array of kobjects for cpuX/cache/indexY */
650 static DEFINE_PER_CPU(struct _index_kobject *, ici_index_kobject);
651 #define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(ici_index_kobject, x))[y]))
653 #define show_one_plus(file_name, object, val) \
654 static ssize_t show_##file_name \
655 (struct _cpuid4_info *this_leaf, char *buf) \
657 return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \
660 show_one_plus(level, eax.split.level, 0);
661 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
662 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
663 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
664 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
666 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
668 return sprintf(buf, "%luK\n", this_leaf->size / 1024);
671 static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
674 ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
678 const struct cpumask *mask;
680 mask = to_cpumask(this_leaf->shared_cpu_map);
682 cpulist_scnprintf(buf, len-2, mask) :
683 cpumask_scnprintf(buf, len-2, mask);
690 static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf)
692 return show_shared_cpu_map_func(leaf, 0, buf);
695 static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf)
697 return show_shared_cpu_map_func(leaf, 1, buf);
700 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf)
702 switch (this_leaf->eax.split.type) {
703 case CACHE_TYPE_DATA:
704 return sprintf(buf, "Data\n");
705 case CACHE_TYPE_INST:
706 return sprintf(buf, "Instruction\n");
707 case CACHE_TYPE_UNIFIED:
708 return sprintf(buf, "Unified\n");
710 return sprintf(buf, "Unknown\n");
714 #define to_object(k) container_of(k, struct _index_kobject, kobj)
715 #define to_attr(a) container_of(a, struct _cache_attr, attr)
717 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
720 int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
721 int node = cpu_to_node(cpu);
722 struct pci_dev *dev = node_to_k8_nb_misc(node);
723 unsigned int reg = 0;
725 if (!this_leaf->can_disable)
731 pci_read_config_dword(dev, 0x1BC + index * 4, ®);
732 return sprintf(buf, "0x%08x\n", reg);
735 #define SHOW_CACHE_DISABLE(index) \
737 show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \
739 return show_cache_disable(this_leaf, buf, index); \
741 SHOW_CACHE_DISABLE(0)
742 SHOW_CACHE_DISABLE(1)
744 static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
745 const char *buf, size_t count, unsigned int index)
747 int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
748 int node = cpu_to_node(cpu);
749 struct pci_dev *dev = node_to_k8_nb_misc(node);
750 unsigned long val = 0;
752 #define SUBCACHE_MASK (3UL << 20)
753 #define SUBCACHE_INDEX 0xfff
755 if (!this_leaf->can_disable)
758 if (!capable(CAP_SYS_ADMIN))
764 if (strict_strtoul(buf, 10, &val) < 0)
767 /* do not allow writes outside of allowed bits */
768 if (val & ~(SUBCACHE_MASK | SUBCACHE_INDEX))
772 pci_write_config_dword(dev, 0x1BC + index * 4, val);
774 * We need to WBINVD on a core on the node containing the L3 cache which
775 * indices we disable therefore a simple wbinvd() is not sufficient.
778 pci_write_config_dword(dev, 0x1BC + index * 4, val | BIT(31));
782 #define STORE_CACHE_DISABLE(index) \
784 store_cache_disable_##index(struct _cpuid4_info *this_leaf, \
785 const char *buf, size_t count) \
787 return store_cache_disable(this_leaf, buf, count, index); \
789 STORE_CACHE_DISABLE(0)
790 STORE_CACHE_DISABLE(1)
793 struct attribute attr;
794 ssize_t (*show)(struct _cpuid4_info *, char *);
795 ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
798 #define define_one_ro(_name) \
799 static struct _cache_attr _name = \
800 __ATTR(_name, 0444, show_##_name, NULL)
802 define_one_ro(level);
804 define_one_ro(coherency_line_size);
805 define_one_ro(physical_line_partition);
806 define_one_ro(ways_of_associativity);
807 define_one_ro(number_of_sets);
809 define_one_ro(shared_cpu_map);
810 define_one_ro(shared_cpu_list);
812 static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644,
813 show_cache_disable_0, store_cache_disable_0);
814 static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
815 show_cache_disable_1, store_cache_disable_1);
817 static struct attribute *default_attrs[] = {
820 &coherency_line_size.attr,
821 &physical_line_partition.attr,
822 &ways_of_associativity.attr,
823 &number_of_sets.attr,
825 &shared_cpu_map.attr,
826 &shared_cpu_list.attr,
827 &cache_disable_0.attr,
828 &cache_disable_1.attr,
832 static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
834 struct _cache_attr *fattr = to_attr(attr);
835 struct _index_kobject *this_leaf = to_object(kobj);
839 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
845 static ssize_t store(struct kobject *kobj, struct attribute *attr,
846 const char *buf, size_t count)
848 struct _cache_attr *fattr = to_attr(attr);
849 struct _index_kobject *this_leaf = to_object(kobj);
853 fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
859 static struct sysfs_ops sysfs_ops = {
864 static struct kobj_type ktype_cache = {
865 .sysfs_ops = &sysfs_ops,
866 .default_attrs = default_attrs,
869 static struct kobj_type ktype_percpu_entry = {
870 .sysfs_ops = &sysfs_ops,
873 static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
875 kfree(per_cpu(ici_cache_kobject, cpu));
876 kfree(per_cpu(ici_index_kobject, cpu));
877 per_cpu(ici_cache_kobject, cpu) = NULL;
878 per_cpu(ici_index_kobject, cpu) = NULL;
879 free_cache_attributes(cpu);
882 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
886 if (num_cache_leaves == 0)
889 err = detect_cache_attributes(cpu);
893 /* Allocate all required memory */
894 per_cpu(ici_cache_kobject, cpu) =
895 kzalloc(sizeof(struct kobject), GFP_KERNEL);
896 if (unlikely(per_cpu(ici_cache_kobject, cpu) == NULL))
899 per_cpu(ici_index_kobject, cpu) = kzalloc(
900 sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL);
901 if (unlikely(per_cpu(ici_index_kobject, cpu) == NULL))
907 cpuid4_cache_sysfs_exit(cpu);
911 static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
913 /* Add/Remove cache interface for CPU device */
914 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
916 unsigned int cpu = sys_dev->id;
918 struct _index_kobject *this_object;
921 retval = cpuid4_cache_sysfs_init(cpu);
922 if (unlikely(retval < 0))
925 retval = kobject_init_and_add(per_cpu(ici_cache_kobject, cpu),
927 &sys_dev->kobj, "%s", "cache");
929 cpuid4_cache_sysfs_exit(cpu);
933 for (i = 0; i < num_cache_leaves; i++) {
934 this_object = INDEX_KOBJECT_PTR(cpu, i);
935 this_object->cpu = cpu;
936 this_object->index = i;
937 retval = kobject_init_and_add(&(this_object->kobj),
939 per_cpu(ici_cache_kobject, cpu),
941 if (unlikely(retval)) {
942 for (j = 0; j < i; j++)
943 kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj));
944 kobject_put(per_cpu(ici_cache_kobject, cpu));
945 cpuid4_cache_sysfs_exit(cpu);
948 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
950 cpumask_set_cpu(cpu, to_cpumask(cache_dev_map));
952 kobject_uevent(per_cpu(ici_cache_kobject, cpu), KOBJ_ADD);
956 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
958 unsigned int cpu = sys_dev->id;
961 if (per_cpu(ici_cpuid4_info, cpu) == NULL)
963 if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map)))
965 cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
967 for (i = 0; i < num_cache_leaves; i++)
968 kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj));
969 kobject_put(per_cpu(ici_cache_kobject, cpu));
970 cpuid4_cache_sysfs_exit(cpu);
973 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
974 unsigned long action, void *hcpu)
976 unsigned int cpu = (unsigned long)hcpu;
977 struct sys_device *sys_dev;
979 sys_dev = get_cpu_sysdev(cpu);
982 case CPU_ONLINE_FROZEN:
983 cache_add_dev(sys_dev);
986 case CPU_DEAD_FROZEN:
987 cache_remove_dev(sys_dev);
993 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = {
994 .notifier_call = cacheinfo_cpu_callback,
997 static int __cpuinit cache_sysfs_init(void)
1001 if (num_cache_leaves == 0)
1004 for_each_online_cpu(i) {
1006 struct sys_device *sys_dev = get_cpu_sysdev(i);
1008 err = cache_add_dev(sys_dev);
1012 register_hotcpu_notifier(&cacheinfo_cpu_notifier);
1016 device_initcall(cache_sysfs_init);