Merge branch 'upstream' of git://lost.foo-projects.org/~ahkok/git/netdev-2.6 into...
[linux-2.6] / arch / i386 / 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              : 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
17 #include <asm/processor.h>
18 #include <asm/smp.h>
19
20 #define LVL_1_INST      1
21 #define LVL_1_DATA      2
22 #define LVL_2           3
23 #define LVL_3           4
24 #define LVL_TRACE       5
25
26 struct _cache_table
27 {
28         unsigned char descriptor;
29         char cache_type;
30         short size;
31 };
32
33 /* all the cache descriptor types we care about (no TLB or trace cache entries) */
34 static struct _cache_table cache_table[] __cpuinitdata =
35 {
36         { 0x06, LVL_1_INST, 8 },        /* 4-way set assoc, 32 byte line size */
37         { 0x08, LVL_1_INST, 16 },       /* 4-way set assoc, 32 byte line size */
38         { 0x0a, LVL_1_DATA, 8 },        /* 2 way set assoc, 32 byte line size */
39         { 0x0c, LVL_1_DATA, 16 },       /* 4-way set assoc, 32 byte line size */
40         { 0x22, LVL_3,      512 },      /* 4-way set assoc, sectored cache, 64 byte line size */
41         { 0x23, LVL_3,      1024 },     /* 8-way set assoc, sectored cache, 64 byte line size */
42         { 0x25, LVL_3,      2048 },     /* 8-way set assoc, sectored cache, 64 byte line size */
43         { 0x29, LVL_3,      4096 },     /* 8-way set assoc, sectored cache, 64 byte line size */
44         { 0x2c, LVL_1_DATA, 32 },       /* 8-way set assoc, 64 byte line size */
45         { 0x30, LVL_1_INST, 32 },       /* 8-way set assoc, 64 byte line size */
46         { 0x39, LVL_2,      128 },      /* 4-way set assoc, sectored cache, 64 byte line size */
47         { 0x3a, LVL_2,      192 },      /* 6-way set assoc, sectored cache, 64 byte line size */
48         { 0x3b, LVL_2,      128 },      /* 2-way set assoc, sectored cache, 64 byte line size */
49         { 0x3c, LVL_2,      256 },      /* 4-way set assoc, sectored cache, 64 byte line size */
50         { 0x3d, LVL_2,      384 },      /* 6-way set assoc, sectored cache, 64 byte line size */
51         { 0x3e, LVL_2,      512 },      /* 4-way set assoc, sectored cache, 64 byte line size */
52         { 0x41, LVL_2,      128 },      /* 4-way set assoc, 32 byte line size */
53         { 0x42, LVL_2,      256 },      /* 4-way set assoc, 32 byte line size */
54         { 0x43, LVL_2,      512 },      /* 4-way set assoc, 32 byte line size */
55         { 0x44, LVL_2,      1024 },     /* 4-way set assoc, 32 byte line size */
56         { 0x45, LVL_2,      2048 },     /* 4-way set assoc, 32 byte line size */
57         { 0x46, LVL_3,      4096 },     /* 4-way set assoc, 64 byte line size */
58         { 0x47, LVL_3,      8192 },     /* 8-way set assoc, 64 byte line size */
59         { 0x49, LVL_3,      4096 },     /* 16-way set assoc, 64 byte line size */
60         { 0x4a, LVL_3,      6144 },     /* 12-way set assoc, 64 byte line size */
61         { 0x4b, LVL_3,      8192 },     /* 16-way set assoc, 64 byte line size */
62         { 0x4c, LVL_3,     12288 },     /* 12-way set assoc, 64 byte line size */
63         { 0x4d, LVL_3,     16384 },     /* 16-way set assoc, 64 byte line size */
64         { 0x60, LVL_1_DATA, 16 },       /* 8-way set assoc, sectored cache, 64 byte line size */
65         { 0x66, LVL_1_DATA, 8 },        /* 4-way set assoc, sectored cache, 64 byte line size */
66         { 0x67, LVL_1_DATA, 16 },       /* 4-way set assoc, sectored cache, 64 byte line size */
67         { 0x68, LVL_1_DATA, 32 },       /* 4-way set assoc, sectored cache, 64 byte line size */
68         { 0x70, LVL_TRACE,  12 },       /* 8-way set assoc */
69         { 0x71, LVL_TRACE,  16 },       /* 8-way set assoc */
70         { 0x72, LVL_TRACE,  32 },       /* 8-way set assoc */
71         { 0x73, LVL_TRACE,  64 },       /* 8-way set assoc */
72         { 0x78, LVL_2,    1024 },       /* 4-way set assoc, 64 byte line size */
73         { 0x79, LVL_2,     128 },       /* 8-way set assoc, sectored cache, 64 byte line size */
74         { 0x7a, LVL_2,     256 },       /* 8-way set assoc, sectored cache, 64 byte line size */
75         { 0x7b, LVL_2,     512 },       /* 8-way set assoc, sectored cache, 64 byte line size */
76         { 0x7c, LVL_2,    1024 },       /* 8-way set assoc, sectored cache, 64 byte line size */
77         { 0x7d, LVL_2,    2048 },       /* 8-way set assoc, 64 byte line size */
78         { 0x7f, LVL_2,     512 },       /* 2-way set assoc, 64 byte line size */
79         { 0x82, LVL_2,     256 },       /* 8-way set assoc, 32 byte line size */
80         { 0x83, LVL_2,     512 },       /* 8-way set assoc, 32 byte line size */
81         { 0x84, LVL_2,    1024 },       /* 8-way set assoc, 32 byte line size */
82         { 0x85, LVL_2,    2048 },       /* 8-way set assoc, 32 byte line size */
83         { 0x86, LVL_2,     512 },       /* 4-way set assoc, 64 byte line size */
84         { 0x87, LVL_2,    1024 },       /* 8-way set assoc, 64 byte line size */
85         { 0x00, 0, 0}
86 };
87
88
89 enum _cache_type
90 {
91         CACHE_TYPE_NULL = 0,
92         CACHE_TYPE_DATA = 1,
93         CACHE_TYPE_INST = 2,
94         CACHE_TYPE_UNIFIED = 3
95 };
96
97 union _cpuid4_leaf_eax {
98         struct {
99                 enum _cache_type        type:5;
100                 unsigned int            level:3;
101                 unsigned int            is_self_initializing:1;
102                 unsigned int            is_fully_associative:1;
103                 unsigned int            reserved:4;
104                 unsigned int            num_threads_sharing:12;
105                 unsigned int            num_cores_on_die:6;
106         } split;
107         u32 full;
108 };
109
110 union _cpuid4_leaf_ebx {
111         struct {
112                 unsigned int            coherency_line_size:12;
113                 unsigned int            physical_line_partition:10;
114                 unsigned int            ways_of_associativity:10;
115         } split;
116         u32 full;
117 };
118
119 union _cpuid4_leaf_ecx {
120         struct {
121                 unsigned int            number_of_sets:32;
122         } split;
123         u32 full;
124 };
125
126 struct _cpuid4_info {
127         union _cpuid4_leaf_eax eax;
128         union _cpuid4_leaf_ebx ebx;
129         union _cpuid4_leaf_ecx ecx;
130         unsigned long size;
131         cpumask_t shared_cpu_map;
132 };
133
134 unsigned short                  num_cache_leaves;
135
136 /* AMD doesn't have CPUID4. Emulate it here to report the same
137    information to the user.  This makes some assumptions about the machine:
138    No L3, L2 not shared, no SMT etc. that is currently true on AMD CPUs.
139
140    In theory the TLBs could be reported as fake type (they are in "dummy").
141    Maybe later */
142 union l1_cache {
143         struct {
144                 unsigned line_size : 8;
145                 unsigned lines_per_tag : 8;
146                 unsigned assoc : 8;
147                 unsigned size_in_kb : 8;
148         };
149         unsigned val;
150 };
151
152 union l2_cache {
153         struct {
154                 unsigned line_size : 8;
155                 unsigned lines_per_tag : 4;
156                 unsigned assoc : 4;
157                 unsigned size_in_kb : 16;
158         };
159         unsigned val;
160 };
161
162 static const unsigned short assocs[] = {
163         [1] = 1, [2] = 2, [4] = 4, [6] = 8,
164         [8] = 16,
165         [0xf] = 0xffff // ??
166         };
167 static const unsigned char levels[] = { 1, 1, 2 };
168 static const unsigned char types[] = { 1, 2, 3 };
169
170 static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
171                        union _cpuid4_leaf_ebx *ebx,
172                        union _cpuid4_leaf_ecx *ecx)
173 {
174         unsigned dummy;
175         unsigned line_size, lines_per_tag, assoc, size_in_kb;
176         union l1_cache l1i, l1d;
177         union l2_cache l2;
178
179         eax->full = 0;
180         ebx->full = 0;
181         ecx->full = 0;
182
183         cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
184         cpuid(0x80000006, &dummy, &dummy, &l2.val, &dummy);
185
186         if (leaf > 2 || !l1d.val || !l1i.val || !l2.val)
187                 return;
188
189         eax->split.is_self_initializing = 1;
190         eax->split.type = types[leaf];
191         eax->split.level = levels[leaf];
192         eax->split.num_threads_sharing = 0;
193         eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
194
195         if (leaf <= 1) {
196                 union l1_cache *l1 = leaf == 0 ? &l1d : &l1i;
197                 assoc = l1->assoc;
198                 line_size = l1->line_size;
199                 lines_per_tag = l1->lines_per_tag;
200                 size_in_kb = l1->size_in_kb;
201         } else {
202                 assoc = l2.assoc;
203                 line_size = l2.line_size;
204                 lines_per_tag = l2.lines_per_tag;
205                 /* cpu_data has errata corrections for K7 applied */
206                 size_in_kb = current_cpu_data.x86_cache_size;
207         }
208
209         if (assoc == 0xf)
210                 eax->split.is_fully_associative = 1;
211         ebx->split.coherency_line_size = line_size - 1;
212         ebx->split.ways_of_associativity = assocs[assoc] - 1;
213         ebx->split.physical_line_partition = lines_per_tag - 1;
214         ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
215                 (ebx->split.ways_of_associativity + 1) - 1;
216 }
217
218 static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
219 {
220         union _cpuid4_leaf_eax  eax;
221         union _cpuid4_leaf_ebx  ebx;
222         union _cpuid4_leaf_ecx  ecx;
223         unsigned                edx;
224
225         if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
226                 amd_cpuid4(index, &eax, &ebx, &ecx);
227         else
228                 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full,  &edx);
229         if (eax.split.type == CACHE_TYPE_NULL)
230                 return -EIO; /* better error ? */
231
232         this_leaf->eax = eax;
233         this_leaf->ebx = ebx;
234         this_leaf->ecx = ecx;
235         this_leaf->size = (ecx.split.number_of_sets + 1) *
236                 (ebx.split.coherency_line_size + 1) *
237                 (ebx.split.physical_line_partition + 1) *
238                 (ebx.split.ways_of_associativity + 1);
239         return 0;
240 }
241
242 /* will only be called once; __init is safe here */
243 static int __init find_num_cache_leaves(void)
244 {
245         unsigned int            eax, ebx, ecx, edx;
246         union _cpuid4_leaf_eax  cache_eax;
247         int                     i = -1;
248
249         do {
250                 ++i;
251                 /* Do cpuid(4) loop to find out num_cache_leaves */
252                 cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
253                 cache_eax.full = eax;
254         } while (cache_eax.split.type != CACHE_TYPE_NULL);
255         return i;
256 }
257
258 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
259 {
260         unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
261         unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
262         unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
263         unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
264 #ifdef CONFIG_X86_HT
265         unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data);
266 #endif
267
268         if (c->cpuid_level > 3) {
269                 static int is_initialized;
270
271                 if (is_initialized == 0) {
272                         /* Init num_cache_leaves from boot CPU */
273                         num_cache_leaves = find_num_cache_leaves();
274                         is_initialized++;
275                 }
276
277                 /*
278                  * Whenever possible use cpuid(4), deterministic cache
279                  * parameters cpuid leaf to find the cache details
280                  */
281                 for (i = 0; i < num_cache_leaves; i++) {
282                         struct _cpuid4_info this_leaf;
283
284                         int retval;
285
286                         retval = cpuid4_cache_lookup(i, &this_leaf);
287                         if (retval >= 0) {
288                                 switch(this_leaf.eax.split.level) {
289                                     case 1:
290                                         if (this_leaf.eax.split.type ==
291                                                         CACHE_TYPE_DATA)
292                                                 new_l1d = this_leaf.size/1024;
293                                         else if (this_leaf.eax.split.type ==
294                                                         CACHE_TYPE_INST)
295                                                 new_l1i = this_leaf.size/1024;
296                                         break;
297                                     case 2:
298                                         new_l2 = this_leaf.size/1024;
299                                         num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
300                                         index_msb = get_count_order(num_threads_sharing);
301                                         l2_id = c->apicid >> index_msb;
302                                         break;
303                                     case 3:
304                                         new_l3 = this_leaf.size/1024;
305                                         num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
306                                         index_msb = get_count_order(num_threads_sharing);
307                                         l3_id = c->apicid >> index_msb;
308                                         break;
309                                     default:
310                                         break;
311                                 }
312                         }
313                 }
314         }
315         /*
316          * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
317          * trace cache
318          */
319         if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
320                 /* supports eax=2  call */
321                 int i, j, n;
322                 int regs[4];
323                 unsigned char *dp = (unsigned char *)regs;
324                 int only_trace = 0;
325
326                 if (num_cache_leaves != 0 && c->x86 == 15)
327                         only_trace = 1;
328
329                 /* Number of times to iterate */
330                 n = cpuid_eax(2) & 0xFF;
331
332                 for ( i = 0 ; i < n ; i++ ) {
333                         cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
334
335                         /* If bit 31 is set, this is an unknown format */
336                         for ( j = 0 ; j < 3 ; j++ ) {
337                                 if ( regs[j] < 0 ) regs[j] = 0;
338                         }
339
340                         /* Byte 0 is level count, not a descriptor */
341                         for ( j = 1 ; j < 16 ; j++ ) {
342                                 unsigned char des = dp[j];
343                                 unsigned char k = 0;
344
345                                 /* look up this descriptor in the table */
346                                 while (cache_table[k].descriptor != 0)
347                                 {
348                                         if (cache_table[k].descriptor == des) {
349                                                 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
350                                                         break;
351                                                 switch (cache_table[k].cache_type) {
352                                                 case LVL_1_INST:
353                                                         l1i += cache_table[k].size;
354                                                         break;
355                                                 case LVL_1_DATA:
356                                                         l1d += cache_table[k].size;
357                                                         break;
358                                                 case LVL_2:
359                                                         l2 += cache_table[k].size;
360                                                         break;
361                                                 case LVL_3:
362                                                         l3 += cache_table[k].size;
363                                                         break;
364                                                 case LVL_TRACE:
365                                                         trace += cache_table[k].size;
366                                                         break;
367                                                 }
368
369                                                 break;
370                                         }
371
372                                         k++;
373                                 }
374                         }
375                 }
376         }
377
378         if (new_l1d)
379                 l1d = new_l1d;
380
381         if (new_l1i)
382                 l1i = new_l1i;
383
384         if (new_l2) {
385                 l2 = new_l2;
386 #ifdef CONFIG_X86_HT
387                 cpu_llc_id[cpu] = l2_id;
388 #endif
389         }
390
391         if (new_l3) {
392                 l3 = new_l3;
393 #ifdef CONFIG_X86_HT
394                 cpu_llc_id[cpu] = l3_id;
395 #endif
396         }
397
398         if (trace)
399                 printk (KERN_INFO "CPU: Trace cache: %dK uops", trace);
400         else if ( l1i )
401                 printk (KERN_INFO "CPU: L1 I cache: %dK", l1i);
402
403         if (l1d)
404                 printk(", L1 D cache: %dK\n", l1d);
405         else
406                 printk("\n");
407
408         if (l2)
409                 printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
410
411         if (l3)
412                 printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
413
414         c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
415
416         return l2;
417 }
418
419 /* pointer to _cpuid4_info array (for each cache leaf) */
420 static struct _cpuid4_info *cpuid4_info[NR_CPUS];
421 #define CPUID4_INFO_IDX(x,y)    (&((cpuid4_info[x])[y]))
422
423 #ifdef CONFIG_SMP
424 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
425 {
426         struct _cpuid4_info     *this_leaf, *sibling_leaf;
427         unsigned long num_threads_sharing;
428         int index_msb, i;
429         struct cpuinfo_x86 *c = cpu_data;
430
431         this_leaf = CPUID4_INFO_IDX(cpu, index);
432         num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
433
434         if (num_threads_sharing == 1)
435                 cpu_set(cpu, this_leaf->shared_cpu_map);
436         else {
437                 index_msb = get_count_order(num_threads_sharing);
438
439                 for_each_online_cpu(i) {
440                         if (c[i].apicid >> index_msb ==
441                             c[cpu].apicid >> index_msb) {
442                                 cpu_set(i, this_leaf->shared_cpu_map);
443                                 if (i != cpu && cpuid4_info[i])  {
444                                         sibling_leaf = CPUID4_INFO_IDX(i, index);
445                                         cpu_set(cpu, sibling_leaf->shared_cpu_map);
446                                 }
447                         }
448                 }
449         }
450 }
451 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
452 {
453         struct _cpuid4_info     *this_leaf, *sibling_leaf;
454         int sibling;
455
456         this_leaf = CPUID4_INFO_IDX(cpu, index);
457         for_each_cpu_mask(sibling, this_leaf->shared_cpu_map) {
458                 sibling_leaf = CPUID4_INFO_IDX(sibling, index); 
459                 cpu_clear(cpu, sibling_leaf->shared_cpu_map);
460         }
461 }
462 #else
463 static void __init cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
464 static void __init cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
465 #endif
466
467 static void free_cache_attributes(unsigned int cpu)
468 {
469         kfree(cpuid4_info[cpu]);
470         cpuid4_info[cpu] = NULL;
471 }
472
473 static int __cpuinit detect_cache_attributes(unsigned int cpu)
474 {
475         struct _cpuid4_info     *this_leaf;
476         unsigned long           j;
477         int                     retval;
478         cpumask_t               oldmask;
479
480         if (num_cache_leaves == 0)
481                 return -ENOENT;
482
483         cpuid4_info[cpu] = kmalloc(
484             sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
485         if (unlikely(cpuid4_info[cpu] == NULL))
486                 return -ENOMEM;
487         memset(cpuid4_info[cpu], 0,
488             sizeof(struct _cpuid4_info) * num_cache_leaves);
489
490         oldmask = current->cpus_allowed;
491         retval = set_cpus_allowed(current, cpumask_of_cpu(cpu));
492         if (retval)
493                 goto out;
494
495         /* Do cpuid and store the results */
496         retval = 0;
497         for (j = 0; j < num_cache_leaves; j++) {
498                 this_leaf = CPUID4_INFO_IDX(cpu, j);
499                 retval = cpuid4_cache_lookup(j, this_leaf);
500                 if (unlikely(retval < 0))
501                         break;
502                 cache_shared_cpu_map_setup(cpu, j);
503         }
504         set_cpus_allowed(current, oldmask);
505
506 out:
507         if (retval)
508                 free_cache_attributes(cpu);
509         return retval;
510 }
511
512 #ifdef CONFIG_SYSFS
513
514 #include <linux/kobject.h>
515 #include <linux/sysfs.h>
516
517 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
518
519 /* pointer to kobject for cpuX/cache */
520 static struct kobject * cache_kobject[NR_CPUS];
521
522 struct _index_kobject {
523         struct kobject kobj;
524         unsigned int cpu;
525         unsigned short index;
526 };
527
528 /* pointer to array of kobjects for cpuX/cache/indexY */
529 static struct _index_kobject *index_kobject[NR_CPUS];
530 #define INDEX_KOBJECT_PTR(x,y)    (&((index_kobject[x])[y]))
531
532 #define show_one_plus(file_name, object, val)                           \
533 static ssize_t show_##file_name                                         \
534                         (struct _cpuid4_info *this_leaf, char *buf)     \
535 {                                                                       \
536         return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \
537 }
538
539 show_one_plus(level, eax.split.level, 0);
540 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
541 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
542 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
543 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
544
545 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
546 {
547         return sprintf (buf, "%luK\n", this_leaf->size / 1024);
548 }
549
550 static ssize_t show_shared_cpu_map(struct _cpuid4_info *this_leaf, char *buf)
551 {
552         char mask_str[NR_CPUS];
553         cpumask_scnprintf(mask_str, NR_CPUS, this_leaf->shared_cpu_map);
554         return sprintf(buf, "%s\n", mask_str);
555 }
556
557 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf) {
558         switch(this_leaf->eax.split.type) {
559             case CACHE_TYPE_DATA:
560                 return sprintf(buf, "Data\n");
561                 break;
562             case CACHE_TYPE_INST:
563                 return sprintf(buf, "Instruction\n");
564                 break;
565             case CACHE_TYPE_UNIFIED:
566                 return sprintf(buf, "Unified\n");
567                 break;
568             default:
569                 return sprintf(buf, "Unknown\n");
570                 break;
571         }
572 }
573
574 struct _cache_attr {
575         struct attribute attr;
576         ssize_t (*show)(struct _cpuid4_info *, char *);
577         ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
578 };
579
580 #define define_one_ro(_name) \
581 static struct _cache_attr _name = \
582         __ATTR(_name, 0444, show_##_name, NULL)
583
584 define_one_ro(level);
585 define_one_ro(type);
586 define_one_ro(coherency_line_size);
587 define_one_ro(physical_line_partition);
588 define_one_ro(ways_of_associativity);
589 define_one_ro(number_of_sets);
590 define_one_ro(size);
591 define_one_ro(shared_cpu_map);
592
593 static struct attribute * default_attrs[] = {
594         &type.attr,
595         &level.attr,
596         &coherency_line_size.attr,
597         &physical_line_partition.attr,
598         &ways_of_associativity.attr,
599         &number_of_sets.attr,
600         &size.attr,
601         &shared_cpu_map.attr,
602         NULL
603 };
604
605 #define to_object(k) container_of(k, struct _index_kobject, kobj)
606 #define to_attr(a) container_of(a, struct _cache_attr, attr)
607
608 static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf)
609 {
610         struct _cache_attr *fattr = to_attr(attr);
611         struct _index_kobject *this_leaf = to_object(kobj);
612         ssize_t ret;
613
614         ret = fattr->show ?
615                 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
616                         buf) :
617                 0;
618         return ret;
619 }
620
621 static ssize_t store(struct kobject * kobj, struct attribute * attr,
622                      const char * buf, size_t count)
623 {
624         return 0;
625 }
626
627 static struct sysfs_ops sysfs_ops = {
628         .show   = show,
629         .store  = store,
630 };
631
632 static struct kobj_type ktype_cache = {
633         .sysfs_ops      = &sysfs_ops,
634         .default_attrs  = default_attrs,
635 };
636
637 static struct kobj_type ktype_percpu_entry = {
638         .sysfs_ops      = &sysfs_ops,
639 };
640
641 static void cpuid4_cache_sysfs_exit(unsigned int cpu)
642 {
643         kfree(cache_kobject[cpu]);
644         kfree(index_kobject[cpu]);
645         cache_kobject[cpu] = NULL;
646         index_kobject[cpu] = NULL;
647         free_cache_attributes(cpu);
648 }
649
650 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
651 {
652
653         if (num_cache_leaves == 0)
654                 return -ENOENT;
655
656         detect_cache_attributes(cpu);
657         if (cpuid4_info[cpu] == NULL)
658                 return -ENOENT;
659
660         /* Allocate all required memory */
661         cache_kobject[cpu] = kmalloc(sizeof(struct kobject), GFP_KERNEL);
662         if (unlikely(cache_kobject[cpu] == NULL))
663                 goto err_out;
664         memset(cache_kobject[cpu], 0, sizeof(struct kobject));
665
666         index_kobject[cpu] = kmalloc(
667             sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL);
668         if (unlikely(index_kobject[cpu] == NULL))
669                 goto err_out;
670         memset(index_kobject[cpu], 0,
671             sizeof(struct _index_kobject) * num_cache_leaves);
672
673         return 0;
674
675 err_out:
676         cpuid4_cache_sysfs_exit(cpu);
677         return -ENOMEM;
678 }
679
680 /* Add/Remove cache interface for CPU device */
681 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
682 {
683         unsigned int cpu = sys_dev->id;
684         unsigned long i, j;
685         struct _index_kobject *this_object;
686         int retval = 0;
687
688         retval = cpuid4_cache_sysfs_init(cpu);
689         if (unlikely(retval < 0))
690                 return retval;
691
692         cache_kobject[cpu]->parent = &sys_dev->kobj;
693         kobject_set_name(cache_kobject[cpu], "%s", "cache");
694         cache_kobject[cpu]->ktype = &ktype_percpu_entry;
695         retval = kobject_register(cache_kobject[cpu]);
696
697         for (i = 0; i < num_cache_leaves; i++) {
698                 this_object = INDEX_KOBJECT_PTR(cpu,i);
699                 this_object->cpu = cpu;
700                 this_object->index = i;
701                 this_object->kobj.parent = cache_kobject[cpu];
702                 kobject_set_name(&(this_object->kobj), "index%1lu", i);
703                 this_object->kobj.ktype = &ktype_cache;
704                 retval = kobject_register(&(this_object->kobj));
705                 if (unlikely(retval)) {
706                         for (j = 0; j < i; j++) {
707                                 kobject_unregister(
708                                         &(INDEX_KOBJECT_PTR(cpu,j)->kobj));
709                         }
710                         kobject_unregister(cache_kobject[cpu]);
711                         cpuid4_cache_sysfs_exit(cpu);
712                         break;
713                 }
714         }
715         return retval;
716 }
717
718 static void __cpuexit cache_remove_dev(struct sys_device * sys_dev)
719 {
720         unsigned int cpu = sys_dev->id;
721         unsigned long i;
722
723         for (i = 0; i < num_cache_leaves; i++) {
724                 cache_remove_shared_cpu_map(cpu, i);
725                 kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
726         }
727         kobject_unregister(cache_kobject[cpu]);
728         cpuid4_cache_sysfs_exit(cpu);
729         return;
730 }
731
732 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
733                                         unsigned long action, void *hcpu)
734 {
735         unsigned int cpu = (unsigned long)hcpu;
736         struct sys_device *sys_dev;
737
738         sys_dev = get_cpu_sysdev(cpu);
739         switch (action) {
740         case CPU_ONLINE:
741                 cache_add_dev(sys_dev);
742                 break;
743         case CPU_DEAD:
744                 cache_remove_dev(sys_dev);
745                 break;
746         }
747         return NOTIFY_OK;
748 }
749
750 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier =
751 {
752     .notifier_call = cacheinfo_cpu_callback,
753 };
754
755 static int __cpuinit cache_sysfs_init(void)
756 {
757         int i;
758
759         if (num_cache_leaves == 0)
760                 return 0;
761
762         register_cpu_notifier(&cacheinfo_cpu_notifier);
763
764         for_each_online_cpu(i) {
765                 cacheinfo_cpu_callback(&cacheinfo_cpu_notifier, CPU_ONLINE,
766                         (void *)(long)i);
767         }
768
769         return 0;
770 }
771
772 device_initcall(cache_sysfs_init);
773
774 #endif