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 this_leaf
->can_disable
= true;
344 this_leaf
->l3_indices
= amd_calc_l3_indices();
347 static ssize_t
show_cache_disable(struct _cpuid4_info
*this_leaf
, char *buf
,
350 int cpu
= cpumask_first(to_cpumask(this_leaf
->shared_cpu_map
));
351 int node
= amd_get_nb_id(cpu
);
352 struct pci_dev
*dev
= node_to_k8_nb_misc(node
);
353 unsigned int reg
= 0;
355 if (!this_leaf
->can_disable
)
361 pci_read_config_dword(dev
, 0x1BC + index
* 4, ®
);
362 return sprintf(buf
, "0x%08x\n", reg
);
365 #define SHOW_CACHE_DISABLE(index) \
367 show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \
369 return show_cache_disable(this_leaf, buf, index); \
371 SHOW_CACHE_DISABLE(0)
372 SHOW_CACHE_DISABLE(1)
374 static ssize_t
store_cache_disable(struct _cpuid4_info
*this_leaf
,
375 const char *buf
, size_t count
, unsigned int index
)
377 int cpu
= cpumask_first(to_cpumask(this_leaf
->shared_cpu_map
));
378 int node
= amd_get_nb_id(cpu
);
379 struct pci_dev
*dev
= node_to_k8_nb_misc(node
);
380 unsigned long val
= 0;
382 #define SUBCACHE_MASK (3UL << 20)
383 #define SUBCACHE_INDEX 0xfff
385 if (!this_leaf
->can_disable
)
388 if (!capable(CAP_SYS_ADMIN
))
394 if (strict_strtoul(buf
, 10, &val
) < 0)
397 /* do not allow writes outside of allowed bits */
398 if ((val
& ~(SUBCACHE_MASK
| SUBCACHE_INDEX
)) ||
399 ((val
& SUBCACHE_INDEX
) > this_leaf
->l3_indices
))
403 pci_write_config_dword(dev
, 0x1BC + index
* 4, val
);
405 * We need to WBINVD on a core on the node containing the L3 cache which
406 * indices we disable therefore a simple wbinvd() is not sufficient.
409 pci_write_config_dword(dev
, 0x1BC + index
* 4, val
| BIT(31));
413 #define STORE_CACHE_DISABLE(index) \
415 store_cache_disable_##index(struct _cpuid4_info *this_leaf, \
416 const char *buf, size_t count) \
418 return store_cache_disable(this_leaf, buf, count, index); \
420 STORE_CACHE_DISABLE(0)
421 STORE_CACHE_DISABLE(1)
423 static struct _cache_attr cache_disable_0
= __ATTR(cache_disable_0
, 0644,
424 show_cache_disable_0
, store_cache_disable_0
);
425 static struct _cache_attr cache_disable_1
= __ATTR(cache_disable_1
, 0644,
426 show_cache_disable_1
, store_cache_disable_1
);
428 #else /* CONFIG_CPU_SUP_AMD */
429 static void __cpuinit
430 amd_check_l3_disable(int index
, struct _cpuid4_info_regs
*this_leaf
)
433 #endif /* CONFIG_CPU_SUP_AMD */
436 __cpuinit
cpuid4_cache_lookup_regs(int index
,
437 struct _cpuid4_info_regs
*this_leaf
)
439 union _cpuid4_leaf_eax eax
;
440 union _cpuid4_leaf_ebx ebx
;
441 union _cpuid4_leaf_ecx ecx
;
444 if (boot_cpu_data
.x86_vendor
== X86_VENDOR_AMD
) {
445 amd_cpuid4(index
, &eax
, &ebx
, &ecx
);
446 if (boot_cpu_data
.x86
>= 0x10)
447 amd_check_l3_disable(index
, this_leaf
);
449 cpuid_count(4, index
, &eax
.full
, &ebx
.full
, &ecx
.full
, &edx
);
452 if (eax
.split
.type
== CACHE_TYPE_NULL
)
453 return -EIO
; /* better error ? */
455 this_leaf
->eax
= eax
;
456 this_leaf
->ebx
= ebx
;
457 this_leaf
->ecx
= ecx
;
458 this_leaf
->size
= (ecx
.split
.number_of_sets
+ 1) *
459 (ebx
.split
.coherency_line_size
+ 1) *
460 (ebx
.split
.physical_line_partition
+ 1) *
461 (ebx
.split
.ways_of_associativity
+ 1);
465 static int __cpuinit
find_num_cache_leaves(void)
467 unsigned int eax
, ebx
, ecx
, edx
;
468 union _cpuid4_leaf_eax cache_eax
;
473 /* Do cpuid(4) loop to find out num_cache_leaves */
474 cpuid_count(4, i
, &eax
, &ebx
, &ecx
, &edx
);
475 cache_eax
.full
= eax
;
476 } while (cache_eax
.split
.type
!= CACHE_TYPE_NULL
);
480 unsigned int __cpuinit
init_intel_cacheinfo(struct cpuinfo_x86
*c
)
483 unsigned int trace
= 0, l1i
= 0, l1d
= 0, l2
= 0, l3
= 0;
484 unsigned int new_l1d
= 0, new_l1i
= 0; /* Cache sizes from cpuid(4) */
485 unsigned int new_l2
= 0, new_l3
= 0, i
; /* Cache sizes from cpuid(4) */
486 unsigned int l2_id
= 0, l3_id
= 0, num_threads_sharing
, index_msb
;
488 unsigned int cpu
= c
->cpu_index
;
491 if (c
->cpuid_level
> 3) {
492 static int is_initialized
;
494 if (is_initialized
== 0) {
495 /* Init num_cache_leaves from boot CPU */
496 num_cache_leaves
= find_num_cache_leaves();
501 * Whenever possible use cpuid(4), deterministic cache
502 * parameters cpuid leaf to find the cache details
504 for (i
= 0; i
< num_cache_leaves
; i
++) {
505 struct _cpuid4_info_regs this_leaf
;
508 retval
= cpuid4_cache_lookup_regs(i
, &this_leaf
);
510 switch (this_leaf
.eax
.split
.level
) {
512 if (this_leaf
.eax
.split
.type
==
514 new_l1d
= this_leaf
.size
/1024;
515 else if (this_leaf
.eax
.split
.type
==
517 new_l1i
= this_leaf
.size
/1024;
520 new_l2
= this_leaf
.size
/1024;
521 num_threads_sharing
= 1 + this_leaf
.eax
.split
.num_threads_sharing
;
522 index_msb
= get_count_order(num_threads_sharing
);
523 l2_id
= c
->apicid
>> index_msb
;
526 new_l3
= this_leaf
.size
/1024;
527 num_threads_sharing
= 1 + this_leaf
.eax
.split
.num_threads_sharing
;
528 index_msb
= get_count_order(
529 num_threads_sharing
);
530 l3_id
= c
->apicid
>> index_msb
;
539 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
542 if ((num_cache_leaves
== 0 || c
->x86
== 15) && c
->cpuid_level
> 1) {
543 /* supports eax=2 call */
545 unsigned int regs
[4];
546 unsigned char *dp
= (unsigned char *)regs
;
549 if (num_cache_leaves
!= 0 && c
->x86
== 15)
552 /* Number of times to iterate */
553 n
= cpuid_eax(2) & 0xFF;
555 for (i
= 0 ; i
< n
; i
++) {
556 cpuid(2, ®s
[0], ®s
[1], ®s
[2], ®s
[3]);
558 /* If bit 31 is set, this is an unknown format */
559 for (j
= 0 ; j
< 3 ; j
++)
560 if (regs
[j
] & (1 << 31))
563 /* Byte 0 is level count, not a descriptor */
564 for (j
= 1 ; j
< 16 ; j
++) {
565 unsigned char des
= dp
[j
];
568 /* look up this descriptor in the table */
569 while (cache_table
[k
].descriptor
!= 0) {
570 if (cache_table
[k
].descriptor
== des
) {
571 if (only_trace
&& cache_table
[k
].cache_type
!= LVL_TRACE
)
573 switch (cache_table
[k
].cache_type
) {
575 l1i
+= cache_table
[k
].size
;
578 l1d
+= cache_table
[k
].size
;
581 l2
+= cache_table
[k
].size
;
584 l3
+= cache_table
[k
].size
;
587 trace
+= cache_table
[k
].size
;
609 per_cpu(cpu_llc_id
, cpu
) = l2_id
;
616 per_cpu(cpu_llc_id
, cpu
) = l3_id
;
620 c
->x86_cache_size
= l3
? l3
: (l2
? l2
: (l1i
+l1d
));
627 /* pointer to _cpuid4_info array (for each cache leaf) */
628 static DEFINE_PER_CPU(struct _cpuid4_info
*, ici_cpuid4_info
);
629 #define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y]))
632 static void __cpuinit
cache_shared_cpu_map_setup(unsigned int cpu
, int index
)
634 struct _cpuid4_info
*this_leaf
, *sibling_leaf
;
635 unsigned long num_threads_sharing
;
636 int index_msb
, i
, sibling
;
637 struct cpuinfo_x86
*c
= &cpu_data(cpu
);
639 if ((index
== 3) && (c
->x86_vendor
== X86_VENDOR_AMD
)) {
640 for_each_cpu(i
, c
->llc_shared_map
) {
641 if (!per_cpu(ici_cpuid4_info
, i
))
643 this_leaf
= CPUID4_INFO_IDX(i
, index
);
644 for_each_cpu(sibling
, c
->llc_shared_map
) {
645 if (!cpu_online(sibling
))
647 set_bit(sibling
, this_leaf
->shared_cpu_map
);
652 this_leaf
= CPUID4_INFO_IDX(cpu
, index
);
653 num_threads_sharing
= 1 + this_leaf
->eax
.split
.num_threads_sharing
;
655 if (num_threads_sharing
== 1)
656 cpumask_set_cpu(cpu
, to_cpumask(this_leaf
->shared_cpu_map
));
658 index_msb
= get_count_order(num_threads_sharing
);
660 for_each_online_cpu(i
) {
661 if (cpu_data(i
).apicid
>> index_msb
==
662 c
->apicid
>> index_msb
) {
664 to_cpumask(this_leaf
->shared_cpu_map
));
665 if (i
!= cpu
&& per_cpu(ici_cpuid4_info
, i
)) {
667 CPUID4_INFO_IDX(i
, index
);
668 cpumask_set_cpu(cpu
, to_cpumask(
669 sibling_leaf
->shared_cpu_map
));
675 static void __cpuinit
cache_remove_shared_cpu_map(unsigned int cpu
, int index
)
677 struct _cpuid4_info
*this_leaf
, *sibling_leaf
;
680 this_leaf
= CPUID4_INFO_IDX(cpu
, index
);
681 for_each_cpu(sibling
, to_cpumask(this_leaf
->shared_cpu_map
)) {
682 sibling_leaf
= CPUID4_INFO_IDX(sibling
, index
);
683 cpumask_clear_cpu(cpu
,
684 to_cpumask(sibling_leaf
->shared_cpu_map
));
688 static void __cpuinit
cache_shared_cpu_map_setup(unsigned int cpu
, int index
)
692 static void __cpuinit
cache_remove_shared_cpu_map(unsigned int cpu
, int index
)
697 static void __cpuinit
free_cache_attributes(unsigned int cpu
)
701 for (i
= 0; i
< num_cache_leaves
; i
++)
702 cache_remove_shared_cpu_map(cpu
, i
);
704 kfree(per_cpu(ici_cpuid4_info
, cpu
));
705 per_cpu(ici_cpuid4_info
, cpu
) = NULL
;
709 __cpuinit
cpuid4_cache_lookup(int index
, struct _cpuid4_info
*this_leaf
)
711 struct _cpuid4_info_regs
*leaf_regs
=
712 (struct _cpuid4_info_regs
*)this_leaf
;
714 return cpuid4_cache_lookup_regs(index
, leaf_regs
);
717 static void __cpuinit
get_cpu_leaves(void *_retval
)
719 int j
, *retval
= _retval
, cpu
= smp_processor_id();
721 /* Do cpuid and store the results */
722 for (j
= 0; j
< num_cache_leaves
; j
++) {
723 struct _cpuid4_info
*this_leaf
;
724 this_leaf
= CPUID4_INFO_IDX(cpu
, j
);
725 *retval
= cpuid4_cache_lookup(j
, this_leaf
);
726 if (unlikely(*retval
< 0)) {
729 for (i
= 0; i
< j
; i
++)
730 cache_remove_shared_cpu_map(cpu
, i
);
733 cache_shared_cpu_map_setup(cpu
, j
);
737 static int __cpuinit
detect_cache_attributes(unsigned int cpu
)
741 if (num_cache_leaves
== 0)
744 per_cpu(ici_cpuid4_info
, cpu
) = kzalloc(
745 sizeof(struct _cpuid4_info
) * num_cache_leaves
, GFP_KERNEL
);
746 if (per_cpu(ici_cpuid4_info
, cpu
) == NULL
)
749 smp_call_function_single(cpu
, get_cpu_leaves
, &retval
, true);
751 kfree(per_cpu(ici_cpuid4_info
, cpu
));
752 per_cpu(ici_cpuid4_info
, cpu
) = NULL
;
758 #include <linux/kobject.h>
759 #include <linux/sysfs.h>
761 extern struct sysdev_class cpu_sysdev_class
; /* from drivers/base/cpu.c */
763 /* pointer to kobject for cpuX/cache */
764 static DEFINE_PER_CPU(struct kobject
*, ici_cache_kobject
);
766 struct _index_kobject
{
769 unsigned short index
;
772 /* pointer to array of kobjects for cpuX/cache/indexY */
773 static DEFINE_PER_CPU(struct _index_kobject
*, ici_index_kobject
);
774 #define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(ici_index_kobject, x))[y]))
776 #define show_one_plus(file_name, object, val) \
777 static ssize_t show_##file_name \
778 (struct _cpuid4_info *this_leaf, char *buf) \
780 return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \
783 show_one_plus(level
, eax
.split
.level
, 0);
784 show_one_plus(coherency_line_size
, ebx
.split
.coherency_line_size
, 1);
785 show_one_plus(physical_line_partition
, ebx
.split
.physical_line_partition
, 1);
786 show_one_plus(ways_of_associativity
, ebx
.split
.ways_of_associativity
, 1);
787 show_one_plus(number_of_sets
, ecx
.split
.number_of_sets
, 1);
789 static ssize_t
show_size(struct _cpuid4_info
*this_leaf
, char *buf
)
791 return sprintf(buf
, "%luK\n", this_leaf
->size
/ 1024);
794 static ssize_t
show_shared_cpu_map_func(struct _cpuid4_info
*this_leaf
,
797 ptrdiff_t len
= PTR_ALIGN(buf
+ PAGE_SIZE
- 1, PAGE_SIZE
) - buf
;
801 const struct cpumask
*mask
;
803 mask
= to_cpumask(this_leaf
->shared_cpu_map
);
805 cpulist_scnprintf(buf
, len
-2, mask
) :
806 cpumask_scnprintf(buf
, len
-2, mask
);
813 static inline ssize_t
show_shared_cpu_map(struct _cpuid4_info
*leaf
, char *buf
)
815 return show_shared_cpu_map_func(leaf
, 0, buf
);
818 static inline ssize_t
show_shared_cpu_list(struct _cpuid4_info
*leaf
, char *buf
)
820 return show_shared_cpu_map_func(leaf
, 1, buf
);
823 static ssize_t
show_type(struct _cpuid4_info
*this_leaf
, char *buf
)
825 switch (this_leaf
->eax
.split
.type
) {
826 case CACHE_TYPE_DATA
:
827 return sprintf(buf
, "Data\n");
828 case CACHE_TYPE_INST
:
829 return sprintf(buf
, "Instruction\n");
830 case CACHE_TYPE_UNIFIED
:
831 return sprintf(buf
, "Unified\n");
833 return sprintf(buf
, "Unknown\n");
837 #define to_object(k) container_of(k, struct _index_kobject, kobj)
838 #define to_attr(a) container_of(a, struct _cache_attr, attr)
840 #define define_one_ro(_name) \
841 static struct _cache_attr _name = \
842 __ATTR(_name, 0444, show_##_name, NULL)
844 define_one_ro(level
);
846 define_one_ro(coherency_line_size
);
847 define_one_ro(physical_line_partition
);
848 define_one_ro(ways_of_associativity
);
849 define_one_ro(number_of_sets
);
851 define_one_ro(shared_cpu_map
);
852 define_one_ro(shared_cpu_list
);
854 #define DEFAULT_SYSFS_CACHE_ATTRS \
857 &coherency_line_size.attr, \
858 &physical_line_partition.attr, \
859 &ways_of_associativity.attr, \
860 &number_of_sets.attr, \
862 &shared_cpu_map.attr, \
863 &shared_cpu_list.attr
865 static struct attribute
*default_attrs
[] = {
866 DEFAULT_SYSFS_CACHE_ATTRS
,
870 static struct attribute
*default_l3_attrs
[] = {
871 DEFAULT_SYSFS_CACHE_ATTRS
,
872 #ifdef CONFIG_CPU_SUP_AMD
873 &cache_disable_0
.attr
,
874 &cache_disable_1
.attr
,
879 static ssize_t
show(struct kobject
*kobj
, struct attribute
*attr
, char *buf
)
881 struct _cache_attr
*fattr
= to_attr(attr
);
882 struct _index_kobject
*this_leaf
= to_object(kobj
);
886 fattr
->show(CPUID4_INFO_IDX(this_leaf
->cpu
, this_leaf
->index
),
892 static ssize_t
store(struct kobject
*kobj
, struct attribute
*attr
,
893 const char *buf
, size_t count
)
895 struct _cache_attr
*fattr
= to_attr(attr
);
896 struct _index_kobject
*this_leaf
= to_object(kobj
);
900 fattr
->store(CPUID4_INFO_IDX(this_leaf
->cpu
, this_leaf
->index
),
906 static const struct sysfs_ops sysfs_ops
= {
911 static struct kobj_type ktype_cache
= {
912 .sysfs_ops
= &sysfs_ops
,
913 .default_attrs
= default_attrs
,
916 static struct kobj_type ktype_percpu_entry
= {
917 .sysfs_ops
= &sysfs_ops
,
920 static void __cpuinit
cpuid4_cache_sysfs_exit(unsigned int cpu
)
922 kfree(per_cpu(ici_cache_kobject
, cpu
));
923 kfree(per_cpu(ici_index_kobject
, cpu
));
924 per_cpu(ici_cache_kobject
, cpu
) = NULL
;
925 per_cpu(ici_index_kobject
, cpu
) = NULL
;
926 free_cache_attributes(cpu
);
929 static int __cpuinit
cpuid4_cache_sysfs_init(unsigned int cpu
)
933 if (num_cache_leaves
== 0)
936 err
= detect_cache_attributes(cpu
);
940 /* Allocate all required memory */
941 per_cpu(ici_cache_kobject
, cpu
) =
942 kzalloc(sizeof(struct kobject
), GFP_KERNEL
);
943 if (unlikely(per_cpu(ici_cache_kobject
, cpu
) == NULL
))
946 per_cpu(ici_index_kobject
, cpu
) = kzalloc(
947 sizeof(struct _index_kobject
) * num_cache_leaves
, GFP_KERNEL
);
948 if (unlikely(per_cpu(ici_index_kobject
, cpu
) == NULL
))
954 cpuid4_cache_sysfs_exit(cpu
);
958 static DECLARE_BITMAP(cache_dev_map
, NR_CPUS
);
960 /* Add/Remove cache interface for CPU device */
961 static int __cpuinit
cache_add_dev(struct sys_device
* sys_dev
)
963 unsigned int cpu
= sys_dev
->id
;
965 struct _index_kobject
*this_object
;
966 struct _cpuid4_info
*this_leaf
;
969 retval
= cpuid4_cache_sysfs_init(cpu
);
970 if (unlikely(retval
< 0))
973 retval
= kobject_init_and_add(per_cpu(ici_cache_kobject
, cpu
),
975 &sys_dev
->kobj
, "%s", "cache");
977 cpuid4_cache_sysfs_exit(cpu
);
981 for (i
= 0; i
< num_cache_leaves
; i
++) {
982 this_object
= INDEX_KOBJECT_PTR(cpu
, i
);
983 this_object
->cpu
= cpu
;
984 this_object
->index
= i
;
986 this_leaf
= CPUID4_INFO_IDX(cpu
, i
);
988 if (this_leaf
->can_disable
)
989 ktype_cache
.default_attrs
= default_l3_attrs
;
991 ktype_cache
.default_attrs
= default_attrs
;
993 retval
= kobject_init_and_add(&(this_object
->kobj
),
995 per_cpu(ici_cache_kobject
, cpu
),
997 if (unlikely(retval
)) {
998 for (j
= 0; j
< i
; j
++)
999 kobject_put(&(INDEX_KOBJECT_PTR(cpu
, j
)->kobj
));
1000 kobject_put(per_cpu(ici_cache_kobject
, cpu
));
1001 cpuid4_cache_sysfs_exit(cpu
);
1004 kobject_uevent(&(this_object
->kobj
), KOBJ_ADD
);
1006 cpumask_set_cpu(cpu
, to_cpumask(cache_dev_map
));
1008 kobject_uevent(per_cpu(ici_cache_kobject
, cpu
), KOBJ_ADD
);
1012 static void __cpuinit
cache_remove_dev(struct sys_device
* sys_dev
)
1014 unsigned int cpu
= sys_dev
->id
;
1017 if (per_cpu(ici_cpuid4_info
, cpu
) == NULL
)
1019 if (!cpumask_test_cpu(cpu
, to_cpumask(cache_dev_map
)))
1021 cpumask_clear_cpu(cpu
, to_cpumask(cache_dev_map
));
1023 for (i
= 0; i
< num_cache_leaves
; i
++)
1024 kobject_put(&(INDEX_KOBJECT_PTR(cpu
, i
)->kobj
));
1025 kobject_put(per_cpu(ici_cache_kobject
, cpu
));
1026 cpuid4_cache_sysfs_exit(cpu
);
1029 static int __cpuinit
cacheinfo_cpu_callback(struct notifier_block
*nfb
,
1030 unsigned long action
, void *hcpu
)
1032 unsigned int cpu
= (unsigned long)hcpu
;
1033 struct sys_device
*sys_dev
;
1035 sys_dev
= get_cpu_sysdev(cpu
);
1038 case CPU_ONLINE_FROZEN
:
1039 cache_add_dev(sys_dev
);
1042 case CPU_DEAD_FROZEN
:
1043 cache_remove_dev(sys_dev
);
1049 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier
= {
1050 .notifier_call
= cacheinfo_cpu_callback
,
1053 static int __cpuinit
cache_sysfs_init(void)
1057 if (num_cache_leaves
== 0)
1060 for_each_online_cpu(i
) {
1062 struct sys_device
*sys_dev
= get_cpu_sysdev(i
);
1064 err
= cache_add_dev(sys_dev
);
1068 register_hotcpu_notifier(&cacheinfo_cpu_notifier
);
1072 device_initcall(cache_sysfs_init
);