diff options
author | Fenghua Yu <fenghua.yu@intel.com> | 2008-10-17 15:14:13 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2008-10-17 15:14:13 -0400 |
commit | 62fdd7678a26efadd6ac5c2869543caff77d2df0 (patch) | |
tree | 0dd67208590c4540ff6a4476579a55bcac0d1fce /arch/ia64/kernel/setup.c | |
parent | 6bb7a935489dab20802dde6c2cb7d8582f4849bf (diff) |
[IA64] Add Variable Page Size and IA64 Support in Intel IOMMU
The patch contains Intel IOMMU IA64 specific code. It defines new
machvec dig_vtd, hooks for IOMMU, DMAR table detection, cache line flush
function, etc.
For a generic kernel with CONFIG_DMAR=y, if Intel IOMMU is detected,
dig_vtd is used for machinve vector. Otherwise, kernel falls back to
dig machine vector. Kernel parameter "machvec=dig" or "intel_iommu=off"
can be used to force kernel to boot dig machine vector.
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/kernel/setup.c')
-rw-r--r-- | arch/ia64/kernel/setup.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index de636b215677..2a67a74a48fe 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
@@ -116,6 +116,13 @@ unsigned int num_io_spaces; | |||
116 | */ | 116 | */ |
117 | #define I_CACHE_STRIDE_SHIFT 5 /* Safest way to go: 32 bytes by 32 bytes */ | 117 | #define I_CACHE_STRIDE_SHIFT 5 /* Safest way to go: 32 bytes by 32 bytes */ |
118 | unsigned long ia64_i_cache_stride_shift = ~0; | 118 | unsigned long ia64_i_cache_stride_shift = ~0; |
119 | /* | ||
120 | * "clflush_cache_range()" needs to know what processor dependent stride size to | ||
121 | * use when it flushes cache lines including both d-cache and i-cache. | ||
122 | */ | ||
123 | /* Safest way to go: 32 bytes by 32 bytes */ | ||
124 | #define CACHE_STRIDE_SHIFT 5 | ||
125 | unsigned long ia64_cache_stride_shift = ~0; | ||
119 | 126 | ||
120 | /* | 127 | /* |
121 | * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1). This | 128 | * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1). This |
@@ -847,13 +854,14 @@ setup_per_cpu_areas (void) | |||
847 | } | 854 | } |
848 | 855 | ||
849 | /* | 856 | /* |
850 | * Calculate the max. cache line size. | 857 | * Do the following calculations: |
851 | * | 858 | * |
852 | * In addition, the minimum of the i-cache stride sizes is calculated for | 859 | * 1. the max. cache line size. |
853 | * "flush_icache_range()". | 860 | * 2. the minimum of the i-cache stride sizes for "flush_icache_range()". |
861 | * 3. the minimum of the cache stride sizes for "clflush_cache_range()". | ||
854 | */ | 862 | */ |
855 | static void __cpuinit | 863 | static void __cpuinit |
856 | get_max_cacheline_size (void) | 864 | get_cache_info(void) |
857 | { | 865 | { |
858 | unsigned long line_size, max = 1; | 866 | unsigned long line_size, max = 1; |
859 | u64 l, levels, unique_caches; | 867 | u64 l, levels, unique_caches; |
@@ -867,12 +875,14 @@ get_max_cacheline_size (void) | |||
867 | max = SMP_CACHE_BYTES; | 875 | max = SMP_CACHE_BYTES; |
868 | /* Safest setup for "flush_icache_range()" */ | 876 | /* Safest setup for "flush_icache_range()" */ |
869 | ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT; | 877 | ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT; |
878 | /* Safest setup for "clflush_cache_range()" */ | ||
879 | ia64_cache_stride_shift = CACHE_STRIDE_SHIFT; | ||
870 | goto out; | 880 | goto out; |
871 | } | 881 | } |
872 | 882 | ||
873 | for (l = 0; l < levels; ++l) { | 883 | for (l = 0; l < levels; ++l) { |
874 | status = ia64_pal_cache_config_info(l, /* cache_type (data_or_unified)= */ 2, | 884 | /* cache_type (data_or_unified)=2 */ |
875 | &cci); | 885 | status = ia64_pal_cache_config_info(l, 2, &cci); |
876 | if (status != 0) { | 886 | if (status != 0) { |
877 | printk(KERN_ERR | 887 | printk(KERN_ERR |
878 | "%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n", | 888 | "%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n", |
@@ -880,15 +890,21 @@ get_max_cacheline_size (void) | |||
880 | max = SMP_CACHE_BYTES; | 890 | max = SMP_CACHE_BYTES; |
881 | /* The safest setup for "flush_icache_range()" */ | 891 | /* The safest setup for "flush_icache_range()" */ |
882 | cci.pcci_stride = I_CACHE_STRIDE_SHIFT; | 892 | cci.pcci_stride = I_CACHE_STRIDE_SHIFT; |
893 | /* The safest setup for "clflush_cache_range()" */ | ||
894 | ia64_cache_stride_shift = CACHE_STRIDE_SHIFT; | ||
883 | cci.pcci_unified = 1; | 895 | cci.pcci_unified = 1; |
896 | } else { | ||
897 | if (cci.pcci_stride < ia64_cache_stride_shift) | ||
898 | ia64_cache_stride_shift = cci.pcci_stride; | ||
899 | |||
900 | line_size = 1 << cci.pcci_line_size; | ||
901 | if (line_size > max) | ||
902 | max = line_size; | ||
884 | } | 903 | } |
885 | line_size = 1 << cci.pcci_line_size; | 904 | |
886 | if (line_size > max) | ||
887 | max = line_size; | ||
888 | if (!cci.pcci_unified) { | 905 | if (!cci.pcci_unified) { |
889 | status = ia64_pal_cache_config_info(l, | 906 | /* cache_type (instruction)=1*/ |
890 | /* cache_type (instruction)= */ 1, | 907 | status = ia64_pal_cache_config_info(l, 1, &cci); |
891 | &cci); | ||
892 | if (status != 0) { | 908 | if (status != 0) { |
893 | printk(KERN_ERR | 909 | printk(KERN_ERR |
894 | "%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n", | 910 | "%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n", |
@@ -942,7 +958,7 @@ cpu_init (void) | |||
942 | } | 958 | } |
943 | #endif | 959 | #endif |
944 | 960 | ||
945 | get_max_cacheline_size(); | 961 | get_cache_info(); |
946 | 962 | ||
947 | /* | 963 | /* |
948 | * We can't pass "local_cpu_data" to identify_cpu() because we haven't called | 964 | * We can't pass "local_cpu_data" to identify_cpu() because we haven't called |