aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Meloun <mmel@FreeBSD.org>2016-04-28 12:05:07 +0000
committerMichal Meloun <mmel@FreeBSD.org>2016-04-28 12:05:07 +0000
commitbdb02ec712e07ee180f624e49bc5c15a9de394b3 (patch)
tree62efd8bd0eb9080d3bf7ca74da19c4ec26ea7ee2
parent8442087f1512274ff2848307eff17b17ccdffe85 (diff)
downloadsrc-bdb02ec712e07ee180f624e49bc5c15a9de394b3.tar.gz
src-bdb02ec712e07ee180f624e49bc5c15a9de394b3.zip
Notes
-rw-r--r--sys/arm/arm/swtch-v6.S34
1 files changed, 23 insertions, 11 deletions
diff --git a/sys/arm/arm/swtch-v6.S b/sys/arm/arm/swtch-v6.S
index ef2156a4f121..c3e6eb29d26f 100644
--- a/sys/arm/arm/swtch-v6.S
+++ b/sys/arm/arm/swtch-v6.S
@@ -114,25 +114,37 @@ __FBSDID("$FreeBSD$");
.Lblocked_lock:
.word _C_LABEL(blocked_lock)
-ENTRY(cpu_context_switch) /* QQQ: What about macro instead of function? */
+ENTRY(cpu_context_switch)
DSB
- mcr CP15_TTBR0(r0) /* set the new TTB */
+ /*
+ * We can directly switch between translation tables only when the
+ * size of the mapping for any given virtual address is the same
+ * in the old and new translation tables.
+ * Thus, we must switch to kernel pmap translation table as
+ * intermediate mapping because all sizes of these mappings are same
+ * (or unmapped). The same is true for switch from kernel pmap
+ * translation table to new pmap one.
+ */
+ mov r2, #(CPU_ASID_KERNEL)
+ ldr r1, =(_C_LABEL(pmap_kern_ttb))
+ ldr r1, [r1]
+ mcr CP15_TTBR0(r1) /* switch to kernel TTB */
+ ISB
+ mcr CP15_TLBIASID(r2) /* flush not global TLBs */
+ DSB
+ mcr CP15_TTBR0(r0) /* switch to new TTB */
ISB
- mov r0, #(CPU_ASID_KERNEL)
- mcr CP15_TLBIASID(r0) /* flush not global TLBs */
+ /*
+ * We must flush not global TLBs again because PT2MAP mapping
+ * is different.
+ */
+ mcr CP15_TLBIASID(r2) /* flush not global TLBs */
/*
* Flush entire Branch Target Cache because of the branch predictor
* is not architecturally invisible. See ARM Architecture Reference
* Manual ARMv7-A and ARMv7-R edition, page B2-1264(65), Branch
* predictors and Requirements for branch predictor maintenance
* operations sections.
- *
- * QQQ: The predictor is virtually addressed and holds virtual target
- * addresses. Therefore, if mapping is changed, the predictor cache
- * must be flushed.The flush is part of entire i-cache invalidation
- * what is always called when code mapping is changed. So herein,
- * it's the only place where standalone predictor flush must be
- * executed in kernel (except self modifying code case).
*/
mcr CP15_BPIALL /* flush entire Branch Target Cache */
DSB