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>
This commit is contained in:
parent
12a8471de9
commit
e2e7f29af8
|
@ -889,33 +889,39 @@ static inline void rm7k_erratum31(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void alias_74k_erratum(struct cpuinfo_mips *c)
|
static inline int alias_74k_erratum(struct cpuinfo_mips *c)
|
||||||
{
|
{
|
||||||
unsigned int imp = c->processor_id & PRID_IMP_MASK;
|
unsigned int imp = c->processor_id & PRID_IMP_MASK;
|
||||||
unsigned int rev = c->processor_id & PRID_REV_MASK;
|
unsigned int rev = c->processor_id & PRID_REV_MASK;
|
||||||
|
int present = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Early versions of the 74K do not update the cache tags on a
|
* Early versions of the 74K do not update the cache tags on a
|
||||||
* vtag miss/ptag hit which can occur in the case of KSEG0/KUSEG
|
* vtag miss/ptag hit which can occur in the case of KSEG0/KUSEG
|
||||||
* aliases. In this case it is better to treat the cache as always
|
* aliases. In this case it is better to treat the cache as always
|
||||||
* having aliases.
|
* having aliases. Also disable the synonym tag update feature
|
||||||
|
* where available. In this case no opportunistic tag update will
|
||||||
|
* happen where a load causes a virtual address miss but a physical
|
||||||
|
* address hit during a D-cache look-up.
|
||||||
*/
|
*/
|
||||||
switch (imp) {
|
switch (imp) {
|
||||||
case PRID_IMP_74K:
|
case PRID_IMP_74K:
|
||||||
if (rev <= PRID_REV_ENCODE_332(2, 4, 0))
|
if (rev <= PRID_REV_ENCODE_332(2, 4, 0))
|
||||||
c->dcache.flags |= MIPS_CACHE_VTAG;
|
present = 1;
|
||||||
if (rev == PRID_REV_ENCODE_332(2, 4, 0))
|
if (rev == PRID_REV_ENCODE_332(2, 4, 0))
|
||||||
write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
|
write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
|
||||||
break;
|
break;
|
||||||
case PRID_IMP_1074K:
|
case PRID_IMP_1074K:
|
||||||
if (rev <= PRID_REV_ENCODE_332(1, 1, 0)) {
|
if (rev <= PRID_REV_ENCODE_332(1, 1, 0)) {
|
||||||
c->dcache.flags |= MIPS_CACHE_VTAG;
|
present = 1;
|
||||||
write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
|
write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return present;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void b5k_instruction_hazard(void)
|
static void b5k_instruction_hazard(void)
|
||||||
|
@ -939,6 +945,7 @@ static void probe_pcache(void)
|
||||||
struct cpuinfo_mips *c = ¤t_cpu_data;
|
struct cpuinfo_mips *c = ¤t_cpu_data;
|
||||||
unsigned int config = read_c0_config();
|
unsigned int config = read_c0_config();
|
||||||
unsigned int prid = read_c0_prid();
|
unsigned int prid = read_c0_prid();
|
||||||
|
int has_74k_erratum = 0;
|
||||||
unsigned long config1;
|
unsigned long config1;
|
||||||
unsigned int lsize;
|
unsigned int lsize;
|
||||||
|
|
||||||
|
@ -1247,7 +1254,7 @@ static void probe_pcache(void)
|
||||||
|
|
||||||
case CPU_74K:
|
case CPU_74K:
|
||||||
case CPU_1074K:
|
case CPU_1074K:
|
||||||
alias_74k_erratum(c);
|
has_74k_erratum = alias_74k_erratum(c);
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
case CPU_M14KC:
|
case CPU_M14KC:
|
||||||
case CPU_M14KEC:
|
case CPU_M14KEC:
|
||||||
|
@ -1262,7 +1269,7 @@ static void probe_pcache(void)
|
||||||
if (!(read_c0_config7() & MIPS_CONF7_IAR) &&
|
if (!(read_c0_config7() & MIPS_CONF7_IAR) &&
|
||||||
(c->icache.waysize > PAGE_SIZE))
|
(c->icache.waysize > PAGE_SIZE))
|
||||||
c->icache.flags |= MIPS_CACHE_ALIASES;
|
c->icache.flags |= MIPS_CACHE_ALIASES;
|
||||||
if (read_c0_config7() & MIPS_CONF7_AR) {
|
if (!has_74k_erratum && (read_c0_config7() & MIPS_CONF7_AR)) {
|
||||||
/*
|
/*
|
||||||
* Effectively physically indexed dcache,
|
* Effectively physically indexed dcache,
|
||||||
* thus no virtual aliases.
|
* thus no virtual aliases.
|
||||||
|
@ -1271,7 +1278,7 @@ static void probe_pcache(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if (c->dcache.waysize > PAGE_SIZE)
|
if (has_74k_erratum || c->dcache.waysize > PAGE_SIZE)
|
||||||
c->dcache.flags |= MIPS_CACHE_ALIASES;
|
c->dcache.flags |= MIPS_CACHE_ALIASES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue