i386: move kernel/cpu
[linux-2.6] / 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
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    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 union l3_cache {
163         struct {
164                 unsigned line_size : 8;
165                 unsigned lines_per_tag : 4;
166                 unsigned assoc : 4;
167                 unsigned res : 2;
168                 unsigned size_encoded : 14;
169         };
170         unsigned val;
171 };
172
173 static const unsigned short assocs[] = {
174         [1] = 1, [2] = 2, [4] = 4, [6] = 8,
175         [8] = 16, [0xa] = 32, [0xb] = 48,
176         [0xc] = 64,
177         [0xf] = 0xffff // ??
178 };
179
180 static const unsigned char levels[] = { 1, 1, 2, 3 };
181 static const unsigned char types[] = { 1, 2, 3, 3 };
182
183 static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
184                        union _cpuid4_leaf_ebx *ebx,
185                        union _cpuid4_leaf_ecx *ecx)
186 {
187         unsigned dummy;
188         unsigned line_size, lines_per_tag, assoc, size_in_kb;
189         union l1_cache l1i, l1d;
190         union l2_cache l2;
191         union l3_cache l3;
192         union l1_cache *l1 = &l1d;
193
194         eax->full = 0;
195         ebx->full = 0;
196         ecx->full = 0;
197
198         cpuid(0x80000005, &dummy, &dummy, &l1d.val, &l1i.val);
199         cpuid(0x80000006, &dummy, &dummy, &l2.val, &l3.val);
200
201         switch (leaf) {
202         case 1:
203                 l1 = &l1i;
204         case 0:
205                 if (!l1->val)
206                         return;
207                 assoc = l1->assoc;
208                 line_size = l1->line_size;
209                 lines_per_tag = l1->lines_per_tag;
210                 size_in_kb = l1->size_in_kb;
211                 break;
212         case 2:
213                 if (!l2.val)
214                         return;
215                 assoc = l2.assoc;
216                 line_size = l2.line_size;
217                 lines_per_tag = l2.lines_per_tag;
218                 /* cpu_data has errata corrections for K7 applied */
219                 size_in_kb = current_cpu_data.x86_cache_size;
220                 break;
221         case 3:
222                 if (!l3.val)
223                         return;
224                 assoc = l3.assoc;
225                 line_size = l3.line_size;
226                 lines_per_tag = l3.lines_per_tag;
227                 size_in_kb = l3.size_encoded * 512;
228                 break;
229         default:
230                 return;
231         }
232
233         eax->split.is_self_initializing = 1;
234         eax->split.type = types[leaf];
235         eax->split.level = levels[leaf];
236         if (leaf == 3)
237                 eax->split.num_threads_sharing = current_cpu_data.x86_max_cores - 1;
238         else
239                 eax->split.num_threads_sharing = 0;
240         eax->split.num_cores_on_die = current_cpu_data.x86_max_cores - 1;
241
242
243         if (assoc == 0xf)
244                 eax->split.is_fully_associative = 1;
245         ebx->split.coherency_line_size = line_size - 1;
246         ebx->split.ways_of_associativity = assocs[assoc] - 1;
247         ebx->split.physical_line_partition = lines_per_tag - 1;
248         ecx->split.number_of_sets = (size_in_kb * 1024) / line_size /
249                 (ebx->split.ways_of_associativity + 1) - 1;
250 }
251
252 static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
253 {
254         union _cpuid4_leaf_eax  eax;
255         union _cpuid4_leaf_ebx  ebx;
256         union _cpuid4_leaf_ecx  ecx;
257         unsigned                edx;
258
259         if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
260                 amd_cpuid4(index, &eax, &ebx, &ecx);
261         else
262                 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full,  &edx);
263         if (eax.split.type == CACHE_TYPE_NULL)
264                 return -EIO; /* better error ? */
265
266         this_leaf->eax = eax;
267         this_leaf->ebx = ebx;
268         this_leaf->ecx = ecx;
269         this_leaf->size = (ecx.split.number_of_sets + 1) *
270                 (ebx.split.coherency_line_size + 1) *
271                 (ebx.split.physical_line_partition + 1) *
272                 (ebx.split.ways_of_associativity + 1);
273         return 0;
274 }
275
276 static int __cpuinit find_num_cache_leaves(void)
277 {
278         unsigned int            eax, ebx, ecx, edx;
279         union _cpuid4_leaf_eax  cache_eax;
280         int                     i = -1;
281
282         do {
283                 ++i;
284                 /* Do cpuid(4) loop to find out num_cache_leaves */
285                 cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
286                 cache_eax.full = eax;
287         } while (cache_eax.split.type != CACHE_TYPE_NULL);
288         return i;
289 }
290
291 unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
292 {
293         unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
294         unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
295         unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
296         unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
297 #ifdef CONFIG_X86_HT
298         unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data);
299 #endif
300
301         if (c->cpuid_level > 3) {
302                 static int is_initialized;
303
304                 if (is_initialized == 0) {
305                         /* Init num_cache_leaves from boot CPU */
306                         num_cache_leaves = find_num_cache_leaves();
307                         is_initialized++;
308                 }
309
310                 /*
311                  * Whenever possible use cpuid(4), deterministic cache
312                  * parameters cpuid leaf to find the cache details
313                  */
314                 for (i = 0; i < num_cache_leaves; i++) {
315                         struct _cpuid4_info this_leaf;
316
317                         int retval;
318
319                         retval = cpuid4_cache_lookup(i, &this_leaf);
320                         if (retval >= 0) {
321                                 switch(this_leaf.eax.split.level) {
322                                     case 1:
323                                         if (this_leaf.eax.split.type ==
324                                                         CACHE_TYPE_DATA)
325                                                 new_l1d = this_leaf.size/1024;
326                                         else if (this_leaf.eax.split.type ==
327                                                         CACHE_TYPE_INST)
328                                                 new_l1i = this_leaf.size/1024;
329                                         break;
330                                     case 2:
331                                         new_l2 = this_leaf.size/1024;
332                                         num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
333                                         index_msb = get_count_order(num_threads_sharing);
334                                         l2_id = c->apicid >> index_msb;
335                                         break;
336                                     case 3:
337                                         new_l3 = this_leaf.size/1024;
338                                         num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
339                                         index_msb = get_count_order(num_threads_sharing);
340                                         l3_id = c->apicid >> index_msb;
341                                         break;
342                                     default:
343                                         break;
344                                 }
345                         }
346                 }
347         }
348         /*
349          * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
350          * trace cache
351          */
352         if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
353                 /* supports eax=2  call */
354                 int i, j, n;
355                 int regs[4];
356                 unsigned char *dp = (unsigned char *)regs;
357                 int only_trace = 0;
358
359                 if (num_cache_leaves != 0 && c->x86 == 15)
360                         only_trace = 1;
361
362                 /* Number of times to iterate */
363                 n = cpuid_eax(2) & 0xFF;
364
365                 for ( i = 0 ; i < n ; i++ ) {
366                         cpuid(2, &regs[0], &regs[1], &regs[2], &regs[3]);
367
368                         /* If bit 31 is set, this is an unknown format */
369                         for ( j = 0 ; j < 3 ; j++ ) {
370                                 if ( regs[j] < 0 ) regs[j] = 0;
371                         }
372
373                         /* Byte 0 is level count, not a descriptor */
374                         for ( j = 1 ; j < 16 ; j++ ) {
375                                 unsigned char des = dp[j];
376                                 unsigned char k = 0;
377
378                                 /* look up this descriptor in the table */
379                                 while (cache_table[k].descriptor != 0)
380                                 {
381                                         if (cache_table[k].descriptor == des) {
382                                                 if (only_trace && cache_table[k].cache_type != LVL_TRACE)
383                                                         break;
384                                                 switch (cache_table[k].cache_type) {
385                                                 case LVL_1_INST:
386                                                         l1i += cache_table[k].size;
387                                                         break;
388                                                 case LVL_1_DATA:
389                                                         l1d += cache_table[k].size;
390                                                         break;
391                                                 case LVL_2:
392                                                         l2 += cache_table[k].size;
393                                                         break;
394                                                 case LVL_3:
395                                                         l3 += cache_table[k].size;
396                                                         break;
397                                                 case LVL_TRACE:
398                                                         trace += cache_table[k].size;
399                                                         break;
400                                                 }
401
402                                                 break;
403                                         }
404
405                                         k++;
406                                 }
407                         }
408                 }
409         }
410
411         if (new_l1d)
412                 l1d = new_l1d;
413
414         if (new_l1i)
415                 l1i = new_l1i;
416
417         if (new_l2) {
418                 l2 = new_l2;
419 #ifdef CONFIG_X86_HT
420                 cpu_llc_id[cpu] = l2_id;
421 #endif
422         }
423
424         if (new_l3) {
425                 l3 = new_l3;
426 #ifdef CONFIG_X86_HT
427                 cpu_llc_id[cpu] = l3_id;
428 #endif
429         }
430
431         if (trace)
432                 printk (KERN_INFO "CPU: Trace cache: %dK uops", trace);
433         else if ( l1i )
434                 printk (KERN_INFO "CPU: L1 I cache: %dK", l1i);
435
436         if (l1d)
437                 printk(", L1 D cache: %dK\n", l1d);
438         else
439                 printk("\n");
440
441         if (l2)
442                 printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
443
444         if (l3)
445                 printk(KERN_INFO "CPU: L3 cache: %dK\n", l3);
446
447         c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d));
448
449         return l2;
450 }
451
452 /* pointer to _cpuid4_info array (for each cache leaf) */
453 static struct _cpuid4_info *cpuid4_info[NR_CPUS];
454 #define CPUID4_INFO_IDX(x,y)    (&((cpuid4_info[x])[y]))
455
456 #ifdef CONFIG_SMP
457 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
458 {
459         struct _cpuid4_info     *this_leaf, *sibling_leaf;
460         unsigned long num_threads_sharing;
461         int index_msb, i;
462         struct cpuinfo_x86 *c = cpu_data;
463
464         this_leaf = CPUID4_INFO_IDX(cpu, index);
465         num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
466
467         if (num_threads_sharing == 1)
468                 cpu_set(cpu, this_leaf->shared_cpu_map);
469         else {
470                 index_msb = get_count_order(num_threads_sharing);
471
472                 for_each_online_cpu(i) {
473                         if (c[i].apicid >> index_msb ==
474                             c[cpu].apicid >> index_msb) {
475                                 cpu_set(i, this_leaf->shared_cpu_map);
476                                 if (i != cpu && cpuid4_info[i])  {
477                                         sibling_leaf = CPUID4_INFO_IDX(i, index);
478                                         cpu_set(cpu, sibling_leaf->shared_cpu_map);
479                                 }
480                         }
481                 }
482         }
483 }
484 static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
485 {
486         struct _cpuid4_info     *this_leaf, *sibling_leaf;
487         int sibling;
488
489         this_leaf = CPUID4_INFO_IDX(cpu, index);
490         for_each_cpu_mask(sibling, this_leaf->shared_cpu_map) {
491                 sibling_leaf = CPUID4_INFO_IDX(sibling, index); 
492                 cpu_clear(cpu, sibling_leaf->shared_cpu_map);
493         }
494 }
495 #else
496 static void __init cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
497 static void __init cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
498 #endif
499
500 static void free_cache_attributes(unsigned int cpu)
501 {
502         kfree(cpuid4_info[cpu]);
503         cpuid4_info[cpu] = NULL;
504 }
505
506 static int __cpuinit detect_cache_attributes(unsigned int cpu)
507 {
508         struct _cpuid4_info     *this_leaf;
509         unsigned long           j;
510         int                     retval;
511         cpumask_t               oldmask;
512
513         if (num_cache_leaves == 0)
514                 return -ENOENT;
515
516         cpuid4_info[cpu] = kzalloc(
517             sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL);
518         if (cpuid4_info[cpu] == NULL)
519                 return -ENOMEM;
520
521         oldmask = current->cpus_allowed;
522         retval = set_cpus_allowed(current, cpumask_of_cpu(cpu));
523         if (retval)
524                 goto out;
525
526         /* Do cpuid and store the results */
527         retval = 0;
528         for (j = 0; j < num_cache_leaves; j++) {
529                 this_leaf = CPUID4_INFO_IDX(cpu, j);
530                 retval = cpuid4_cache_lookup(j, this_leaf);
531                 if (unlikely(retval < 0))
532                         break;
533                 cache_shared_cpu_map_setup(cpu, j);
534         }
535         set_cpus_allowed(current, oldmask);
536
537 out:
538         if (retval)
539                 free_cache_attributes(cpu);
540         return retval;
541 }
542
543 #ifdef CONFIG_SYSFS
544
545 #include <linux/kobject.h>
546 #include <linux/sysfs.h>
547
548 extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
549
550 /* pointer to kobject for cpuX/cache */
551 static struct kobject * cache_kobject[NR_CPUS];
552
553 struct _index_kobject {
554         struct kobject kobj;
555         unsigned int cpu;
556         unsigned short index;
557 };
558
559 /* pointer to array of kobjects for cpuX/cache/indexY */
560 static struct _index_kobject *index_kobject[NR_CPUS];
561 #define INDEX_KOBJECT_PTR(x,y)    (&((index_kobject[x])[y]))
562
563 #define show_one_plus(file_name, object, val)                           \
564 static ssize_t show_##file_name                                         \
565                         (struct _cpuid4_info *this_leaf, char *buf)     \
566 {                                                                       \
567         return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \
568 }
569
570 show_one_plus(level, eax.split.level, 0);
571 show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
572 show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
573 show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
574 show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
575
576 static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf)
577 {
578         return sprintf (buf, "%luK\n", this_leaf->size / 1024);
579 }
580
581 static ssize_t show_shared_cpu_map(struct _cpuid4_info *this_leaf, char *buf)
582 {
583         char mask_str[NR_CPUS];
584         cpumask_scnprintf(mask_str, NR_CPUS, this_leaf->shared_cpu_map);
585         return sprintf(buf, "%s\n", mask_str);
586 }
587
588 static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf) {
589         switch(this_leaf->eax.split.type) {
590             case CACHE_TYPE_DATA:
591                 return sprintf(buf, "Data\n");
592                 break;
593             case CACHE_TYPE_INST:
594                 return sprintf(buf, "Instruction\n");
595                 break;
596             case CACHE_TYPE_UNIFIED:
597                 return sprintf(buf, "Unified\n");
598                 break;
599             default:
600                 return sprintf(buf, "Unknown\n");
601                 break;
602         }
603 }
604
605 struct _cache_attr {
606         struct attribute attr;
607         ssize_t (*show)(struct _cpuid4_info *, char *);
608         ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count);
609 };
610
611 #define define_one_ro(_name) \
612 static struct _cache_attr _name = \
613         __ATTR(_name, 0444, show_##_name, NULL)
614
615 define_one_ro(level);
616 define_one_ro(type);
617 define_one_ro(coherency_line_size);
618 define_one_ro(physical_line_partition);
619 define_one_ro(ways_of_associativity);
620 define_one_ro(number_of_sets);
621 define_one_ro(size);
622 define_one_ro(shared_cpu_map);
623
624 static struct attribute * default_attrs[] = {
625         &type.attr,
626         &level.attr,
627         &coherency_line_size.attr,
628         &physical_line_partition.attr,
629         &ways_of_associativity.attr,
630         &number_of_sets.attr,
631         &size.attr,
632         &shared_cpu_map.attr,
633         NULL
634 };
635
636 #define to_object(k) container_of(k, struct _index_kobject, kobj)
637 #define to_attr(a) container_of(a, struct _cache_attr, attr)
638
639 static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf)
640 {
641         struct _cache_attr *fattr = to_attr(attr);
642         struct _index_kobject *this_leaf = to_object(kobj);
643         ssize_t ret;
644
645         ret = fattr->show ?
646                 fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index),
647                         buf) :
648                 0;
649         return ret;
650 }
651
652 static ssize_t store(struct kobject * kobj, struct attribute * attr,
653                      const char * buf, size_t count)
654 {
655         return 0;
656 }
657
658 static struct sysfs_ops sysfs_ops = {
659         .show   = show,
660         .store  = store,
661 };
662
663 static struct kobj_type ktype_cache = {
664         .sysfs_ops      = &sysfs_ops,
665         .default_attrs  = default_attrs,
666 };
667
668 static struct kobj_type ktype_percpu_entry = {
669         .sysfs_ops      = &sysfs_ops,
670 };
671
672 static void cpuid4_cache_sysfs_exit(unsigned int cpu)
673 {
674         kfree(cache_kobject[cpu]);
675         kfree(index_kobject[cpu]);
676         cache_kobject[cpu] = NULL;
677         index_kobject[cpu] = NULL;
678         free_cache_attributes(cpu);
679 }
680
681 static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
682 {
683
684         if (num_cache_leaves == 0)
685                 return -ENOENT;
686
687         detect_cache_attributes(cpu);
688         if (cpuid4_info[cpu] == NULL)
689                 return -ENOENT;
690
691         /* Allocate all required memory */
692         cache_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL);
693         if (unlikely(cache_kobject[cpu] == NULL))
694                 goto err_out;
695
696         index_kobject[cpu] = kzalloc(
697             sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL);
698         if (unlikely(index_kobject[cpu] == NULL))
699                 goto err_out;
700
701         return 0;
702
703 err_out:
704         cpuid4_cache_sysfs_exit(cpu);
705         return -ENOMEM;
706 }
707
708 /* Add/Remove cache interface for CPU device */
709 static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
710 {
711         unsigned int cpu = sys_dev->id;
712         unsigned long i, j;
713         struct _index_kobject *this_object;
714         int retval = 0;
715
716         retval = cpuid4_cache_sysfs_init(cpu);
717         if (unlikely(retval < 0))
718                 return retval;
719
720         cache_kobject[cpu]->parent = &sys_dev->kobj;
721         kobject_set_name(cache_kobject[cpu], "%s", "cache");
722         cache_kobject[cpu]->ktype = &ktype_percpu_entry;
723         retval = kobject_register(cache_kobject[cpu]);
724
725         for (i = 0; i < num_cache_leaves; i++) {
726                 this_object = INDEX_KOBJECT_PTR(cpu,i);
727                 this_object->cpu = cpu;
728                 this_object->index = i;
729                 this_object->kobj.parent = cache_kobject[cpu];
730                 kobject_set_name(&(this_object->kobj), "index%1lu", i);
731                 this_object->kobj.ktype = &ktype_cache;
732                 retval = kobject_register(&(this_object->kobj));
733                 if (unlikely(retval)) {
734                         for (j = 0; j < i; j++) {
735                                 kobject_unregister(
736                                         &(INDEX_KOBJECT_PTR(cpu,j)->kobj));
737                         }
738                         kobject_unregister(cache_kobject[cpu]);
739                         cpuid4_cache_sysfs_exit(cpu);
740                         break;
741                 }
742         }
743         return retval;
744 }
745
746 static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
747 {
748         unsigned int cpu = sys_dev->id;
749         unsigned long i;
750
751         if (cpuid4_info[cpu] == NULL)
752                 return;
753         for (i = 0; i < num_cache_leaves; i++) {
754                 cache_remove_shared_cpu_map(cpu, i);
755                 kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
756         }
757         kobject_unregister(cache_kobject[cpu]);
758         cpuid4_cache_sysfs_exit(cpu);
759         return;
760 }
761
762 static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
763                                         unsigned long action, void *hcpu)
764 {
765         unsigned int cpu = (unsigned long)hcpu;
766         struct sys_device *sys_dev;
767
768         sys_dev = get_cpu_sysdev(cpu);
769         switch (action) {
770         case CPU_ONLINE:
771         case CPU_ONLINE_FROZEN:
772                 cache_add_dev(sys_dev);
773                 break;
774         case CPU_DEAD:
775         case CPU_DEAD_FROZEN:
776                 cache_remove_dev(sys_dev);
777                 break;
778         }
779         return NOTIFY_OK;
780 }
781
782 static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier =
783 {
784     .notifier_call = cacheinfo_cpu_callback,
785 };
786
787 static int __cpuinit cache_sysfs_init(void)
788 {
789         int i;
790
791         if (num_cache_leaves == 0)
792                 return 0;
793
794         register_hotcpu_notifier(&cacheinfo_cpu_notifier);
795
796         for_each_online_cpu(i) {
797                 cacheinfo_cpu_callback(&cacheinfo_cpu_notifier, CPU_ONLINE,
798                         (void *)(long)i);
799         }
800
801         return 0;
802 }
803
804 device_initcall(cache_sysfs_init);
805
806 #endif