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 #define MB(x) ((x) * 1024)
37 /* All the cache descriptor types we care about (no TLB or
38 trace cache entries) */
40 static const struct _cache_table __cpuinitconst cache_table[] =
42 { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
43 { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */
44 { 0x09, LVL_1_INST, 32 }, /* 4-way set assoc, 64 byte line size */
45 { 0x0a, LVL_1_DATA, 8 }, /* 2 way set assoc, 32 byte line size */
46 { 0x0c, LVL_1_DATA, 16 }, /* 4-way set assoc, 32 byte line size */
47 { 0x0d, LVL_1_DATA, 16 }, /* 4-way set assoc, 64 byte line size */
48 { 0x21, LVL_2, 256 }, /* 8-way set assoc, 64 byte line size */
49 { 0x22, LVL_3, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
50 { 0x23, LVL_3, MB(1) }, /* 8-way set assoc, sectored cache, 64 byte line size */
51 { 0x25, LVL_3, MB(2) }, /* 8-way set assoc, sectored cache, 64 byte line size */
52 { 0x29, LVL_3, MB(4) }, /* 8-way set assoc, sectored cache, 64 byte line size */
53 { 0x2c, LVL_1_DATA, 32 }, /* 8-way set assoc, 64 byte line size */
54 { 0x30, LVL_1_INST, 32 }, /* 8-way set assoc, 64 byte line size */
55 { 0x39, LVL_2, 128 }, /* 4-way set assoc, sectored cache, 64 byte line size */
56 { 0x3a, LVL_2, 192 }, /* 6-way set assoc, sectored cache, 64 byte line size */
57 { 0x3b, LVL_2, 128 }, /* 2-way set assoc, sectored cache, 64 byte line size */
58 { 0x3c, LVL_2, 256 }, /* 4-way set assoc, sectored cache, 64 byte line size */
59 { 0x3d, LVL_2, 384 }, /* 6-way set assoc, sectored cache, 64 byte line size */
60 { 0x3e, LVL_2, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
61 { 0x3f, LVL_2, 256 }, /* 2-way set assoc, 64 byte line size */
62 { 0x41, LVL_2, 128 }, /* 4-way set assoc, 32 byte line size */
63 { 0x42, LVL_2, 256 }, /* 4-way set assoc, 32 byte line size */
64 { 0x43, LVL_2, 512 }, /* 4-way set assoc, 32 byte line size */
65 { 0x44, LVL_2, MB(1) }, /* 4-way set assoc, 32 byte line size */
66 { 0x45, LVL_2, MB(2) }, /* 4-way set assoc, 32 byte line size */
67 { 0x46, LVL_3, MB(4) }, /* 4-way set assoc, 64 byte line size */
68 { 0x47, LVL_3, MB(8) }, /* 8-way set assoc, 64 byte line size */
69 { 0x49, LVL_3, MB(4) }, /* 16-way set assoc, 64 byte line size */
70 { 0x4a, LVL_3, MB(6) }, /* 12-way set assoc, 64 byte line size */
71 { 0x4b, LVL_3, MB(8) }, /* 16-way set assoc, 64 byte line size */
72 { 0x4c, LVL_3, MB(12) }, /* 12-way set assoc, 64 byte line size */
73 { 0x4d, LVL_3, MB(16) }, /* 16-way set assoc, 64 byte line size */
74 { 0x4e, LVL_2, MB(6) }, /* 24-way set assoc, 64 byte line size */
75 { 0x60, LVL_1_DATA, 16 }, /* 8-way set assoc, sectored cache, 64 byte line size */
76 { 0x66, LVL_1_DATA, 8 }, /* 4-way set assoc, sectored cache, 64 byte line size */
77 { 0x67, LVL_1_DATA, 16 }, /* 4-way set assoc, sectored cache, 64 byte line size */
78 { 0x68, LVL_1_DATA, 32 }, /* 4-way set assoc, sectored cache, 64 byte line size */
79 { 0x70, LVL_TRACE, 12 }, /* 8-way set assoc */
80 { 0x71, LVL_TRACE, 16 }, /* 8-way set assoc */
81 { 0x72, LVL_TRACE, 32 }, /* 8-way set assoc */
82 { 0x73, LVL_TRACE, 64 }, /* 8-way set assoc */
83 { 0x78, LVL_2, MB(1) }, /* 4-way set assoc, 64 byte line size */
84 { 0x79, LVL_2, 128 }, /* 8-way set assoc, sectored cache, 64 byte line size */
85 { 0x7a, LVL_2, 256 }, /* 8-way set assoc, sectored cache, 64 byte line size */
86 { 0x7b, LVL_2, 512 }, /* 8-way set assoc, sectored cache, 64 byte line size */
87 { 0x7c, LVL_2, MB(1) }, /* 8-way set assoc, sectored cache, 64 byte line size */
88 { 0x7d, LVL_2, MB(2) }, /* 8-way set assoc, 64 byte line size */
89 { 0x7f, LVL_2, 512 }, /* 2-way set assoc, 64 byte line size */
90 { 0x82, LVL_2, 256 }, /* 8-way set assoc, 32 byte line size */
91 { 0x83, LVL_2, 512 }, /* 8-way set assoc, 32 byte line size */
92 { 0x84, LVL_2, MB(1) }, /* 8-way set assoc, 32 byte line size */
93 { 0x85, LVL_2, MB(2) }, /* 8-way set assoc, 32 byte line size */
94 { 0x86, LVL_2, 512 }, /* 4-way set assoc, 64 byte line size */
95 { 0x87, LVL_2, MB(1) }, /* 8-way set assoc, 64 byte line size */
96 { 0xd0, LVL_3, 512 }, /* 4-way set assoc, 64 byte line size */
97 { 0xd1, LVL_3, MB(1) }, /* 4-way set assoc, 64 byte line size */
98 { 0xd2, LVL_3, MB(2) }, /* 4-way set assoc, 64 byte line size */
99 { 0xd6, LVL_3, MB(1) }, /* 8-way set assoc, 64 byte line size */
100 { 0xd7, LVL_3, MB(2) }, /* 8-way set assoc, 64 byte line size */
101 { 0xd8, LVL_3, MB(4) }, /* 12-way set assoc, 64 byte line size */
102 { 0xdc, LVL_3, MB(2) }, /* 12-way set assoc, 64 byte line size */
103 { 0xdd, LVL_3, MB(4) }, /* 12-way set assoc, 64 byte line size */
104 { 0xde, LVL_3, MB(8) }, /* 12-way set assoc, 64 byte line size */
105 { 0xe2, LVL_3, MB(2) }, /* 16-way set assoc, 64 byte line size */
106 { 0xe3, LVL_3, MB(4) }, /* 16-way set assoc, 64 byte line size */
107 { 0xe4, LVL_3, MB(8) }, /* 16-way set assoc, 64 byte line size */
108 { 0xea, LVL_3, MB(12) }, /* 24-way set assoc, 64 byte line size */
109 { 0xeb, LVL_3, MB(18) }, /* 24-way set assoc, 64 byte line size */
110 { 0xec, LVL_3, MB(24) }, /* 24-way set assoc, 64 byte line size */
119 CACHE_TYPE_UNIFIED = 3
122 union _cpuid4_leaf_eax {
124 enum _cache_type type:5;
125 unsigned int level:3;
126 unsigned int is_self_initializing:1;
127 unsigned int is_fully_associative:1;
128 unsigned int reserved:4;
129 unsigned int num_threads_sharing:12;
130 unsigned int num_cores_on_die:6;
135 union _cpuid4_leaf_ebx {
137 unsigned int coherency_line_size:12;
138 unsigned int physical_line_partition:10;
139 unsigned int ways_of_associativity:10;
144 union _cpuid4_leaf_ecx {
146 unsigned int number_of_sets:32;
151 struct _cpuid4_info {
152 union _cpuid4_leaf_eax eax;
153 union _cpuid4_leaf_ebx ebx;
154 union _cpuid4_leaf_ecx ecx;
157 unsigned int l3_indices;
158 DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
161 /* subset of above _cpuid4_info w/o shared_cpu_map */
162 struct _cpuid4_info_regs {
163 union _cpuid4_leaf_eax eax;
164 union _cpuid4_leaf_ebx ebx;
165 union _cpuid4_leaf_ecx ecx;
168 unsigned int l3_indices;
171 unsigned short num_cache_leaves;
173 /* AMD doesn't have CPUID4. Emulate it here to report the same
174 information to the user. This makes some assumptions about the machine:
175 L2 not shared, no SMT etc. that is currently true on AMD CPUs.
177 In theory the TLBs could be reported as fake type (they are in "dummy").
181 unsigned line_size:8;
182 unsigned lines_per_tag:8;
184 unsigned size_in_kb:8;
191 unsigned line_size:8;
192 unsigned lines_per_tag:4;
194 unsigned size_in_kb:16;
201 unsigned line_size:8;
202 unsigned lines_per_tag:4;
205 unsigned size_encoded:14;
210 static const unsigned short __cpuinitconst assocs[] = {
221 [0xf] = 0xffff /* fully associative - no way to show this currently */
224 static const unsigned char __cpuinitconst levels[] = { 1, 1, 2, 3 };
225 static const unsigned char __cpuinitconst types[] = { 1, 2, 3, 3 };
227 static void __cpuinit
228 amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
229 union _cpuid4_leaf_ebx *ebx,
230 union _cpuid4_leaf_ecx *ecx)
233 unsigned line_size, lines_per_tag, assoc, size_in_kb;
234 union l1_cache l1i, l1d;
237 union l1_cache *l1 = &l1d;
243 cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
244 cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
252 assoc = assocs[l1->assoc];
253 line_size = l1->line_size;
254 lines_per_tag = l1->lines_per_tag;
255 size_in_kb = l1->size_in_kb;
260 assoc = assocs[l2.assoc];
261 line_size = l2.line_size;
262 lines_per_tag = l2.lines_per_tag;
263 /* cpu_data has errata corrections for K7 applied */
264 size_in_kb = current_cpu_data.x86_cache_size;
269 assoc = assocs[l3.assoc];
270 line_size = l3.line_size;
271 lines_per_tag = l3.lines_per_tag;
272 size_in_kb = l3.size_encoded * 512;
273 if (boot_cpu_has(X86_FEATURE_AMD_DCM)) {
274 size_in_kb = size_in_kb >> 1;
282 eax->split.is_self_initializing = 1;
283 eax->split.type = types[leaf];
284 eax->split.level = levels[leaf];
285 eax->split.num_threads_sharing = 0;
286 eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
290 eax->split.is_fully_associative = 1;
291 ebx->split.coherency_line_size = line_size - 1;
292 ebx->split.ways_of_associativity = assoc - 1;
293 ebx->split.physical_line_partition = lines_per_tag - 1;
294 ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
295 (ebx->split.ways_of_associativity + 1) - 1;
299 struct attribute attr;
300 ssize_t (*show)(struct _cpuid4_info *, char *);
301 ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
304 #ifdef CONFIG_CPU_SUP_AMD
305 static unsigned int __cpuinit amd_calc_l3_indices(void)
308 * We're called over smp_call_function_single() and therefore
309 * are on the correct cpu.
311 int cpu = smp_processor_id();
312 int node = cpu_to_node(cpu);
313 struct pci_dev *dev = node_to_k8_nb_misc(node);
314 unsigned int sc0, sc1, sc2, sc3;
317 pci_read_config_dword(dev, 0x1C4, &val);
319 /* calculate subcache sizes */
320 sc0 = !(val & BIT(0));
321 sc1 = !(val & BIT(4));
322 sc2 = !(val & BIT(8)) + !(val & BIT(9));
323 sc3 = !(val & BIT(12)) + !(val & BIT(13));
325 return (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
328 static void __cpuinit
329 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
334 if (boot_cpu_data.x86 == 0x11)
337 /* see errata #382 and #388 */
338 if ((boot_cpu_data.x86 == 0x10) &&
339 ((boot_cpu_data.x86_model < 0x8) ||
340 (boot_cpu_data.x86_mask < 0x1)))
343 /* not in virtualized environments */
344 if (num_k8_northbridges == 0)
347 this_leaf->can_disable = true;
348 this_leaf->l3_indices = amd_calc_l3_indices();
351 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
354 int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
355 int node = amd_get_nb_id(cpu);
356 struct pci_dev *dev = node_to_k8_nb_misc(node);
357 unsigned int reg = 0;
359 if (!this_leaf->can_disable)
365 pci_read_config_dword(dev, 0x1BC + index * 4, ®);
366 return sprintf(buf, "0x%08x\n", reg);
369 #define SHOW_CACHE_DISABLE(index) \
371 show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \
373 return show_cache_disable(this_leaf, buf, index); \
375 SHOW_CACHE_DISABLE(0)
376 SHOW_CACHE_DISABLE(1)
378 static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
379 const char *buf, size_t count, unsigned int index)
381 int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
382 int node = amd_get_nb_id(cpu);
383 struct pci_dev *dev = node_to_k8_nb_misc(node);
384 unsigned long val = 0;
386 #define SUBCACHE_MASK (3UL << 20)
387 #define SUBCACHE_INDEX 0xfff
389 if (!this_leaf->can_disable)
392 if (!capable(CAP_SYS_ADMIN))
398 if (strict_strtoul(buf, 10, &val) < 0)
401 /* do not allow writes outside of allowed bits */
402 if ((val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) ||
403 ((val & SUBCACHE_INDEX) > this_leaf->l3_indices))
407 pci_write_config_dword(dev, 0x1BC + index * 4, val);
409 * We need to WBINVD on a core on the node containing the L3 cache which
410 * indices we disable therefore a simple wbinvd() is not sufficient.
413 pci_write_config_dword(dev, 0x1BC + index * 4, val | BIT(31));
417 #define STORE_CACHE_DISABLE(index) \
419 store_cache_disable_##index(struct _cpuid4_info *this_leaf, \
420 const char *buf, size_t count) \
422 return store_cache_disable(this_leaf, buf, count, index); \
424 STORE_CACHE_DISABLE(0)
425 STORE_CACHE_DISABLE(1)
427 static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644,
428 show_cache_disable_0, store_cache_disable_0);
429 static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
430 show_cache_disable_1, store_cache_disable_1);
432 #else /* CONFIG_CPU_SUP_AMD */
433 static void __cpuinit
434 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
437 #endif /* CONFIG_CPU_SUP_AMD */
440 __cpuinit cpuid4_cache_lookup_regs(int index,
441 struct _cpuid4_info_regs *this_leaf)
443 union _cpuid4_leaf_eax eax;
444 union _cpuid4_leaf_ebx ebx;
445 union _cpuid4_leaf_ecx ecx;
448 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
449 amd_cpuid4(index, &eax, &ebx, &ecx);
450 if (boot_cpu_data.x86 >= 0x10)
451 amd_check_l3_disable(index, this_leaf);
453 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
456 if (eax.split.type == CACHE_TYPE_NULL)
457 return -EIO; /* better error ? */
459 this_leaf->eax = eax;
460 this_leaf->ebx = ebx;
461 this_leaf->ecx = ecx;
462 this_leaf->size = (ecx.split.number_of_sets + 1) *
463 (ebx.split.coherency_line_size + 1) *
464 (ebx.split.physical_line_partition + 1) *
465 (ebx.split.ways_of_associativity + 1);
469 static int __cpuinit find_num_cache_leaves(void)
471 unsigned int eax, ebx, ecx, edx;
472 union _cpuid4_leaf_eax cache_eax;
477 /* Do cpuid(4) loop to find out num_cache_leaves */
478 cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
479 cache_eax.full = eax;
480 } while (cache_eax.split.type != CACHE_TYPE_NULL);
484 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
487 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0;
488 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
489 unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
490 unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
492 unsigned int cpu = c->cpu_index;
495 if (c->cpuid_level > 3) {
496 static int is_initialized;
498 if (is_initialized == 0) {
499 /* Init num_cache_leaves from boot CPU */
500 num_cache_leaves = find_num_cache_leaves();
505 * Whenever possible use cpuid(4), deterministic cache
506 * parameters cpuid leaf to find the cache details
508 for (i = 0; i < num_cache_leaves; i++) {
509 struct _cpuid4_info_regs this_leaf;
512 retval = cpuid4_cache_lookup_regs(i, &this_leaf);
514 switch (this_leaf.eax.split.level) {
516 if (this_leaf.eax.split.type ==
518 new_l1d = this_leaf.size/1024;
519 else if (this_leaf.eax.split.type ==
521 new_l1i = this_leaf.size/1024;
524 new_l2 = this_leaf.size/1024;
525 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
526 index_msb = get_count_order(num_threads_sharing);
527 l2_id = c->apicid >> index_msb;
530 new_l3 = this_leaf.size/1024;
531 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
532 index_msb = get_count_order(
533 num_threads_sharing);
534 l3_id = c->apicid >> index_msb;
543 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
546 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
547 /* supports eax=2 call */
549 unsigned int regs[4];
550 unsigned char *dp = (unsigned char *)regs;
553 if (num_cache_leaves != 0 && c->x86 == 15)
556 /* Number of times to iterate */
557 n = cpuid_eax(2) & 0xFF;
559 for (i = 0 ; i < n ; i++) {
560 cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]);
562 /* If bit 31 is set, this is an unknown format */
563 for (j = 0 ; j < 3 ; j++)
564 if (regs[j] & (1 << 31))
567 /* Byte 0 is level count, not a descriptor */
568 for (j = 1 ; j < 16 ; j++) {
569 unsigned char des = dp[j];
572 /* look up this descriptor in the table */
573 while (cache_table[k].descriptor != 0) {
574 if (cache_table[k].descriptor == des) {
575 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
577 switch (cache_table[k].cache_type) {
579 l1i += cache_table[k].size;
582 l1d += cache_table[k].size;
585 l2 += cache_table[k].size;
588 l3 += cache_table[k].size;
591 trace += cache_table[k].size;
613 per_cpu(cpu_llc_id, cpu) = l2_id;
620 per_cpu(cpu_llc_id, cpu) = l3_id;
624 c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
631 /* pointer to _cpuid4_info array (for each cache leaf) */
632 static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);
633 #define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y]))
636 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
638 struct _cpuid4_info *this_leaf, *sibling_leaf;
639 unsigned long num_threads_sharing;
640 int index_msb, i, sibling;
641 struct cpuinfo_x86 *c = &cpu_data(cpu);
643 if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
644 for_each_cpu(i, c->llc_shared_map) {
645 if (!per_cpu(ici_cpuid4_info, i))
647 this_leaf = CPUID4_INFO_IDX(i, index);
648 for_each_cpu(sibling, c->llc_shared_map) {
649 if (!cpu_online(sibling))
651 set_bit(sibling, this_leaf->shared_cpu_map);
656 this_leaf = CPUID4_INFO_IDX(cpu, index);
657 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
659 if (num_threads_sharing == 1)
660 cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map));
662 index_msb = get_count_order(num_threads_sharing);
664 for_each_online_cpu(i) {
665 if (cpu_data(i).apicid >> index_msb ==
666 c->apicid >> index_msb) {
668 to_cpumask(this_leaf->shared_cpu_map));
669 if (i != cpu && per_cpu(ici_cpuid4_info, i)) {
671 CPUID4_INFO_IDX(i, index);
672 cpumask_set_cpu(cpu, to_cpumask(
673 sibling_leaf->shared_cpu_map));
679 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
681 struct _cpuid4_info *this_leaf, *sibling_leaf;
684 this_leaf = CPUID4_INFO_IDX(cpu, index);
685 for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) {
686 sibling_leaf = CPUID4_INFO_IDX(sibling, index);
687 cpumask_clear_cpu(cpu,
688 to_cpumask(sibling_leaf->shared_cpu_map));
692 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
696 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
701 static void __cpuinit free_cache_attributes(unsigned int cpu)
705 for (i = 0; i < num_cache_leaves; i++)
706 cache_remove_shared_cpu_map(cpu, i);
708 kfree(per_cpu(ici_cpuid4_info, cpu));
709 per_cpu(ici_cpuid4_info, cpu) = NULL;
713 __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
715 struct _cpuid4_info_regs *leaf_regs =
716 (struct _cpuid4_info_regs *)this_leaf;
718 return cpuid4_cache_lookup_regs(index, leaf_regs);
721 static void __cpuinit get_cpu_leaves(void *_retval)
723 int j, *retval = _retval, cpu = smp_processor_id();
725 /* Do cpuid and store the results */
726 for (j = 0; j < num_cache_leaves; j++) {
727 struct _cpuid4_info *this_leaf;
728 this_leaf = CPUID4_INFO_IDX(cpu, j);
729 *retval = cpuid4_cache_lookup(j, this_leaf);
730 if (unlikely(*retval < 0)) {
733 for (i = 0; i < j; i++)
734 cache_remove_shared_cpu_map(cpu, i);
737 cache_shared_cpu_map_setup(cpu, j);
741 static int __cpuinit detect_cache_attributes(unsigned int cpu)
745 if (num_cache_leaves == 0)
748 per_cpu(ici_cpuid4_info, cpu) = kzalloc(
749 sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
750 if (per_cpu(ici_cpuid4_info, cpu) == NULL)
753 smp_call_function_single(cpu, get_cpu_leaves, &retval, true);
755 kfree(per_cpu(ici_cpuid4_info, cpu));
756 per_cpu(ici_cpuid4_info, cpu) = NULL;
762 #include <linux/kobject.h>
763 #include <linux/sysfs.h>
765 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
767 /* pointer to kobject for cpuX/cache */
768 static DEFINE_PER_CPU(struct kobject *, ici_cache_kobject);
770 struct _index_kobject {
773 unsigned short index;
776 /* pointer to array of kobjects for cpuX/cache/indexY */
777 static DEFINE_PER_CPU(struct _index_kobject *, ici_index_kobject);
778 #define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(ici_index_kobject, x))[y]))
780 #define show_one_plus(file_name, object, val) \
781 static ssize_t show_##file_name \
782 (struct _cpuid4_info *this_leaf, char *buf) \
784 return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \
787 show_one_plus(level, eax.split.level, 0);
788 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
789 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
790 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
791 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
793 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
795 return sprintf(buf, "%luK\n", this_leaf->size / 1024);
798 static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
801 ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
805 const struct cpumask *mask;
807 mask = to_cpumask(this_leaf->shared_cpu_map);
809 cpulist_scnprintf(buf, len-2, mask) :
810 cpumask_scnprintf(buf, len-2, mask);
817 static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf)
819 return show_shared_cpu_map_func(leaf, 0, buf);
822 static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf)
824 return show_shared_cpu_map_func(leaf, 1, buf);
827 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf)
829 switch (this_leaf->eax.split.type) {
830 case CACHE_TYPE_DATA:
831 return sprintf(buf, "Data\n");
832 case CACHE_TYPE_INST:
833 return sprintf(buf, "Instruction\n");
834 case CACHE_TYPE_UNIFIED:
835 return sprintf(buf, "Unified\n");
837 return sprintf(buf, "Unknown\n");
841 #define to_object(k) container_of(k, struct _index_kobject, kobj)
842 #define to_attr(a) container_of(a, struct _cache_attr, attr)
844 #define define_one_ro(_name) \
845 static struct _cache_attr _name = \
846 __ATTR(_name, 0444, show_##_name, NULL)
848 define_one_ro(level);
850 define_one_ro(coherency_line_size);
851 define_one_ro(physical_line_partition);
852 define_one_ro(ways_of_associativity);
853 define_one_ro(number_of_sets);
855 define_one_ro(shared_cpu_map);
856 define_one_ro(shared_cpu_list);
858 #define DEFAULT_SYSFS_CACHE_ATTRS \
861 &coherency_line_size.attr, \
862 &physical_line_partition.attr, \
863 &ways_of_associativity.attr, \
864 &number_of_sets.attr, \
866 &shared_cpu_map.attr, \
867 &shared_cpu_list.attr
869 static struct attribute *default_attrs[] = {
870 DEFAULT_SYSFS_CACHE_ATTRS,
874 static struct attribute *default_l3_attrs[] = {
875 DEFAULT_SYSFS_CACHE_ATTRS,
876 #ifdef CONFIG_CPU_SUP_AMD
877 &cache_disable_0.attr,
878 &cache_disable_1.attr,
883 static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
885 struct _cache_attr *fattr = to_attr(attr);
886 struct _index_kobject *this_leaf = to_object(kobj);
890 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
896 static ssize_t store(struct kobject *kobj, struct attribute *attr,
897 const char *buf, size_t count)
899 struct _cache_attr *fattr = to_attr(attr);
900 struct _index_kobject *this_leaf = to_object(kobj);
904 fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
910 static const struct sysfs_ops sysfs_ops = {
915 static struct kobj_type ktype_cache = {
916 .sysfs_ops = &sysfs_ops,
917 .default_attrs = default_attrs,
920 static struct kobj_type ktype_percpu_entry = {
921 .sysfs_ops = &sysfs_ops,
924 static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
926 kfree(per_cpu(ici_cache_kobject, cpu));
927 kfree(per_cpu(ici_index_kobject, cpu));
928 per_cpu(ici_cache_kobject, cpu) = NULL;
929 per_cpu(ici_index_kobject, cpu) = NULL;
930 free_cache_attributes(cpu);
933 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
937 if (num_cache_leaves == 0)
940 err = detect_cache_attributes(cpu);
944 /* Allocate all required memory */
945 per_cpu(ici_cache_kobject, cpu) =
946 kzalloc(sizeof(struct kobject), GFP_KERNEL);
947 if (unlikely(per_cpu(ici_cache_kobject, cpu) == NULL))
950 per_cpu(ici_index_kobject, cpu) = kzalloc(
951 sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL);
952 if (unlikely(per_cpu(ici_index_kobject, cpu) == NULL))
958 cpuid4_cache_sysfs_exit(cpu);
962 static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
964 /* Add/Remove cache interface for CPU device */
965 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
967 unsigned int cpu = sys_dev->id;
969 struct _index_kobject *this_object;
970 struct _cpuid4_info *this_leaf;
973 retval = cpuid4_cache_sysfs_init(cpu);
974 if (unlikely(retval < 0))
977 retval = kobject_init_and_add(per_cpu(ici_cache_kobject, cpu),
979 &sys_dev->kobj, "%s", "cache");
981 cpuid4_cache_sysfs_exit(cpu);
985 for (i = 0; i < num_cache_leaves; i++) {
986 this_object = INDEX_KOBJECT_PTR(cpu, i);
987 this_object->cpu = cpu;
988 this_object->index = i;
990 this_leaf = CPUID4_INFO_IDX(cpu, i);
992 if (this_leaf->can_disable)
993 ktype_cache.default_attrs = default_l3_attrs;
995 ktype_cache.default_attrs = default_attrs;
997 retval = kobject_init_and_add(&(this_object->kobj),
999 per_cpu(ici_cache_kobject, cpu),
1001 if (unlikely(retval)) {
1002 for (j = 0; j < i; j++)
1003 kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj));
1004 kobject_put(per_cpu(ici_cache_kobject, cpu));
1005 cpuid4_cache_sysfs_exit(cpu);
1008 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
1010 cpumask_set_cpu(cpu, to_cpumask(cache_dev_map));
1012 kobject_uevent(per_cpu(ici_cache_kobject, cpu), KOBJ_ADD);
1016 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
1018 unsigned int cpu = sys_dev->id;
1021 if (per_cpu(ici_cpuid4_info, cpu) == NULL)
1023 if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map)))
1025 cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
1027 for (i = 0; i < num_cache_leaves; i++)
1028 kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj));
1029 kobject_put(per_cpu(ici_cache_kobject, cpu));
1030 cpuid4_cache_sysfs_exit(cpu);
1033 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
1034 unsigned long action, void *hcpu)
1036 unsigned int cpu = (unsigned long)hcpu;
1037 struct sys_device *sys_dev;
1039 sys_dev = get_cpu_sysdev(cpu);
1042 case CPU_ONLINE_FROZEN:
1043 cache_add_dev(sys_dev);
1046 case CPU_DEAD_FROZEN:
1047 cache_remove_dev(sys_dev);
1053 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = {
1054 .notifier_call = cacheinfo_cpu_callback,
1057 static int __cpuinit cache_sysfs_init(void)
1061 if (num_cache_leaves == 0)
1064 for_each_online_cpu(i) {
1066 struct sys_device *sys_dev = get_cpu_sysdev(i);
1068 err = cache_add_dev(sys_dev);
1072 register_hotcpu_notifier(&cacheinfo_cpu_notifier);
1076 device_initcall(cache_sysfs_init);