x86, cpu: mv display_cacheinfo -> cpu_detect_cache_sizes
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / x86 / kernel / cpu / intel_cacheinfo.c
blob0df4c2b7107f936d2ebe11190b3a6aac04feaccc
1 /*
2 * Routines to indentify caches on Intel CPU.
4 * Changes:
5 * Venkatesh Pallipadi : Adding cache identification through cpuid(4)
6 * Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
7 * Andi Kleen / Andreas Herrmann : CPUID4 emulation on AMD.
8 */
10 #include <linux/init.h>
11 #include <linux/slab.h>
12 #include <linux/device.h>
13 #include <linux/compiler.h>
14 #include <linux/cpu.h>
15 #include <linux/sched.h>
16 #include <linux/pci.h>
18 #include <asm/processor.h>
19 #include <linux/smp.h>
20 #include <asm/k8.h>
22 #define LVL_1_INST 1
23 #define LVL_1_DATA 2
24 #define LVL_2 3
25 #define LVL_3 4
26 #define LVL_TRACE 5
28 struct _cache_table {
29 unsigned char descriptor;
30 char cache_type;
31 short size;
34 /* All the cache descriptor types we care about (no TLB or
35 trace cache entries) */
37 static const struct _cache_table __cpuinitconst cache_table[] =
39 { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
40 { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */
41 { 0x09, LVL_1_INST, 32 }, /* 4-way set assoc, 64 byte line size */
42 { 0x0a, LVL_1_DATA, 8 }, /* 2 way set assoc, 32 byte line size */
43 { 0x0c, LVL_1_DATA, 16 }, /* 4-way set assoc, 32 byte line size */
44 { 0x0d, LVL_1_DATA, 16 }, /* 4-way set assoc, 64 byte line size */
45 { 0x21, LVL_2, 256 }, /* 8-way set assoc, 64 byte line size */
46 { 0x22, LVL_3, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
47 { 0x23, LVL_3, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */
48 { 0x25, LVL_3, 2048 }, /* 8-way set assoc, sectored cache, 64 byte line size */
49 { 0x29, LVL_3, 4096 }, /* 8-way set assoc, sectored cache, 64 byte line size */
50 { 0x2c, LVL_1_DATA, 32 }, /* 8-way set assoc, 64 byte line size */
51 { 0x30, LVL_1_INST, 32 }, /* 8-way set assoc, 64 byte line size */
52 { 0x39, LVL_2, 128 }, /* 4-way set assoc, sectored cache, 64 byte line size */
53 { 0x3a, LVL_2, 192 }, /* 6-way set assoc, sectored cache, 64 byte line size */
54 { 0x3b, LVL_2, 128 }, /* 2-way set assoc, sectored cache, 64 byte line size */
55 { 0x3c, LVL_2, 256 }, /* 4-way set assoc, sectored cache, 64 byte line size */
56 { 0x3d, LVL_2, 384 }, /* 6-way set assoc, sectored cache, 64 byte line size */
57 { 0x3e, LVL_2, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
58 { 0x3f, LVL_2, 256 }, /* 2-way set assoc, 64 byte line size */
59 { 0x41, LVL_2, 128 }, /* 4-way set assoc, 32 byte line size */
60 { 0x42, LVL_2, 256 }, /* 4-way set assoc, 32 byte line size */
61 { 0x43, LVL_2, 512 }, /* 4-way set assoc, 32 byte line size */
62 { 0x44, LVL_2, 1024 }, /* 4-way set assoc, 32 byte line size */
63 { 0x45, LVL_2, 2048 }, /* 4-way set assoc, 32 byte line size */
64 { 0x46, LVL_3, 4096 }, /* 4-way set assoc, 64 byte line size */
65 { 0x47, LVL_3, 8192 }, /* 8-way set assoc, 64 byte line size */
66 { 0x49, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */
67 { 0x4a, LVL_3, 6144 }, /* 12-way set assoc, 64 byte line size */
68 { 0x4b, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */
69 { 0x4c, LVL_3, 12288 }, /* 12-way set assoc, 64 byte line size */
70 { 0x4d, LVL_3, 16384 }, /* 16-way set assoc, 64 byte line size */
71 { 0x4e, LVL_2, 6144 }, /* 24-way set assoc, 64 byte line size */
72 { 0x60, LVL_1_DATA, 16 }, /* 8-way set assoc, sectored cache, 64 byte line size */
73 { 0x66, LVL_1_DATA, 8 }, /* 4-way set assoc, sectored cache, 64 byte line size */
74 { 0x67, LVL_1_DATA, 16 }, /* 4-way set assoc, sectored cache, 64 byte line size */
75 { 0x68, LVL_1_DATA, 32 }, /* 4-way set assoc, sectored cache, 64 byte line size */
76 { 0x70, LVL_TRACE, 12 }, /* 8-way set assoc */
77 { 0x71, LVL_TRACE, 16 }, /* 8-way set assoc */
78 { 0x72, LVL_TRACE, 32 }, /* 8-way set assoc */
79 { 0x73, LVL_TRACE, 64 }, /* 8-way set assoc */
80 { 0x78, LVL_2, 1024 }, /* 4-way set assoc, 64 byte line size */
81 { 0x79, LVL_2, 128 }, /* 8-way set assoc, sectored cache, 64 byte line size */
82 { 0x7a, LVL_2, 256 }, /* 8-way set assoc, sectored cache, 64 byte line size */
83 { 0x7b, LVL_2, 512 }, /* 8-way set assoc, sectored cache, 64 byte line size */
84 { 0x7c, LVL_2, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */
85 { 0x7d, LVL_2, 2048 }, /* 8-way set assoc, 64 byte line size */
86 { 0x7f, LVL_2, 512 }, /* 2-way set assoc, 64 byte line size */
87 { 0x82, LVL_2, 256 }, /* 8-way set assoc, 32 byte line size */
88 { 0x83, LVL_2, 512 }, /* 8-way set assoc, 32 byte line size */
89 { 0x84, LVL_2, 1024 }, /* 8-way set assoc, 32 byte line size */
90 { 0x85, LVL_2, 2048 }, /* 8-way set assoc, 32 byte line size */
91 { 0x86, LVL_2, 512 }, /* 4-way set assoc, 64 byte line size */
92 { 0x87, LVL_2, 1024 }, /* 8-way set assoc, 64 byte line size */
93 { 0xd0, LVL_3, 512 }, /* 4-way set assoc, 64 byte line size */
94 { 0xd1, LVL_3, 1024 }, /* 4-way set assoc, 64 byte line size */
95 { 0xd2, LVL_3, 2048 }, /* 4-way set assoc, 64 byte line size */
96 { 0xd6, LVL_3, 1024 }, /* 8-way set assoc, 64 byte line size */
97 { 0xd7, LVL_3, 2038 }, /* 8-way set assoc, 64 byte line size */
98 { 0xd8, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */
99 { 0xdc, LVL_3, 2048 }, /* 12-way set assoc, 64 byte line size */
100 { 0xdd, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */
101 { 0xde, LVL_3, 8192 }, /* 12-way set assoc, 64 byte line size */
102 { 0xe2, LVL_3, 2048 }, /* 16-way set assoc, 64 byte line size */
103 { 0xe3, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */
104 { 0xe4, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */
105 { 0x00, 0, 0}
109 enum _cache_type {
110 CACHE_TYPE_NULL = 0,
111 CACHE_TYPE_DATA = 1,
112 CACHE_TYPE_INST = 2,
113 CACHE_TYPE_UNIFIED = 3
116 union _cpuid4_leaf_eax {
117 struct {
118 enum _cache_type type:5;
119 unsigned int level:3;
120 unsigned int is_self_initializing:1;
121 unsigned int is_fully_associative:1;
122 unsigned int reserved:4;
123 unsigned int num_threads_sharing:12;
124 unsigned int num_cores_on_die:6;
125 } split;
126 u32 full;
129 union _cpuid4_leaf_ebx {
130 struct {
131 unsigned int coherency_line_size:12;
132 unsigned int physical_line_partition:10;
133 unsigned int ways_of_associativity:10;
134 } split;
135 u32 full;
138 union _cpuid4_leaf_ecx {
139 struct {
140 unsigned int number_of_sets:32;
141 } split;
142 u32 full;
145 struct _cpuid4_info {
146 union _cpuid4_leaf_eax eax;
147 union _cpuid4_leaf_ebx ebx;
148 union _cpuid4_leaf_ecx ecx;
149 unsigned long size;
150 unsigned long can_disable;
151 DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
154 /* subset of above _cpuid4_info w/o shared_cpu_map */
155 struct _cpuid4_info_regs {
156 union _cpuid4_leaf_eax eax;
157 union _cpuid4_leaf_ebx ebx;
158 union _cpuid4_leaf_ecx ecx;
159 unsigned long size;
160 unsigned long can_disable;
163 unsigned short num_cache_leaves;
165 /* AMD doesn't have CPUID4. Emulate it here to report the same
166 information to the user. This makes some assumptions about the machine:
167 L2 not shared, no SMT etc. that is currently true on AMD CPUs.
169 In theory the TLBs could be reported as fake type (they are in "dummy").
170 Maybe later */
171 union l1_cache {
172 struct {
173 unsigned line_size:8;
174 unsigned lines_per_tag:8;
175 unsigned assoc:8;
176 unsigned size_in_kb:8;
178 unsigned val;
181 union l2_cache {
182 struct {
183 unsigned line_size:8;
184 unsigned lines_per_tag:4;
185 unsigned assoc:4;
186 unsigned size_in_kb:16;
188 unsigned val;
191 union l3_cache {
192 struct {
193 unsigned line_size:8;
194 unsigned lines_per_tag:4;
195 unsigned assoc:4;
196 unsigned res:2;
197 unsigned size_encoded:14;
199 unsigned val;
202 static const unsigned short __cpuinitconst assocs[] = {
203 [1] = 1,
204 [2] = 2,
205 [4] = 4,
206 [6] = 8,
207 [8] = 16,
208 [0xa] = 32,
209 [0xb] = 48,
210 [0xc] = 64,
211 [0xd] = 96,
212 [0xe] = 128,
213 [0xf] = 0xffff /* fully associative - no way to show this currently */
216 static const unsigned char __cpuinitconst levels[] = { 1, 1, 2, 3 };
217 static const unsigned char __cpuinitconst types[] = { 1, 2, 3, 3 };
219 static void __cpuinit
220 amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
221 union _cpuid4_leaf_ebx *ebx,
222 union _cpuid4_leaf_ecx *ecx)
224 unsigned dummy;
225 unsigned line_size, lines_per_tag, assoc, size_in_kb;
226 union l1_cache l1i, l1d;
227 union l2_cache l2;
228 union l3_cache l3;
229 union l1_cache *l1 = &l1d;
231 eax->full = 0;
232 ebx->full = 0;
233 ecx->full = 0;
235 cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
236 cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
238 switch (leaf) {
239 case 1:
240 l1 = &l1i;
241 case 0:
242 if (!l1->val)
243 return;
244 assoc = assocs[l1->assoc];
245 line_size = l1->line_size;
246 lines_per_tag = l1->lines_per_tag;
247 size_in_kb = l1->size_in_kb;
248 break;
249 case 2:
250 if (!l2.val)
251 return;
252 assoc = assocs[l2.assoc];
253 line_size = l2.line_size;
254 lines_per_tag = l2.lines_per_tag;
255 /* cpu_data has errata corrections for K7 applied */
256 size_in_kb = current_cpu_data.x86_cache_size;
257 break;
258 case 3:
259 if (!l3.val)
260 return;
261 assoc = assocs[l3.assoc];
262 line_size = l3.line_size;
263 lines_per_tag = l3.lines_per_tag;
264 size_in_kb = l3.size_encoded * 512;
265 if (boot_cpu_has(X86_FEATURE_AMD_DCM)) {
266 size_in_kb = size_in_kb >> 1;
267 assoc = assoc >> 1;
269 break;
270 default:
271 return;
274 eax->split.is_self_initializing = 1;
275 eax->split.type = types[leaf];
276 eax->split.level = levels[leaf];
277 eax->split.num_threads_sharing = 0;
278 eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
281 if (assoc == 0xffff)
282 eax->split.is_fully_associative = 1;
283 ebx->split.coherency_line_size = line_size - 1;
284 ebx->split.ways_of_associativity = assoc - 1;
285 ebx->split.physical_line_partition = lines_per_tag - 1;
286 ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
287 (ebx->split.ways_of_associativity + 1) - 1;
290 static void __cpuinit
291 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
293 if (index < 3)
294 return;
296 if (boot_cpu_data.x86 == 0x11)
297 return;
299 /* see erratum #382 */
300 if ((boot_cpu_data.x86 == 0x10) && (boot_cpu_data.x86_model < 0x8))
301 return;
303 this_leaf->can_disable = 1;
306 static int
307 __cpuinit cpuid4_cache_lookup_regs(int index,
308 struct _cpuid4_info_regs *this_leaf)
310 union _cpuid4_leaf_eax eax;
311 union _cpuid4_leaf_ebx ebx;
312 union _cpuid4_leaf_ecx ecx;
313 unsigned edx;
315 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
316 amd_cpuid4(index, &eax, &ebx, &ecx);
317 if (boot_cpu_data.x86 >= 0x10)
318 amd_check_l3_disable(index, this_leaf);
319 } else {
320 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
323 if (eax.split.type == CACHE_TYPE_NULL)
324 return -EIO; /* better error ? */
326 this_leaf->eax = eax;
327 this_leaf->ebx = ebx;
328 this_leaf->ecx = ecx;
329 this_leaf->size = (ecx.split.number_of_sets + 1) *
330 (ebx.split.coherency_line_size + 1) *
331 (ebx.split.physical_line_partition + 1) *
332 (ebx.split.ways_of_associativity + 1);
333 return 0;
336 static int __cpuinit find_num_cache_leaves(void)
338 unsigned int eax, ebx, ecx, edx;
339 union _cpuid4_leaf_eax cache_eax;
340 int i = -1;
342 do {
343 ++i;
344 /* Do cpuid(4) loop to find out num_cache_leaves */
345 cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
346 cache_eax.full = eax;
347 } while (cache_eax.split.type != CACHE_TYPE_NULL);
348 return i;
351 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
353 /* Cache sizes */
354 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0;
355 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
356 unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
357 unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
358 #ifdef CONFIG_X86_HT
359 unsigned int cpu = c->cpu_index;
360 #endif
362 if (c->cpuid_level > 3) {
363 static int is_initialized;
365 if (is_initialized == 0) {
366 /* Init num_cache_leaves from boot CPU */
367 num_cache_leaves = find_num_cache_leaves();
368 is_initialized++;
372 * Whenever possible use cpuid(4), deterministic cache
373 * parameters cpuid leaf to find the cache details
375 for (i = 0; i < num_cache_leaves; i++) {
376 struct _cpuid4_info_regs this_leaf;
377 int retval;
379 retval = cpuid4_cache_lookup_regs(i, &this_leaf);
380 if (retval >= 0) {
381 switch (this_leaf.eax.split.level) {
382 case 1:
383 if (this_leaf.eax.split.type ==
384 CACHE_TYPE_DATA)
385 new_l1d = this_leaf.size/1024;
386 else if (this_leaf.eax.split.type ==
387 CACHE_TYPE_INST)
388 new_l1i = this_leaf.size/1024;
389 break;
390 case 2:
391 new_l2 = this_leaf.size/1024;
392 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
393 index_msb = get_count_order(num_threads_sharing);
394 l2_id = c->apicid >> index_msb;
395 break;
396 case 3:
397 new_l3 = this_leaf.size/1024;
398 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
399 index_msb = get_count_order(
400 num_threads_sharing);
401 l3_id = c->apicid >> index_msb;
402 break;
403 default:
404 break;
410 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
411 * trace cache
413 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
414 /* supports eax=2 call */
415 int j, n;
416 unsigned int regs[4];
417 unsigned char *dp = (unsigned char *)regs;
418 int only_trace = 0;
420 if (num_cache_leaves != 0 && c->x86 == 15)
421 only_trace = 1;
423 /* Number of times to iterate */
424 n = cpuid_eax(2) & 0xFF;
426 for (i = 0 ; i < n ; i++) {
427 cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
429 /* If bit 31 is set, this is an unknown format */
430 for (j = 0 ; j < 3 ; j++)
431 if (regs[j] & (1 << 31))
432 regs[j] = 0;
434 /* Byte 0 is level count, not a descriptor */
435 for (j = 1 ; j < 16 ; j++) {
436 unsigned char des = dp[j];
437 unsigned char k = 0;
439 /* look up this descriptor in the table */
440 while (cache_table[k].descriptor != 0) {
441 if (cache_table[k].descriptor == des) {
442 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
443 break;
444 switch (cache_table[k].cache_type) {
445 case LVL_1_INST:
446 l1i += cache_table[k].size;
447 break;
448 case LVL_1_DATA:
449 l1d += cache_table[k].size;
450 break;
451 case LVL_2:
452 l2 += cache_table[k].size;
453 break;
454 case LVL_3:
455 l3 += cache_table[k].size;
456 break;
457 case LVL_TRACE:
458 trace += cache_table[k].size;
459 break;
462 break;
465 k++;
471 if (new_l1d)
472 l1d = new_l1d;
474 if (new_l1i)
475 l1i = new_l1i;
477 if (new_l2) {
478 l2 = new_l2;
479 #ifdef CONFIG_X86_HT
480 per_cpu(cpu_llc_id, cpu) = l2_id;
481 #endif
484 if (new_l3) {
485 l3 = new_l3;
486 #ifdef CONFIG_X86_HT
487 per_cpu(cpu_llc_id, cpu) = l3_id;
488 #endif
491 c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
493 return l2;
496 #ifdef CONFIG_SYSFS
498 /* pointer to _cpuid4_info array (for each cache leaf) */
499 static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info);
500 #define CPUID4_INFO_IDX(x, y) (&((per_cpu(cpuid4_info, x))[y]))
502 #ifdef CONFIG_SMP
503 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
505 struct _cpuid4_info *this_leaf, *sibling_leaf;
506 unsigned long num_threads_sharing;
507 int index_msb, i;
508 struct cpuinfo_x86 *c = &cpu_data(cpu);
510 if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
511 struct cpuinfo_x86 *d;
512 for_each_online_cpu(i) {
513 if (!per_cpu(cpuid4_info, i))
514 continue;
515 d = &cpu_data(i);
516 this_leaf = CPUID4_INFO_IDX(i, index);
517 cpumask_copy(to_cpumask(this_leaf->shared_cpu_map),
518 d->llc_shared_map);
520 return;
522 this_leaf = CPUID4_INFO_IDX(cpu, index);
523 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
525 if (num_threads_sharing == 1)
526 cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map));
527 else {
528 index_msb = get_count_order(num_threads_sharing);
530 for_each_online_cpu(i) {
531 if (cpu_data(i).apicid >> index_msb ==
532 c->apicid >> index_msb) {
533 cpumask_set_cpu(i,
534 to_cpumask(this_leaf->shared_cpu_map));
535 if (i != cpu && per_cpu(cpuid4_info, i)) {
536 sibling_leaf =
537 CPUID4_INFO_IDX(i, index);
538 cpumask_set_cpu(cpu, to_cpumask(
539 sibling_leaf->shared_cpu_map));
545 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
547 struct _cpuid4_info *this_leaf, *sibling_leaf;
548 int sibling;
550 this_leaf = CPUID4_INFO_IDX(cpu, index);
551 for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) {
552 sibling_leaf = CPUID4_INFO_IDX(sibling, index);
553 cpumask_clear_cpu(cpu,
554 to_cpumask(sibling_leaf->shared_cpu_map));
557 #else
558 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
562 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
565 #endif
567 static void __cpuinit free_cache_attributes(unsigned int cpu)
569 int i;
571 for (i = 0; i < num_cache_leaves; i++)
572 cache_remove_shared_cpu_map(cpu, i);
574 kfree(per_cpu(cpuid4_info, cpu));
575 per_cpu(cpuid4_info, cpu) = NULL;
578 static int
579 __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
581 struct _cpuid4_info_regs *leaf_regs =
582 (struct _cpuid4_info_regs *)this_leaf;
584 return cpuid4_cache_lookup_regs(index, leaf_regs);
587 static void __cpuinit get_cpu_leaves(void *_retval)
589 int j, *retval = _retval, cpu = smp_processor_id();
591 /* Do cpuid and store the results */
592 for (j = 0; j < num_cache_leaves; j++) {
593 struct _cpuid4_info *this_leaf;
594 this_leaf = CPUID4_INFO_IDX(cpu, j);
595 *retval = cpuid4_cache_lookup(j, this_leaf);
596 if (unlikely(*retval < 0)) {
597 int i;
599 for (i = 0; i < j; i++)
600 cache_remove_shared_cpu_map(cpu, i);
601 break;
603 cache_shared_cpu_map_setup(cpu, j);
607 static int __cpuinit detect_cache_attributes(unsigned int cpu)
609 int retval;
611 if (num_cache_leaves == 0)
612 return -ENOENT;
614 per_cpu(cpuid4_info, cpu) = kzalloc(
615 sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
616 if (per_cpu(cpuid4_info, cpu) == NULL)
617 return -ENOMEM;
619 smp_call_function_single(cpu, get_cpu_leaves, &retval, true);
620 if (retval) {
621 kfree(per_cpu(cpuid4_info, cpu));
622 per_cpu(cpuid4_info, cpu) = NULL;
625 return retval;
628 #include <linux/kobject.h>
629 #include <linux/sysfs.h>
631 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
633 /* pointer to kobject for cpuX/cache */
634 static DEFINE_PER_CPU(struct kobject *, cache_kobject);
636 struct _index_kobject {
637 struct kobject kobj;
638 unsigned int cpu;
639 unsigned short index;
642 /* pointer to array of kobjects for cpuX/cache/indexY */
643 static DEFINE_PER_CPU(struct _index_kobject *, index_kobject);
644 #define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(index_kobject, x))[y]))
646 #define show_one_plus(file_name, object, val) \
647 static ssize_t show_##file_name \
648 (struct _cpuid4_info *this_leaf, char *buf) \
650 return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \
653 show_one_plus(level, eax.split.level, 0);
654 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
655 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
656 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
657 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
659 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
661 return sprintf(buf, "%luK\n", this_leaf->size / 1024);
664 static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
665 int type, char *buf)
667 ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
668 int n = 0;
670 if (len > 1) {
671 const struct cpumask *mask;
673 mask = to_cpumask(this_leaf->shared_cpu_map);
674 n = type ?
675 cpulist_scnprintf(buf, len-2, mask) :
676 cpumask_scnprintf(buf, len-2, mask);
677 buf[n++] = '\n';
678 buf[n] = '\0';
680 return n;
683 static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf)
685 return show_shared_cpu_map_func(leaf, 0, buf);
688 static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf)
690 return show_shared_cpu_map_func(leaf, 1, buf);
693 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf)
695 switch (this_leaf->eax.split.type) {
696 case CACHE_TYPE_DATA:
697 return sprintf(buf, "Data\n");
698 case CACHE_TYPE_INST:
699 return sprintf(buf, "Instruction\n");
700 case CACHE_TYPE_UNIFIED:
701 return sprintf(buf, "Unified\n");
702 default:
703 return sprintf(buf, "Unknown\n");
707 #define to_object(k) container_of(k, struct _index_kobject, kobj)
708 #define to_attr(a) container_of(a, struct _cache_attr, attr)
710 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
711 unsigned int index)
713 int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
714 int node = cpu_to_node(cpu);
715 struct pci_dev *dev = node_to_k8_nb_misc(node);
716 unsigned int reg = 0;
718 if (!this_leaf->can_disable)
719 return -EINVAL;
721 if (!dev)
722 return -EINVAL;
724 pci_read_config_dword(dev, 0x1BC + index * 4, &reg);
725 return sprintf(buf, "%x\n", reg);
728 #define SHOW_CACHE_DISABLE(index) \
729 static ssize_t \
730 show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \
732 return show_cache_disable(this_leaf, buf, index); \
734 SHOW_CACHE_DISABLE(0)
735 SHOW_CACHE_DISABLE(1)
737 static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
738 const char *buf, size_t count, unsigned int index)
740 int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
741 int node = cpu_to_node(cpu);
742 struct pci_dev *dev = node_to_k8_nb_misc(node);
743 unsigned long val = 0;
744 unsigned int scrubber = 0;
746 if (!this_leaf->can_disable)
747 return -EINVAL;
749 if (!capable(CAP_SYS_ADMIN))
750 return -EPERM;
752 if (!dev)
753 return -EINVAL;
755 if (strict_strtoul(buf, 10, &val) < 0)
756 return -EINVAL;
758 val |= 0xc0000000;
760 pci_read_config_dword(dev, 0x58, &scrubber);
761 scrubber &= ~0x1f000000;
762 pci_write_config_dword(dev, 0x58, scrubber);
764 pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000);
765 wbinvd();
766 pci_write_config_dword(dev, 0x1BC + index * 4, val);
767 return count;
770 #define STORE_CACHE_DISABLE(index) \
771 static ssize_t \
772 store_cache_disable_##index(struct _cpuid4_info *this_leaf, \
773 const char *buf, size_t count) \
775 return store_cache_disable(this_leaf, buf, count, index); \
777 STORE_CACHE_DISABLE(0)
778 STORE_CACHE_DISABLE(1)
780 struct _cache_attr {
781 struct attribute attr;
782 ssize_t (*show)(struct _cpuid4_info *, char *);
783 ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
786 #define define_one_ro(_name) \
787 static struct _cache_attr _name = \
788 __ATTR(_name, 0444, show_##_name, NULL)
790 define_one_ro(level);
791 define_one_ro(type);
792 define_one_ro(coherency_line_size);
793 define_one_ro(physical_line_partition);
794 define_one_ro(ways_of_associativity);
795 define_one_ro(number_of_sets);
796 define_one_ro(size);
797 define_one_ro(shared_cpu_map);
798 define_one_ro(shared_cpu_list);
800 static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644,
801 show_cache_disable_0, store_cache_disable_0);
802 static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
803 show_cache_disable_1, store_cache_disable_1);
805 static struct attribute *default_attrs[] = {
806 &type.attr,
807 &level.attr,
808 &coherency_line_size.attr,
809 &physical_line_partition.attr,
810 &ways_of_associativity.attr,
811 &number_of_sets.attr,
812 &size.attr,
813 &shared_cpu_map.attr,
814 &shared_cpu_list.attr,
815 &cache_disable_0.attr,
816 &cache_disable_1.attr,
817 NULL
820 static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
822 struct _cache_attr *fattr = to_attr(attr);
823 struct _index_kobject *this_leaf = to_object(kobj);
824 ssize_t ret;
826 ret = fattr->show ?
827 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
828 buf) :
830 return ret;
833 static ssize_t store(struct kobject *kobj, struct attribute *attr,
834 const char *buf, size_t count)
836 struct _cache_attr *fattr = to_attr(attr);
837 struct _index_kobject *this_leaf = to_object(kobj);
838 ssize_t ret;
840 ret = fattr->store ?
841 fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
842 buf, count) :
844 return ret;
847 static struct sysfs_ops sysfs_ops = {
848 .show = show,
849 .store = store,
852 static struct kobj_type ktype_cache = {
853 .sysfs_ops = &sysfs_ops,
854 .default_attrs = default_attrs,
857 static struct kobj_type ktype_percpu_entry = {
858 .sysfs_ops = &sysfs_ops,
861 static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
863 kfree(per_cpu(cache_kobject, cpu));
864 kfree(per_cpu(index_kobject, cpu));
865 per_cpu(cache_kobject, cpu) = NULL;
866 per_cpu(index_kobject, cpu) = NULL;
867 free_cache_attributes(cpu);
870 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
872 int err;
874 if (num_cache_leaves == 0)
875 return -ENOENT;
877 err = detect_cache_attributes(cpu);
878 if (err)
879 return err;
881 /* Allocate all required memory */
882 per_cpu(cache_kobject, cpu) =
883 kzalloc(sizeof(struct kobject), GFP_KERNEL);
884 if (unlikely(per_cpu(cache_kobject, cpu) == NULL))
885 goto err_out;
887 per_cpu(index_kobject, cpu) = kzalloc(
888 sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL);
889 if (unlikely(per_cpu(index_kobject, cpu) == NULL))
890 goto err_out;
892 return 0;
894 err_out:
895 cpuid4_cache_sysfs_exit(cpu);
896 return -ENOMEM;
899 static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
901 /* Add/Remove cache interface for CPU device */
902 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
904 unsigned int cpu = sys_dev->id;
905 unsigned long i, j;
906 struct _index_kobject *this_object;
907 int retval;
909 retval = cpuid4_cache_sysfs_init(cpu);
910 if (unlikely(retval < 0))
911 return retval;
913 retval = kobject_init_and_add(per_cpu(cache_kobject, cpu),
914 &ktype_percpu_entry,
915 &sys_dev->kobj, "%s", "cache");
916 if (retval < 0) {
917 cpuid4_cache_sysfs_exit(cpu);
918 return retval;
921 for (i = 0; i < num_cache_leaves; i++) {
922 this_object = INDEX_KOBJECT_PTR(cpu, i);
923 this_object->cpu = cpu;
924 this_object->index = i;
925 retval = kobject_init_and_add(&(this_object->kobj),
926 &ktype_cache,
927 per_cpu(cache_kobject, cpu),
928 "index%1lu", i);
929 if (unlikely(retval)) {
930 for (j = 0; j < i; j++)
931 kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj));
932 kobject_put(per_cpu(cache_kobject, cpu));
933 cpuid4_cache_sysfs_exit(cpu);
934 return retval;
936 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
938 cpumask_set_cpu(cpu, to_cpumask(cache_dev_map));
940 kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
941 return 0;
944 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
946 unsigned int cpu = sys_dev->id;
947 unsigned long i;
949 if (per_cpu(cpuid4_info, cpu) == NULL)
950 return;
951 if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map)))
952 return;
953 cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
955 for (i = 0; i < num_cache_leaves; i++)
956 kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj));
957 kobject_put(per_cpu(cache_kobject, cpu));
958 cpuid4_cache_sysfs_exit(cpu);
961 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
962 unsigned long action, void *hcpu)
964 unsigned int cpu = (unsigned long)hcpu;
965 struct sys_device *sys_dev;
967 sys_dev = get_cpu_sysdev(cpu);
968 switch (action) {
969 case CPU_ONLINE:
970 case CPU_ONLINE_FROZEN:
971 cache_add_dev(sys_dev);
972 break;
973 case CPU_DEAD:
974 case CPU_DEAD_FROZEN:
975 cache_remove_dev(sys_dev);
976 break;
978 return NOTIFY_OK;
981 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = {
982 .notifier_call = cacheinfo_cpu_callback,
985 static int __cpuinit cache_sysfs_init(void)
987 int i;
989 if (num_cache_leaves == 0)
990 return 0;
992 for_each_online_cpu(i) {
993 int err;
994 struct sys_device *sys_dev = get_cpu_sysdev(i);
996 err = cache_add_dev(sys_dev);
997 if (err)
998 return err;
1000 register_hotcpu_notifier(&cacheinfo_cpu_notifier);
1001 return 0;
1004 device_initcall(cache_sysfs_init);
1006 #endif