aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/intel_cacheinfo.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/x86/kernel/cpu/intel_cacheinfo.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'arch/x86/kernel/cpu/intel_cacheinfo.c')
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c259
1 files changed, 115 insertions, 144 deletions
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index fe9edec6698..c105c533ed9 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -151,17 +151,28 @@ union _cpuid4_leaf_ecx {
151 u32 full; 151 u32 full;
152}; 152};
153 153
154struct _cpuid4_info_regs { 154struct amd_l3_cache {
155 struct amd_northbridge *nb;
156 unsigned indices;
157 u8 subcaches[4];
158};
159
160struct _cpuid4_info {
155 union _cpuid4_leaf_eax eax; 161 union _cpuid4_leaf_eax eax;
156 union _cpuid4_leaf_ebx ebx; 162 union _cpuid4_leaf_ebx ebx;
157 union _cpuid4_leaf_ecx ecx; 163 union _cpuid4_leaf_ecx ecx;
158 unsigned long size; 164 unsigned long size;
159 struct amd_northbridge *nb; 165 struct amd_l3_cache *l3;
166 DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
160}; 167};
161 168
162struct _cpuid4_info { 169/* subset of above _cpuid4_info w/o shared_cpu_map */
163 struct _cpuid4_info_regs base; 170struct _cpuid4_info_regs {
164 DECLARE_BITMAP(shared_cpu_map, NR_CPUS); 171 union _cpuid4_leaf_eax eax;
172 union _cpuid4_leaf_ebx ebx;
173 union _cpuid4_leaf_ecx ecx;
174 unsigned long size;
175 struct amd_l3_cache *l3;
165}; 176};
166 177
167unsigned short num_cache_leaves; 178unsigned short num_cache_leaves;
@@ -303,41 +314,52 @@ struct _cache_attr {
303/* 314/*
304 * L3 cache descriptors 315 * L3 cache descriptors
305 */ 316 */
306static void __cpuinit amd_calc_l3_indices(struct amd_northbridge *nb) 317static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3)
307{ 318{
308 struct amd_l3_cache *l3 = &nb->l3_cache;
309 unsigned int sc0, sc1, sc2, sc3; 319 unsigned int sc0, sc1, sc2, sc3;
310 u32 val = 0; 320 u32 val = 0;
311 321
312 pci_read_config_dword(nb->misc, 0x1C4, &val); 322 pci_read_config_dword(l3->nb->misc, 0x1C4, &val);
313 323
314 /* calculate subcache sizes */ 324 /* calculate subcache sizes */
315 l3->subcaches[0] = sc0 = !(val & BIT(0)); 325 l3->subcaches[0] = sc0 = !(val & BIT(0));
316 l3->subcaches[1] = sc1 = !(val & BIT(4)); 326 l3->subcaches[1] = sc1 = !(val & BIT(4));
317
318 if (boot_cpu_data.x86 == 0x15) {
319 l3->subcaches[0] = sc0 += !(val & BIT(1));
320 l3->subcaches[1] = sc1 += !(val & BIT(5));
321 }
322
323 l3->subcaches[2] = sc2 = !(val & BIT(8)) + !(val & BIT(9)); 327 l3->subcaches[2] = sc2 = !(val & BIT(8)) + !(val & BIT(9));
324 l3->subcaches[3] = sc3 = !(val & BIT(12)) + !(val & BIT(13)); 328 l3->subcaches[3] = sc3 = !(val & BIT(12)) + !(val & BIT(13));
325 329
326 l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1; 330 l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1;
327} 331}
328 332
329static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index) 333static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf,
334 int index)
330{ 335{
336 static struct amd_l3_cache *__cpuinitdata l3_caches;
331 int node; 337 int node;
332 338
333 /* only for L3, and not in virtualized environments */ 339 /* only for L3, and not in virtualized environments */
334 if (index < 3) 340 if (index < 3 || amd_nb_num() == 0)
335 return; 341 return;
336 342
343 /*
344 * Strictly speaking, the amount in @size below is leaked since it is
345 * never freed but this is done only on shutdown so it doesn't matter.
346 */
347 if (!l3_caches) {
348 int size = amd_nb_num() * sizeof(struct amd_l3_cache);
349
350 l3_caches = kzalloc(size, GFP_ATOMIC);
351 if (!l3_caches)
352 return;
353 }
354
337 node = amd_get_nb_id(smp_processor_id()); 355 node = amd_get_nb_id(smp_processor_id());
338 this_leaf->nb = node_to_amd_nb(node); 356
339 if (this_leaf->nb && !this_leaf->nb->l3_cache.indices) 357 if (!l3_caches[node].nb) {
340 amd_calc_l3_indices(this_leaf->nb); 358 l3_caches[node].nb = node_to_amd_nb(node);
359 amd_calc_l3_indices(&l3_caches[node]);
360 }
361
362 this_leaf->l3 = &l3_caches[node];
341} 363}
342 364
343/* 365/*
@@ -347,11 +369,11 @@ static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int
347 * 369 *
348 * @returns: the disabled index if used or negative value if slot free. 370 * @returns: the disabled index if used or negative value if slot free.
349 */ 371 */
350int amd_get_l3_disable_slot(struct amd_northbridge *nb, unsigned slot) 372int amd_get_l3_disable_slot(struct amd_l3_cache *l3, unsigned slot)
351{ 373{
352 unsigned int reg = 0; 374 unsigned int reg = 0;
353 375
354 pci_read_config_dword(nb->misc, 0x1BC + slot * 4, &reg); 376 pci_read_config_dword(l3->nb->misc, 0x1BC + slot * 4, &reg);
355 377
356 /* check whether this slot is activated already */ 378 /* check whether this slot is activated already */
357 if (reg & (3UL << 30)) 379 if (reg & (3UL << 30))
@@ -365,10 +387,11 @@ static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
365{ 387{
366 int index; 388 int index;
367 389
368 if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) 390 if (!this_leaf->l3 ||
391 !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE))
369 return -EINVAL; 392 return -EINVAL;
370 393
371 index = amd_get_l3_disable_slot(this_leaf->base.nb, slot); 394 index = amd_get_l3_disable_slot(this_leaf->l3, slot);
372 if (index >= 0) 395 if (index >= 0)
373 return sprintf(buf, "%d\n", index); 396 return sprintf(buf, "%d\n", index);
374 397
@@ -385,7 +408,7 @@ show_cache_disable_##slot(struct _cpuid4_info *this_leaf, char *buf, \
385SHOW_CACHE_DISABLE(0) 408SHOW_CACHE_DISABLE(0)
386SHOW_CACHE_DISABLE(1) 409SHOW_CACHE_DISABLE(1)
387 410
388static void amd_l3_disable_index(struct amd_northbridge *nb, int cpu, 411static void amd_l3_disable_index(struct amd_l3_cache *l3, int cpu,
389 unsigned slot, unsigned long idx) 412 unsigned slot, unsigned long idx)
390{ 413{
391 int i; 414 int i;
@@ -398,10 +421,10 @@ static void amd_l3_disable_index(struct amd_northbridge *nb, int cpu,
398 for (i = 0; i < 4; i++) { 421 for (i = 0; i < 4; i++) {
399 u32 reg = idx | (i << 20); 422 u32 reg = idx | (i << 20);
400 423
401 if (!nb->l3_cache.subcaches[i]) 424 if (!l3->subcaches[i])
402 continue; 425 continue;
403 426
404 pci_write_config_dword(nb->misc, 0x1BC + slot * 4, reg); 427 pci_write_config_dword(l3->nb->misc, 0x1BC + slot * 4, reg);
405 428
406 /* 429 /*
407 * We need to WBINVD on a core on the node containing the L3 430 * We need to WBINVD on a core on the node containing the L3
@@ -411,7 +434,7 @@ static void amd_l3_disable_index(struct amd_northbridge *nb, int cpu,
411 wbinvd_on_cpu(cpu); 434 wbinvd_on_cpu(cpu);
412 435
413 reg |= BIT(31); 436 reg |= BIT(31);
414 pci_write_config_dword(nb->misc, 0x1BC + slot * 4, reg); 437 pci_write_config_dword(l3->nb->misc, 0x1BC + slot * 4, reg);
415 } 438 }
416} 439}
417 440
@@ -425,24 +448,24 @@ static void amd_l3_disable_index(struct amd_northbridge *nb, int cpu,
425 * 448 *
426 * @return: 0 on success, error status on failure 449 * @return: 0 on success, error status on failure
427 */ 450 */
428int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, unsigned slot, 451int amd_set_l3_disable_slot(struct amd_l3_cache *l3, int cpu, unsigned slot,
429 unsigned long index) 452 unsigned long index)
430{ 453{
431 int ret = 0; 454 int ret = 0;
432 455
433 /* check if @slot is already used or the index is already disabled */ 456 /* check if @slot is already used or the index is already disabled */
434 ret = amd_get_l3_disable_slot(nb, slot); 457 ret = amd_get_l3_disable_slot(l3, slot);
435 if (ret >= 0) 458 if (ret >= 0)
436 return -EEXIST; 459 return -EINVAL;
437 460
438 if (index > nb->l3_cache.indices) 461 if (index > l3->indices)
439 return -EINVAL; 462 return -EINVAL;
440 463
441 /* check whether the other slot has disabled the same index already */ 464 /* check whether the other slot has disabled the same index already */
442 if (index == amd_get_l3_disable_slot(nb, !slot)) 465 if (index == amd_get_l3_disable_slot(l3, !slot))
443 return -EEXIST; 466 return -EINVAL;
444 467
445 amd_l3_disable_index(nb, cpu, slot, index); 468 amd_l3_disable_index(l3, cpu, slot, index);
446 469
447 return 0; 470 return 0;
448} 471}
@@ -457,7 +480,8 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
457 if (!capable(CAP_SYS_ADMIN)) 480 if (!capable(CAP_SYS_ADMIN))
458 return -EPERM; 481 return -EPERM;
459 482
460 if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) 483 if (!this_leaf->l3 ||
484 !amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE))
461 return -EINVAL; 485 return -EINVAL;
462 486
463 cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); 487 cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
@@ -465,11 +489,11 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
465 if (strict_strtoul(buf, 10, &val) < 0) 489 if (strict_strtoul(buf, 10, &val) < 0)
466 return -EINVAL; 490 return -EINVAL;
467 491
468 err = amd_set_l3_disable_slot(this_leaf->base.nb, cpu, slot, val); 492 err = amd_set_l3_disable_slot(this_leaf->l3, cpu, slot, val);
469 if (err) { 493 if (err) {
470 if (err == -EEXIST) 494 if (err == -EEXIST)
471 pr_warning("L3 slot %d in use/index already disabled!\n", 495 printk(KERN_WARNING "L3 disable slot %d in use!\n",
472 slot); 496 slot);
473 return err; 497 return err;
474 } 498 }
475 return count; 499 return count;
@@ -494,7 +518,7 @@ static struct _cache_attr cache_disable_1 = __ATTR(cache_disable_1, 0644,
494static ssize_t 518static ssize_t
495show_subcaches(struct _cpuid4_info *this_leaf, char *buf, unsigned int cpu) 519show_subcaches(struct _cpuid4_info *this_leaf, char *buf, unsigned int cpu)
496{ 520{
497 if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) 521 if (!this_leaf->l3 || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
498 return -EINVAL; 522 return -EINVAL;
499 523
500 return sprintf(buf, "%x\n", amd_get_subcaches(cpu)); 524 return sprintf(buf, "%x\n", amd_get_subcaches(cpu));
@@ -509,7 +533,7 @@ store_subcaches(struct _cpuid4_info *this_leaf, const char *buf, size_t count,
509 if (!capable(CAP_SYS_ADMIN)) 533 if (!capable(CAP_SYS_ADMIN))
510 return -EPERM; 534 return -EPERM;
511 535
512 if (!this_leaf->base.nb || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) 536 if (!this_leaf->l3 || !amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
513 return -EINVAL; 537 return -EINVAL;
514 538
515 if (strict_strtoul(buf, 16, &val) < 0) 539 if (strict_strtoul(buf, 16, &val) < 0)
@@ -538,11 +562,7 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
538 unsigned edx; 562 unsigned edx;
539 563
540 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { 564 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
541 if (cpu_has_topoext) 565 amd_cpuid4(index, &eax, &ebx, &ecx);
542 cpuid_count(0x8000001d, index, &eax.full,
543 &ebx.full, &ecx.full, &edx);
544 else
545 amd_cpuid4(index, &eax, &ebx, &ecx);
546 amd_init_l3_cache(this_leaf, index); 566 amd_init_l3_cache(this_leaf, index);
547 } else { 567 } else {
548 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); 568 cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
@@ -561,39 +581,21 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
561 return 0; 581 return 0;
562} 582}
563 583
564static int __cpuinit find_num_cache_leaves(struct cpuinfo_x86 *c) 584static int __cpuinit find_num_cache_leaves(void)
565{ 585{
566 unsigned int eax, ebx, ecx, edx, op; 586 unsigned int eax, ebx, ecx, edx;
567 union _cpuid4_leaf_eax cache_eax; 587 union _cpuid4_leaf_eax cache_eax;
568 int i = -1; 588 int i = -1;
569 589
570 if (c->x86_vendor == X86_VENDOR_AMD)
571 op = 0x8000001d;
572 else
573 op = 4;
574
575 do { 590 do {
576 ++i; 591 ++i;
577 /* Do cpuid(op) loop to find out num_cache_leaves */ 592 /* Do cpuid(4) loop to find out num_cache_leaves */
578 cpuid_count(op, i, &eax, &ebx, &ecx, &edx); 593 cpuid_count(4, i, &eax, &ebx, &ecx, &edx);
579 cache_eax.full = eax; 594 cache_eax.full = eax;
580 } while (cache_eax.split.type != CACHE_TYPE_NULL); 595 } while (cache_eax.split.type != CACHE_TYPE_NULL);
581 return i; 596 return i;
582} 597}
583 598
584void __cpuinit init_amd_cacheinfo(struct cpuinfo_x86 *c)
585{
586
587 if (cpu_has_topoext) {
588 num_cache_leaves = find_num_cache_leaves(c);
589 } else if (c->extended_cpuid_level >= 0x80000006) {
590 if (cpuid_edx(0x80000006) & 0xf000)
591 num_cache_leaves = 4;
592 else
593 num_cache_leaves = 3;
594 }
595}
596
597unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) 599unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
598{ 600{
599 /* Cache sizes */ 601 /* Cache sizes */
@@ -610,7 +612,7 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
610 612
611 if (is_initialized == 0) { 613 if (is_initialized == 0) {
612 /* Init num_cache_leaves from boot CPU */ 614 /* Init num_cache_leaves from boot CPU */
613 num_cache_leaves = find_num_cache_leaves(c); 615 num_cache_leaves = find_num_cache_leaves();
614 is_initialized++; 616 is_initialized++;
615 } 617 }
616 618
@@ -637,14 +639,14 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
637 new_l2 = this_leaf.size/1024; 639 new_l2 = this_leaf.size/1024;
638 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; 640 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
639 index_msb = get_count_order(num_threads_sharing); 641 index_msb = get_count_order(num_threads_sharing);
640 l2_id = c->apicid & ~((1 << index_msb) - 1); 642 l2_id = c->apicid >> index_msb;
641 break; 643 break;
642 case 3: 644 case 3:
643 new_l3 = this_leaf.size/1024; 645 new_l3 = this_leaf.size/1024;
644 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; 646 num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing;
645 index_msb = get_count_order( 647 index_msb = get_count_order(
646 num_threads_sharing); 648 num_threads_sharing);
647 l3_id = c->apicid & ~((1 << index_msb) - 1); 649 l3_id = c->apicid >> index_msb;
648 break; 650 break;
649 default: 651 default:
650 break; 652 break;
@@ -746,40 +748,14 @@ static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);
746#define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y])) 748#define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y]))
747 749
748#ifdef CONFIG_SMP 750#ifdef CONFIG_SMP
749 751static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
750static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index)
751{ 752{
752 struct _cpuid4_info *this_leaf; 753 struct _cpuid4_info *this_leaf, *sibling_leaf;
753 int i, sibling; 754 unsigned long num_threads_sharing;
754 755 int index_msb, i, sibling;
755 if (cpu_has_topoext) { 756 struct cpuinfo_x86 *c = &cpu_data(cpu);
756 unsigned int apicid, nshared, first, last;
757
758 if (!per_cpu(ici_cpuid4_info, cpu))
759 return 0;
760
761 this_leaf = CPUID4_INFO_IDX(cpu, index);
762 nshared = this_leaf->base.eax.split.num_threads_sharing + 1;
763 apicid = cpu_data(cpu).apicid;
764 first = apicid - (apicid % nshared);
765 last = first + nshared - 1;
766
767 for_each_online_cpu(i) {
768 apicid = cpu_data(i).apicid;
769 if ((apicid < first) || (apicid > last))
770 continue;
771 if (!per_cpu(ici_cpuid4_info, i))
772 continue;
773 this_leaf = CPUID4_INFO_IDX(i, index);
774 757
775 for_each_online_cpu(sibling) { 758 if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
776 apicid = cpu_data(sibling).apicid;
777 if ((apicid < first) || (apicid > last))
778 continue;
779 set_bit(sibling, this_leaf->shared_cpu_map);
780 }
781 }
782 } else if (index == 3) {
783 for_each_cpu(i, cpu_llc_shared_mask(cpu)) { 759 for_each_cpu(i, cpu_llc_shared_mask(cpu)) {
784 if (!per_cpu(ici_cpuid4_info, i)) 760 if (!per_cpu(ici_cpuid4_info, i))
785 continue; 761 continue;
@@ -790,26 +766,10 @@ static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index)
790 set_bit(sibling, this_leaf->shared_cpu_map); 766 set_bit(sibling, this_leaf->shared_cpu_map);
791 } 767 }
792 } 768 }
793 } else 769 return;
794 return 0;
795
796 return 1;
797}
798
799static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
800{
801 struct _cpuid4_info *this_leaf, *sibling_leaf;
802 unsigned long num_threads_sharing;
803 int index_msb, i;
804 struct cpuinfo_x86 *c = &cpu_data(cpu);
805
806 if (c->x86_vendor == X86_VENDOR_AMD) {
807 if (cache_shared_amd_cpu_map_setup(cpu, index))
808 return;
809 } 770 }
810
811 this_leaf = CPUID4_INFO_IDX(cpu, index); 771 this_leaf = CPUID4_INFO_IDX(cpu, index);
812 num_threads_sharing = 1 + this_leaf->base.eax.split.num_threads_sharing; 772 num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
813 773
814 if (num_threads_sharing == 1) 774 if (num_threads_sharing == 1)
815 cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map)); 775 cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map));
@@ -860,19 +820,29 @@ static void __cpuinit free_cache_attributes(unsigned int cpu)
860 for (i = 0; i < num_cache_leaves; i++) 820 for (i = 0; i < num_cache_leaves; i++)
861 cache_remove_shared_cpu_map(cpu, i); 821 cache_remove_shared_cpu_map(cpu, i);
862 822
823 kfree(per_cpu(ici_cpuid4_info, cpu)->l3);
863 kfree(per_cpu(ici_cpuid4_info, cpu)); 824 kfree(per_cpu(ici_cpuid4_info, cpu));
864 per_cpu(ici_cpuid4_info, cpu) = NULL; 825 per_cpu(ici_cpuid4_info, cpu) = NULL;
865} 826}
866 827
828static int
829__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
830{
831 struct _cpuid4_info_regs *leaf_regs =
832 (struct _cpuid4_info_regs *)this_leaf;
833
834 return cpuid4_cache_lookup_regs(index, leaf_regs);
835}
836
867static void __cpuinit get_cpu_leaves(void *_retval) 837static void __cpuinit get_cpu_leaves(void *_retval)
868{ 838{
869 int j, *retval = _retval, cpu = smp_processor_id(); 839 int j, *retval = _retval, cpu = smp_processor_id();
870 840
871 /* Do cpuid and store the results */ 841 /* Do cpuid and store the results */
872 for (j = 0; j < num_cache_leaves; j++) { 842 for (j = 0; j < num_cache_leaves; j++) {
873 struct _cpuid4_info *this_leaf = CPUID4_INFO_IDX(cpu, j); 843 struct _cpuid4_info *this_leaf;
874 844 this_leaf = CPUID4_INFO_IDX(cpu, j);
875 *retval = cpuid4_cache_lookup_regs(j, &this_leaf->base); 845 *retval = cpuid4_cache_lookup(j, this_leaf);
876 if (unlikely(*retval < 0)) { 846 if (unlikely(*retval < 0)) {
877 int i; 847 int i;
878 848
@@ -907,7 +877,8 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu)
907 877
908#include <linux/kobject.h> 878#include <linux/kobject.h>
909#include <linux/sysfs.h> 879#include <linux/sysfs.h>
910#include <linux/cpu.h> 880
881extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */
911 882
912/* pointer to kobject for cpuX/cache */ 883/* pointer to kobject for cpuX/cache */
913static DEFINE_PER_CPU(struct kobject *, ici_cache_kobject); 884static DEFINE_PER_CPU(struct kobject *, ici_cache_kobject);
@@ -929,16 +900,16 @@ static ssize_t show_##file_name(struct _cpuid4_info *this_leaf, char *buf, \
929 return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \ 900 return sprintf(buf, "%lu\n", (unsigned long)this_leaf->object + val); \
930} 901}
931 902
932show_one_plus(level, base.eax.split.level, 0); 903show_one_plus(level, eax.split.level, 0);
933show_one_plus(coherency_line_size, base.ebx.split.coherency_line_size, 1); 904show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1);
934show_one_plus(physical_line_partition, base.ebx.split.physical_line_partition, 1); 905show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1);
935show_one_plus(ways_of_associativity, base.ebx.split.ways_of_associativity, 1); 906show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1);
936show_one_plus(number_of_sets, base.ecx.split.number_of_sets, 1); 907show_one_plus(number_of_sets, ecx.split.number_of_sets, 1);
937 908
938static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf, 909static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf,
939 unsigned int cpu) 910 unsigned int cpu)
940{ 911{
941 return sprintf(buf, "%luK\n", this_leaf->base.size / 1024); 912 return sprintf(buf, "%luK\n", this_leaf->size / 1024);
942} 913}
943 914
944static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf, 915static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
@@ -975,7 +946,7 @@ static inline ssize_t show_shared_cpu_list(struct _cpuid4_info *leaf, char *buf,
975static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf, 946static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf,
976 unsigned int cpu) 947 unsigned int cpu)
977{ 948{
978 switch (this_leaf->base.eax.split.type) { 949 switch (this_leaf->eax.split.type) {
979 case CACHE_TYPE_DATA: 950 case CACHE_TYPE_DATA:
980 return sprintf(buf, "Data\n"); 951 return sprintf(buf, "Data\n");
981 case CACHE_TYPE_INST: 952 case CACHE_TYPE_INST:
@@ -1026,7 +997,7 @@ static struct attribute ** __cpuinit amd_l3_attrs(void)
1026 if (attrs) 997 if (attrs)
1027 return attrs; 998 return attrs;
1028 999
1029 n = ARRAY_SIZE(default_attrs); 1000 n = sizeof (default_attrs) / sizeof (struct attribute *);
1030 1001
1031 if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE)) 1002 if (amd_nb_has_feature(AMD_NB_L3_INDEX_DISABLE))
1032 n += 2; 1003 n += 2;
@@ -1135,9 +1106,9 @@ err_out:
1135static DECLARE_BITMAP(cache_dev_map, NR_CPUS); 1106static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
1136 1107
1137/* Add/Remove cache interface for CPU device */ 1108/* Add/Remove cache interface for CPU device */
1138static int __cpuinit cache_add_dev(struct device *dev) 1109static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
1139{ 1110{
1140 unsigned int cpu = dev->id; 1111 unsigned int cpu = sys_dev->id;
1141 unsigned long i, j; 1112 unsigned long i, j;
1142 struct _index_kobject *this_object; 1113 struct _index_kobject *this_object;
1143 struct _cpuid4_info *this_leaf; 1114 struct _cpuid4_info *this_leaf;
@@ -1149,7 +1120,7 @@ static int __cpuinit cache_add_dev(struct device *dev)
1149 1120
1150 retval = kobject_init_and_add(per_cpu(ici_cache_kobject, cpu), 1121 retval = kobject_init_and_add(per_cpu(ici_cache_kobject, cpu),
1151 &ktype_percpu_entry, 1122 &ktype_percpu_entry,
1152 &dev->kobj, "%s", "cache"); 1123 &sys_dev->kobj, "%s", "cache");
1153 if (retval < 0) { 1124 if (retval < 0) {
1154 cpuid4_cache_sysfs_exit(cpu); 1125 cpuid4_cache_sysfs_exit(cpu);
1155 return retval; 1126 return retval;
@@ -1164,7 +1135,7 @@ static int __cpuinit cache_add_dev(struct device *dev)
1164 1135
1165 ktype_cache.default_attrs = default_attrs; 1136 ktype_cache.default_attrs = default_attrs;
1166#ifdef CONFIG_AMD_NB 1137#ifdef CONFIG_AMD_NB
1167 if (this_leaf->base.nb) 1138 if (this_leaf->l3)
1168 ktype_cache.default_attrs = amd_l3_attrs(); 1139 ktype_cache.default_attrs = amd_l3_attrs();
1169#endif 1140#endif
1170 retval = kobject_init_and_add(&(this_object->kobj), 1141 retval = kobject_init_and_add(&(this_object->kobj),
@@ -1186,9 +1157,9 @@ static int __cpuinit cache_add_dev(struct device *dev)
1186 return 0; 1157 return 0;
1187} 1158}
1188 1159
1189static void __cpuinit cache_remove_dev(struct device *dev) 1160static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
1190{ 1161{
1191 unsigned int cpu = dev->id; 1162 unsigned int cpu = sys_dev->id;
1192 unsigned long i; 1163 unsigned long i;
1193 1164
1194 if (per_cpu(ici_cpuid4_info, cpu) == NULL) 1165 if (per_cpu(ici_cpuid4_info, cpu) == NULL)
@@ -1207,17 +1178,17 @@ static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
1207 unsigned long action, void *hcpu) 1178 unsigned long action, void *hcpu)
1208{ 1179{
1209 unsigned int cpu = (unsigned long)hcpu; 1180 unsigned int cpu = (unsigned long)hcpu;
1210 struct device *dev; 1181 struct sys_device *sys_dev;
1211 1182
1212 dev = get_cpu_device(cpu); 1183 sys_dev = get_cpu_sysdev(cpu);
1213 switch (action) { 1184 switch (action) {
1214 case CPU_ONLINE: 1185 case CPU_ONLINE:
1215 case CPU_ONLINE_FROZEN: 1186 case CPU_ONLINE_FROZEN:
1216 cache_add_dev(dev); 1187 cache_add_dev(sys_dev);
1217 break; 1188 break;
1218 case CPU_DEAD: 1189 case CPU_DEAD:
1219 case CPU_DEAD_FROZEN: 1190 case CPU_DEAD_FROZEN:
1220 cache_remove_dev(dev); 1191 cache_remove_dev(sys_dev);
1221 break; 1192 break;
1222 } 1193 }
1223 return NOTIFY_OK; 1194 return NOTIFY_OK;
@@ -1236,9 +1207,9 @@ static int __cpuinit cache_sysfs_init(void)
1236 1207
1237 for_each_online_cpu(i) { 1208 for_each_online_cpu(i) {
1238 int err; 1209 int err;
1239 struct device *dev = get_cpu_device(i); 1210 struct sys_device *sys_dev = get_cpu_sysdev(i);
1240 1211
1241 err = cache_add_dev(dev); 1212 err = cache_add_dev(sys_dev);
1242 if (err) 1213 if (err)
1243 return err; 1214 return err;
1244 } 1215 }