aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/setup.c
diff options
context:
space:
mode:
authorZoltan Menyhart <Zoltan.Menyhart@bull.net>2005-06-03 08:36:00 -0400
committerTony Luck <tony.luck@intel.com>2005-07-12 18:33:18 -0400
commit08357f82d4decc48bbfd39ae30d5fe0754f7f576 (patch)
treec8516a8f208e1cb253bd33f41857b0699104b130 /arch/ia64/kernel/setup.c
parent60a762b6a6dec17cc4339b60154902fd04c2f9f2 (diff)
[IA64] improve flush_icache_range()
Check with PAL to see what the i-cache line size is for each level of the cache, and so use the correct stride when flushing the cache. Acked-by: David Mosberger Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/kernel/setup.c')
-rw-r--r--arch/ia64/kernel/setup.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 2693e1522d7c..7fc891aca446 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -20,6 +20,7 @@
20 * 02/01/00 R.Seth fixed get_cpuinfo for SMP 20 * 02/01/00 R.Seth fixed get_cpuinfo for SMP
21 * 01/07/99 S.Eranian added the support for command line argument 21 * 01/07/99 S.Eranian added the support for command line argument
22 * 06/24/99 W.Drummond added boot_cpu_data. 22 * 06/24/99 W.Drummond added boot_cpu_data.
23 * 05/28/05 Z. Menyhart Dynamic stride size for "flush_icache_range()"
23 */ 24 */
24#include <linux/config.h> 25#include <linux/config.h>
25#include <linux/module.h> 26#include <linux/module.h>
@@ -83,6 +84,13 @@ EXPORT_SYMBOL(io_space);
83unsigned int num_io_spaces; 84unsigned int num_io_spaces;
84 85
85/* 86/*
87 * "flush_icache_range()" needs to know what processor dependent stride size to use
88 * when it makes i-cache(s) coherent with d-caches.
89 */
90#define I_CACHE_STRIDE_SHIFT 5 /* Safest way to go: 32 bytes by 32 bytes */
91unsigned long ia64_i_cache_stride_shift = ~0;
92
93/*
86 * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1). This 94 * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1). This
87 * mask specifies a mask of address bits that must be 0 in order for two buffers to be 95 * mask specifies a mask of address bits that must be 0 in order for two buffers to be
88 * mergeable by the I/O MMU (i.e., the end address of the first buffer and the start 96 * mergeable by the I/O MMU (i.e., the end address of the first buffer and the start
@@ -626,6 +634,12 @@ setup_per_cpu_areas (void)
626 /* start_kernel() requires this... */ 634 /* start_kernel() requires this... */
627} 635}
628 636
637/*
638 * Calculate the max. cache line size.
639 *
640 * In addition, the minimum of the i-cache stride sizes is calculated for
641 * "flush_icache_range()".
642 */
629static void 643static void
630get_max_cacheline_size (void) 644get_max_cacheline_size (void)
631{ 645{
@@ -639,6 +653,8 @@ get_max_cacheline_size (void)
639 printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n", 653 printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n",
640 __FUNCTION__, status); 654 __FUNCTION__, status);
641 max = SMP_CACHE_BYTES; 655 max = SMP_CACHE_BYTES;
656 /* Safest setup for "flush_icache_range()" */
657 ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT;
642 goto out; 658 goto out;
643 } 659 }
644 660
@@ -647,14 +663,31 @@ get_max_cacheline_size (void)
647 &cci); 663 &cci);
648 if (status != 0) { 664 if (status != 0) {
649 printk(KERN_ERR 665 printk(KERN_ERR
650 "%s: ia64_pal_cache_config_info(l=%lu) failed (status=%ld)\n", 666 "%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n",
651 __FUNCTION__, l, status); 667 __FUNCTION__, l, status);
652 max = SMP_CACHE_BYTES; 668 max = SMP_CACHE_BYTES;
669 /* The safest setup for "flush_icache_range()" */
670 cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
671 cci.pcci_unified = 1;
653 } 672 }
654 line_size = 1 << cci.pcci_line_size; 673 line_size = 1 << cci.pcci_line_size;
655 if (line_size > max) 674 if (line_size > max)
656 max = line_size; 675 max = line_size;
657 } 676 if (!cci.pcci_unified) {
677 status = ia64_pal_cache_config_info(l,
678 /* cache_type (instruction)= */ 1,
679 &cci);
680 if (status != 0) {
681 printk(KERN_ERR
682 "%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n",
683 __FUNCTION__, l, status);
684 /* The safest setup for "flush_icache_range()" */
685 cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
686 }
687 }
688 if (cci.pcci_stride < ia64_i_cache_stride_shift)
689 ia64_i_cache_stride_shift = cci.pcci_stride;
690 }
658 out: 691 out:
659 if (max > ia64_max_cacheline_size) 692 if (max > ia64_max_cacheline_size)
660 ia64_max_cacheline_size = max; 693 ia64_max_cacheline_size = max;