diff options
Diffstat (limited to 'arch/ia64/kernel/setup.c')
| -rw-r--r-- | arch/ia64/kernel/setup.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index 5c7c95737bbf..84f89da7c640 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> |
| @@ -85,6 +86,13 @@ EXPORT_SYMBOL(io_space); | |||
| 85 | unsigned int num_io_spaces; | 86 | unsigned int num_io_spaces; |
| 86 | 87 | ||
| 87 | /* | 88 | /* |
| 89 | * "flush_icache_range()" needs to know what processor dependent stride size to use | ||
| 90 | * when it makes i-cache(s) coherent with d-caches. | ||
| 91 | */ | ||
| 92 | #define I_CACHE_STRIDE_SHIFT 5 /* Safest way to go: 32 bytes by 32 bytes */ | ||
| 93 | unsigned long ia64_i_cache_stride_shift = ~0; | ||
| 94 | |||
| 95 | /* | ||
| 88 | * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1). This | 96 | * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1). This |
| 89 | * mask specifies a mask of address bits that must be 0 in order for two buffers to be | 97 | * mask specifies a mask of address bits that must be 0 in order for two buffers to be |
| 90 | * mergeable by the I/O MMU (i.e., the end address of the first buffer and the start | 98 | * mergeable by the I/O MMU (i.e., the end address of the first buffer and the start |
| @@ -628,6 +636,12 @@ setup_per_cpu_areas (void) | |||
| 628 | /* start_kernel() requires this... */ | 636 | /* start_kernel() requires this... */ |
| 629 | } | 637 | } |
| 630 | 638 | ||
| 639 | /* | ||
| 640 | * Calculate the max. cache line size. | ||
| 641 | * | ||
| 642 | * In addition, the minimum of the i-cache stride sizes is calculated for | ||
| 643 | * "flush_icache_range()". | ||
| 644 | */ | ||
| 631 | static void | 645 | static void |
| 632 | get_max_cacheline_size (void) | 646 | get_max_cacheline_size (void) |
| 633 | { | 647 | { |
| @@ -641,6 +655,8 @@ get_max_cacheline_size (void) | |||
| 641 | printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n", | 655 | printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n", |
| 642 | __FUNCTION__, status); | 656 | __FUNCTION__, status); |
| 643 | max = SMP_CACHE_BYTES; | 657 | max = SMP_CACHE_BYTES; |
| 658 | /* Safest setup for "flush_icache_range()" */ | ||
| 659 | ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT; | ||
| 644 | goto out; | 660 | goto out; |
| 645 | } | 661 | } |
| 646 | 662 | ||
| @@ -649,14 +665,31 @@ get_max_cacheline_size (void) | |||
| 649 | &cci); | 665 | &cci); |
| 650 | if (status != 0) { | 666 | if (status != 0) { |
| 651 | printk(KERN_ERR | 667 | printk(KERN_ERR |
| 652 | "%s: ia64_pal_cache_config_info(l=%lu) failed (status=%ld)\n", | 668 | "%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n", |
| 653 | __FUNCTION__, l, status); | 669 | __FUNCTION__, l, status); |
| 654 | max = SMP_CACHE_BYTES; | 670 | max = SMP_CACHE_BYTES; |
| 671 | /* The safest setup for "flush_icache_range()" */ | ||
| 672 | cci.pcci_stride = I_CACHE_STRIDE_SHIFT; | ||
| 673 | cci.pcci_unified = 1; | ||
| 655 | } | 674 | } |
| 656 | line_size = 1 << cci.pcci_line_size; | 675 | line_size = 1 << cci.pcci_line_size; |
| 657 | if (line_size > max) | 676 | if (line_size > max) |
| 658 | max = line_size; | 677 | max = line_size; |
| 659 | } | 678 | if (!cci.pcci_unified) { |
| 679 | status = ia64_pal_cache_config_info(l, | ||
| 680 | /* cache_type (instruction)= */ 1, | ||
| 681 | &cci); | ||
| 682 | if (status != 0) { | ||
| 683 | printk(KERN_ERR | ||
| 684 | "%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n", | ||
| 685 | __FUNCTION__, l, status); | ||
| 686 | /* The safest setup for "flush_icache_range()" */ | ||
| 687 | cci.pcci_stride = I_CACHE_STRIDE_SHIFT; | ||
| 688 | } | ||
| 689 | } | ||
| 690 | if (cci.pcci_stride < ia64_i_cache_stride_shift) | ||
| 691 | ia64_i_cache_stride_shift = cci.pcci_stride; | ||
| 692 | } | ||
| 660 | out: | 693 | out: |
| 661 | if (max > ia64_max_cacheline_size) | 694 | if (max > ia64_max_cacheline_size) |
| 662 | ia64_max_cacheline_size = max; | 695 | ia64_max_cacheline_size = max; |
