xref: /optee_os/core/drivers/crypto/caam/caam_sm.c (revision 461cf006f26c8f9af67271c010f5b838c7479e1f)
12a12ae23SClement Faure // SPDX-License-Identifier: BSD-2-Clause
22a12ae23SClement Faure /*
3*461cf006SSahil Malhotra  * Copyright 2019, 2023-2024 NXP
42a12ae23SClement Faure  */
52a12ae23SClement Faure #include <caam_common.h>
62a12ae23SClement Faure #include <caam_hal_ctrl.h>
72a12ae23SClement Faure #include <caam_hal_sm.h>
82a12ae23SClement Faure #include <caam_jr.h>
92a12ae23SClement Faure #include <caam_status.h>
102a12ae23SClement Faure #include <caam_sm.h>
112a12ae23SClement Faure #include <tee_api_defines.h>
122a12ae23SClement Faure 
132a12ae23SClement Faure /*
142a12ae23SClement Faure  * Secure memory module private data
152a12ae23SClement Faure  */
162a12ae23SClement Faure static struct sm_privdata {
172a12ae23SClement Faure 	vaddr_t baseaddr;  /* Secure memory base address */
182a12ae23SClement Faure 	vaddr_t ctrl_addr; /* CAAM base address */
192a12ae23SClement Faure 	vaddr_t jr_addr;   /* Job Ring base address */
202a12ae23SClement Faure 	paddr_t jr_offset; /* Job Ring offset */
212a12ae23SClement Faure } sm_privdata;
222a12ae23SClement Faure 
caam_sm_alloc(const struct caam_sm_page_desc * page_desc,struct caam_sm_page_addr * page_addr)232a12ae23SClement Faure enum caam_status caam_sm_alloc(const struct caam_sm_page_desc *page_desc,
242a12ae23SClement Faure 			       struct caam_sm_page_addr *page_addr)
252a12ae23SClement Faure {
262a12ae23SClement Faure 	enum caam_status ret = CAAM_FAILURE;
272a12ae23SClement Faure 
282a12ae23SClement Faure 	if (!page_desc || !page_addr)
292a12ae23SClement Faure 		return TEE_ERROR_BAD_PARAMETERS;
302a12ae23SClement Faure 
312a12ae23SClement Faure 	ret = caam_hal_sm_check_page_partition(sm_privdata.jr_addr, page_desc);
322a12ae23SClement Faure 	if (ret != CAAM_NO_ERROR) {
332a12ae23SClement Faure 		SM_TRACE("Pages %u to %u or partition %u are out of bounds",
342a12ae23SClement Faure 			 page_desc->page,
352a12ae23SClement Faure 			 page_desc->page + page_desc->page_count - 1,
362a12ae23SClement Faure 			 page_desc->partition);
372a12ae23SClement Faure 		return ret;
382a12ae23SClement Faure 	}
392a12ae23SClement Faure 
402a12ae23SClement Faure 	/* Check if partition is already allocated */
412a12ae23SClement Faure 	if (!caam_hal_sm_prtn_is_free(sm_privdata.jr_addr,
422a12ae23SClement Faure 				      page_desc->partition)) {
432a12ae23SClement Faure 		SM_TRACE("Partition %u not available", page_desc->partition);
442a12ae23SClement Faure 		return CAAM_BUSY;
452a12ae23SClement Faure 	}
462a12ae23SClement Faure 
472a12ae23SClement Faure 	/* Open secure memory partition to all groups */
482a12ae23SClement Faure 	caam_hal_sm_open_access_perm(sm_privdata.jr_addr, page_desc->partition);
492a12ae23SClement Faure 	caam_hal_sm_set_access_all_group(sm_privdata.jr_addr,
502a12ae23SClement Faure 					 page_desc->partition);
512a12ae23SClement Faure 
522a12ae23SClement Faure 	ret = caam_hal_sm_allocate_page(sm_privdata.jr_addr, page_desc);
532a12ae23SClement Faure 	if (ret != CAAM_NO_ERROR) {
542a12ae23SClement Faure 		SM_TRACE("Error allocation Pages %u to %u into partition %u",
552a12ae23SClement Faure 			 page_desc->page,
562a12ae23SClement Faure 			 page_desc->page + page_desc->page_count - 1,
572a12ae23SClement Faure 			 page_desc->partition);
582a12ae23SClement Faure 
592a12ae23SClement Faure 		/* Free all potientiel pages allocated before failure */
602a12ae23SClement Faure 		return caam_hal_sm_deallocate_pages(sm_privdata.jr_addr,
612a12ae23SClement Faure 						    page_desc);
622a12ae23SClement Faure 	}
632a12ae23SClement Faure 
642a12ae23SClement Faure 	page_addr->paddr = caam_hal_ctrl_get_smvaddr(sm_privdata.ctrl_addr,
652a12ae23SClement Faure 						     sm_privdata.jr_offset) +
662a12ae23SClement Faure 			   caam_hal_sm_get_pages_size(sm_privdata.jr_addr,
672a12ae23SClement Faure 						      page_desc->page);
682a12ae23SClement Faure 	page_addr->vaddr = sm_privdata.baseaddr +
692a12ae23SClement Faure 			   caam_hal_sm_get_pages_size(sm_privdata.jr_addr,
702a12ae23SClement Faure 						      page_desc->page);
712a12ae23SClement Faure 
722a12ae23SClement Faure 	SM_TRACE("Partition %u Pages %u to %u allocated @0x%" PRIxVA
732a12ae23SClement Faure 		 " (phys 0x@%" PRIxPA,
742a12ae23SClement Faure 		 page_desc->partition, page_desc->page,
752a12ae23SClement Faure 		 page_desc->page + page_desc->page_count - 1, page_addr->vaddr,
762a12ae23SClement Faure 		 page_addr->paddr);
772a12ae23SClement Faure 
782a12ae23SClement Faure 	return CAAM_NO_ERROR;
792a12ae23SClement Faure }
802a12ae23SClement Faure 
caam_sm_free(const struct caam_sm_page_desc * page_desc)812a12ae23SClement Faure enum caam_status caam_sm_free(const struct caam_sm_page_desc *page_desc)
822a12ae23SClement Faure {
832a12ae23SClement Faure 	enum caam_status ret = CAAM_FAILURE;
842a12ae23SClement Faure 
852a12ae23SClement Faure 	SM_TRACE("Free Secure Memory pages %u to %u from partition %u",
862a12ae23SClement Faure 		 page_desc->page, page_desc->page + page_desc->page_count,
872a12ae23SClement Faure 		 page_desc->partition);
882a12ae23SClement Faure 
892a12ae23SClement Faure 	/*
902a12ae23SClement Faure 	 * De-allocate partition. It automatically releases partition's pages
912a12ae23SClement Faure 	 * to the pool of available pages. if the partition if marked as CSP,
922a12ae23SClement Faure 	 * pages will be zeroized. If the partition is marked as PSP,
932a12ae23SClement Faure 	 * partition and pages will not be de-allocated and a PSP will be
942a12ae23SClement Faure 	 * returned.
952a12ae23SClement Faure 	 */
962a12ae23SClement Faure 	if (!caam_hal_sm_prtn_is_owned(sm_privdata.jr_addr,
972a12ae23SClement Faure 				       page_desc->partition)) {
982a12ae23SClement Faure 		SM_TRACE("Partition %u not owned by used JR",
992a12ae23SClement Faure 			 page_desc->partition);
1002a12ae23SClement Faure 		return TEE_ERROR_ACCESS_DENIED;
1012a12ae23SClement Faure 	}
1022a12ae23SClement Faure 
1032a12ae23SClement Faure 	ret = caam_hal_sm_deallocate_pages(sm_privdata.jr_addr, page_desc);
1042a12ae23SClement Faure 	if (ret) {
1052a12ae23SClement Faure 		SM_TRACE("De-alloc pages %u to %u error 0x%" PRIx32,
1062a12ae23SClement Faure 			 page_desc->page,
1072a12ae23SClement Faure 			 page_desc->page + page_desc->page_count, ret);
1082a12ae23SClement Faure 
1092a12ae23SClement Faure 		return ret;
1102a12ae23SClement Faure 	}
1112a12ae23SClement Faure 
1122a12ae23SClement Faure 	ret = caam_hal_sm_deallocate_partition(sm_privdata.jr_addr,
1132a12ae23SClement Faure 					       page_desc->partition);
1142a12ae23SClement Faure 	if (ret) {
1152a12ae23SClement Faure 		SM_TRACE("De-alloc partition %u error 0x%" PRIx32,
1162a12ae23SClement Faure 			 page_desc->partition, ret);
1172a12ae23SClement Faure 		return ret;
1182a12ae23SClement Faure 	}
1192a12ae23SClement Faure 
1202a12ae23SClement Faure 	return CAAM_NO_ERROR;
1212a12ae23SClement Faure }
1222a12ae23SClement Faure 
1232a12ae23SClement Faure enum caam_status
caam_sm_set_access_perm(const struct caam_sm_page_desc * page_desc,unsigned int grp1_perm,unsigned int grp2_perm)1242a12ae23SClement Faure caam_sm_set_access_perm(const struct caam_sm_page_desc *page_desc,
1252a12ae23SClement Faure 			unsigned int grp1_perm, unsigned int grp2_perm)
1262a12ae23SClement Faure {
127*461cf006SSahil Malhotra 	uint32_t grp1 = 0;
128*461cf006SSahil Malhotra 	uint32_t grp2 = 0;
1292a12ae23SClement Faure 
1302a12ae23SClement Faure 	if (!page_desc)
1312a12ae23SClement Faure 		return CAAM_BAD_PARAM;
1322a12ae23SClement Faure 
1332a12ae23SClement Faure 	/* Check if the partition is already owned */
1342a12ae23SClement Faure 	if (!caam_hal_sm_prtn_is_owned(sm_privdata.jr_addr,
1352a12ae23SClement Faure 				       page_desc->partition)) {
1362a12ae23SClement Faure 		SM_TRACE("Partition %d not owned by current JR",
1372a12ae23SClement Faure 			 page_desc->partition);
1382a12ae23SClement Faure 		return CAAM_FAILURE;
1392a12ae23SClement Faure 	}
1402a12ae23SClement Faure 
1412a12ae23SClement Faure 	/*
1422a12ae23SClement Faure 	 * Set ourself to access Secure Memory group 1 and/or group 2
1432a12ae23SClement Faure 	 * function if @grp1_perm and/or @grp2_perm not equal 0.
1442a12ae23SClement Faure 	 *
1452a12ae23SClement Faure 	 * The Access Group is related to the Job Ring owner setting without
1462a12ae23SClement Faure 	 * the Secure Bit setting already managed by the Job Ring.
147*461cf006SSahil Malhotra 	 *
148*461cf006SSahil Malhotra 	 * If any group permissions are set, need to enable Secure World MID
149*461cf006SSahil Malhotra 	 * access in SMAG1/2 registers.
150*461cf006SSahil Malhotra 	 * Since both Non-Secure/Secure world has same MID, using JROWN_ARM_NS
151*461cf006SSahil Malhotra 	 * and if any grp1_perm/grp2_perm is set, need to enable permission
152*461cf006SSahil Malhotra 	 * for Secure World for partition in SMAG1/2 Registers.
1532a12ae23SClement Faure 	 */
1542a12ae23SClement Faure 	if (grp1_perm)
155*461cf006SSahil Malhotra 		grp1 = SHIFT_U32(1, JROWN_ARM_NS);
1562a12ae23SClement Faure 
1572a12ae23SClement Faure 	if (grp2_perm)
158*461cf006SSahil Malhotra 		grp2 = SHIFT_U32(1, JROWN_ARM_NS);
1592a12ae23SClement Faure 
1602a12ae23SClement Faure 	caam_hal_sm_set_access_group(sm_privdata.jr_addr, page_desc->partition,
1612a12ae23SClement Faure 				     grp1, grp2);
1622a12ae23SClement Faure 	caam_hal_sm_set_access_perm(sm_privdata.jr_addr, page_desc->partition,
1632a12ae23SClement Faure 				    grp1_perm, grp2_perm);
1642a12ae23SClement Faure 
1652a12ae23SClement Faure 	return CAAM_NO_ERROR;
1662a12ae23SClement Faure }
1672a12ae23SClement Faure 
caam_sm_init(struct caam_jrcfg * jrcfg)1682a12ae23SClement Faure enum caam_status caam_sm_init(struct caam_jrcfg *jrcfg)
1692a12ae23SClement Faure {
1702a12ae23SClement Faure 	if (!jrcfg)
1712a12ae23SClement Faure 		return CAAM_FAILURE;
1722a12ae23SClement Faure 
1732a12ae23SClement Faure 	sm_privdata.ctrl_addr = jrcfg->base;
1742a12ae23SClement Faure 	sm_privdata.jr_addr = jrcfg->base + jrcfg->offset;
1752a12ae23SClement Faure 	sm_privdata.jr_offset = jrcfg->offset;
1762a12ae23SClement Faure 	sm_privdata.baseaddr = caam_hal_sm_get_base();
1772a12ae23SClement Faure 
1782a12ae23SClement Faure 	if (!sm_privdata.baseaddr)
1792a12ae23SClement Faure 		return CAAM_FAILURE;
1802a12ae23SClement Faure 
1812a12ae23SClement Faure 	SM_TRACE("Secure Memory Base address = 0x%" PRIxVA,
1822a12ae23SClement Faure 		 sm_privdata.baseaddr);
1832a12ae23SClement Faure 	SM_TRACE("CAAM controller address = 0x%" PRIxVA, sm_privdata.ctrl_addr);
1842a12ae23SClement Faure 	SM_TRACE("CAAM Job Ring address = 0x%" PRIxVA, sm_privdata.jr_addr);
1852a12ae23SClement Faure 
1862a12ae23SClement Faure 	return CAAM_NO_ERROR;
1872a12ae23SClement Faure }
188