diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-21 07:34:21 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-28 10:17:47 -0400 |
commit | 7a4983bb5f94f6521aa3236fe5c035cf9bef543f (patch) | |
tree | e59ffae31d197e007b8a3755dd47b453a558b644 /arch/x86/kernel/cpu/intel_cacheinfo.c | |
parent | 8cb22bcb1f3ef70d4d48092e9b057175ad9ec78d (diff) |
x86: L3 cache index disable for 2.6.26, cleanups
No change in functionality.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/cpu/intel_cacheinfo.c')
-rw-r--r-- | arch/x86/kernel/cpu/intel_cacheinfo.c | 115 |
1 files changed, 61 insertions, 54 deletions
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index d6ea50e270e0..a61c9e399ba9 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
@@ -253,14 +253,16 @@ static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, | |||
253 | (ebx->split.ways_of_associativity + 1) - 1; | 253 | (ebx->split.ways_of_associativity + 1) - 1; |
254 | } | 254 | } |
255 | 255 | ||
256 | static void __cpuinit amd_check_l3_disable(int index, struct _cpuid4_info *this_leaf) | 256 | static void __cpuinit |
257 | amd_check_l3_disable(int index, struct _cpuid4_info *this_leaf) | ||
257 | { | 258 | { |
258 | if (index < 3) | 259 | if (index < 3) |
259 | return; | 260 | return; |
260 | this_leaf->can_disable = 1; | 261 | this_leaf->can_disable = 1; |
261 | } | 262 | } |
262 | 263 | ||
263 | static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) | 264 | static int |
265 | __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) | ||
264 | { | 266 | { |
265 | union _cpuid4_leaf_eax eax; | 267 | union _cpuid4_leaf_eax eax; |
266 | union _cpuid4_leaf_ebx ebx; | 268 | union _cpuid4_leaf_ebx ebx; |
@@ -271,19 +273,20 @@ static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_le | |||
271 | amd_cpuid4(index, &eax, &ebx, &ecx); | 273 | amd_cpuid4(index, &eax, &ebx, &ecx); |
272 | if (boot_cpu_data.x86 >= 0x10) | 274 | if (boot_cpu_data.x86 >= 0x10) |
273 | amd_check_l3_disable(index, this_leaf); | 275 | amd_check_l3_disable(index, this_leaf); |
274 | 276 | } else { | |
275 | } else | 277 | cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); |
276 | cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); | 278 | } |
279 | |||
277 | if (eax.split.type == CACHE_TYPE_NULL) | 280 | if (eax.split.type == CACHE_TYPE_NULL) |
278 | return -EIO; /* better error ? */ | 281 | return -EIO; /* better error ? */ |
279 | 282 | ||
280 | this_leaf->eax = eax; | 283 | this_leaf->eax = eax; |
281 | this_leaf->ebx = ebx; | 284 | this_leaf->ebx = ebx; |
282 | this_leaf->ecx = ecx; | 285 | this_leaf->ecx = ecx; |
283 | this_leaf->size = (ecx.split.number_of_sets + 1) * | 286 | this_leaf->size = (ecx.split.number_of_sets + 1) * |
284 | (ebx.split.coherency_line_size + 1) * | 287 | (ebx.split.coherency_line_size + 1) * |
285 | (ebx.split.physical_line_partition + 1) * | 288 | (ebx.split.physical_line_partition + 1) * |
286 | (ebx.split.ways_of_associativity + 1); | 289 | (ebx.split.ways_of_associativity + 1); |
287 | return 0; | 290 | return 0; |
288 | } | 291 | } |
289 | 292 | ||
@@ -649,59 +652,63 @@ static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf) { | |||
649 | } | 652 | } |
650 | } | 653 | } |
651 | 654 | ||
652 | #define to_object(k) container_of(k, struct _index_kobject, kobj) | 655 | #define to_object(k) container_of(k, struct _index_kobject, kobj) |
653 | #define to_attr(a) container_of(a, struct _cache_attr, attr) | 656 | #define to_attr(a) container_of(a, struct _cache_attr, attr) |
654 | 657 | ||
655 | static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf) | 658 | static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf) |
656 | { | 659 | { |
657 | struct pci_dev *dev; | 660 | int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map)); |
658 | if (this_leaf->can_disable) { | 661 | struct pci_dev *dev = k8_northbridges[node]; |
659 | int i; | 662 | ssize_t ret = 0; |
660 | ssize_t ret = 0; | 663 | int i; |
661 | int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map)); | ||
662 | dev = k8_northbridges[node]; | ||
663 | |||
664 | for (i = 0; i < 2; i++) { | ||
665 | unsigned int reg; | ||
666 | pci_read_config_dword(dev, 0x1BC + i * 4, ®); | ||
667 | ret += sprintf(buf, "%sEntry: %d\n", buf, i); | ||
668 | ret += sprintf(buf, "%sReads: %s\tNew Entries: %s\n", | ||
669 | buf, | ||
670 | reg & 0x80000000 ? "Disabled" : "Allowed", | ||
671 | reg & 0x40000000 ? "Disabled" : "Allowed"); | ||
672 | ret += sprintf(buf, "%sSubCache: %x\tIndex: %x\n", buf, | ||
673 | (reg & 0x30000) >> 16, reg & 0xfff); | ||
674 | 664 | ||
675 | } | 665 | if (!this_leaf->can_disable) |
676 | return ret; | 666 | return sprintf(buf, "Feature not enabled\n"); |
667 | |||
668 | for (i = 0; i < 2; i++) { | ||
669 | unsigned int reg; | ||
670 | |||
671 | pci_read_config_dword(dev, 0x1BC + i * 4, ®); | ||
672 | |||
673 | ret += sprintf(buf, "%sEntry: %d\n", buf, i); | ||
674 | ret += sprintf(buf, "%sReads: %s\tNew Entries: %s\n", | ||
675 | buf, | ||
676 | reg & 0x80000000 ? "Disabled" : "Allowed", | ||
677 | reg & 0x40000000 ? "Disabled" : "Allowed"); | ||
678 | ret += sprintf(buf, "%sSubCache: %x\tIndex: %x\n", | ||
679 | buf, (reg & 0x30000) >> 16, reg & 0xfff); | ||
677 | } | 680 | } |
678 | return sprintf(buf, "Feature not enabled\n"); | 681 | return ret; |
679 | } | 682 | } |
680 | 683 | ||
681 | static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf, size_t count) | 684 | static ssize_t |
685 | store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf, | ||
686 | size_t count) | ||
682 | { | 687 | { |
683 | struct pci_dev *dev; | 688 | int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map)); |
684 | if (this_leaf->can_disable) { | 689 | struct pci_dev *dev = k8_northbridges[node]; |
685 | /* write the MSR value */ | 690 | unsigned int ret, index, val; |
686 | unsigned int ret; | 691 | |
687 | unsigned int index, val; | 692 | if (!this_leaf->can_disable) |
688 | int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map)); | 693 | return 0; |
689 | dev = k8_northbridges[node]; | 694 | |
690 | 695 | /* write the MSR value */ | |
691 | if (strlen(buf) > 15) | 696 | |
692 | return -EINVAL; | 697 | if (strlen(buf) > 15) |
693 | ret = sscanf(buf, "%x %x", &index, &val); | 698 | return -EINVAL; |
694 | if (ret != 2) | 699 | |
695 | return -EINVAL; | 700 | ret = sscanf(buf, "%x %x", &index, &val); |
696 | if (index > 1) | 701 | if (ret != 2) |
697 | return -EINVAL; | 702 | return -EINVAL; |
698 | val |= 0xc0000000; | 703 | if (index > 1) |
699 | pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000); | 704 | return -EINVAL; |
700 | wbinvd(); | 705 | |
701 | pci_write_config_dword(dev, 0x1BC + index * 4, val); | 706 | val |= 0xc0000000; |
702 | return 1; | 707 | pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000); |
703 | } | 708 | wbinvd(); |
704 | return 0; | 709 | pci_write_config_dword(dev, 0x1BC + index * 4, val); |
710 | |||
711 | return 1; | ||
705 | } | 712 | } |
706 | 713 | ||
707 | struct _cache_attr { | 714 | struct _cache_attr { |