aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@codesourcery.com>2014-11-15 20:02:29 -0500
committerRalf Baechle <ralf@linux-mips.org>2015-04-02 07:54:18 -0400
commite2e7f29af84aa59dd8191b9f6fee80aafa4e06cd (patch)
treed24402478d2956b93d2d881673d527f0a483eb11
parent12a8471de9e8dc3c867e15bbf4a37152d2f690b8 (diff)
MIPS: c-r4k.c: Fix the 74K D-cache alias erratum workaround
Fix the 74K D-cache alias erratum workaround so that it actually works. Our current code sets MIPS_CACHE_VTAG for the D-cache, but that flag only has any effect for the I-cache. Additionally MIPS_CACHE_PINDEX is set for the D-cache if CP0.Config7.AR is also set for an affected processor, leading to confusing information in the bootstrap log (the flag isn't used beyond that). So delete the setting of MIPS_CACHE_VTAG and rely on MIPS_CACHE_ALIASES, set in a common place, removing I-cache coherency issues seen in GDB testing with software breakpoints, gdbserver and ptrace(2), on affected systems. While at it add a little piece of explanation of what CP0.Config6.SYND is so that people do not have to chase documentation. Signed-off-by: Maciej W. Rozycki <macro@codesourcery.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8507/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/mm/c-r4k.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 58e2eeddc391..0dbb65a51ce5 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -889,33 +889,39 @@ static inline void rm7k_erratum31(void)
889 } 889 }
890} 890}
891 891
892static inline void alias_74k_erratum(struct cpuinfo_mips *c) 892static inline int alias_74k_erratum(struct cpuinfo_mips *c)
893{ 893{
894 unsigned int imp = c->processor_id & PRID_IMP_MASK; 894 unsigned int imp = c->processor_id & PRID_IMP_MASK;
895 unsigned int rev = c->processor_id & PRID_REV_MASK; 895 unsigned int rev = c->processor_id & PRID_REV_MASK;
896 int present = 0;
896 897
897 /* 898 /*
898 * Early versions of the 74K do not update the cache tags on a 899 * Early versions of the 74K do not update the cache tags on a
899 * vtag miss/ptag hit which can occur in the case of KSEG0/KUSEG 900 * vtag miss/ptag hit which can occur in the case of KSEG0/KUSEG
900 * aliases. In this case it is better to treat the cache as always 901 * aliases. In this case it is better to treat the cache as always
901 * having aliases. 902 * having aliases. Also disable the synonym tag update feature
903 * where available. In this case no opportunistic tag update will
904 * happen where a load causes a virtual address miss but a physical
905 * address hit during a D-cache look-up.
902 */ 906 */
903 switch (imp) { 907 switch (imp) {
904 case PRID_IMP_74K: 908 case PRID_IMP_74K:
905 if (rev <= PRID_REV_ENCODE_332(2, 4, 0)) 909 if (rev <= PRID_REV_ENCODE_332(2, 4, 0))
906 c->dcache.flags |= MIPS_CACHE_VTAG; 910 present = 1;
907 if (rev == PRID_REV_ENCODE_332(2, 4, 0)) 911 if (rev == PRID_REV_ENCODE_332(2, 4, 0))
908 write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND); 912 write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
909 break; 913 break;
910 case PRID_IMP_1074K: 914 case PRID_IMP_1074K:
911 if (rev <= PRID_REV_ENCODE_332(1, 1, 0)) { 915 if (rev <= PRID_REV_ENCODE_332(1, 1, 0)) {
912 c->dcache.flags |= MIPS_CACHE_VTAG; 916 present = 1;
913 write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND); 917 write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
914 } 918 }
915 break; 919 break;
916 default: 920 default:
917 BUG(); 921 BUG();
918 } 922 }
923
924 return present;
919} 925}
920 926
921static void b5k_instruction_hazard(void) 927static void b5k_instruction_hazard(void)
@@ -939,6 +945,7 @@ static void probe_pcache(void)
939 struct cpuinfo_mips *c = &current_cpu_data; 945 struct cpuinfo_mips *c = &current_cpu_data;
940 unsigned int config = read_c0_config(); 946 unsigned int config = read_c0_config();
941 unsigned int prid = read_c0_prid(); 947 unsigned int prid = read_c0_prid();
948 int has_74k_erratum = 0;
942 unsigned long config1; 949 unsigned long config1;
943 unsigned int lsize; 950 unsigned int lsize;
944 951
@@ -1247,7 +1254,7 @@ static void probe_pcache(void)
1247 1254
1248 case CPU_74K: 1255 case CPU_74K:
1249 case CPU_1074K: 1256 case CPU_1074K:
1250 alias_74k_erratum(c); 1257 has_74k_erratum = alias_74k_erratum(c);
1251 /* Fall through. */ 1258 /* Fall through. */
1252 case CPU_M14KC: 1259 case CPU_M14KC:
1253 case CPU_M14KEC: 1260 case CPU_M14KEC:
@@ -1262,7 +1269,7 @@ static void probe_pcache(void)
1262 if (!(read_c0_config7() & MIPS_CONF7_IAR) && 1269 if (!(read_c0_config7() & MIPS_CONF7_IAR) &&
1263 (c->icache.waysize > PAGE_SIZE)) 1270 (c->icache.waysize > PAGE_SIZE))
1264 c->icache.flags |= MIPS_CACHE_ALIASES; 1271 c->icache.flags |= MIPS_CACHE_ALIASES;
1265 if (read_c0_config7() & MIPS_CONF7_AR) { 1272 if (!has_74k_erratum && (read_c0_config7() & MIPS_CONF7_AR)) {
1266 /* 1273 /*
1267 * Effectively physically indexed dcache, 1274 * Effectively physically indexed dcache,
1268 * thus no virtual aliases. 1275 * thus no virtual aliases.
@@ -1271,7 +1278,7 @@ static void probe_pcache(void)
1271 break; 1278 break;
1272 } 1279 }
1273 default: 1280 default:
1274 if (c->dcache.waysize > PAGE_SIZE) 1281 if (has_74k_erratum || c->dcache.waysize > PAGE_SIZE)
1275 c->dcache.flags |= MIPS_CACHE_ALIASES; 1282 c->dcache.flags |= MIPS_CACHE_ALIASES;
1276 } 1283 }
1277 1284