supplicant.c 2.2 KB

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