static bool arm_va2pa_helper(void *va, paddr_t *pa) { uint32_t exceptions = thread_mask_exceptions(THREAD_EXCP_ALL); paddr_t par; paddr_t par_pa_mask; bool ret = false; #ifdef ARM32 write_ats1cpr((vaddr_t)va); isb(); #ifdef CFG_WITH_LPAE par = read_par64(); par_pa_mask = PAR64_PA_MASK; #else par = read_par32(); par_pa_mask = PAR32_PA_MASK; #endif #endif /*ARM32*/ #ifdef ARM64 write_at_s1e1r((vaddr_t)va); isb(); par = read_par_el1(); par_pa_mask = PAR_PA_MASK; #endif if (par & PAR_F) goto out; *pa = (par & (par_pa_mask << PAR_PA_SHIFT)) | ((vaddr_t)va & ((1 << PAR_PA_SHIFT) - 1)); ret = true; out: thread_unmask_exceptions(exceptions); return ret; }
/******************************************************************************* * This function helps the SP to translate NS/S virtual addresses. ******************************************************************************/ uint64_t tlkd_va_translate(uintptr_t va, int type) { uint64_t pa; if (type & TLK_TRANSLATE_NS_VADDR) { /* save secure context */ cm_el1_sysregs_context_save(SECURE); /* restore non-secure context */ cm_el1_sysregs_context_restore(NON_SECURE); /* switch NS bit to start using 64-bit, non-secure mappings */ write_scr(cm_get_scr_el3(NON_SECURE)); isb(); } int at = type & AT_MASK; switch (at) { case 0: ats12e1r(va); break; case 1: ats12e1w(va); break; case 2: ats12e0r(va); break; case 3: ats12e0w(va); break; default: assert(0); } /* get the (NS/S) physical address */ isb(); pa = read_par_el1(); /* Restore secure state */ if (type & TLK_TRANSLATE_NS_VADDR) { /* restore secure context */ cm_el1_sysregs_context_restore(SECURE); /* switch NS bit to start using 32-bit, secure mappings */ write_scr(cm_get_scr_el3(SECURE)); isb(); } return pa; }