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>
29 unsigned char descriptor
;
34 #define MB(x) ((x) * 1024)
36 /* All the cache descriptor types we care about (no TLB or
37 trace cache entries) */
39 static const struct _cache_table __cpuinitconst cache_table
[] =
41 { 0x06, LVL_1_INST
, 8 }, /* 4-way set assoc, 32 byte line size */
42 { 0x08, LVL_1_INST
, 16 }, /* 4-way set assoc, 32 byte line size */
43 { 0x09, LVL_1_INST
, 32 }, /* 4-way set assoc, 64 byte line size */
44 { 0x0a, LVL_1_DATA
, 8 }, /* 2 way set assoc, 32 byte line size */
45 { 0x0c, LVL_1_DATA
, 16 }, /* 4-way set assoc, 32 byte line size */
46 { 0x0d, LVL_1_DATA
, 16 }, /* 4-way set assoc, 64 byte line size */
47 { 0x21, LVL_2
, 256 }, /* 8-way set assoc, 64 byte line size */
48 { 0x22, LVL_3
, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
49 { 0x23, LVL_3
, MB(1) }, /* 8-way set assoc, sectored cache, 64 byte line size */
50 { 0x25, LVL_3
, MB(2) }, /* 8-way set assoc, sectored cache, 64 byte line size */
51 { 0x29, LVL_3
, MB(4) }, /* 8-way set assoc, sectored cache, 64 byte line size */
52 { 0x2c, LVL_1_DATA
, 32 }, /* 8-way set assoc, 64 byte line size */
53 { 0x30, LVL_1_INST
, 32 }, /* 8-way set assoc, 64 byte line size */
54 { 0x39, LVL_2
, 128 }, /* 4-way set assoc, sectored cache, 64 byte line size */
55 { 0x3a, LVL_2
, 192 }, /* 6-way set assoc, sectored cache, 64 byte line size */
56 { 0x3b, LVL_2
, 128 }, /* 2-way set assoc, sectored cache, 64 byte line size */
57 { 0x3c, LVL_2
, 256 }, /* 4-way set assoc, sectored cache, 64 byte line size */
58 { 0x3d, LVL_2
, 384 }, /* 6-way set assoc, sectored cache, 64 byte line size */
59 { 0x3e, LVL_2
, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
60 { 0x3f, LVL_2
, 256 }, /* 2-way set assoc, 64 byte line size */
61 { 0x41, LVL_2
, 128 }, /* 4-way set assoc, 32 byte line size */
62 { 0x42, LVL_2
, 256 }, /* 4-way set assoc, 32 byte line size */
63 { 0x43, LVL_2
, 512 }, /* 4-way set assoc, 32 byte line size */
64 { 0x44, LVL_2
, MB(1) }, /* 4-way set assoc, 32 byte line size */
65 { 0x45, LVL_2
, MB(2) }, /* 4-way set assoc, 32 byte line size */
66 { 0x46, LVL_3
, MB(4) }, /* 4-way set assoc, 64 byte line size */
67 { 0x47, LVL_3
, MB(8) }, /* 8-way set assoc, 64 byte line size */
68 { 0x49, LVL_3
, MB(4) }, /* 16-way set assoc, 64 byte line size */
69 { 0x4a, LVL_3
, MB(6) }, /* 12-way set assoc, 64 byte line size */
70 { 0x4b, LVL_3
, MB(8) }, /* 16-way set assoc, 64 byte line size */
71 { 0x4c, LVL_3
, MB(12) }, /* 12-way set assoc, 64 byte line size */
72 { 0x4d, LVL_3
, MB(16) }, /* 16-way set assoc, 64 byte line size */
73 { 0x4e, LVL_2
, MB(6) }, /* 24-way set assoc, 64 byte line size */
74 { 0x60, LVL_1_DATA
, 16 }, /* 8-way set assoc, sectored cache, 64 byte line size */
75 { 0x66, LVL_1_DATA
, 8 }, /* 4-way set assoc, sectored cache, 64 byte line size */
76 { 0x67, LVL_1_DATA
, 16 }, /* 4-way set assoc, sectored cache, 64 byte line size */
77 { 0x68, LVL_1_DATA
, 32 }, /* 4-way set assoc, sectored cache, 64 byte line size */
78 { 0x70, LVL_TRACE
, 12 }, /* 8-way set assoc */
79 { 0x71, LVL_TRACE
, 16 }, /* 8-way set assoc */
80 { 0x72, LVL_TRACE
, 32 }, /* 8-way set assoc */
81 { 0x73, LVL_TRACE
, 64 }, /* 8-way set assoc */
82 { 0x78, LVL_2
, MB(1) }, /* 4-way set assoc, 64 byte line size */
83 { 0x79, LVL_2
, 128 }, /* 8-way set assoc, sectored cache, 64 byte line size */
84 { 0x7a, LVL_2
, 256 }, /* 8-way set assoc, sectored cache, 64 byte line size */
85 { 0x7b, LVL_2
, 512 }, /* 8-way set assoc, sectored cache, 64 byte line size */
86 { 0x7c, LVL_2
, MB(1) }, /* 8-way set assoc, sectored cache, 64 byte line size */
87 { 0x7d, LVL_2
, MB(2) }, /* 8-way set assoc, 64 byte line size */
88 { 0x7f, LVL_2
, 512 }, /* 2-way set assoc, 64 byte line size */
89 { 0x82, LVL_2
, 256 }, /* 8-way set assoc, 32 byte line size */
90 { 0x83, LVL_2
, 512 }, /* 8-way set assoc, 32 byte line size */
91 { 0x84, LVL_2
, MB(1) }, /* 8-way set assoc, 32 byte line size */
92 { 0x85, LVL_2
, MB(2) }, /* 8-way set assoc, 32 byte line size */
93 { 0x86, LVL_2
, 512 }, /* 4-way set assoc, 64 byte line size */
94 { 0x87, LVL_2
, MB(1) }, /* 8-way set assoc, 64 byte line size */
95 { 0xd0, LVL_3
, 512 }, /* 4-way set assoc, 64 byte line size */
96 { 0xd1, LVL_3
, MB(1) }, /* 4-way set assoc, 64 byte line size */
97 { 0xd2, LVL_3
, MB(2) }, /* 4-way set assoc, 64 byte line size */
98 { 0xd6, LVL_3
, MB(1) }, /* 8-way set assoc, 64 byte line size */
99 { 0xd7, LVL_3
, MB(2) }, /* 8-way set assoc, 64 byte line size */
100 { 0xd8, LVL_3
, MB(4) }, /* 12-way set assoc, 64 byte line size */
101 { 0xdc, LVL_3
, MB(2) }, /* 12-way set assoc, 64 byte line size */
102 { 0xdd, LVL_3
, MB(4) }, /* 12-way set assoc, 64 byte line size */
103 { 0xde, LVL_3
, MB(8) }, /* 12-way set assoc, 64 byte line size */
104 { 0xe2, LVL_3
, MB(2) }, /* 16-way set assoc, 64 byte line size */
105 { 0xe3, LVL_3
, MB(4) }, /* 16-way set assoc, 64 byte line size */
106 { 0xe4, LVL_3
, MB(8) }, /* 16-way set assoc, 64 byte line size */
107 { 0xea, LVL_3
, MB(12) }, /* 24-way set assoc, 64 byte line size */
108 { 0xeb, LVL_3
, MB(18) }, /* 24-way set assoc, 64 byte line size */
109 { 0xec, LVL_3
, MB(24) }, /* 24-way set assoc, 64 byte line size */
118 CACHE_TYPE_UNIFIED
= 3
121 union _cpuid4_leaf_eax
{
123 enum _cache_type type
:5;
124 unsigned int level
:3;
125 unsigned int is_self_initializing
:1;
126 unsigned int is_fully_associative
:1;
127 unsigned int reserved
:4;
128 unsigned int num_threads_sharing
:12;
129 unsigned int num_cores_on_die
:6;
134 union _cpuid4_leaf_ebx
{
136 unsigned int coherency_line_size
:12;
137 unsigned int physical_line_partition
:10;
138 unsigned int ways_of_associativity
:10;
143 union _cpuid4_leaf_ecx
{
145 unsigned int number_of_sets
:32;
150 struct _cpuid4_info
{
151 union _cpuid4_leaf_eax eax
;
152 union _cpuid4_leaf_ebx ebx
;
153 union _cpuid4_leaf_ecx ecx
;
155 unsigned long can_disable
;
156 DECLARE_BITMAP(shared_cpu_map
, NR_CPUS
);
159 /* subset of above _cpuid4_info w/o shared_cpu_map */
160 struct _cpuid4_info_regs
{
161 union _cpuid4_leaf_eax eax
;
162 union _cpuid4_leaf_ebx ebx
;
163 union _cpuid4_leaf_ecx ecx
;
165 unsigned long can_disable
;
168 unsigned short num_cache_leaves
;
170 /* AMD doesn't have CPUID4. Emulate it here to report the same
171 information to the user. This makes some assumptions about the machine:
172 L2 not shared, no SMT etc. that is currently true on AMD CPUs.
174 In theory the TLBs could be reported as fake type (they are in "dummy").
178 unsigned line_size
:8;
179 unsigned lines_per_tag
:8;
181 unsigned size_in_kb
:8;
188 unsigned line_size
:8;
189 unsigned lines_per_tag
:4;
191 unsigned size_in_kb
:16;
198 unsigned line_size
:8;
199 unsigned lines_per_tag
:4;
202 unsigned size_encoded
:14;
207 static const unsigned short __cpuinitconst assocs
[] = {
218 [0xf] = 0xffff /* fully associative - no way to show this currently */
221 static const unsigned char __cpuinitconst levels
[] = { 1, 1, 2, 3 };
222 static const unsigned char __cpuinitconst types
[] = { 1, 2, 3, 3 };
224 static void __cpuinit
225 amd_cpuid4(int leaf
, union _cpuid4_leaf_eax
*eax
,
226 union _cpuid4_leaf_ebx
*ebx
,
227 union _cpuid4_leaf_ecx
*ecx
)
230 unsigned line_size
, lines_per_tag
, assoc
, size_in_kb
;
231 union l1_cache l1i
, l1d
;
234 union l1_cache
*l1
= &l1d
;
240 cpuid(0x80000005, &dummy
, &dummy
, &l1d
.val
, &l1i
.val
);
241 cpuid(0x80000006, &dummy
, &dummy
, &l2
.val
, &l3
.val
);
249 assoc
= assocs
[l1
->assoc
];
250 line_size
= l1
->line_size
;
251 lines_per_tag
= l1
->lines_per_tag
;
252 size_in_kb
= l1
->size_in_kb
;
257 assoc
= assocs
[l2
.assoc
];
258 line_size
= l2
.line_size
;
259 lines_per_tag
= l2
.lines_per_tag
;
260 /* cpu_data has errata corrections for K7 applied */
261 size_in_kb
= current_cpu_data
.x86_cache_size
;
266 assoc
= assocs
[l3
.assoc
];
267 line_size
= l3
.line_size
;
268 lines_per_tag
= l3
.lines_per_tag
;
269 size_in_kb
= l3
.size_encoded
* 512;
270 if (boot_cpu_has(X86_FEATURE_AMD_DCM
)) {
271 size_in_kb
= size_in_kb
>> 1;
279 eax
->split
.is_self_initializing
= 1;
280 eax
->split
.type
= types
[leaf
];
281 eax
->split
.level
= levels
[leaf
];
282 eax
->split
.num_threads_sharing
= 0;
283 eax
->split
.num_cores_on_die
= current_cpu_data
.x86_max_cores
- 1;
287 eax
->split
.is_fully_associative
= 1;
288 ebx
->split
.coherency_line_size
= line_size
- 1;
289 ebx
->split
.ways_of_associativity
= assoc
- 1;
290 ebx
->split
.physical_line_partition
= lines_per_tag
- 1;
291 ecx
->split
.number_of_sets
= (size_in_kb
* 1024) / line_size
/
292 (ebx
->split
.ways_of_associativity
+ 1) - 1;
295 static void __cpuinit
296 amd_check_l3_disable(int index
, struct _cpuid4_info_regs
*this_leaf
)
301 if (boot_cpu_data
.x86
== 0x11)
304 /* see erratum #382 */
305 if ((boot_cpu_data
.x86
== 0x10) && (boot_cpu_data
.x86_model
< 0x8))
308 this_leaf
->can_disable
= 1;
312 __cpuinit
cpuid4_cache_lookup_regs(int index
,
313 struct _cpuid4_info_regs
*this_leaf
)
315 union _cpuid4_leaf_eax eax
;
316 union _cpuid4_leaf_ebx ebx
;
317 union _cpuid4_leaf_ecx ecx
;
320 if (boot_cpu_data
.x86_vendor
== X86_VENDOR_AMD
) {
321 amd_cpuid4(index
, &eax
, &ebx
, &ecx
);
322 if (boot_cpu_data
.x86
>= 0x10)
323 amd_check_l3_disable(index
, this_leaf
);
325 cpuid_count(4, index
, &eax
.full
, &ebx
.full
, &ecx
.full
, &edx
);
328 if (eax
.split
.type
== CACHE_TYPE_NULL
)
329 return -EIO
; /* better error ? */
331 this_leaf
->eax
= eax
;
332 this_leaf
->ebx
= ebx
;
333 this_leaf
->ecx
= ecx
;
334 this_leaf
->size
= (ecx
.split
.number_of_sets
+ 1) *
335 (ebx
.split
.coherency_line_size
+ 1) *
336 (ebx
.split
.physical_line_partition
+ 1) *
337 (ebx
.split
.ways_of_associativity
+ 1);
341 static int __cpuinit
find_num_cache_leaves(void)
343 unsigned int eax
, ebx
, ecx
, edx
;
344 union _cpuid4_leaf_eax cache_eax
;
349 /* Do cpuid(4) loop to find out num_cache_leaves */
350 cpuid_count(4, i
, &eax
, &ebx
, &ecx
, &edx
);
351 cache_eax
.full
= eax
;
352 } while (cache_eax
.split
.type
!= CACHE_TYPE_NULL
);
356 unsigned int __cpuinit
init_intel_cacheinfo(struct cpuinfo_x86
*c
)
359 unsigned int trace
= 0, l1i
= 0, l1d
= 0, l2
= 0, l3
= 0;
360 unsigned int new_l1d
= 0, new_l1i
= 0; /* Cache sizes from cpuid(4) */
361 unsigned int new_l2
= 0, new_l3
= 0, i
; /* Cache sizes from cpuid(4) */
362 unsigned int l2_id
= 0, l3_id
= 0, num_threads_sharing
, index_msb
;
364 unsigned int cpu
= c
->cpu_index
;
367 if (c
->cpuid_level
> 3) {
368 static int is_initialized
;
370 if (is_initialized
== 0) {
371 /* Init num_cache_leaves from boot CPU */
372 num_cache_leaves
= find_num_cache_leaves();
377 * Whenever possible use cpuid(4), deterministic cache
378 * parameters cpuid leaf to find the cache details
380 for (i
= 0; i
< num_cache_leaves
; i
++) {
381 struct _cpuid4_info_regs this_leaf
;
384 retval
= cpuid4_cache_lookup_regs(i
, &this_leaf
);
386 switch (this_leaf
.eax
.split
.level
) {
388 if (this_leaf
.eax
.split
.type
==
390 new_l1d
= this_leaf
.size
/1024;
391 else if (this_leaf
.eax
.split
.type
==
393 new_l1i
= this_leaf
.size
/1024;
396 new_l2
= this_leaf
.size
/1024;
397 num_threads_sharing
= 1 + this_leaf
.eax
.split
.num_threads_sharing
;
398 index_msb
= get_count_order(num_threads_sharing
);
399 l2_id
= c
->apicid
>> index_msb
;
402 new_l3
= this_leaf
.size
/1024;
403 num_threads_sharing
= 1 + this_leaf
.eax
.split
.num_threads_sharing
;
404 index_msb
= get_count_order(
405 num_threads_sharing
);
406 l3_id
= c
->apicid
>> index_msb
;
415 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
418 if ((num_cache_leaves
== 0 || c
->x86
== 15) && c
->cpuid_level
> 1) {
419 /* supports eax=2 call */
421 unsigned int regs
[4];
422 unsigned char *dp
= (unsigned char *)regs
;
425 if (num_cache_leaves
!= 0 && c
->x86
== 15)
428 /* Number of times to iterate */
429 n
= cpuid_eax(2) & 0xFF;
431 for (i
= 0 ; i
< n
; i
++) {
432 cpuid(2, ®s
[0], ®s
[1], ®s
[2], ®s
[3]);
434 /* If bit 31 is set, this is an unknown format */
435 for (j
= 0 ; j
< 3 ; j
++)
436 if (regs
[j
] & (1 << 31))
439 /* Byte 0 is level count, not a descriptor */
440 for (j
= 1 ; j
< 16 ; j
++) {
441 unsigned char des
= dp
[j
];
444 /* look up this descriptor in the table */
445 while (cache_table
[k
].descriptor
!= 0) {
446 if (cache_table
[k
].descriptor
== des
) {
447 if (only_trace
&& cache_table
[k
].cache_type
!= LVL_TRACE
)
449 switch (cache_table
[k
].cache_type
) {
451 l1i
+= cache_table
[k
].size
;
454 l1d
+= cache_table
[k
].size
;
457 l2
+= cache_table
[k
].size
;
460 l3
+= cache_table
[k
].size
;
463 trace
+= cache_table
[k
].size
;
485 per_cpu(cpu_llc_id
, cpu
) = l2_id
;
492 per_cpu(cpu_llc_id
, cpu
) = l3_id
;
496 c
->x86_cache_size
= l3
? l3
: (l2
? l2
: (l1i
+l1d
));
503 /* pointer to _cpuid4_info array (for each cache leaf) */
504 static DEFINE_PER_CPU(struct _cpuid4_info
*, ici_cpuid4_info
);
505 #define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y]))
508 static void __cpuinit
cache_shared_cpu_map_setup(unsigned int cpu
, int index
)
510 struct _cpuid4_info
*this_leaf
, *sibling_leaf
;
511 unsigned long num_threads_sharing
;
512 int index_msb
, i
, sibling
;
513 struct cpuinfo_x86
*c
= &cpu_data(cpu
);
515 if ((index
== 3) && (c
->x86_vendor
== X86_VENDOR_AMD
)) {
516 for_each_cpu(i
, c
->llc_shared_map
) {
517 if (!per_cpu(ici_cpuid4_info
, i
))
519 this_leaf
= CPUID4_INFO_IDX(i
, index
);
520 for_each_cpu(sibling
, c
->llc_shared_map
) {
521 if (!cpu_online(sibling
))
523 set_bit(sibling
, this_leaf
->shared_cpu_map
);
528 this_leaf
= CPUID4_INFO_IDX(cpu
, index
);
529 num_threads_sharing
= 1 + this_leaf
->eax
.split
.num_threads_sharing
;
531 if (num_threads_sharing
== 1)
532 cpumask_set_cpu(cpu
, to_cpumask(this_leaf
->shared_cpu_map
));
534 index_msb
= get_count_order(num_threads_sharing
);
536 for_each_online_cpu(i
) {
537 if (cpu_data(i
).apicid
>> index_msb
==
538 c
->apicid
>> index_msb
) {
540 to_cpumask(this_leaf
->shared_cpu_map
));
541 if (i
!= cpu
&& per_cpu(ici_cpuid4_info
, i
)) {
543 CPUID4_INFO_IDX(i
, index
);
544 cpumask_set_cpu(cpu
, to_cpumask(
545 sibling_leaf
->shared_cpu_map
));
551 static void __cpuinit
cache_remove_shared_cpu_map(unsigned int cpu
, int index
)
553 struct _cpuid4_info
*this_leaf
, *sibling_leaf
;
556 this_leaf
= CPUID4_INFO_IDX(cpu
, index
);
557 for_each_cpu(sibling
, to_cpumask(this_leaf
->shared_cpu_map
)) {
558 sibling_leaf
= CPUID4_INFO_IDX(sibling
, index
);
559 cpumask_clear_cpu(cpu
,
560 to_cpumask(sibling_leaf
->shared_cpu_map
));
564 static void __cpuinit
cache_shared_cpu_map_setup(unsigned int cpu
, int index
)
568 static void __cpuinit
cache_remove_shared_cpu_map(unsigned int cpu
, int index
)
573 static void __cpuinit
free_cache_attributes(unsigned int cpu
)
577 for (i
= 0; i
< num_cache_leaves
; i
++)
578 cache_remove_shared_cpu_map(cpu
, i
);
580 kfree(per_cpu(ici_cpuid4_info
, cpu
));
581 per_cpu(ici_cpuid4_info
, cpu
) = NULL
;
585 __cpuinit
cpuid4_cache_lookup(int index
, struct _cpuid4_info
*this_leaf
)
587 struct _cpuid4_info_regs
*leaf_regs
=
588 (struct _cpuid4_info_regs
*)this_leaf
;
590 return cpuid4_cache_lookup_regs(index
, leaf_regs
);
593 static void __cpuinit
get_cpu_leaves(void *_retval
)
595 int j
, *retval
= _retval
, cpu
= smp_processor_id();
597 /* Do cpuid and store the results */
598 for (j
= 0; j
< num_cache_leaves
; j
++) {
599 struct _cpuid4_info
*this_leaf
;
600 this_leaf
= CPUID4_INFO_IDX(cpu
, j
);
601 *retval
= cpuid4_cache_lookup(j
, this_leaf
);
602 if (unlikely(*retval
< 0)) {
605 for (i
= 0; i
< j
; i
++)
606 cache_remove_shared_cpu_map(cpu
, i
);
609 cache_shared_cpu_map_setup(cpu
, j
);
613 static int __cpuinit
detect_cache_attributes(unsigned int cpu
)
617 if (num_cache_leaves
== 0)
620 per_cpu(ici_cpuid4_info
, cpu
) = kzalloc(
621 sizeof(struct _cpuid4_info
) * num_cache_leaves
, GFP_KERNEL
);
622 if (per_cpu(ici_cpuid4_info
, cpu
) == NULL
)
625 smp_call_function_single(cpu
, get_cpu_leaves
, &retval
, true);
627 kfree(per_cpu(ici_cpuid4_info
, cpu
));
628 per_cpu(ici_cpuid4_info
, cpu
) = NULL
;
634 #include <linux/kobject.h>
635 #include <linux/sysfs.h>
637 extern struct sysdev_class cpu_sysdev_class
; /* from drivers/base/cpu.c */
639 /* pointer to kobject for cpuX/cache */
640 static DEFINE_PER_CPU(struct kobject
*, ici_cache_kobject
);
642 struct _index_kobject
{
645 unsigned short index
;
648 /* pointer to array of kobjects for cpuX/cache/indexY */
649 static DEFINE_PER_CPU(struct _index_kobject
*, ici_index_kobject
);
650 #define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(ici_index_kobject, x))[y]))
652 #define show_one_plus(file_name, object, val) \
653 static ssize_t show_##file_name \
654 (struct _cpuid4_info *this_leaf, char *buf) \
656 return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \
659 show_one_plus(level
, eax
.split
.level
, 0);
660 show_one_plus(coherency_line_size
, ebx
.split
.coherency_line_size
, 1);
661 show_one_plus(physical_line_partition
, ebx
.split
.physical_line_partition
, 1);
662 show_one_plus(ways_of_associativity
, ebx
.split
.ways_of_associativity
, 1);
663 show_one_plus(number_of_sets
, ecx
.split
.number_of_sets
, 1);
665 static ssize_t
show_size(struct _cpuid4_info
*this_leaf
, char *buf
)
667 return sprintf(buf
, "%luK\n", this_leaf
->size
/ 1024);
670 static ssize_t
show_shared_cpu_map_func(struct _cpuid4_info
*this_leaf
,
673 ptrdiff_t len
= PTR_ALIGN(buf
+ PAGE_SIZE
- 1, PAGE_SIZE
) - buf
;
677 const struct cpumask
*mask
;
679 mask
= to_cpumask(this_leaf
->shared_cpu_map
);
681 cpulist_scnprintf(buf
, len
-2, mask
) :
682 cpumask_scnprintf(buf
, len
-2, mask
);
689 static inline ssize_t
show_shared_cpu_map(struct _cpuid4_info
*leaf
, char *buf
)
691 return show_shared_cpu_map_func(leaf
, 0, buf
);
694 static inline ssize_t
show_shared_cpu_list(struct _cpuid4_info
*leaf
, char *buf
)
696 return show_shared_cpu_map_func(leaf
, 1, buf
);
699 static ssize_t
show_type(struct _cpuid4_info
*this_leaf
, char *buf
)
701 switch (this_leaf
->eax
.split
.type
) {
702 case CACHE_TYPE_DATA
:
703 return sprintf(buf
, "Data\n");
704 case CACHE_TYPE_INST
:
705 return sprintf(buf
, "Instruction\n");
706 case CACHE_TYPE_UNIFIED
:
707 return sprintf(buf
, "Unified\n");
709 return sprintf(buf
, "Unknown\n");
713 #define to_object(k) container_of(k, struct _index_kobject, kobj)
714 #define to_attr(a) container_of(a, struct _cache_attr, attr)
716 static ssize_t
show_cache_disable(struct _cpuid4_info
*this_leaf
, char *buf
,
719 int cpu
= cpumask_first(to_cpumask(this_leaf
->shared_cpu_map
));
720 int node
= cpu_to_node(cpu
);
721 struct pci_dev
*dev
= node_to_k8_nb_misc(node
);
722 unsigned int reg
= 0;
724 if (!this_leaf
->can_disable
)
730 pci_read_config_dword(dev
, 0x1BC + index
* 4, ®
);
731 return sprintf(buf
, "%x\n", reg
);
734 #define SHOW_CACHE_DISABLE(index) \
736 show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \
738 return show_cache_disable(this_leaf, buf, index); \
740 SHOW_CACHE_DISABLE(0)
741 SHOW_CACHE_DISABLE(1)
743 static ssize_t
store_cache_disable(struct _cpuid4_info
*this_leaf
,
744 const char *buf
, size_t count
, unsigned int index
)
746 int cpu
= cpumask_first(to_cpumask(this_leaf
->shared_cpu_map
));
747 int node
= cpu_to_node(cpu
);
748 struct pci_dev
*dev
= node_to_k8_nb_misc(node
);
749 unsigned long val
= 0;
750 unsigned int scrubber
= 0;
752 if (!this_leaf
->can_disable
)
755 if (!capable(CAP_SYS_ADMIN
))
761 if (strict_strtoul(buf
, 10, &val
) < 0)
766 pci_read_config_dword(dev
, 0x58, &scrubber
);
767 scrubber
&= ~0x1f000000;
768 pci_write_config_dword(dev
, 0x58, scrubber
);
770 pci_write_config_dword(dev
, 0x1BC + index
* 4, val
& ~0x40000000);
772 pci_write_config_dword(dev
, 0x1BC + index
* 4, val
);
776 #define STORE_CACHE_DISABLE(index) \
778 store_cache_disable_##index(struct _cpuid4_info *this_leaf, \
779 const char *buf, size_t count) \
781 return store_cache_disable(this_leaf, buf, count, index); \
783 STORE_CACHE_DISABLE(0)
784 STORE_CACHE_DISABLE(1)
787 struct attribute attr
;
788 ssize_t (*show
)(struct _cpuid4_info
*, char *);
789 ssize_t (*store
)(struct _cpuid4_info
*, const char *, size_t count
);
792 #define define_one_ro(_name) \
793 static struct _cache_attr _name = \
794 __ATTR(_name, 0444, show_##_name, NULL)
796 define_one_ro(level
);
798 define_one_ro(coherency_line_size
);
799 define_one_ro(physical_line_partition
);
800 define_one_ro(ways_of_associativity
);
801 define_one_ro(number_of_sets
);
803 define_one_ro(shared_cpu_map
);
804 define_one_ro(shared_cpu_list
);
806 static struct _cache_attr cache_disable_0
= __ATTR(cache_disable_0
, 0644,
807 show_cache_disable_0
, store_cache_disable_0
);
808 static struct _cache_attr cache_disable_1
= __ATTR(cache_disable_1
, 0644,
809 show_cache_disable_1
, store_cache_disable_1
);
811 static struct attribute
*default_attrs
[] = {
814 &coherency_line_size
.attr
,
815 &physical_line_partition
.attr
,
816 &ways_of_associativity
.attr
,
817 &number_of_sets
.attr
,
819 &shared_cpu_map
.attr
,
820 &shared_cpu_list
.attr
,
821 &cache_disable_0
.attr
,
822 &cache_disable_1
.attr
,
826 static ssize_t
show(struct kobject
*kobj
, struct attribute
*attr
, char *buf
)
828 struct _cache_attr
*fattr
= to_attr(attr
);
829 struct _index_kobject
*this_leaf
= to_object(kobj
);
833 fattr
->show(CPUID4_INFO_IDX(this_leaf
->cpu
, this_leaf
->index
),
839 static ssize_t
store(struct kobject
*kobj
, struct attribute
*attr
,
840 const char *buf
, size_t count
)
842 struct _cache_attr
*fattr
= to_attr(attr
);
843 struct _index_kobject
*this_leaf
= to_object(kobj
);
847 fattr
->store(CPUID4_INFO_IDX(this_leaf
->cpu
, this_leaf
->index
),
853 static struct sysfs_ops sysfs_ops
= {
858 static struct kobj_type ktype_cache
= {
859 .sysfs_ops
= &sysfs_ops
,
860 .default_attrs
= default_attrs
,
863 static struct kobj_type ktype_percpu_entry
= {
864 .sysfs_ops
= &sysfs_ops
,
867 static void __cpuinit
cpuid4_cache_sysfs_exit(unsigned int cpu
)
869 kfree(per_cpu(ici_cache_kobject
, cpu
));
870 kfree(per_cpu(ici_index_kobject
, cpu
));
871 per_cpu(ici_cache_kobject
, cpu
) = NULL
;
872 per_cpu(ici_index_kobject
, cpu
) = NULL
;
873 free_cache_attributes(cpu
);
876 static int __cpuinit
cpuid4_cache_sysfs_init(unsigned int cpu
)
880 if (num_cache_leaves
== 0)
883 err
= detect_cache_attributes(cpu
);
887 /* Allocate all required memory */
888 per_cpu(ici_cache_kobject
, cpu
) =
889 kzalloc(sizeof(struct kobject
), GFP_KERNEL
);
890 if (unlikely(per_cpu(ici_cache_kobject
, cpu
) == NULL
))
893 per_cpu(ici_index_kobject
, cpu
) = kzalloc(
894 sizeof(struct _index_kobject
) * num_cache_leaves
, GFP_KERNEL
);
895 if (unlikely(per_cpu(ici_index_kobject
, cpu
) == NULL
))
901 cpuid4_cache_sysfs_exit(cpu
);
905 static DECLARE_BITMAP(cache_dev_map
, NR_CPUS
);
907 /* Add/Remove cache interface for CPU device */
908 static int __cpuinit
cache_add_dev(struct sys_device
* sys_dev
)
910 unsigned int cpu
= sys_dev
->id
;
912 struct _index_kobject
*this_object
;
915 retval
= cpuid4_cache_sysfs_init(cpu
);
916 if (unlikely(retval
< 0))
919 retval
= kobject_init_and_add(per_cpu(ici_cache_kobject
, cpu
),
921 &sys_dev
->kobj
, "%s", "cache");
923 cpuid4_cache_sysfs_exit(cpu
);
927 for (i
= 0; i
< num_cache_leaves
; i
++) {
928 this_object
= INDEX_KOBJECT_PTR(cpu
, i
);
929 this_object
->cpu
= cpu
;
930 this_object
->index
= i
;
931 retval
= kobject_init_and_add(&(this_object
->kobj
),
933 per_cpu(ici_cache_kobject
, cpu
),
935 if (unlikely(retval
)) {
936 for (j
= 0; j
< i
; j
++)
937 kobject_put(&(INDEX_KOBJECT_PTR(cpu
, j
)->kobj
));
938 kobject_put(per_cpu(ici_cache_kobject
, cpu
));
939 cpuid4_cache_sysfs_exit(cpu
);
942 kobject_uevent(&(this_object
->kobj
), KOBJ_ADD
);
944 cpumask_set_cpu(cpu
, to_cpumask(cache_dev_map
));
946 kobject_uevent(per_cpu(ici_cache_kobject
, cpu
), KOBJ_ADD
);
950 static void __cpuinit
cache_remove_dev(struct sys_device
* sys_dev
)
952 unsigned int cpu
= sys_dev
->id
;
955 if (per_cpu(ici_cpuid4_info
, cpu
) == NULL
)
957 if (!cpumask_test_cpu(cpu
, to_cpumask(cache_dev_map
)))
959 cpumask_clear_cpu(cpu
, to_cpumask(cache_dev_map
));
961 for (i
= 0; i
< num_cache_leaves
; i
++)
962 kobject_put(&(INDEX_KOBJECT_PTR(cpu
, i
)->kobj
));
963 kobject_put(per_cpu(ici_cache_kobject
, cpu
));
964 cpuid4_cache_sysfs_exit(cpu
);
967 static int __cpuinit
cacheinfo_cpu_callback(struct notifier_block
*nfb
,
968 unsigned long action
, void *hcpu
)
970 unsigned int cpu
= (unsigned long)hcpu
;
971 struct sys_device
*sys_dev
;
973 sys_dev
= get_cpu_sysdev(cpu
);
976 case CPU_ONLINE_FROZEN
:
977 cache_add_dev(sys_dev
);
980 case CPU_DEAD_FROZEN
:
981 cache_remove_dev(sys_dev
);
987 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier
= {
988 .notifier_call
= cacheinfo_cpu_callback
,
991 static int __cpuinit
cache_sysfs_init(void)
995 if (num_cache_leaves
== 0)
998 for_each_online_cpu(i
) {
1000 struct sys_device
*sys_dev
= get_cpu_sysdev(i
);
1002 err
= cache_add_dev(sys_dev
);
1006 register_hotcpu_notifier(&cacheinfo_cpu_notifier
);
1010 device_initcall(cache_sysfs_init
);