x86, cacheinfo: Calculate L3 indices
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / x86 / kernel / cpu / intel_cacheinfo.c
blob1294c9e40f2d2d1ee32a49b58c1057c22191976b
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>
21 #include <asm/smp.h>
23 #define LVL_1_INST 1
24 #define LVL_1_DATA 2
25 #define LVL_2 3
26 #define LVL_3 4
27 #define LVL_TRACE 5
29 struct _cache_table {
30 unsigned char descriptor;
31 char cache_type;
32 short size;
35 /* All the cache descriptor types we care about (no TLB or
36 trace cache entries) */
38 static const struct _cache_table __cpuinitconst cache_table[] =
40 { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
41 { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */
42 { 0x09, LVL_1_INST, 32 }, /* 4-way set assoc, 64 byte line size */
43 { 0x0a, LVL_1_DATA, 8 }, /* 2 way set assoc, 32 byte line size */
44 { 0x0c, LVL_1_DATA, 16 }, /* 4-way set assoc, 32 byte line size */
45 { 0x0d, LVL_1_DATA, 16 }, /* 4-way set assoc, 64 byte line size */
46 { 0x21, LVL_2, 256 }, /* 8-way set assoc, 64 byte line size */
47 { 0x22, LVL_3, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
48 { 0x23, LVL_3, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */
49 { 0x25, LVL_3, 2048 }, /* 8-way set assoc, sectored cache, 64 byte line size */
50 { 0x29, LVL_3, 4096 }, /* 8-way set assoc, sectored cache, 64 byte line size */
51 { 0x2c, LVL_1_DATA, 32 }, /* 8-way set assoc, 64 byte line size */
52 { 0x30, LVL_1_INST, 32 }, /* 8-way set assoc, 64 byte line size */
53 { 0x39, LVL_2, 128 }, /* 4-way set assoc, sectored cache, 64 byte line size */
54 { 0x3a, LVL_2, 192 }, /* 6-way set assoc, sectored cache, 64 byte line size */
55 { 0x3b, LVL_2, 128 }, /* 2-way set assoc, sectored cache, 64 byte line size */
56 { 0x3c, LVL_2, 256 }, /* 4-way set assoc, sectored cache, 64 byte line size */
57 { 0x3d, LVL_2, 384 }, /* 6-way set assoc, sectored cache, 64 byte line size */
58 { 0x3e, LVL_2, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
59 { 0x3f, LVL_2, 256 }, /* 2-way set assoc, 64 byte line size */
60 { 0x41, LVL_2, 128 }, /* 4-way set assoc, 32 byte line size */
61 { 0x42, LVL_2, 256 }, /* 4-way set assoc, 32 byte line size */
62 { 0x43, LVL_2, 512 }, /* 4-way set assoc, 32 byte line size */
63 { 0x44, LVL_2, 1024 }, /* 4-way set assoc, 32 byte line size */
64 { 0x45, LVL_2, 2048 }, /* 4-way set assoc, 32 byte line size */
65 { 0x46, LVL_3, 4096 }, /* 4-way set assoc, 64 byte line size */
66 { 0x47, LVL_3, 8192 }, /* 8-way set assoc, 64 byte line size */
67 { 0x49, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */
68 { 0x4a, LVL_3, 6144 }, /* 12-way set assoc, 64 byte line size */
69 { 0x4b, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */
70 { 0x4c, LVL_3, 12288 }, /* 12-way set assoc, 64 byte line size */
71 { 0x4d, LVL_3, 16384 }, /* 16-way set assoc, 64 byte line size */
72 { 0x4e, LVL_2, 6144 }, /* 24-way set assoc, 64 byte line size */
73 { 0x60, LVL_1_DATA, 16 }, /* 8-way set assoc, sectored cache, 64 byte line size */
74 { 0x66, LVL_1_DATA, 8 }, /* 4-way set assoc, sectored cache, 64 byte line size */
75 { 0x67, LVL_1_DATA, 16 }, /* 4-way set assoc, sectored cache, 64 byte line size */
76 { 0x68, LVL_1_DATA, 32 }, /* 4-way set assoc, sectored cache, 64 byte line size */
77 { 0x70, LVL_TRACE, 12 }, /* 8-way set assoc */
78 { 0x71, LVL_TRACE, 16 }, /* 8-way set assoc */
79 { 0x72, LVL_TRACE, 32 }, /* 8-way set assoc */
80 { 0x73, LVL_TRACE, 64 }, /* 8-way set assoc */
81 { 0x78, LVL_2, 1024 }, /* 4-way set assoc, 64 byte line size */
82 { 0x79, LVL_2, 128 }, /* 8-way set assoc, sectored cache, 64 byte line size */
83 { 0x7a, LVL_2, 256 }, /* 8-way set assoc, sectored cache, 64 byte line size */
84 { 0x7b, LVL_2, 512 }, /* 8-way set assoc, sectored cache, 64 byte line size */
85 { 0x7c, LVL_2, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */
86 { 0x7d, LVL_2, 2048 }, /* 8-way set assoc, 64 byte line size */
87 { 0x7f, LVL_2, 512 }, /* 2-way set assoc, 64 byte line size */
88 { 0x82, LVL_2, 256 }, /* 8-way set assoc, 32 byte line size */
89 { 0x83, LVL_2, 512 }, /* 8-way set assoc, 32 byte line size */
90 { 0x84, LVL_2, 1024 }, /* 8-way set assoc, 32 byte line size */
91 { 0x85, LVL_2, 2048 }, /* 8-way set assoc, 32 byte line size */
92 { 0x86, LVL_2, 512 }, /* 4-way set assoc, 64 byte line size */
93 { 0x87, LVL_2, 1024 }, /* 8-way set assoc, 64 byte line size */
94 { 0xd0, LVL_3, 512 }, /* 4-way set assoc, 64 byte line size */
95 { 0xd1, LVL_3, 1024 }, /* 4-way set assoc, 64 byte line size */
96 { 0xd2, LVL_3, 2048 }, /* 4-way set assoc, 64 byte line size */
97 { 0xd6, LVL_3, 1024 }, /* 8-way set assoc, 64 byte line size */
98 { 0xd7, LVL_3, 2048 }, /* 8-way set assoc, 64 byte line size */
99 { 0xd8, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */
100 { 0xdc, LVL_3, 2048 }, /* 12-way set assoc, 64 byte line size */
101 { 0xdd, LVL_3, 4096 }, /* 12-way set assoc, 64 byte line size */
102 { 0xde, LVL_3, 8192 }, /* 12-way set assoc, 64 byte line size */
103 { 0xe2, LVL_3, 2048 }, /* 16-way set assoc, 64 byte line size */
104 { 0xe3, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */
105 { 0xe4, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */
106 { 0xea, LVL_3, 12288 }, /* 24-way set assoc, 64 byte line size */
107 { 0xeb, LVL_3, 18432 }, /* 24-way set assoc, 64 byte line size */
108 { 0xec, LVL_3, 24576 }, /* 24-way set assoc, 64 byte line size */
109 { 0x00, 0, 0}
113 enum _cache_type {
114 CACHE_TYPE_NULL = 0,
115 CACHE_TYPE_DATA = 1,
116 CACHE_TYPE_INST = 2,
117 CACHE_TYPE_UNIFIED = 3
120 union _cpuid4_leaf_eax {
121 struct {
122 enum _cache_type type:5;
123 unsigned int level:3;
124 unsigned int is_self_initializing:1;
125 unsigned int is_fully_associative:1;
126 unsigned int reserved:4;
127 unsigned int num_threads_sharing:12;
128 unsigned int num_cores_on_die:6;
129 } split;
130 u32 full;
133 union _cpuid4_leaf_ebx {
134 struct {
135 unsigned int coherency_line_size:12;
136 unsigned int physical_line_partition:10;
137 unsigned int ways_of_associativity:10;
138 } split;
139 u32 full;
142 union _cpuid4_leaf_ecx {
143 struct {
144 unsigned int number_of_sets:32;
145 } split;
146 u32 full;
149 struct _cpuid4_info {
150 union _cpuid4_leaf_eax eax;
151 union _cpuid4_leaf_ebx ebx;
152 union _cpuid4_leaf_ecx ecx;
153 unsigned long size;
154 bool can_disable;
155 unsigned int l3_indices;
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;
164 unsigned long size;
165 bool can_disable;
166 unsigned int l3_indices;
169 unsigned short num_cache_leaves;
171 /* AMD doesn't have CPUID4. Emulate it here to report the same
172 information to the user. This makes some assumptions about the machine:
173 L2 not shared, no SMT etc. that is currently true on AMD CPUs.
175 In theory the TLBs could be reported as fake type (they are in "dummy").
176 Maybe later */
177 union l1_cache {
178 struct {
179 unsigned line_size:8;
180 unsigned lines_per_tag:8;
181 unsigned assoc:8;
182 unsigned size_in_kb:8;
184 unsigned val;
187 union l2_cache {
188 struct {
189 unsigned line_size:8;
190 unsigned lines_per_tag:4;
191 unsigned assoc:4;
192 unsigned size_in_kb:16;
194 unsigned val;
197 union l3_cache {
198 struct {
199 unsigned line_size:8;
200 unsigned lines_per_tag:4;
201 unsigned assoc:4;
202 unsigned res:2;
203 unsigned size_encoded:14;
205 unsigned val;
208 static const unsigned short __cpuinitconst assocs[] = {
209 [1] = 1,
210 [2] = 2,
211 [4] = 4,
212 [6] = 8,
213 [8] = 16,
214 [0xa] = 32,
215 [0xb] = 48,
216 [0xc] = 64,
217 [0xd] = 96,
218 [0xe] = 128,
219 [0xf] = 0xffff /* fully associative - no way to show this currently */
222 static const unsigned char __cpuinitconst levels[] = { 1, 1, 2, 3 };
223 static const unsigned char __cpuinitconst types[] = { 1, 2, 3, 3 };
225 static void __cpuinit
226 amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
227 union _cpuid4_leaf_ebx *ebx,
228 union _cpuid4_leaf_ecx *ecx)
230 unsigned dummy;
231 unsigned line_size, lines_per_tag, assoc, size_in_kb;
232 union l1_cache l1i, l1d;
233 union l2_cache l2;
234 union l3_cache l3;
235 union l1_cache *l1 = &l1d;
237 eax->full = 0;
238 ebx->full = 0;
239 ecx->full = 0;
241 cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
242 cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
244 switch (leaf) {
245 case 1:
246 l1 = &l1i;
247 case 0:
248 if (!l1->val)
249 return;
250 assoc = assocs[l1->assoc];
251 line_size = l1->line_size;
252 lines_per_tag = l1->lines_per_tag;
253 size_in_kb = l1->size_in_kb;
254 break;
255 case 2:
256 if (!l2.val)
257 return;
258 assoc = assocs[l2.assoc];
259 line_size = l2.line_size;
260 lines_per_tag = l2.lines_per_tag;
261 /* cpu_data has errata corrections for K7 applied */
262 size_in_kb = current_cpu_data.x86_cache_size;
263 break;
264 case 3:
265 if (!l3.val)
266 return;
267 assoc = assocs[l3.assoc];
268 line_size = l3.line_size;
269 lines_per_tag = l3.lines_per_tag;
270 size_in_kb = l3.size_encoded * 512;
271 if (boot_cpu_has(X86_FEATURE_AMD_DCM)) {
272 size_in_kb = size_in_kb >> 1;
273 assoc = assoc >> 1;
275 break;
276 default:
277 return;
280 eax->split.is_self_initializing = 1;
281 eax->split.type = types[leaf];
282 eax->split.level = levels[leaf];
283 eax->split.num_threads_sharing = 0;
284 eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
287 if (assoc == 0xffff)
288 eax->split.is_fully_associative = 1;
289 ebx->split.coherency_line_size = line_size - 1;
290 ebx->split.ways_of_associativity = assoc - 1;
291 ebx->split.physical_line_partition = lines_per_tag - 1;
292 ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
293 (ebx->split.ways_of_associativity + 1) - 1;
296 static unsigned int __cpuinit amd_calc_l3_indices(void)
299 * We're called over smp_call_function_single() and therefore
300 * are on the correct cpu.
302 int cpu = smp_processor_id();
303 int node = cpu_to_node(cpu);
304 struct pci_dev *dev = node_to_k8_nb_misc(node);
305 unsigned int sc0, sc1, sc2, sc3;
306 u32 val;
308 pci_read_config_dword(dev, 0x1C4, &val);
310 /* calculate subcache sizes */
311 sc0 = !(val & BIT(0));
312 sc1 = !(val & BIT(4));
313 sc2 = !(val & BIT(8)) + !(val & BIT(9));
314 sc3 = !(val & BIT(12)) + !(val & BIT(13));
316 return (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
319 static void __cpuinit
320 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
322 if (index < 3)
323 return;
325 if (boot_cpu_data.x86 == 0x11)
326 return;
328 /* see errata #382 and #388 */
329 if ((boot_cpu_data.x86 == 0x10) &&
330 ((boot_cpu_data.x86_model < 0x9) ||
331 (boot_cpu_data.x86_mask < 0x1)))
332 return;
334 this_leaf->can_disable = true;
335 this_leaf->l3_indices = amd_calc_l3_indices();
338 static int
339 __cpuinit cpuid4_cache_lookup_regs(int index,
340 struct _cpuid4_info_regs *this_leaf)
342 union _cpuid4_leaf_eax eax;
343 union _cpuid4_leaf_ebx ebx;
344 union _cpuid4_leaf_ecx ecx;
345 unsigned edx;
347 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
348 amd_cpuid4(index, &eax, &ebx, &ecx);
349 if (boot_cpu_data.x86 >= 0x10)
350 amd_check_l3_disable(index, this_leaf);
351 } else {
352 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
355 if (eax.split.type == CACHE_TYPE_NULL)
356 return -EIO; /* better error ? */
358 this_leaf->eax = eax;
359 this_leaf->ebx = ebx;
360 this_leaf->ecx = ecx;
361 this_leaf->size = (ecx.split.number_of_sets + 1) *
362 (ebx.split.coherency_line_size + 1) *
363 (ebx.split.physical_line_partition + 1) *
364 (ebx.split.ways_of_associativity + 1);
365 return 0;
368 static int __cpuinit find_num_cache_leaves(void)
370 unsigned int eax, ebx, ecx, edx;
371 union _cpuid4_leaf_eax cache_eax;
372 int i = -1;
374 do {
375 ++i;
376 /* Do cpuid(4) loop to find out num_cache_leaves */
377 cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
378 cache_eax.full = eax;
379 } while (cache_eax.split.type != CACHE_TYPE_NULL);
380 return i;
383 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
385 /* Cache sizes */
386 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0;
387 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
388 unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
389 unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
390 #ifdef CONFIG_X86_HT
391 unsigned int cpu = c->cpu_index;
392 #endif
394 if (c->cpuid_level > 3) {
395 static int is_initialized;
397 if (is_initialized == 0) {
398 /* Init num_cache_leaves from boot CPU */
399 num_cache_leaves = find_num_cache_leaves();
400 is_initialized++;
404 * Whenever possible use cpuid(4), deterministic cache
405 * parameters cpuid leaf to find the cache details
407 for (i = 0; i < num_cache_leaves; i++) {
408 struct _cpuid4_info_regs this_leaf;
409 int retval;
411 retval = cpuid4_cache_lookup_regs(i, &this_leaf);
412 if (retval >= 0) {
413 switch (this_leaf.eax.split.level) {
414 case 1:
415 if (this_leaf.eax.split.type ==
416 CACHE_TYPE_DATA)
417 new_l1d = this_leaf.size/1024;
418 else if (this_leaf.eax.split.type ==
419 CACHE_TYPE_INST)
420 new_l1i = this_leaf.size/1024;
421 break;
422 case 2:
423 new_l2 = this_leaf.size/1024;
424 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
425 index_msb = get_count_order(num_threads_sharing);
426 l2_id = c->apicid >> index_msb;
427 break;
428 case 3:
429 new_l3 = this_leaf.size/1024;
430 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
431 index_msb = get_count_order(
432 num_threads_sharing);
433 l3_id = c->apicid >> index_msb;
434 break;
435 default:
436 break;
442 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
443 * trace cache
445 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
446 /* supports eax=2 call */
447 int j, n;
448 unsigned int regs[4];
449 unsigned char *dp = (unsigned char *)regs;
450 int only_trace = 0;
452 if (num_cache_leaves != 0 && c->x86 == 15)
453 only_trace = 1;
455 /* Number of times to iterate */
456 n = cpuid_eax(2) & 0xFF;
458 for (i = 0 ; i < n ; i++) {
459 cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
461 /* If bit 31 is set, this is an unknown format */
462 for (j = 0 ; j < 3 ; j++)
463 if (regs[j] & (1 << 31))
464 regs[j] = 0;
466 /* Byte 0 is level count, not a descriptor */
467 for (j = 1 ; j < 16 ; j++) {
468 unsigned char des = dp[j];
469 unsigned char k = 0;
471 /* look up this descriptor in the table */
472 while (cache_table[k].descriptor != 0) {
473 if (cache_table[k].descriptor == des) {
474 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
475 break;
476 switch (cache_table[k].cache_type) {
477 case LVL_1_INST:
478 l1i += cache_table[k].size;
479 break;
480 case LVL_1_DATA:
481 l1d += cache_table[k].size;
482 break;
483 case LVL_2:
484 l2 += cache_table[k].size;
485 break;
486 case LVL_3:
487 l3 += cache_table[k].size;
488 break;
489 case LVL_TRACE:
490 trace += cache_table[k].size;
491 break;
494 break;
497 k++;
503 if (new_l1d)
504 l1d = new_l1d;
506 if (new_l1i)
507 l1i = new_l1i;
509 if (new_l2) {
510 l2 = new_l2;
511 #ifdef CONFIG_X86_HT
512 per_cpu(cpu_llc_id, cpu) = l2_id;
513 #endif
516 if (new_l3) {
517 l3 = new_l3;
518 #ifdef CONFIG_X86_HT
519 per_cpu(cpu_llc_id, cpu) = l3_id;
520 #endif
523 if (trace)
524 printk(KERN_INFO "CPU: Trace cache: %dK uops", trace);
525 else if (l1i)
526 printk(KERN_INFO "CPU: L1 I cache: %dK", l1i);
528 if (l1d)
529 printk(KERN_CONT ", L1 D cache: %dK\n", l1d);
530 else
531 printk(KERN_CONT "\n");
533 if (l2)
534 printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
536 if (l3)
537 printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
539 c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
541 return l2;
544 #ifdef CONFIG_SYSFS
546 /* pointer to _cpuid4_info array (for each cache leaf) */
547 static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info);
548 #define CPUID4_INFO_IDX(x, y) (&((per_cpu(cpuid4_info, x))[y]))
550 #ifdef CONFIG_SMP
551 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
553 struct _cpuid4_info *this_leaf, *sibling_leaf;
554 unsigned long num_threads_sharing;
555 int index_msb, i;
556 struct cpuinfo_x86 *c = &cpu_data(cpu);
558 if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
559 struct cpuinfo_x86 *d;
560 for_each_online_cpu(i) {
561 if (!per_cpu(cpuid4_info, i))
562 continue;
563 d = &cpu_data(i);
564 this_leaf = CPUID4_INFO_IDX(i, index);
565 cpumask_copy(to_cpumask(this_leaf->shared_cpu_map),
566 d->llc_shared_map);
568 return;
570 this_leaf = CPUID4_INFO_IDX(cpu, index);
571 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
573 if (num_threads_sharing == 1)
574 cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map));
575 else {
576 index_msb = get_count_order(num_threads_sharing);
578 for_each_online_cpu(i) {
579 if (cpu_data(i).apicid >> index_msb ==
580 c->apicid >> index_msb) {
581 cpumask_set_cpu(i,
582 to_cpumask(this_leaf->shared_cpu_map));
583 if (i != cpu && per_cpu(cpuid4_info, i)) {
584 sibling_leaf =
585 CPUID4_INFO_IDX(i, index);
586 cpumask_set_cpu(cpu, to_cpumask(
587 sibling_leaf->shared_cpu_map));
593 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
595 struct _cpuid4_info *this_leaf, *sibling_leaf;
596 int sibling;
598 this_leaf = CPUID4_INFO_IDX(cpu, index);
599 for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) {
600 sibling_leaf = CPUID4_INFO_IDX(sibling, index);
601 cpumask_clear_cpu(cpu,
602 to_cpumask(sibling_leaf->shared_cpu_map));
605 #else
606 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
610 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
613 #endif
615 static void __cpuinit free_cache_attributes(unsigned int cpu)
617 int i;
619 for (i = 0; i < num_cache_leaves; i++)
620 cache_remove_shared_cpu_map(cpu, i);
622 kfree(per_cpu(cpuid4_info, cpu));
623 per_cpu(cpuid4_info, cpu) = NULL;
626 static int
627 __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
629 struct _cpuid4_info_regs *leaf_regs =
630 (struct _cpuid4_info_regs *)this_leaf;
632 return cpuid4_cache_lookup_regs(index, leaf_regs);
635 static void __cpuinit get_cpu_leaves(void *_retval)
637 int j, *retval = _retval, cpu = smp_processor_id();
639 /* Do cpuid and store the results */
640 for (j = 0; j < num_cache_leaves; j++) {
641 struct _cpuid4_info *this_leaf;
642 this_leaf = CPUID4_INFO_IDX(cpu, j);
643 *retval = cpuid4_cache_lookup(j, this_leaf);
644 if (unlikely(*retval < 0)) {
645 int i;
647 for (i = 0; i < j; i++)
648 cache_remove_shared_cpu_map(cpu, i);
649 break;
651 cache_shared_cpu_map_setup(cpu, j);
655 static int __cpuinit detect_cache_attributes(unsigned int cpu)
657 int retval;
659 if (num_cache_leaves == 0)
660 return -ENOENT;
662 per_cpu(cpuid4_info, cpu) = kzalloc(
663 sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
664 if (per_cpu(cpuid4_info, cpu) == NULL)
665 return -ENOMEM;
667 smp_call_function_single(cpu, get_cpu_leaves, &retval, true);
668 if (retval) {
669 kfree(per_cpu(cpuid4_info, cpu));
670 per_cpu(cpuid4_info, cpu) = NULL;
673 return retval;
676 #include <linux/kobject.h>
677 #include <linux/sysfs.h>
679 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
681 /* pointer to kobject for cpuX/cache */
682 static DEFINE_PER_CPU(struct kobject *, cache_kobject);
684 struct _index_kobject {
685 struct kobject kobj;
686 unsigned int cpu;
687 unsigned short index;
690 /* pointer to array of kobjects for cpuX/cache/indexY */
691 static DEFINE_PER_CPU(struct _index_kobject *, index_kobject);
692 #define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(index_kobject, x))[y]))
694 #define show_one_plus(file_name, object, val) \
695 static ssize_t show_##file_name \
696 (struct _cpuid4_info *this_leaf, char *buf) \
698 return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \
701 show_one_plus(level, eax.split.level, 0);
702 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
703 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
704 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
705 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
707 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
709 return sprintf(buf, "%luK\n", this_leaf->size / 1024);
712 static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
713 int type, char *buf)
715 ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
716 int n = 0;
718 if (len > 1) {
719 const struct cpumask *mask;
721 mask = to_cpumask(this_leaf->shared_cpu_map);
722 n = type ?
723 cpulist_scnprintf(buf, len-2, mask) :
724 cpumask_scnprintf(buf, len-2, mask);
725 buf[n++] = '\n';
726 buf[n] = '\0';
728 return n;
731 static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf)
733 return show_shared_cpu_map_func(leaf, 0, buf);
736 static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf)
738 return show_shared_cpu_map_func(leaf, 1, buf);
741 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf)
743 switch (this_leaf->eax.split.type) {
744 case CACHE_TYPE_DATA:
745 return sprintf(buf, "Data\n");
746 case CACHE_TYPE_INST:
747 return sprintf(buf, "Instruction\n");
748 case CACHE_TYPE_UNIFIED:
749 return sprintf(buf, "Unified\n");
750 default:
751 return sprintf(buf, "Unknown\n");
755 #define to_object(k) container_of(k, struct _index_kobject, kobj)
756 #define to_attr(a) container_of(a, struct _cache_attr, attr)
758 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
759 unsigned int index)
761 int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
762 int node = cpu_to_node(cpu);
763 struct pci_dev *dev = node_to_k8_nb_misc(node);
764 unsigned int reg = 0;
766 if (!this_leaf->can_disable)
767 return -EINVAL;
769 if (!dev)
770 return -EINVAL;
772 pci_read_config_dword(dev, 0x1BC + index * 4, &reg);
773 return sprintf(buf, "0x%08x\n", reg);
776 #define SHOW_CACHE_DISABLE(index) \
777 static ssize_t \
778 show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \
780 return show_cache_disable(this_leaf, buf, index); \
782 SHOW_CACHE_DISABLE(0)
783 SHOW_CACHE_DISABLE(1)
785 static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
786 const char *buf, size_t count, unsigned int index)
788 int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
789 int node = cpu_to_node(cpu);
790 struct pci_dev *dev = node_to_k8_nb_misc(node);
791 unsigned long val = 0;
793 #define SUBCACHE_MASK (3UL << 20)
794 #define SUBCACHE_INDEX 0xfff
796 if (!this_leaf->can_disable)
797 return -EINVAL;
799 if (!capable(CAP_SYS_ADMIN))
800 return -EPERM;
802 if (!dev)
803 return -EINVAL;
805 if (strict_strtoul(buf, 10, &val) < 0)
806 return -EINVAL;
808 /* do not allow writes outside of allowed bits */
809 if ((val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) ||
810 ((val & SUBCACHE_INDEX) > this_leaf->l3_indices))
811 return -EINVAL;
813 val |= BIT(30);
814 pci_write_config_dword(dev, 0x1BC + index * 4, val);
816 * We need to WBINVD on a core on the node containing the L3 cache which
817 * indices we disable therefore a simple wbinvd() is not sufficient.
819 wbinvd_on_cpu(cpu);
820 pci_write_config_dword(dev, 0x1BC + index * 4, val | BIT(31));
821 return count;
824 #define STORE_CACHE_DISABLE(index) \
825 static ssize_t \
826 store_cache_disable_##index(struct _cpuid4_info *this_leaf, \
827 const char *buf, size_t count) \
829 return store_cache_disable(this_leaf, buf, count, index); \
831 STORE_CACHE_DISABLE(0)
832 STORE_CACHE_DISABLE(1)
834 struct _cache_attr {
835 struct attribute attr;
836 ssize_t (*show)(struct _cpuid4_info *, char *);
837 ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
840 #define define_one_ro(_name) \
841 static struct _cache_attr _name = \
842 __ATTR(_name, 0444, show_##_name, NULL)
844 define_one_ro(level);
845 define_one_ro(type);
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);
850 define_one_ro(size);
851 define_one_ro(shared_cpu_map);
852 define_one_ro(shared_cpu_list);
854 static struct _cache_attr cache_disable_0 = __ATTR(cache_disable_0, 0644,
855 show_cache_disable_0, store_cache_disable_0);
856 static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
857 show_cache_disable_1, store_cache_disable_1);
859 #define DEFAULT_SYSFS_CACHE_ATTRS \
860 &type.attr, \
861 &level.attr, \
862 &coherency_line_size.attr, \
863 &physical_line_partition.attr, \
864 &ways_of_associativity.attr, \
865 &number_of_sets.attr, \
866 &size.attr, \
867 &shared_cpu_map.attr, \
868 &shared_cpu_list.attr
870 static struct attribute *default_attrs[] = {
871 DEFAULT_SYSFS_CACHE_ATTRS,
872 NULL
875 static struct attribute *default_l3_attrs[] = {
876 DEFAULT_SYSFS_CACHE_ATTRS,
877 &cache_disable_0.attr,
878 &cache_disable_1.attr,
879 NULL
882 static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
884 struct _cache_attr *fattr = to_attr(attr);
885 struct _index_kobject *this_leaf = to_object(kobj);
886 ssize_t ret;
888 ret = fattr->show ?
889 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
890 buf) :
892 return ret;
895 static ssize_t store(struct kobject *kobj, struct attribute *attr,
896 const char *buf, size_t count)
898 struct _cache_attr *fattr = to_attr(attr);
899 struct _index_kobject *this_leaf = to_object(kobj);
900 ssize_t ret;
902 ret = fattr->store ?
903 fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
904 buf, count) :
906 return ret;
909 static struct sysfs_ops sysfs_ops = {
910 .show = show,
911 .store = store,
914 static struct kobj_type ktype_cache = {
915 .sysfs_ops = &sysfs_ops,
916 .default_attrs = default_attrs,
919 static struct kobj_type ktype_percpu_entry = {
920 .sysfs_ops = &sysfs_ops,
923 static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
925 kfree(per_cpu(cache_kobject, cpu));
926 kfree(per_cpu(index_kobject, cpu));
927 per_cpu(cache_kobject, cpu) = NULL;
928 per_cpu(index_kobject, cpu) = NULL;
929 free_cache_attributes(cpu);
932 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
934 int err;
936 if (num_cache_leaves == 0)
937 return -ENOENT;
939 err = detect_cache_attributes(cpu);
940 if (err)
941 return err;
943 /* Allocate all required memory */
944 per_cpu(cache_kobject, cpu) =
945 kzalloc(sizeof(struct kobject), GFP_KERNEL);
946 if (unlikely(per_cpu(cache_kobject, cpu) == NULL))
947 goto err_out;
949 per_cpu(index_kobject, cpu) = kzalloc(
950 sizeof(struct _index_kobject) * num_cache_leaves, GFP_KERNEL);
951 if (unlikely(per_cpu(index_kobject, cpu) == NULL))
952 goto err_out;
954 return 0;
956 err_out:
957 cpuid4_cache_sysfs_exit(cpu);
958 return -ENOMEM;
961 static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
963 /* Add/Remove cache interface for CPU device */
964 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
966 unsigned int cpu = sys_dev->id;
967 unsigned long i, j;
968 struct _index_kobject *this_object;
969 struct _cpuid4_info *this_leaf;
970 int retval;
972 retval = cpuid4_cache_sysfs_init(cpu);
973 if (unlikely(retval < 0))
974 return retval;
976 retval = kobject_init_and_add(per_cpu(cache_kobject, cpu),
977 &ktype_percpu_entry,
978 &sys_dev->kobj, "%s", "cache");
979 if (retval < 0) {
980 cpuid4_cache_sysfs_exit(cpu);
981 return retval;
984 for (i = 0; i < num_cache_leaves; i++) {
985 this_object = INDEX_KOBJECT_PTR(cpu, i);
986 this_object->cpu = cpu;
987 this_object->index = i;
989 this_leaf = CPUID4_INFO_IDX(cpu, i);
991 if (this_leaf->can_disable)
992 ktype_cache.default_attrs = default_l3_attrs;
993 else
994 ktype_cache.default_attrs = default_attrs;
996 retval = kobject_init_and_add(&(this_object->kobj),
997 &ktype_cache,
998 per_cpu(cache_kobject, cpu),
999 "index%1lu", i);
1000 if (unlikely(retval)) {
1001 for (j = 0; j < i; j++)
1002 kobject_put(&(INDEX_KOBJECT_PTR(cpu, j)->kobj));
1003 kobject_put(per_cpu(cache_kobject, cpu));
1004 cpuid4_cache_sysfs_exit(cpu);
1005 return retval;
1007 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
1009 cpumask_set_cpu(cpu, to_cpumask(cache_dev_map));
1011 kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
1012 return 0;
1015 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
1017 unsigned int cpu = sys_dev->id;
1018 unsigned long i;
1020 if (per_cpu(cpuid4_info, cpu) == NULL)
1021 return;
1022 if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map)))
1023 return;
1024 cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
1026 for (i = 0; i < num_cache_leaves; i++)
1027 kobject_put(&(INDEX_KOBJECT_PTR(cpu, i)->kobj));
1028 kobject_put(per_cpu(cache_kobject, cpu));
1029 cpuid4_cache_sysfs_exit(cpu);
1032 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
1033 unsigned long action, void *hcpu)
1035 unsigned int cpu = (unsigned long)hcpu;
1036 struct sys_device *sys_dev;
1038 sys_dev = get_cpu_sysdev(cpu);
1039 switch (action) {
1040 case CPU_ONLINE:
1041 case CPU_ONLINE_FROZEN:
1042 cache_add_dev(sys_dev);
1043 break;
1044 case CPU_DEAD:
1045 case CPU_DEAD_FROZEN:
1046 cache_remove_dev(sys_dev);
1047 break;
1049 return NOTIFY_OK;
1052 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = {
1053 .notifier_call = cacheinfo_cpu_callback,
1056 static int __cpuinit cache_sysfs_init(void)
1058 int i;
1060 if (num_cache_leaves == 0)
1061 return 0;
1063 for_each_online_cpu(i) {
1064 int err;
1065 struct sys_device *sys_dev = get_cpu_sysdev(i);
1067 err = cache_add_dev(sys_dev);
1068 if (err)
1069 return err;
1071 register_hotcpu_notifier(&cacheinfo_cpu_notifier);
1072 return 0;
1075 device_initcall(cache_sysfs_init);
1077 #endif