smcinvoke_object.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
  2. /*
  3. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #ifndef __SMCINVOKE_OBJECT_H
  7. #define __SMCINVOKE_OBJECT_H
  8. #include <linux/types.h>
  9. #include <linux/firmware.h>
  10. #include <linux/qtee_shmbridge.h>
  11. #include "smcinvoke.h"
  12. /*
  13. * Method bits are not modified by transport layers. These describe the
  14. * method (member function) being requested by the client.
  15. */
  16. #define OBJECT_OP_METHOD_MASK (0x0000FFFFu)
  17. #define OBJECT_OP_METHODID(op) ((op) & OBJECT_OP_METHOD_MASK)
  18. #define OBJECT_OP_RELEASE (OBJECT_OP_METHOD_MASK - 0)
  19. #define OBJECT_OP_RETAIN (OBJECT_OP_METHOD_MASK - 1)
  20. #define OBJECT_OP_MAP_REGION 0
  21. #define OBJECT_OP_YIELD 1
  22. #define OBJECT_OP_SLEEP 2
  23. #define OBJECT_COUNTS_MAX_BI 0xF
  24. #define OBJECT_COUNTS_MAX_BO 0xF
  25. #define OBJECT_COUNTS_MAX_OI 0xF
  26. #define OBJECT_COUNTS_MAX_OO 0xF
  27. /* unpack counts */
  28. #define OBJECT_COUNTS_NUM_BI(k) ((size_t) (((k) >> 0) & OBJECT_COUNTS_MAX_BI))
  29. #define OBJECT_COUNTS_NUM_BO(k) ((size_t) (((k) >> 4) & OBJECT_COUNTS_MAX_BO))
  30. #define OBJECT_COUNTS_NUM_OI(k) ((size_t) (((k) >> 8) & OBJECT_COUNTS_MAX_OI))
  31. #define OBJECT_COUNTS_NUM_OO(k) ((size_t) (((k) >> 12) & OBJECT_COUNTS_MAX_OO))
  32. #define OBJECT_COUNTS_NUM_buffers(k) \
  33. (OBJECT_COUNTS_NUM_BI(k) + OBJECT_COUNTS_NUM_BO(k))
  34. #define OBJECT_COUNTS_NUM_objects(k) \
  35. (OBJECT_COUNTS_NUM_OI(k) + OBJECT_COUNTS_NUM_OO(k))
  36. /* Indices into args[] */
  37. #define OBJECT_COUNTS_INDEX_BI(k) 0
  38. #define OBJECT_COUNTS_INDEX_BO(k) \
  39. (OBJECT_COUNTS_INDEX_BI(k) + OBJECT_COUNTS_NUM_BI(k))
  40. #define OBJECT_COUNTS_INDEX_OI(k) \
  41. (OBJECT_COUNTS_INDEX_BO(k) + OBJECT_COUNTS_NUM_BO(k))
  42. #define OBJECT_COUNTS_INDEX_OO(k) \
  43. (OBJECT_COUNTS_INDEX_OI(k) + OBJECT_COUNTS_NUM_OI(k))
  44. #define OBJECT_COUNTS_TOTAL(k) \
  45. (OBJECT_COUNTS_INDEX_OO(k) + OBJECT_COUNTS_NUM_OO(k))
  46. #define OBJECT_COUNTS_PACK(in_bufs, out_bufs, in_objs, out_objs) \
  47. ((uint32_t) ((in_bufs) | ((out_bufs) << 4) | \
  48. ((in_objs) << 8) | ((out_objs) << 12)))
  49. #define OBJECT_COUNTS_INDEX_buffers(k) OBJECT_COUNTS_INDEX_BI(k)
  50. /* Object_invoke return codes */
  51. #define OBJECT_isOK(err) ((err) == 0)
  52. #define OBJECT_isERROR(err) ((err) != 0)
  53. /* Generic error codes */
  54. #define OBJECT_OK 0 /* non-specific success code */
  55. #define OBJECT_ERROR 1 /* non-specific error */
  56. #define OBJECT_ERROR_INVALID 2 /* unsupported/unrecognized request */
  57. #define OBJECT_ERROR_SIZE_IN 3 /* supplied buffer/string too large */
  58. #define OBJECT_ERROR_SIZE_OUT 4 /* supplied output buffer too small */
  59. #define OBJECT_ERROR_USERBASE 10 /* start of user-defined error range */
  60. /* Transport layer error codes */
  61. #define OBJECT_ERROR_DEFUNCT -90 /* object no longer exists */
  62. #define OBJECT_ERROR_ABORT -91 /* calling thread must exit */
  63. #define OBJECT_ERROR_BADOBJ -92 /* invalid object context */
  64. #define OBJECT_ERROR_NOSLOTS -93 /* caller's object table full */
  65. #define OBJECT_ERROR_MAXARGS -94 /* too many args */
  66. #define OBJECT_ERROR_MAXDATA -95 /* buffers too large */
  67. #define OBJECT_ERROR_UNAVAIL -96 /* the request could not be processed */
  68. #define OBJECT_ERROR_KMEM -97 /* kernel out of memory */
  69. #define OBJECT_ERROR_REMOTE -98 /* local method sent to remote object */
  70. #define OBJECT_ERROR_BUSY -99 /* Object is busy */
  71. #define Object_ERROR_TIMEOUT -103 /* Call Back Object invocation timed out. */
  72. #define FOR_ARGS(ndxvar, counts, section) \
  73. for (ndxvar = OBJECT_COUNTS_INDEX_##section(counts); \
  74. ndxvar < (OBJECT_COUNTS_INDEX_##section(counts) \
  75. + OBJECT_COUNTS_NUM_##section(counts)); \
  76. ++ndxvar)
  77. /* ObjectOp */
  78. #define ObjectOp_METHOD_MASK ((uint32_t) 0x0000FFFFu)
  79. #define ObjectOp_methodID(op) ((op) & ObjectOp_METHOD_MASK)
  80. #define ObjectOp_LOCAL ((uint32_t) 0x00008000U)
  81. #define ObjectOp_isLocal(op) (((op) & ObjectOp_LOCAL) != 0)
  82. #define Object_OP_release (ObjectOp_METHOD_MASK - 0)
  83. #define Object_OP_retain (ObjectOp_METHOD_MASK - 1)
  84. /* Object */
  85. #define ObjectCounts_pack(nBuffersIn, nBuffersOut, nObjectsIn, nObjectsOut) \
  86. ((uint32_t) ((nBuffersIn) | \
  87. ((nBuffersOut) << 4) | \
  88. ((nObjectsIn) << 8) | \
  89. ((nObjectsOut) << 12)))
  90. union ObjectArg;
  91. struct smcinvoke_cmd_req;
  92. typedef int32_t (*ObjectInvoke)(void *h,
  93. uint32_t op,
  94. union ObjectArg *args,
  95. uint32_t counts);
  96. struct Object {
  97. ObjectInvoke invoke;
  98. void *context;
  99. };
  100. struct ObjectBuf {
  101. void *ptr;
  102. size_t size;
  103. };
  104. struct ObjectBufIn {
  105. const void *ptr;
  106. size_t size;
  107. };
  108. union ObjectArg {
  109. struct ObjectBuf b;
  110. struct ObjectBufIn bi;
  111. struct Object o;
  112. };
  113. static inline int32_t Object_invoke(struct Object o, uint32_t op,
  114. union ObjectArg *args, uint32_t k)
  115. {
  116. return o.invoke(o.context, op, args, k);
  117. }
  118. #define Object_NULL ((struct Object){NULL, NULL})
  119. #define OBJECT_NOT_RETAINED
  120. #define OBJECT_CONSUMED
  121. static inline int32_t Object_release(OBJECT_CONSUMED struct Object o)
  122. {
  123. return Object_invoke((o), Object_OP_release, 0, 0);
  124. }
  125. static inline int32_t Object_retain(struct Object o)
  126. {
  127. return Object_invoke((o), Object_OP_retain, 0, 0);
  128. }
  129. #define Object_isNull(o) ((o).invoke == NULL)
  130. #define Object_RELEASE_IF(o) \
  131. do { \
  132. struct Object o_ = (o); \
  133. if (!Object_isNull(o_)) \
  134. (void) Object_release(o_); \
  135. } while (0)
  136. static inline void Object_replace(struct Object *loc, struct Object objNew)
  137. {
  138. if (!Object_isNull(*loc))
  139. Object_release(*loc);
  140. if (!Object_isNull(objNew))
  141. Object_retain(objNew);
  142. *loc = objNew;
  143. }
  144. #define Object_ASSIGN_NULL(loc) Object_replace(&(loc), Object_NULL)
  145. #define SMCINVOKE_INTERFACE_MAX_RETRY 5
  146. #define SMCINVOKE_INTERFACE_BUSY_WAIT_MS 5
  147. int smcinvoke_release_from_kernel_client(int fd);
  148. int get_root_fd(int *root_fd);
  149. int process_invoke_request_from_kernel_client(
  150. int fd, struct smcinvoke_cmd_req *req);
  151. char *firmware_request_from_smcinvoke(const char *appname, size_t *fw_size, struct qtee_shm *shm);
  152. int32_t get_client_env_object(struct Object *clientEnvObj);
  153. #endif /* __SMCINVOKE_OBJECT_H */