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