58527a9fc404b613ab9f8abeb5312be30d4dd01e
[deliverable/linux.git] / arch / x86 / kernel / cpu / intel_cacheinfo.c
1 /*
2 * Routines to indentify caches on Intel CPU.
3 *
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 */
9
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>
17
18 #include <asm/processor.h>
19 #include <asm/smp.h>
20
21 #define LVL_1_INST 1
22 #define LVL_1_DATA 2
23 #define LVL_2 3
24 #define LVL_3 4
25 #define LVL_TRACE 5
26
27 struct _cache_table
28 {
29 unsigned char descriptor;
30 char cache_type;
31 short size;
32 };
33
34 /* all the cache descriptor types we care about (no TLB or trace cache entries) */
35 static struct _cache_table cache_table[] __cpuinitdata =
36 {
37 { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
38 { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */
39 { 0x0a, LVL_1_DATA, 8 }, /* 2 way set assoc, 32 byte line size */
40 { 0x0c, LVL_1_DATA, 16 }, /* 4-way set assoc, 32 byte line size */
41 { 0x22, LVL_3, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
42 { 0x23, LVL_3, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */
43 { 0x25, LVL_3, 2048 }, /* 8-way set assoc, sectored cache, 64 byte line size */
44 { 0x29, LVL_3, 4096 }, /* 8-way set assoc, sectored cache, 64 byte line size */
45 { 0x2c, LVL_1_DATA, 32 }, /* 8-way set assoc, 64 byte line size */
46 { 0x30, LVL_1_INST, 32 }, /* 8-way set assoc, 64 byte line size */
47 { 0x39, LVL_2, 128 }, /* 4-way set assoc, sectored cache, 64 byte line size */
48 { 0x3a, LVL_2, 192 }, /* 6-way set assoc, sectored cache, 64 byte line size */
49 { 0x3b, LVL_2, 128 }, /* 2-way set assoc, sectored cache, 64 byte line size */
50 { 0x3c, LVL_2, 256 }, /* 4-way set assoc, sectored cache, 64 byte line size */
51 { 0x3d, LVL_2, 384 }, /* 6-way set assoc, sectored cache, 64 byte line size */
52 { 0x3e, LVL_2, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */
53 { 0x3f, LVL_2, 256 }, /* 2-way set assoc, 64 byte line size */
54 { 0x41, LVL_2, 128 }, /* 4-way set assoc, 32 byte line size */
55 { 0x42, LVL_2, 256 }, /* 4-way set assoc, 32 byte line size */
56 { 0x43, LVL_2, 512 }, /* 4-way set assoc, 32 byte line size */
57 { 0x44, LVL_2, 1024 }, /* 4-way set assoc, 32 byte line size */
58 { 0x45, LVL_2, 2048 }, /* 4-way set assoc, 32 byte line size */
59 { 0x46, LVL_3, 4096 }, /* 4-way set assoc, 64 byte line size */
60 { 0x47, LVL_3, 8192 }, /* 8-way set assoc, 64 byte line size */
61 { 0x49, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */
62 { 0x4a, LVL_3, 6144 }, /* 12-way set assoc, 64 byte line size */
63 { 0x4b, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */
64 { 0x4c, LVL_3, 12288 }, /* 12-way set assoc, 64 byte line size */
65 { 0x4d, LVL_3, 16384 }, /* 16-way set assoc, 64 byte line size */
66 { 0x4e, LVL_2, 6144 }, /* 24-way set assoc, 64 byte line size */
67 { 0x60, LVL_1_DATA, 16 }, /* 8-way set assoc, sectored cache, 64 byte line size */
68 { 0x66, LVL_1_DATA, 8 }, /* 4-way set assoc, sectored cache, 64 byte line size */
69 { 0x67, LVL_1_DATA, 16 }, /* 4-way set assoc, sectored cache, 64 byte line size */
70 { 0x68, LVL_1_DATA, 32 }, /* 4-way set assoc, sectored cache, 64 byte line size */
71 { 0x70, LVL_TRACE, 12 }, /* 8-way set assoc */
72 { 0x71, LVL_TRACE, 16 }, /* 8-way set assoc */
73 { 0x72, LVL_TRACE, 32 }, /* 8-way set assoc */
74 { 0x73, LVL_TRACE, 64 }, /* 8-way set assoc */
75 { 0x78, LVL_2, 1024 }, /* 4-way set assoc, 64 byte line size */
76 { 0x79, LVL_2, 128 }, /* 8-way set assoc, sectored cache, 64 byte line size */
77 { 0x7a, LVL_2, 256 }, /* 8-way set assoc, sectored cache, 64 byte line size */
78 { 0x7b, LVL_2, 512 }, /* 8-way set assoc, sectored cache, 64 byte line size */
79 { 0x7c, LVL_2, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */
80 { 0x7d, LVL_2, 2048 }, /* 8-way set assoc, 64 byte line size */
81 { 0x7f, LVL_2, 512 }, /* 2-way set assoc, 64 byte line size */
82 { 0x82, LVL_2, 256 }, /* 8-way set assoc, 32 byte line size */
83 { 0x83, LVL_2, 512 }, /* 8-way set assoc, 32 byte line size */
84 { 0x84, LVL_2, 1024 }, /* 8-way set assoc, 32 byte line size */
85 { 0x85, LVL_2, 2048 }, /* 8-way set assoc, 32 byte line size */
86 { 0x86, LVL_2, 512 }, /* 4-way set assoc, 64 byte line size */
87 { 0x87, LVL_2, 1024 }, /* 8-way set assoc, 64 byte line size */
88 { 0x00, 0, 0}
89 };
90
91
92 enum _cache_type
93 {
94 CACHE_TYPE_NULL = 0,
95 CACHE_TYPE_DATA = 1,
96 CACHE_TYPE_INST = 2,
97 CACHE_TYPE_UNIFIED = 3
98 };
99
100 union _cpuid4_leaf_eax {
101 struct {
102 enum _cache_type type:5;
103 unsigned int level:3;
104 unsigned int is_self_initializing:1;
105 unsigned int is_fully_associative:1;
106 unsigned int reserved:4;
107 unsigned int num_threads_sharing:12;
108 unsigned int num_cores_on_die:6;
109 } split;
110 u32 full;
111 };
112
113 union _cpuid4_leaf_ebx {
114 struct {
115 unsigned int coherency_line_size:12;
116 unsigned int physical_line_partition:10;
117 unsigned int ways_of_associativity:10;
118 } split;
119 u32 full;
120 };
121
122 union _cpuid4_leaf_ecx {
123 struct {
124 unsigned int number_of_sets:32;
125 } split;
126 u32 full;
127 };
128
129 struct _cpuid4_info {
130 union _cpuid4_leaf_eax eax;
131 union _cpuid4_leaf_ebx ebx;
132 union _cpuid4_leaf_ecx ecx;
133 unsigned long size;
134 unsigned long can_disable;
135 DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
136 };
137
138 /* subset of above _cpuid4_info w/o shared_cpu_map */
139 struct _cpuid4_info_regs {
140 union _cpuid4_leaf_eax eax;
141 union _cpuid4_leaf_ebx ebx;
142 union _cpuid4_leaf_ecx ecx;
143 unsigned long size;
144 unsigned long can_disable;
145 };
146
147 #ifdef CONFIG_PCI
148 static struct pci_device_id k8_nb_id[] = {
149 { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) },
150 { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1203) },
151 {}
152 };
153 #endif
154
155 unsigned short num_cache_leaves;
156
157 /* AMD doesn't have CPUID4. Emulate it here to report the same
158 information to the user. This makes some assumptions about the machine:
159 L2 not shared, no SMT etc. that is currently true on AMD CPUs.
160
161 In theory the TLBs could be reported as fake type (they are in "dummy").
162 Maybe later */
163 union l1_cache {
164 struct {
165 unsigned line_size : 8;
166 unsigned lines_per_tag : 8;
167 unsigned assoc : 8;
168 unsigned size_in_kb : 8;
169 };
170 unsigned val;
171 };
172
173 union l2_cache {
174 struct {
175 unsigned line_size : 8;
176 unsigned lines_per_tag : 4;
177 unsigned assoc : 4;
178 unsigned size_in_kb : 16;
179 };
180 unsigned val;
181 };
182
183 union l3_cache {
184 struct {
185 unsigned line_size : 8;
186 unsigned lines_per_tag : 4;
187 unsigned assoc : 4;
188 unsigned res : 2;
189 unsigned size_encoded : 14;
190 };
191 unsigned val;
192 };
193
194 static unsigned short assocs[] __cpuinitdata = {
195 [1] = 1, [2] = 2, [4] = 4, [6] = 8,
196 [8] = 16, [0xa] = 32, [0xb] = 48,
197 [0xc] = 64,
198 [0xf] = 0xffff // ??
199 };
200
201 static unsigned char levels[] __cpuinitdata = { 1, 1, 2, 3 };
202 static unsigned char types[] __cpuinitdata = { 1, 2, 3, 3 };
203
204 static void __cpuinit
205 amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
206 union _cpuid4_leaf_ebx *ebx,
207 union _cpuid4_leaf_ecx *ecx)
208 {
209 unsigned dummy;
210 unsigned line_size, lines_per_tag, assoc, size_in_kb;
211 union l1_cache l1i, l1d;
212 union l2_cache l2;
213 union l3_cache l3;
214 union l1_cache *l1 = &l1d;
215
216 eax->full = 0;
217 ebx->full = 0;
218 ecx->full = 0;
219
220 cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
221 cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
222
223 switch (leaf) {
224 case 1:
225 l1 = &l1i;
226 case 0:
227 if (!l1->val)
228 return;
229 assoc = l1->assoc;
230 line_size = l1->line_size;
231 lines_per_tag = l1->lines_per_tag;
232 size_in_kb = l1->size_in_kb;
233 break;
234 case 2:
235 if (!l2.val)
236 return;
237 assoc = l2.assoc;
238 line_size = l2.line_size;
239 lines_per_tag = l2.lines_per_tag;
240 /* cpu_data has errata corrections for K7 applied */
241 size_in_kb = current_cpu_data.x86_cache_size;
242 break;
243 case 3:
244 if (!l3.val)
245 return;
246 assoc = l3.assoc;
247 line_size = l3.line_size;
248 lines_per_tag = l3.lines_per_tag;
249 size_in_kb = l3.size_encoded * 512;
250 break;
251 default:
252 return;
253 }
254
255 eax->split.is_self_initializing = 1;
256 eax->split.type = types[leaf];
257 eax->split.level = levels[leaf];
258 if (leaf == 3)
259 eax->split.num_threads_sharing = current_cpu_data.x86_max_cores - 1;
260 else
261 eax->split.num_threads_sharing = 0;
262 eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
263
264
265 if (assoc == 0xf)
266 eax->split.is_fully_associative = 1;
267 ebx->split.coherency_line_size = line_size - 1;
268 ebx->split.ways_of_associativity = assocs[assoc] - 1;
269 ebx->split.physical_line_partition = lines_per_tag - 1;
270 ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
271 (ebx->split.ways_of_associativity + 1) - 1;
272 }
273
274 static void __cpuinit
275 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
276 {
277 if (index < 3)
278 return;
279 this_leaf->can_disable = 1;
280 }
281
282 static int
283 __cpuinit cpuid4_cache_lookup_regs(int index,
284 struct _cpuid4_info_regs *this_leaf)
285 {
286 union _cpuid4_leaf_eax eax;
287 union _cpuid4_leaf_ebx ebx;
288 union _cpuid4_leaf_ecx ecx;
289 unsigned edx;
290
291 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
292 amd_cpuid4(index, &eax, &ebx, &ecx);
293 if (boot_cpu_data.x86 >= 0x10)
294 amd_check_l3_disable(index, this_leaf);
295 } else {
296 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
297 }
298
299 if (eax.split.type == CACHE_TYPE_NULL)
300 return -EIO; /* better error ? */
301
302 this_leaf->eax = eax;
303 this_leaf->ebx = ebx;
304 this_leaf->ecx = ecx;
305 this_leaf->size = (ecx.split.number_of_sets + 1) *
306 (ebx.split.coherency_line_size + 1) *
307 (ebx.split.physical_line_partition + 1) *
308 (ebx.split.ways_of_associativity + 1);
309 return 0;
310 }
311
312 static int
313 __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
314 {
315 struct _cpuid4_info_regs *leaf_regs =
316 (struct _cpuid4_info_regs *)this_leaf;
317
318 return cpuid4_cache_lookup_regs(index, leaf_regs);
319 }
320
321 static int __cpuinit find_num_cache_leaves(void)
322 {
323 unsigned int eax, ebx, ecx, edx;
324 union _cpuid4_leaf_eax cache_eax;
325 int i = -1;
326
327 do {
328 ++i;
329 /* Do cpuid(4) loop to find out num_cache_leaves */
330 cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
331 cache_eax.full = eax;
332 } while (cache_eax.split.type != CACHE_TYPE_NULL);
333 return i;
334 }
335
336 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
337 {
338 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
339 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
340 unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
341 unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
342 #ifdef CONFIG_X86_HT
343 unsigned int cpu = c->cpu_index;
344 #endif
345
346 if (c->cpuid_level > 3) {
347 static int is_initialized;
348
349 if (is_initialized == 0) {
350 /* Init num_cache_leaves from boot CPU */
351 num_cache_leaves = find_num_cache_leaves();
352 is_initialized++;
353 }
354
355 /*
356 * Whenever possible use cpuid(4), deterministic cache
357 * parameters cpuid leaf to find the cache details
358 */
359 for (i = 0; i < num_cache_leaves; i++) {
360 struct _cpuid4_info_regs this_leaf;
361 int retval;
362
363 retval = cpuid4_cache_lookup_regs(i, &this_leaf);
364 if (retval >= 0) {
365 switch(this_leaf.eax.split.level) {
366 case 1:
367 if (this_leaf.eax.split.type ==
368 CACHE_TYPE_DATA)
369 new_l1d = this_leaf.size/1024;
370 else if (this_leaf.eax.split.type ==
371 CACHE_TYPE_INST)
372 new_l1i = this_leaf.size/1024;
373 break;
374 case 2:
375 new_l2 = this_leaf.size/1024;
376 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
377 index_msb = get_count_order(num_threads_sharing);
378 l2_id = c->apicid >> index_msb;
379 break;
380 case 3:
381 new_l3 = this_leaf.size/1024;
382 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
383 index_msb = get_count_order(num_threads_sharing);
384 l3_id = c->apicid >> index_msb;
385 break;
386 default:
387 break;
388 }
389 }
390 }
391 }
392 /*
393 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
394 * trace cache
395 */
396 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
397 /* supports eax=2 call */
398 int j, n;
399 unsigned int regs[4];
400 unsigned char *dp = (unsigned char *)regs;
401 int only_trace = 0;
402
403 if (num_cache_leaves != 0 && c->x86 == 15)
404 only_trace = 1;
405
406 /* Number of times to iterate */
407 n = cpuid_eax(2) & 0xFF;
408
409 for ( i = 0 ; i < n ; i++ ) {
410 cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
411
412 /* If bit 31 is set, this is an unknown format */
413 for ( j = 0 ; j < 3 ; j++ ) {
414 if (regs[j] & (1 << 31)) regs[j] = 0;
415 }
416
417 /* Byte 0 is level count, not a descriptor */
418 for ( j = 1 ; j < 16 ; j++ ) {
419 unsigned char des = dp[j];
420 unsigned char k = 0;
421
422 /* look up this descriptor in the table */
423 while (cache_table[k].descriptor != 0)
424 {
425 if (cache_table[k].descriptor == des) {
426 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
427 break;
428 switch (cache_table[k].cache_type) {
429 case LVL_1_INST:
430 l1i += cache_table[k].size;
431 break;
432 case LVL_1_DATA:
433 l1d += cache_table[k].size;
434 break;
435 case LVL_2:
436 l2 += cache_table[k].size;
437 break;
438 case LVL_3:
439 l3 += cache_table[k].size;
440 break;
441 case LVL_TRACE:
442 trace += cache_table[k].size;
443 break;
444 }
445
446 break;
447 }
448
449 k++;
450 }
451 }
452 }
453 }
454
455 if (new_l1d)
456 l1d = new_l1d;
457
458 if (new_l1i)
459 l1i = new_l1i;
460
461 if (new_l2) {
462 l2 = new_l2;
463 #ifdef CONFIG_X86_HT
464 per_cpu(cpu_llc_id, cpu) = l2_id;
465 #endif
466 }
467
468 if (new_l3) {
469 l3 = new_l3;
470 #ifdef CONFIG_X86_HT
471 per_cpu(cpu_llc_id, cpu) = l3_id;
472 #endif
473 }
474
475 if (trace)
476 printk (KERN_INFO "CPU: Trace cache: %dK uops", trace);
477 else if ( l1i )
478 printk (KERN_INFO "CPU: L1 I cache: %dK", l1i);
479
480 if (l1d)
481 printk(", L1 D cache: %dK\n", l1d);
482 else
483 printk("\n");
484
485 if (l2)
486 printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
487
488 if (l3)
489 printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
490
491 c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
492
493 return l2;
494 }
495
496 /* pointer to _cpuid4_info array (for each cache leaf) */
497 static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info);
498 #define CPUID4_INFO_IDX(x, y) (&((per_cpu(cpuid4_info, x))[y]))
499
500 #ifdef CONFIG_SMP
501 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
502 {
503 struct _cpuid4_info *this_leaf, *sibling_leaf;
504 unsigned long num_threads_sharing;
505 int index_msb, i;
506 struct cpuinfo_x86 *c = &cpu_data(cpu);
507
508 this_leaf = CPUID4_INFO_IDX(cpu, index);
509 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
510
511 if (num_threads_sharing == 1)
512 cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map));
513 else {
514 index_msb = get_count_order(num_threads_sharing);
515
516 for_each_online_cpu(i) {
517 if (cpu_data(i).apicid >> index_msb ==
518 c->apicid >> index_msb) {
519 cpumask_set_cpu(i,
520 to_cpumask(this_leaf->shared_cpu_map));
521 if (i != cpu && per_cpu(cpuid4_info, i)) {
522 sibling_leaf =
523 CPUID4_INFO_IDX(i, index);
524 cpumask_set_cpu(cpu, to_cpumask(
525 sibling_leaf->shared_cpu_map));
526 }
527 }
528 }
529 }
530 }
531 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
532 {
533 struct _cpuid4_info *this_leaf, *sibling_leaf;
534 int sibling;
535
536 this_leaf = CPUID4_INFO_IDX(cpu, index);
537 for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) {
538 sibling_leaf = CPUID4_INFO_IDX(sibling, index);
539 cpumask_clear_cpu(cpu,
540 to_cpumask(sibling_leaf->shared_cpu_map));
541 }
542 }
543 #else
544 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
545 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
546 #endif
547
548 static void __cpuinit free_cache_attributes(unsigned int cpu)
549 {
550 int i;
551
552 for (i = 0; i < num_cache_leaves; i++)
553 cache_remove_shared_cpu_map(cpu, i);
554
555 kfree(per_cpu(cpuid4_info, cpu));
556 per_cpu(cpuid4_info, cpu) = NULL;
557 }
558
559 static void __cpuinit get_cpu_leaves(void *_retval)
560 {
561 int j, *retval = _retval, cpu = smp_processor_id();
562
563 /* Do cpuid and store the results */
564 for (j = 0; j < num_cache_leaves; j++) {
565 struct _cpuid4_info *this_leaf;
566 this_leaf = CPUID4_INFO_IDX(cpu, j);
567 *retval = cpuid4_cache_lookup(j, this_leaf);
568 if (unlikely(*retval < 0)) {
569 int i;
570
571 for (i = 0; i < j; i++)
572 cache_remove_shared_cpu_map(cpu, i);
573 break;
574 }
575 cache_shared_cpu_map_setup(cpu, j);
576 }
577 }
578
579 static int __cpuinit detect_cache_attributes(unsigned int cpu)
580 {
581 int retval;
582
583 if (num_cache_leaves == 0)
584 return -ENOENT;
585
586 per_cpu(cpuid4_info, cpu) = kzalloc(
587 sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
588 if (per_cpu(cpuid4_info, cpu) == NULL)
589 return -ENOMEM;
590
591 smp_call_function_single(cpu, get_cpu_leaves, &retval, true);
592 if (retval) {
593 kfree(per_cpu(cpuid4_info, cpu));
594 per_cpu(cpuid4_info, cpu) = NULL;
595 }
596
597 return retval;
598 }
599
600 #ifdef CONFIG_SYSFS
601
602 #include <linux/kobject.h>
603 #include <linux/sysfs.h>
604
605 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
606
607 /* pointer to kobject for cpuX/cache */
608 static DEFINE_PER_CPU(struct kobject *, cache_kobject);
609
610 struct _index_kobject {
611 struct kobject kobj;
612 unsigned int cpu;
613 unsigned short index;
614 };
615
616 /* pointer to array of kobjects for cpuX/cache/indexY */
617 static DEFINE_PER_CPU(struct _index_kobject *, index_kobject);
618 #define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(index_kobject, x))[y]))
619
620 #define show_one_plus(file_name, object, val) \
621 static ssize_t show_##file_name \
622 (struct _cpuid4_info *this_leaf, char *buf) \
623 { \
624 return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \
625 }
626
627 show_one_plus(level, eax.split.level, 0);
628 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
629 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
630 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
631 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
632
633 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
634 {
635 return sprintf (buf, "%luK\n", this_leaf->size / 1024);
636 }
637
638 static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
639 int type, char *buf)
640 {
641 ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
642 int n = 0;
643
644 if (len > 1) {
645 const struct cpumask *mask;
646
647 mask = to_cpumask(this_leaf->shared_cpu_map);
648 n = type?
649 cpulist_scnprintf(buf, len-2, mask) :
650 cpumask_scnprintf(buf, len-2, mask);
651 buf[n++] = '\n';
652 buf[n] = '\0';
653 }
654 return n;
655 }
656
657 static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf)
658 {
659 return show_shared_cpu_map_func(leaf, 0, buf);
660 }
661
662 static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf)
663 {
664 return show_shared_cpu_map_func(leaf, 1, buf);
665 }
666
667 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf)
668 {
669 switch (this_leaf->eax.split.type) {
670 case CACHE_TYPE_DATA:
671 return sprintf(buf, "Data\n");
672 case CACHE_TYPE_INST:
673 return sprintf(buf, "Instruction\n");
674 case CACHE_TYPE_UNIFIED:
675 return sprintf(buf, "Unified\n");
676 default:
677 return sprintf(buf, "Unknown\n");
678 }
679 }
680
681 #define to_object(k) container_of(k, struct _index_kobject, kobj)
682 #define to_attr(a) container_of(a, struct _cache_attr, attr)
683
684 #ifdef CONFIG_PCI
685 static struct pci_dev *get_k8_northbridge(int node)
686 {
687 struct pci_dev *dev = NULL;
688 int i;
689
690 for (i = 0; i <= node; i++) {
691 do {
692 dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
693 if (!dev)
694 break;
695 } while (!pci_match_id(&k8_nb_id[0], dev));
696 if (!dev)
697 break;
698 }
699 return dev;
700 }
701 #else
702 static struct pci_dev *get_k8_northbridge(int node)
703 {
704 return NULL;
705 }
706 #endif
707
708 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf)
709 {
710 const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map);
711 int node = cpu_to_node(cpumask_first(mask));
712 struct pci_dev *dev = NULL;
713 ssize_t ret = 0;
714 int i;
715
716 if (!this_leaf->can_disable)
717 return sprintf(buf, "Feature not enabled\n");
718
719 dev = get_k8_northbridge(node);
720 if (!dev) {
721 printk(KERN_ERR "Attempting AMD northbridge operation on a system with no northbridge\n");
722 return -EINVAL;
723 }
724
725 for (i = 0; i < 2; i++) {
726 unsigned int reg;
727
728 pci_read_config_dword(dev, 0x1BC + i * 4, &reg);
729
730 ret += sprintf(buf, "%sEntry: %d\n", buf, i);
731 ret += sprintf(buf, "%sReads: %s\tNew Entries: %s\n",
732 buf,
733 reg & 0x80000000 ? "Disabled" : "Allowed",
734 reg & 0x40000000 ? "Disabled" : "Allowed");
735 ret += sprintf(buf, "%sSubCache: %x\tIndex: %x\n",
736 buf, (reg & 0x30000) >> 16, reg & 0xfff);
737 }
738 return ret;
739 }
740
741 static ssize_t
742 store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf,
743 size_t count)
744 {
745 const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map);
746 int node = cpu_to_node(cpumask_first(mask));
747 struct pci_dev *dev = NULL;
748 unsigned int ret, index, val;
749
750 if (!this_leaf->can_disable)
751 return 0;
752
753 if (strlen(buf) > 15)
754 return -EINVAL;
755
756 ret = sscanf(buf, "%x %x", &index, &val);
757 if (ret != 2)
758 return -EINVAL;
759 if (index > 1)
760 return -EINVAL;
761
762 val |= 0xc0000000;
763 dev = get_k8_northbridge(node);
764 if (!dev) {
765 printk(KERN_ERR "Attempting AMD northbridge operation on a system with no northbridge\n");
766 return -EINVAL;
767 }
768
769 pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000);
770 wbinvd();
771 pci_write_config_dword(dev, 0x1BC + index * 4, val);
772
773 return 1;
774 }
775
776 struct _cache_attr {
777 struct attribute attr;
778 ssize_t (*show)(struct _cpuid4_info *, char *);
779 ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
780 };
781
782 #define define_one_ro(_name) \
783 static struct _cache_attr _name = \
784 __ATTR(_name, 0444, show_##_name, NULL)
785
786 define_one_ro(level);
787 define_one_ro(type);
788 define_one_ro(coherency_line_size);
789 define_one_ro(physical_line_partition);
790 define_one_ro(ways_of_associativity);
791 define_one_ro(number_of_sets);
792 define_one_ro(size);
793 define_one_ro(shared_cpu_map);
794 define_one_ro(shared_cpu_list);
795
796 static struct _cache_attr cache_disable = __ATTR(cache_disable, 0644, show_cache_disable, store_cache_disable);
797
798 static struct attribute * default_attrs[] = {
799 &type.attr,
800 &level.attr,
801 &coherency_line_size.attr,
802 &physical_line_partition.attr,
803 &ways_of_associativity.attr,
804 &number_of_sets.attr,
805 &size.attr,
806 &shared_cpu_map.attr,
807 &shared_cpu_list.attr,
808 &cache_disable.attr,
809 NULL
810 };
811
812 static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf)
813 {
814 struct _cache_attr *fattr = to_attr(attr);
815 struct _index_kobject *this_leaf = to_object(kobj);
816 ssize_t ret;
817
818 ret = fattr->show ?
819 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
820 buf) :
821 0;
822 return ret;
823 }
824
825 static ssize_t store(struct kobject * kobj, struct attribute * attr,
826 const char * buf, size_t count)
827 {
828 struct _cache_attr *fattr = to_attr(attr);
829 struct _index_kobject *this_leaf = to_object(kobj);
830 ssize_t ret;
831
832 ret = fattr->store ?
833 fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
834 buf, count) :
835 0;
836 return ret;
837 }
838
839 static struct sysfs_ops sysfs_ops = {
840 .show = show,
841 .store = store,
842 };
843
844 static struct kobj_type ktype_cache = {
845 .sysfs_ops = &sysfs_ops,
846 .default_attrs = default_attrs,
847 };
848
849 static struct kobj_type ktype_percpu_entry = {
850 .sysfs_ops = &sysfs_ops,
851 };
852
853 static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
854 {
855 kfree(per_cpu(cache_kobject, cpu));
856 kfree(per_cpu(index_kobject, cpu));
857 per_cpu(cache_kobject, cpu) = NULL;
858 per_cpu(index_kobject, cpu) = NULL;
859 free_cache_attributes(cpu);
860 }
861
862 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
863 {
864 int err;
865
866 if (num_cache_leaves == 0)
867 return -ENOENT;
868
869 err = detect_cache_attributes(cpu);
870 if (err)
871 return err;
872
873 /* Allocate all required memory */
874 per_cpu(cache_kobject, cpu) =
875 kzalloc(sizeof(struct kobject), GFP_KERNEL);
876 if (unlikely(per_cpu(cache_kobject, cpu) == NULL))
877 goto err_out;
878
879 per_cpu(index_kobject, cpu) = kzalloc(
880 sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL);
881 if (unlikely(per_cpu(index_kobject, cpu) == NULL))
882 goto err_out;
883
884 return 0;
885
886 err_out:
887 cpuid4_cache_sysfs_exit(cpu);
888 return -ENOMEM;
889 }
890
891 static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
892
893 /* Add/Remove cache interface for CPU device */
894 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
895 {
896 unsigned int cpu = sys_dev->id;
897 unsigned long i, j;
898 struct _index_kobject *this_object;
899 int retval;
900
901 retval = cpuid4_cache_sysfs_init(cpu);
902 if (unlikely(retval < 0))
903 return retval;
904
905 retval = kobject_init_and_add(per_cpu(cache_kobject, cpu),
906 &ktype_percpu_entry,
907 &sys_dev->kobj, "%s", "cache");
908 if (retval < 0) {
909 cpuid4_cache_sysfs_exit(cpu);
910 return retval;
911 }
912
913 for (i = 0; i < num_cache_leaves; i++) {
914 this_object = INDEX_KOBJECT_PTR(cpu,i);
915 this_object->cpu = cpu;
916 this_object->index = i;
917 retval = kobject_init_and_add(&(this_object->kobj),
918 &ktype_cache,
919 per_cpu(cache_kobject, cpu),
920 "index%1lu", i);
921 if (unlikely(retval)) {
922 for (j = 0; j < i; j++) {
923 kobject_put(&(INDEX_KOBJECT_PTR(cpu,j)->kobj));
924 }
925 kobject_put(per_cpu(cache_kobject, cpu));
926 cpuid4_cache_sysfs_exit(cpu);
927 return retval;
928 }
929 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
930 }
931 cpumask_set_cpu(cpu, to_cpumask(cache_dev_map));
932
933 kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
934 return 0;
935 }
936
937 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
938 {
939 unsigned int cpu = sys_dev->id;
940 unsigned long i;
941
942 if (per_cpu(cpuid4_info, cpu) == NULL)
943 return;
944 if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map)))
945 return;
946 cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
947
948 for (i = 0; i < num_cache_leaves; i++)
949 kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
950 kobject_put(per_cpu(cache_kobject, cpu));
951 cpuid4_cache_sysfs_exit(cpu);
952 }
953
954 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
955 unsigned long action, void *hcpu)
956 {
957 unsigned int cpu = (unsigned long)hcpu;
958 struct sys_device *sys_dev;
959
960 sys_dev = get_cpu_sysdev(cpu);
961 switch (action) {
962 case CPU_ONLINE:
963 case CPU_ONLINE_FROZEN:
964 cache_add_dev(sys_dev);
965 break;
966 case CPU_DEAD:
967 case CPU_DEAD_FROZEN:
968 cache_remove_dev(sys_dev);
969 break;
970 }
971 return NOTIFY_OK;
972 }
973
974 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier =
975 {
976 .notifier_call = cacheinfo_cpu_callback,
977 };
978
979 static int __cpuinit cache_sysfs_init(void)
980 {
981 int i;
982
983 if (num_cache_leaves == 0)
984 return 0;
985
986 for_each_online_cpu(i) {
987 int err;
988 struct sys_device *sys_dev = get_cpu_sysdev(i);
989
990 err = cache_add_dev(sys_dev);
991 if (err)
992 return err;
993 }
994 register_hotcpu_notifier(&cacheinfo_cpu_notifier);
995 return 0;
996 }
997
998 device_initcall(cache_sysfs_init);
999
1000 #endif
This page took 0.050977 seconds and 4 git commands to generate.