| /* |
| * Copyright (c) 2023 EPAM Systems |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <zephyr/drivers/tee.h> |
| |
| int tee_add_shm(const struct device *dev, void *addr, size_t align, size_t size, |
| uint32_t flags, struct tee_shm **shmp) |
| { |
| int rc; |
| void *p = addr; |
| struct tee_shm *shm; |
| |
| if (!shmp) { |
| return -EINVAL; |
| } |
| |
| if (flags & TEE_SHM_ALLOC) { |
| if (align) { |
| p = k_aligned_alloc(align, size); |
| } else { |
| p = k_malloc(size); |
| } |
| } |
| |
| if (!p) { |
| return -ENOMEM; |
| } |
| |
| shm = k_malloc(sizeof(struct tee_shm)); |
| if (!shm) { |
| rc = -ENOMEM; |
| goto err; |
| } |
| |
| shm->addr = p; |
| shm->size = size; |
| shm->flags = flags; |
| shm->dev = dev; |
| |
| if (flags & TEE_SHM_REGISTER) { |
| const struct tee_driver_api *api = (const struct tee_driver_api *)dev->api; |
| |
| if (!api->shm_register) { |
| rc = -ENOSYS; |
| goto err; |
| } |
| |
| rc = api->shm_register(dev, shm); |
| if (rc) { |
| goto err; |
| } |
| } |
| |
| *shmp = shm; |
| |
| return 0; |
| err: |
| k_free(shm); |
| if (flags & TEE_SHM_ALLOC) { |
| k_free(p); |
| } |
| |
| return rc; |
| } |
| |
| int tee_rm_shm(const struct device *dev, struct tee_shm *shm) |
| { |
| int rc = 0; |
| |
| if (!shm) { |
| return -EINVAL; |
| } |
| |
| if (shm->flags & TEE_SHM_REGISTER) { |
| const struct tee_driver_api *api = (const struct tee_driver_api *)dev->api; |
| |
| if (api->shm_unregister) { |
| /* |
| * We don't return immediately if callback returned error, |
| * just return this code after cleanup. |
| */ |
| rc = api->shm_unregister(dev, shm); |
| } else { |
| /* |
| * Set ENOSYS is SHM_REGISTER flag was set, but callback |
| * is not set. |
| */ |
| rc = -ENOSYS; |
| } |
| } |
| |
| if (shm->flags & TEE_SHM_ALLOC) { |
| k_free(shm->addr); |
| } |
| |
| k_free(shm); |
| |
| return rc; |
| } |