#------------------------------------------------------------------------------ # # Copyright (c) 2016, Linaro Limited. All rights reserved. # # SPDX-License-Identifier: BSD-2-Clause-Patent # #------------------------------------------------------------------------------ #include .set CTRL_M_BIT, (1 << 0) .macro __replace_entry, el // check whether we should disable the MMU cbz x3, .L1_\@ // clean and invalidate first so that we don't clobber // adjacent entries that are dirty in the caches dc civac, x0 dsb nsh // disable the MMU mrs x8, sctlr_el\el bic x9, x8, #CTRL_M_BIT msr sctlr_el\el, x9 isb // write updated entry str x1, [x0] // invalidate again to get rid of stale clean cachelines that may // have been filled speculatively since the last invalidate dmb sy dc ivac, x0 // flush translations for the target address from the TLBs lsr x2, x2, #12 .if \el == 1 tlbi vaae1, x2 .else tlbi vae\el, x2 .endif dsb nsh // re-enable the MMU msr sctlr_el\el, x8 isb b .L2_\@ .L1_\@: // write invalid entry str xzr, [x0] dsb nshst // flush translations for the target address from the TLBs lsr x2, x2, #12 .if \el == 1 tlbi vaae1, x2 .else tlbi vae\el, x2 .endif dsb nsh // write updated entry str x1, [x0] dsb nshst isb .L2_\@: .endm //VOID //ArmReplaceLiveTranslationEntry ( // IN UINT64 *Entry, // IN UINT64 Value, // IN UINT64 Address // ) // // Align this routine to a log2 upper bound of its size, so that it is // guaranteed not to cross a page or block boundary. ASM_FUNC_ALIGN(ArmReplaceLiveTranslationEntry, 0x200) // disable interrupts mrs x4, daif msr daifset, #0xf isb EL1_OR_EL2(x5) 1:__replace_entry 1 b 4f 2:__replace_entry 2 4:msr daif, x4 ret ASM_GLOBAL ASM_PFX(ArmReplaceLiveTranslationEntrySize) ASM_PFX(ArmReplaceLiveTranslationEntrySize): .long . - ArmReplaceLiveTranslationEntry // Double check that we did not overrun the assumed maximum size or cross a // 0x200 boundary (and thus implicitly not any larger power of two, including // the page size). .balign 0x200 .org ArmReplaceLiveTranslationEntry + 0x200