uboot/drivers/tee/optee/supplicant.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-2-Clause
   2/*
   3 * Copyright (c) 2018, Linaro Limited
   4 */
   5
   6#include <common.h>
   7#include <log.h>
   8#include <malloc.h>
   9#include <tee.h>
  10#include <linux/types.h>
  11
  12#include "optee_msg.h"
  13#include "optee_msg_supplicant.h"
  14#include "optee_private.h"
  15#include "optee_smc.h"
  16
  17static void cmd_shm_alloc(struct udevice *dev, struct optee_msg_arg *arg,
  18                          void **page_list)
  19{
  20        int rc;
  21        struct tee_shm *shm;
  22        void *pl;
  23        u64 ph_ptr;
  24
  25        arg->ret_origin = TEE_ORIGIN_COMMS;
  26
  27        if (arg->num_params != 1 ||
  28            arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
  29                arg->ret = TEE_ERROR_BAD_PARAMETERS;
  30                return;
  31        }
  32
  33        rc = __tee_shm_add(dev, 0, NULL, arg->params[0].u.value.b,
  34                           TEE_SHM_REGISTER | TEE_SHM_ALLOC, &shm);
  35        if (rc) {
  36                if (rc == -ENOMEM)
  37                        arg->ret = TEE_ERROR_OUT_OF_MEMORY;
  38                else
  39                        arg->ret = TEE_ERROR_GENERIC;
  40                return;
  41        }
  42
  43        pl = optee_alloc_and_init_page_list(shm->addr, shm->size, &ph_ptr);
  44        if (!pl) {
  45                arg->ret = TEE_ERROR_OUT_OF_MEMORY;
  46                tee_shm_free(shm);
  47                return;
  48        }
  49
  50        *page_list = pl;
  51        arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT |
  52                              OPTEE_MSG_ATTR_NONCONTIG;
  53        arg->params[0].u.tmem.buf_ptr = ph_ptr;
  54        arg->params[0].u.tmem.size = shm->size;
  55        arg->params[0].u.tmem.shm_ref = (ulong)shm;
  56        arg->ret = TEE_SUCCESS;
  57}
  58
  59static void cmd_shm_free(struct optee_msg_arg *arg)
  60{
  61        arg->ret_origin = TEE_ORIGIN_COMMS;
  62
  63        if (arg->num_params != 1 ||
  64            arg->params[0].attr != OPTEE_MSG_ATTR_TYPE_VALUE_INPUT) {
  65                arg->ret = TEE_ERROR_BAD_PARAMETERS;
  66                return;
  67        }
  68
  69        tee_shm_free((struct tee_shm *)(ulong)arg->params[0].u.value.b);
  70        arg->ret = TEE_SUCCESS;
  71}
  72
  73void optee_suppl_cmd(struct udevice *dev, struct tee_shm *shm_arg,
  74                     void **page_list)
  75{
  76        struct optee_msg_arg *arg = shm_arg->addr;
  77
  78        switch (arg->cmd) {
  79        case OPTEE_MSG_RPC_CMD_SHM_ALLOC:
  80                cmd_shm_alloc(dev, arg, page_list);
  81                break;
  82        case OPTEE_MSG_RPC_CMD_SHM_FREE:
  83                cmd_shm_free(arg);
  84                break;
  85        case OPTEE_MSG_RPC_CMD_FS:
  86                debug("REE FS storage isn't available\n");
  87                arg->ret = TEE_ERROR_STORAGE_NOT_AVAILABLE;
  88                break;
  89        case OPTEE_MSG_RPC_CMD_RPMB:
  90                optee_suppl_cmd_rpmb(dev, arg);
  91                break;
  92        case OPTEE_MSG_RPC_CMD_I2C_TRANSFER:
  93                optee_suppl_cmd_i2c_transfer(arg);
  94                break;
  95        default:
  96                arg->ret = TEE_ERROR_NOT_IMPLEMENTED;
  97        }
  98
  99        arg->ret_origin = TEE_ORIGIN_COMMS;
 100}
 101