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