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>
29 unsigned char descriptor;
34 /* all the cache descriptor types we care about (no TLB or trace cache entries) */
35 static struct _cache_table cache_table[] __cpuinitdata =
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 */
97 CACHE_TYPE_UNIFIED = 3
100 union _cpuid4_leaf_eax {
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;
113 union _cpuid4_leaf_ebx {
115 unsigned int coherency_line_size:12;
116 unsigned int physical_line_partition:10;
117 unsigned int ways_of_associativity:10;
122 union _cpuid4_leaf_ecx {
124 unsigned int number_of_sets:32;
129 struct _cpuid4_info {
130 union _cpuid4_leaf_eax eax;
131 union _cpuid4_leaf_ebx ebx;
132 union _cpuid4_leaf_ecx ecx;
134 unsigned long can_disable;
135 cpumask_t shared_cpu_map; /* future?: only cpus/node is needed */
138 static struct pci_device_id k8_nb_id[] = {
139 { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1103) },
140 { PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x1203) },
144 unsigned short num_cache_leaves;
146 /* AMD doesn't have CPUID4. Emulate it here to report the same
147 information to the user. This makes some assumptions about the machine:
148 L2 not shared, no SMT etc. that is currently true on AMD CPUs.
150 In theory the TLBs could be reported as fake type (they are in "dummy").
154 unsigned line_size : 8;
155 unsigned lines_per_tag : 8;
157 unsigned size_in_kb : 8;
164 unsigned line_size : 8;
165 unsigned lines_per_tag : 4;
167 unsigned size_in_kb : 16;
174 unsigned line_size : 8;
175 unsigned lines_per_tag : 4;
178 unsigned size_encoded : 14;
183 static unsigned short assocs[] __cpuinitdata = {
184 [1] = 1, [2] = 2, [4] = 4, [6] = 8,
185 [8] = 16, [0xa] = 32, [0xb] = 48,
190 static unsigned char levels[] __cpuinitdata = { 1, 1, 2, 3 };
191 static unsigned char types[] __cpuinitdata = { 1, 2, 3, 3 };
193 static void __cpuinit
194 amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
195 union _cpuid4_leaf_ebx *ebx,
196 union _cpuid4_leaf_ecx *ecx)
199 unsigned line_size, lines_per_tag, assoc, size_in_kb;
200 union l1_cache l1i, l1d;
203 union l1_cache *l1 = &l1d;
209 cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
210 cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
219 line_size = l1->line_size;
220 lines_per_tag = l1->lines_per_tag;
221 size_in_kb = l1->size_in_kb;
227 line_size = l2.line_size;
228 lines_per_tag = l2.lines_per_tag;
229 /* cpu_data has errata corrections for K7 applied */
230 size_in_kb = current_cpu_data.x86_cache_size;
236 line_size = l3.line_size;
237 lines_per_tag = l3.lines_per_tag;
238 size_in_kb = l3.size_encoded * 512;
244 eax->split.is_self_initializing = 1;
245 eax->split.type = types[leaf];
246 eax->split.level = levels[leaf];
248 eax->split.num_threads_sharing = current_cpu_data.x86_max_cores - 1;
250 eax->split.num_threads_sharing = 0;
251 eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
255 eax->split.is_fully_associative = 1;
256 ebx->split.coherency_line_size = line_size - 1;
257 ebx->split.ways_of_associativity = assocs[assoc] - 1;
258 ebx->split.physical_line_partition = lines_per_tag - 1;
259 ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
260 (ebx->split.ways_of_associativity + 1) - 1;
263 static void __cpuinit
264 amd_check_l3_disable(int index, struct _cpuid4_info *this_leaf)
268 this_leaf->can_disable = 1;
272 __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
274 union _cpuid4_leaf_eax eax;
275 union _cpuid4_leaf_ebx ebx;
276 union _cpuid4_leaf_ecx ecx;
279 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
280 amd_cpuid4(index, &eax, &ebx, &ecx);
281 if (boot_cpu_data.x86 >= 0x10)
282 amd_check_l3_disable(index, this_leaf);
284 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
287 if (eax.split.type == CACHE_TYPE_NULL)
288 return -EIO; /* better error ? */
290 this_leaf->eax = eax;
291 this_leaf->ebx = ebx;
292 this_leaf->ecx = ecx;
293 this_leaf->size = (ecx.split.number_of_sets + 1) *
294 (ebx.split.coherency_line_size + 1) *
295 (ebx.split.physical_line_partition + 1) *
296 (ebx.split.ways_of_associativity + 1);
300 static int __cpuinit find_num_cache_leaves(void)
302 unsigned int eax, ebx, ecx, edx;
303 union _cpuid4_leaf_eax cache_eax;
308 /* Do cpuid(4) loop to find out num_cache_leaves */
309 cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
310 cache_eax.full = eax;
311 } while (cache_eax.split.type != CACHE_TYPE_NULL);
315 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
317 unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
318 unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
319 unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
320 unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
322 unsigned int cpu = c->cpu_index;
325 if (c->cpuid_level > 3) {
326 static int is_initialized;
328 if (is_initialized == 0) {
329 /* Init num_cache_leaves from boot CPU */
330 num_cache_leaves = find_num_cache_leaves();
335 * Whenever possible use cpuid(4), deterministic cache
336 * parameters cpuid leaf to find the cache details
338 for (i = 0; i < num_cache_leaves; i++) {
339 struct _cpuid4_info this_leaf;
343 retval = cpuid4_cache_lookup(i, &this_leaf);
345 switch(this_leaf.eax.split.level) {
347 if (this_leaf.eax.split.type ==
349 new_l1d = this_leaf.size/1024;
350 else if (this_leaf.eax.split.type ==
352 new_l1i = this_leaf.size/1024;
355 new_l2 = this_leaf.size/1024;
356 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
357 index_msb = get_count_order(num_threads_sharing);
358 l2_id = c->apicid >> index_msb;
361 new_l3 = this_leaf.size/1024;
362 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
363 index_msb = get_count_order(num_threads_sharing);
364 l3_id = c->apicid >> index_msb;
373 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
376 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
377 /* supports eax=2 call */
379 unsigned int regs[4];
380 unsigned char *dp = (unsigned char *)regs;
383 if (num_cache_leaves != 0 && c->x86 == 15)
386 /* Number of times to iterate */
387 n = cpuid_eax(2) & 0xFF;
389 for ( i = 0 ; i < n ; i++ ) {
390 cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]);
392 /* If bit 31 is set, this is an unknown format */
393 for ( j = 0 ; j < 3 ; j++ ) {
394 if (regs[j] & (1 << 31)) regs[j] = 0;
397 /* Byte 0 is level count, not a descriptor */
398 for ( j = 1 ; j < 16 ; j++ ) {
399 unsigned char des = dp[j];
402 /* look up this descriptor in the table */
403 while (cache_table[k].descriptor != 0)
405 if (cache_table[k].descriptor == des) {
406 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
408 switch (cache_table[k].cache_type) {
410 l1i += cache_table[k].size;
413 l1d += cache_table[k].size;
416 l2 += cache_table[k].size;
419 l3 += cache_table[k].size;
422 trace += cache_table[k].size;
444 per_cpu(cpu_llc_id, cpu) = l2_id;
451 per_cpu(cpu_llc_id, cpu) = l3_id;
456 printk (KERN_INFO "CPU: Trace cache: %dK uops", trace);
458 printk (KERN_INFO "CPU: L1 I cache: %dK", l1i);
461 printk(", L1 D cache: %dK\n", l1d);
466 printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
469 printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
471 c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
476 /* pointer to _cpuid4_info array (for each cache leaf) */
477 static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info);
478 #define CPUID4_INFO_IDX(x, y) (&((per_cpu(cpuid4_info, x))[y]))
481 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
483 struct _cpuid4_info *this_leaf, *sibling_leaf;
484 unsigned long num_threads_sharing;
486 struct cpuinfo_x86 *c = &cpu_data(cpu);
488 this_leaf = CPUID4_INFO_IDX(cpu, index);
489 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
491 if (num_threads_sharing == 1)
492 cpu_set(cpu, this_leaf->shared_cpu_map);
494 index_msb = get_count_order(num_threads_sharing);
496 for_each_online_cpu(i) {
497 if (cpu_data(i).apicid >> index_msb ==
498 c->apicid >> index_msb) {
499 cpu_set(i, this_leaf->shared_cpu_map);
500 if (i != cpu && per_cpu(cpuid4_info, i)) {
501 sibling_leaf = CPUID4_INFO_IDX(i, index);
502 cpu_set(cpu, sibling_leaf->shared_cpu_map);
508 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
510 struct _cpuid4_info *this_leaf, *sibling_leaf;
513 this_leaf = CPUID4_INFO_IDX(cpu, index);
514 for_each_cpu_mask_nr(sibling, this_leaf->shared_cpu_map) {
515 sibling_leaf = CPUID4_INFO_IDX(sibling, index);
516 cpu_clear(cpu, sibling_leaf->shared_cpu_map);
520 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
521 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
524 static void __cpuinit free_cache_attributes(unsigned int cpu)
528 for (i = 0; i < num_cache_leaves; i++)
529 cache_remove_shared_cpu_map(cpu, i);
531 kfree(per_cpu(cpuid4_info, cpu));
532 per_cpu(cpuid4_info, cpu) = NULL;
535 static int __cpuinit detect_cache_attributes(unsigned int cpu)
537 struct _cpuid4_info *this_leaf;
541 cpumask_of_cpu_ptr(newmask, cpu);
543 if (num_cache_leaves == 0)
546 per_cpu(cpuid4_info, cpu) = kzalloc(
547 sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
548 if (per_cpu(cpuid4_info, cpu) == NULL)
551 oldmask = current->cpus_allowed;
552 retval = set_cpus_allowed_ptr(current, newmask);
556 /* Do cpuid and store the results */
557 for (j = 0; j < num_cache_leaves; j++) {
558 this_leaf = CPUID4_INFO_IDX(cpu, j);
559 retval = cpuid4_cache_lookup(j, this_leaf);
560 if (unlikely(retval < 0)) {
563 for (i = 0; i < j; i++)
564 cache_remove_shared_cpu_map(cpu, i);
567 cache_shared_cpu_map_setup(cpu, j);
569 set_cpus_allowed_ptr(current, &oldmask);
573 kfree(per_cpu(cpuid4_info, cpu));
574 per_cpu(cpuid4_info, cpu) = NULL;
582 #include <linux/kobject.h>
583 #include <linux/sysfs.h>
585 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
587 /* pointer to kobject for cpuX/cache */
588 static DEFINE_PER_CPU(struct kobject *, cache_kobject);
590 struct _index_kobject {
593 unsigned short index;
596 /* pointer to array of kobjects for cpuX/cache/indexY */
597 static DEFINE_PER_CPU(struct _index_kobject *, index_kobject);
598 #define INDEX_KOBJECT_PTR(x, y) (&((per_cpu(index_kobject, x))[y]))
600 #define show_one_plus(file_name, object, val) \
601 static ssize_t show_##file_name \
602 (struct _cpuid4_info *this_leaf, char *buf) \
604 return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \
607 show_one_plus(level, eax.split.level, 0);
608 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
609 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
610 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
611 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
613 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
615 return sprintf (buf, "%luK\n", this_leaf->size / 1024);
618 static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
621 ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
625 cpumask_t *mask = &this_leaf->shared_cpu_map;
628 cpulist_scnprintf(buf, len-2, *mask):
629 cpumask_scnprintf(buf, len-2, *mask);
636 static inline ssize_t show_shared_cpu_map(struct _cpuid4_info *leaf, char *buf)
638 return show_shared_cpu_map_func(leaf, 0, buf);
641 static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf)
643 return show_shared_cpu_map_func(leaf, 1, buf);
646 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf) {
647 switch(this_leaf->eax.split.type) {
648 case CACHE_TYPE_DATA:
649 return sprintf(buf, "Data\n");
651 case CACHE_TYPE_INST:
652 return sprintf(buf, "Instruction\n");
654 case CACHE_TYPE_UNIFIED:
655 return sprintf(buf, "Unified\n");
658 return sprintf(buf, "Unknown\n");
663 #define to_object(k) container_of(k, struct _index_kobject, kobj)
664 #define to_attr(a) container_of(a, struct _cache_attr, attr)
666 static struct pci_dev *get_k8_northbridge(int node)
668 struct pci_dev *dev = NULL;
671 for (i = 0; i <= node; i++) {
673 dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
676 } while (!pci_match_id(&k8_nb_id[0], dev));
683 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf)
685 int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map));
686 struct pci_dev *dev = NULL;
690 if (!this_leaf->can_disable)
691 return sprintf(buf, "Feature not enabled\n");
693 dev = get_k8_northbridge(node);
695 printk(KERN_ERR "Attempting AMD northbridge operation on a system with no northbridge\n");
699 for (i = 0; i < 2; i++) {
702 pci_read_config_dword(dev, 0x1BC + i * 4, ®);
704 ret += sprintf(buf, "%sEntry: %d\n", buf, i);
705 ret += sprintf(buf, "%sReads: %s\tNew Entries: %s\n",
707 reg & 0x80000000 ? "Disabled" : "Allowed",
708 reg & 0x40000000 ? "Disabled" : "Allowed");
709 ret += sprintf(buf, "%sSubCache: %x\tIndex: %x\n",
710 buf, (reg & 0x30000) >> 16, reg & 0xfff);
716 store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf,
719 int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map));
720 struct pci_dev *dev = NULL;
721 unsigned int ret, index, val;
723 if (!this_leaf->can_disable)
726 if (strlen(buf) > 15)
729 ret = sscanf(buf, "%x %x", &index, &val);
736 dev = get_k8_northbridge(node);
738 printk(KERN_ERR "Attempting AMD northbridge operation on a system with no northbridge\n");
742 pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000);
744 pci_write_config_dword(dev, 0x1BC + index * 4, val);
750 struct attribute attr;
751 ssize_t (*show)(struct _cpuid4_info *, char *);
752 ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
755 #define define_one_ro(_name) \
756 static struct _cache_attr _name = \
757 __ATTR(_name, 0444, show_##_name, NULL)
759 define_one_ro(level);
761 define_one_ro(coherency_line_size);
762 define_one_ro(physical_line_partition);
763 define_one_ro(ways_of_associativity);
764 define_one_ro(number_of_sets);
766 define_one_ro(shared_cpu_map);
767 define_one_ro(shared_cpu_list);
769 static struct _cache_attr cache_disable = __ATTR(cache_disable, 0644, show_cache_disable, store_cache_disable);
771 static struct attribute * default_attrs[] = {
774 &coherency_line_size.attr,
775 &physical_line_partition.attr,
776 &ways_of_associativity.attr,
777 &number_of_sets.attr,
779 &shared_cpu_map.attr,
780 &shared_cpu_list.attr,
785 static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf)
787 struct _cache_attr *fattr = to_attr(attr);
788 struct _index_kobject *this_leaf = to_object(kobj);
792 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
798 static ssize_t store(struct kobject * kobj, struct attribute * attr,
799 const char * buf, size_t count)
801 struct _cache_attr *fattr = to_attr(attr);
802 struct _index_kobject *this_leaf = to_object(kobj);
806 fattr->store(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
812 static struct sysfs_ops sysfs_ops = {
817 static struct kobj_type ktype_cache = {
818 .sysfs_ops = &sysfs_ops,
819 .default_attrs = default_attrs,
822 static struct kobj_type ktype_percpu_entry = {
823 .sysfs_ops = &sysfs_ops,
826 static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu)
828 kfree(per_cpu(cache_kobject, cpu));
829 kfree(per_cpu(index_kobject, cpu));
830 per_cpu(cache_kobject, cpu) = NULL;
831 per_cpu(index_kobject, cpu) = NULL;
832 free_cache_attributes(cpu);
835 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
839 if (num_cache_leaves == 0)
842 err = detect_cache_attributes(cpu);
846 /* Allocate all required memory */
847 per_cpu(cache_kobject, cpu) =
848 kzalloc(sizeof(struct kobject), GFP_KERNEL);
849 if (unlikely(per_cpu(cache_kobject, cpu) == NULL))
852 per_cpu(index_kobject, cpu) = kzalloc(
853 sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL);
854 if (unlikely(per_cpu(index_kobject, cpu) == NULL))
860 cpuid4_cache_sysfs_exit(cpu);
864 static cpumask_t cache_dev_map = CPU_MASK_NONE;
866 /* Add/Remove cache interface for CPU device */
867 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
869 unsigned int cpu = sys_dev->id;
871 struct _index_kobject *this_object;
874 retval = cpuid4_cache_sysfs_init(cpu);
875 if (unlikely(retval < 0))
878 retval = kobject_init_and_add(per_cpu(cache_kobject, cpu),
880 &sys_dev->kobj, "%s", "cache");
882 cpuid4_cache_sysfs_exit(cpu);
886 for (i = 0; i < num_cache_leaves; i++) {
887 this_object = INDEX_KOBJECT_PTR(cpu,i);
888 this_object->cpu = cpu;
889 this_object->index = i;
890 retval = kobject_init_and_add(&(this_object->kobj),
892 per_cpu(cache_kobject, cpu),
894 if (unlikely(retval)) {
895 for (j = 0; j < i; j++) {
896 kobject_put(&(INDEX_KOBJECT_PTR(cpu,j)->kobj));
898 kobject_put(per_cpu(cache_kobject, cpu));
899 cpuid4_cache_sysfs_exit(cpu);
902 kobject_uevent(&(this_object->kobj), KOBJ_ADD);
904 cpu_set(cpu, cache_dev_map);
906 kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
910 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
912 unsigned int cpu = sys_dev->id;
915 if (per_cpu(cpuid4_info, cpu) == NULL)
917 if (!cpu_isset(cpu, cache_dev_map))
919 cpu_clear(cpu, cache_dev_map);
921 for (i = 0; i < num_cache_leaves; i++)
922 kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
923 kobject_put(per_cpu(cache_kobject, cpu));
924 cpuid4_cache_sysfs_exit(cpu);
927 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
928 unsigned long action, void *hcpu)
930 unsigned int cpu = (unsigned long)hcpu;
931 struct sys_device *sys_dev;
933 sys_dev = get_cpu_sysdev(cpu);
936 case CPU_ONLINE_FROZEN:
937 cache_add_dev(sys_dev);
940 case CPU_DEAD_FROZEN:
941 cache_remove_dev(sys_dev);
947 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier =
949 .notifier_call = cacheinfo_cpu_callback,
952 static int __cpuinit cache_sysfs_init(void)
956 if (num_cache_leaves == 0)
959 for_each_online_cpu(i) {
961 struct sys_device *sys_dev = get_cpu_sysdev(i);
963 err = cache_add_dev(sys_dev);
967 register_hotcpu_notifier(&cacheinfo_cpu_notifier);
971 device_initcall(cache_sysfs_init);