summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2017-07-25 19:37:28 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2017-07-25 19:37:28 +0000
commit8520d5e4bddd9aab52356a93d71c14f0bd6d5f08 (patch)
treec70e2d8ef7ae235192902ef145c332fe670d5fb9
parenta86b433820f351bc94b70663f41942f4aab3e038 (diff)
The Cortex-A17 TRM explicitly says that there is an intermediate table
walk cache and that its cache entries are associated with an ASID. Our armv7 pmap doesn't use ASIDs and we only ever insert "global" page table entries which match (and get flushed) regardless of the ASID. The current ASID is specified vy the CONTEXTIDR register, which is initialized to some "unknown" value. And on my hardware that value isn't zero! So the intermediate table walk cache entries are tagged with this unknown value. But our TLB flushes are done with ASID 0. This means that the intermediate table walk cache entries are never flushed because the ASID doesn't match. As a result the hardware may look at the wrong page table page when looking up a translation. So initialize CONTEXTIDR to zero before we initialize the first level page table pointer, flush the TLB and enable the MMU. Fixes the hangs previously seen on Cortex-A12/A17. ok patrick@
-rw-r--r--sys/arch/armv7/armv7/locore0.S7
1 files changed, 6 insertions, 1 deletions
diff --git a/sys/arch/armv7/armv7/locore0.S b/sys/arch/armv7/armv7/locore0.S
index b90d94e9812..b683e00027f 100644
--- a/sys/arch/armv7/armv7/locore0.S
+++ b/sys/arch/armv7/armv7/locore0.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore0.S,v 1.2 2017/07/23 10:11:27 kettenis Exp $ */
+/* $OpenBSD: locore0.S,v 1.3 2017/07/25 19:37:27 kettenis Exp $ */
/* $NetBSD: lubbock_start.S,v 1.1 2003/06/18 10:51:15 bsh Exp $ */
/*
@@ -139,6 +139,11 @@ _C_LABEL(bootstrap_start):
cmp r1, #0
bne 3b
+ /* Set ASID to zero */
+ mov r1, #0
+ mcr CP15_CONTEXTIDR(r1)
+ isb
+
mcr CP15_TTBR0(r0) /* Set TTB */
mcr CP15_TLBIALL(r0) /* Flush TLB */