1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014, STMicroelectronics International N.V. 4 * Copyright (c) 2015, Linaro Limited 5 */ 6 7 #include <mm/core_memprot.h> 8 #include <mm/core_mmu.h> 9 #include <tee/cache.h> 10 11 /* 12 * tee_uta_cache_operation - dynamic cache clean/inval request from a TA. 13 * It follows ARM recommendation: 14 * https://developer.arm.com/documentation/ddi0246/c/Beicdhde 15 * Note that this implementation assumes dsb operations are part of 16 * cache_op_inner(), and outer cache sync are part of cache_op_outer(). 17 */ 18 TEE_Result cache_operation(enum utee_cache_operation op, void *va, size_t len) 19 { 20 TEE_Result res; 21 paddr_t pa; 22 23 pa = virt_to_phys(va); 24 if (!pa) 25 return TEE_ERROR_ACCESS_DENIED; 26 27 switch (op) { 28 case TEE_CACHEFLUSH: 29 #ifdef CFG_PL310 /* prevent initial L1 clean in case there is no outer L2 */ 30 /* Clean L1, Flush L2, Flush L1 */ 31 res = cache_op_inner(DCACHE_AREA_CLEAN, va, len); 32 if (res != TEE_SUCCESS) 33 return res; 34 res = cache_op_outer(DCACHE_AREA_CLEAN_INV, pa, len); 35 if (res != TEE_SUCCESS) 36 return res; 37 #endif 38 return cache_op_inner(DCACHE_AREA_CLEAN_INV, va, len); 39 40 case TEE_CACHECLEAN: 41 /* Clean L1, Clean L2 */ 42 res = cache_op_inner(DCACHE_AREA_CLEAN, va, len); 43 if (res != TEE_SUCCESS) 44 return res; 45 return cache_op_outer(DCACHE_AREA_CLEAN, pa, len); 46 47 case TEE_CACHEINVALIDATE: 48 /* Inval L2, Inval L1 */ 49 res = cache_op_outer(DCACHE_AREA_INVALIDATE, pa, len); 50 if (res != TEE_SUCCESS) 51 return res; 52 return cache_op_inner(DCACHE_AREA_INVALIDATE, va, len); 53 54 default: 55 return TEE_ERROR_NOT_SUPPORTED; 56 } 57 } 58