summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/mips64/mips64/cache_r5k.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/sys/arch/mips64/mips64/cache_r5k.c b/sys/arch/mips64/mips64/cache_r5k.c
index 7e56bfcab8a..fb164d00468 100644
--- a/sys/arch/mips64/mips64/cache_r5k.c
+++ b/sys/arch/mips64/mips64/cache_r5k.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cache_r5k.c,v 1.10 2014/03/09 10:12:17 miod Exp $ */
+/* $OpenBSD: cache_r5k.c,v 1.11 2014/03/11 20:32:42 miod Exp $ */
/*
* Copyright (c) 2012 Miodrag Vallat.
@@ -149,6 +149,7 @@ static __inline__ void mips5k_hitwbinv_secondary(vaddr_t, vsize_t);
void mips5k_l2_init(register_t);
void mips7k_l2_init(register_t);
void mips7k_l3_init(register_t);
+void mips5k_c0_cca_update(register_t);
static void run_uncached(void (*)(register_t), register_t);
/*
@@ -223,25 +224,25 @@ mips7k_l2_init(register_t l2size)
va = PHYS_TO_XKPHYS(0, CCA_CACHED);
eva = va + l2size;
while (va != eva) {
+ cache(IndexStoreTag_S, 0, va);
va += R5K_LINE;
- cache(IndexStoreTag_S, -4, va);
}
mips_sync();
va = PHYS_TO_XKPHYS(0, CCA_CACHED);
eva = va + l2size;
while (va != eva) {
- va += R5K_LINE;
__asm__ __volatile__
- ("lw $zero, %0(%1)" :: "i"(-4), "r"(va));
+ ("lw $zero, 0(%0)" :: "r"(va));
+ va += R5K_LINE;
}
mips_sync();
va = PHYS_TO_XKPHYS(0, CCA_CACHED);
eva = va + l2size;
while (va != eva) {
+ cache(IndexStoreTag_S, 0, va);
va += R5K_LINE;
- cache(IndexStoreTag_S, -4, va);
}
mips_sync();
}
@@ -273,6 +274,28 @@ mips7k_l3_init(register_t l3size)
}
/*
+ * Update the coherency of KSEG0.
+ * INTENDED TO BE RUN UNCACHED - BE SURE TO CHECK THAT IT WON'T STORE ANYTHING
+ * ON THE STACK IN THE ASSEMBLY OUTPUT EVERYTIME YOU CHANGE IT.
+ */
+void
+mips5k_c0_cca_update(register_t cfg)
+{
+ set_config(cfg);
+
+#if defined(CPU_R5000) || defined(CPU_RM7000)
+ /*
+ * RM52xx and RM7000 hazard: after updating the K0 field of the Config
+ * register, the KSEG0 and CKSEG0 address segments should not be used
+ * for 5 cycles. The register modification and the use of these address
+ * segments should be separated by at least five (RM52xx) or
+ * ten (RM7000) integer instructions.
+ */
+ nop10();
+#endif
+}
+
+/*
* Discover cache configuration and update cpu_info accordingly.
* Initialize L2 and L3 caches found if necessary.
*/
@@ -396,7 +419,7 @@ Mips5k_ConfigCache(struct cpu_info *ci)
ncfg = (cfg & ~CFGR_CCA_MASK) | CCA_CACHED;
if (cfg != ncfg)
- run_uncached(cp0_set_config, ncfg);
+ run_uncached(mips5k_c0_cca_update, ncfg);
}
/*