diff options
author | danh-arm <dan.handley@arm.com> | 2014-05-08 11:55:13 +0100 |
---|---|---|
committer | danh-arm <dan.handley@arm.com> | 2014-05-08 11:55:13 +0100 |
commit | b3e2268eeb5881c82d0c930d2d61748bffd57f05 (patch) | |
tree | 3d561cba11948ef8850e819aba480895af72f9de /plat | |
parent | aefebcc35ac0abd7ecf1a844b467331a600d4574 (diff) | |
parent | 8cec598ba3b689b86d9dfc58bca5610bdc48f55a (diff) | |
download | arm-trusted-firmware-b3e2268eeb5881c82d0c930d2d61748bffd57f05.tar.gz |
Merge pull request #59 from athoelke/review-barriers-v2
Correct usage of data and instruction barriers v2
Diffstat (limited to 'plat')
-rw-r--r-- | plat/fvp/aarch64/plat_common.c | 21 | ||||
-rw-r--r-- | plat/fvp/plat_gic.c | 3 | ||||
-rw-r--r-- | plat/fvp/plat_pm.c | 6 |
3 files changed, 29 insertions, 1 deletions
diff --git a/plat/fvp/aarch64/plat_common.c b/plat/fvp/aarch64/plat_common.c index c8e529d..e2f2343 100644 --- a/plat/fvp/aarch64/plat_common.c +++ b/plat/fvp/aarch64/plat_common.c @@ -69,6 +69,8 @@ void enable_mmu() ttbr = (unsigned long) l1_xlation_table; if (GET_EL(current_el) == MODE_EL3) { + assert((read_sctlr_el3() & SCTLR_M_BIT) == 0); + write_mair_el3(mair); tcr |= TCR_EL3_RES1; /* Invalidate EL3 TLBs */ @@ -77,11 +79,19 @@ void enable_mmu() write_tcr_el3(tcr); write_ttbr0_el3(ttbr); + /* ensure all translation table writes have drained into memory, + * the TLB invalidation is complete, and translation register + * writes are committed before enabling the MMU + */ + dsb(); + isb(); + sctlr = read_sctlr_el3(); sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT | SCTLR_I_BIT; sctlr |= SCTLR_A_BIT | SCTLR_C_BIT; write_sctlr_el3(sctlr); } else { + assert((read_sctlr_el1() & SCTLR_M_BIT) == 0); write_mair_el1(mair); /* Invalidate EL1 TLBs */ @@ -90,11 +100,20 @@ void enable_mmu() write_tcr_el1(tcr); write_ttbr0_el1(ttbr); + /* ensure all translation table writes have drained into memory, + * the TLB invalidation is complete, and translation register + * writes are committed before enabling the MMU + */ + dsb(); + isb(); + sctlr = read_sctlr_el1(); sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT | SCTLR_I_BIT; sctlr |= SCTLR_A_BIT | SCTLR_C_BIT; write_sctlr_el1(sctlr); } + /* ensure the MMU enable takes effect immediately */ + isb(); return; } @@ -113,6 +132,8 @@ void disable_mmu(void) sctlr = sctlr & ~(SCTLR_M_BIT | SCTLR_C_BIT); write_sctlr_el1(sctlr); } + /* ensure the MMU disable takes effect immediately */ + isb(); /* Flush the caches */ dcsw_op_all(DCCISW); diff --git a/plat/fvp/plat_gic.c b/plat/fvp/plat_gic.c index 8457af1..db3c9cf 100644 --- a/plat/fvp/plat_gic.c +++ b/plat/fvp/plat_gic.c @@ -86,6 +86,7 @@ void gicv3_cpuif_setup(void) */ scr_val = read_scr(); write_scr(scr_val | SCR_NS_BIT); + isb(); /* ensure NS=1 takes effect before accessing ICC_SRE_EL2 */ /* * By default EL2 and NS-EL1 software should be able to enable GICv3 @@ -103,9 +104,11 @@ void gicv3_cpuif_setup(void) write_icc_sre_el2(val | ICC_SRE_EN | ICC_SRE_SRE); write_icc_pmr_el1(GIC_PRI_MASK); + isb(); /* commite ICC_* changes before setting NS=0 */ /* Restore SCR_EL3 */ write_scr(scr_val); + isb(); /* ensure NS=0 takes effect immediately */ } /******************************************************************************* diff --git a/plat/fvp/plat_pm.c b/plat/fvp/plat_pm.c index 5430fff..f80e2d7 100644 --- a/plat/fvp/plat_pm.c +++ b/plat/fvp/plat_pm.c @@ -54,7 +54,11 @@ int fvp_affinst_standby(unsigned int power_state) if (target_afflvl != MPIDR_AFFLVL0) return PSCI_E_INVALID_PARAMS; - /* Enter standby state */ + /* + * Enter standby state + * dsb is good practice before using wfi to enter low power states + */ + dsb(); wfi(); return PSCI_E_SUCCESS; |