xref: /optee_os/core/arch/arm/tee/cache.c (revision 2de2880065f3f8232873dfb1dd4b94322f0f3971)
11bb92983SJerome Forissier // SPDX-License-Identifier: BSD-2-Clause
22221cb56SEtienne Carriere /*
32221cb56SEtienne Carriere  * Copyright (c) 2014, STMicroelectronics International N.V.
42221cb56SEtienne Carriere  * Copyright (c) 2015, Linaro Limited
52221cb56SEtienne Carriere  */
62221cb56SEtienne Carriere 
72221cb56SEtienne Carriere #include <mm/core_memprot.h>
893a2ed07SEtienne Carriere #include <mm/core_mmu.h>
92221cb56SEtienne Carriere #include <tee/cache.h>
102221cb56SEtienne Carriere 
112221cb56SEtienne Carriere /*
12cba1d39bSEtienne Carriere  * tee_uta_cache_operation - dynamic cache clean/inval request from a TA.
132221cb56SEtienne Carriere  * It follows ARM recommendation:
14*2de28800SJorge Ramirez-Ortiz  *     https://developer.arm.com/documentation/ddi0246/c/Beicdhde
152221cb56SEtienne Carriere  * Note that this implementation assumes dsb operations are part of
16cba1d39bSEtienne Carriere  * cache_op_inner(), and outer cache sync are part of cache_op_outer().
172221cb56SEtienne Carriere  */
cache_operation(enum utee_cache_operation op,void * va,size_t len)182221cb56SEtienne Carriere TEE_Result cache_operation(enum utee_cache_operation op, void *va, size_t len)
192221cb56SEtienne Carriere {
202221cb56SEtienne Carriere 	TEE_Result res;
212221cb56SEtienne Carriere 	paddr_t pa;
222221cb56SEtienne Carriere 
232221cb56SEtienne Carriere 	pa = virt_to_phys(va);
242221cb56SEtienne Carriere 	if (!pa)
252221cb56SEtienne Carriere 		return TEE_ERROR_ACCESS_DENIED;
262221cb56SEtienne Carriere 
272221cb56SEtienne Carriere 	switch (op) {
282221cb56SEtienne Carriere 	case TEE_CACHEFLUSH:
2993a2ed07SEtienne Carriere #ifdef CFG_PL310 /* prevent initial L1 clean in case there is no outer L2 */
302221cb56SEtienne Carriere 		/* Clean L1, Flush L2, Flush L1 */
31cba1d39bSEtienne Carriere 		res = cache_op_inner(DCACHE_AREA_CLEAN, va, len);
322221cb56SEtienne Carriere 		if (res != TEE_SUCCESS)
332221cb56SEtienne Carriere 			return res;
341cdd34d8SEtienne Carriere 		res = cache_op_outer(DCACHE_AREA_CLEAN_INV, pa, len);
352221cb56SEtienne Carriere 		if (res != TEE_SUCCESS)
362221cb56SEtienne Carriere 			return res;
37725e80afSEtienne Carriere #endif
38cba1d39bSEtienne Carriere 		return cache_op_inner(DCACHE_AREA_CLEAN_INV, va, len);
392221cb56SEtienne Carriere 
402221cb56SEtienne Carriere 	case TEE_CACHECLEAN:
412221cb56SEtienne Carriere 		/* Clean L1, Clean L2 */
42cba1d39bSEtienne Carriere 		res = cache_op_inner(DCACHE_AREA_CLEAN, va, len);
432221cb56SEtienne Carriere 		if (res != TEE_SUCCESS)
442221cb56SEtienne Carriere 			return res;
451cdd34d8SEtienne Carriere 		return cache_op_outer(DCACHE_AREA_CLEAN, pa, len);
462221cb56SEtienne Carriere 
472221cb56SEtienne Carriere 	case TEE_CACHEINVALIDATE:
482221cb56SEtienne Carriere 		/* Inval L2, Inval L1 */
491cdd34d8SEtienne Carriere 		res = cache_op_outer(DCACHE_AREA_INVALIDATE, pa, len);
502221cb56SEtienne Carriere 		if (res != TEE_SUCCESS)
512221cb56SEtienne Carriere 			return res;
52cba1d39bSEtienne Carriere 		return cache_op_inner(DCACHE_AREA_INVALIDATE, va, len);
532221cb56SEtienne Carriere 
542221cb56SEtienne Carriere 	default:
552221cb56SEtienne Carriere 		return TEE_ERROR_NOT_SUPPORTED;
562221cb56SEtienne Carriere 	}
572221cb56SEtienne Carriere }
58