diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2017-07-25 19:37:28 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2017-07-25 19:37:28 +0000 |
commit | 8520d5e4bddd9aab52356a93d71c14f0bd6d5f08 (patch) | |
tree | c70e2d8ef7ae235192902ef145c332fe670d5fb9 | |
parent | a86b433820f351bc94b70663f41942f4aab3e038 (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.S | 7 |
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 */ |