gunyah.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  4. */
  5. #ifndef _LINUX_GUNYAH_H
  6. #define _LINUX_GUNYAH_H
  7. #include <linux/bitfield.h>
  8. #include <linux/errno.h>
  9. #include <linux/interrupt.h>
  10. #include <linux/limits.h>
  11. #include <linux/mailbox_controller.h>
  12. #include <linux/mailbox_client.h>
  13. #include <linux/types.h>
  14. /* Matches resource manager's resource types for VM_GET_HYP_RESOURCES RPC */
  15. enum gh_resource_type {
  16. GH_RESOURCE_TYPE_BELL_TX = 0,
  17. GH_RESOURCE_TYPE_BELL_RX = 1,
  18. GH_RESOURCE_TYPE_MSGQ_TX = 2,
  19. GH_RESOURCE_TYPE_MSGQ_RX = 3,
  20. GH_RESOURCE_TYPE_VCPU = 4,
  21. };
  22. struct gh_resource {
  23. enum gh_resource_type type;
  24. u64 capid;
  25. unsigned int irq;
  26. struct list_head list;
  27. u32 rm_label;
  28. };
  29. /**
  30. * Gunyah Message Queues
  31. */
  32. #define GH_MSGQ_MAX_MSG_SIZE 240
  33. struct gh_msgq_tx_data {
  34. size_t length;
  35. bool push;
  36. char data[];
  37. };
  38. struct gh_msgq_rx_data {
  39. size_t length;
  40. char data[GH_MSGQ_MAX_MSG_SIZE];
  41. };
  42. struct gh_msgq {
  43. struct gh_resource *tx_ghrsc;
  44. struct gh_resource *rx_ghrsc;
  45. /* msgq private */
  46. int last_ret; /* Linux error, not GH_STATUS_* */
  47. struct mbox_chan mbox_chan;
  48. struct mbox_controller mbox;
  49. struct tasklet_struct txdone_tasklet;
  50. };
  51. int gh_msgq_init(struct device *parent, struct gh_msgq *msgq, struct mbox_client *cl,
  52. struct gh_resource *tx_ghrsc, struct gh_resource *rx_ghrsc);
  53. void gh_msgq_remove(struct gh_msgq *msgq);
  54. static inline struct mbox_chan *gh_msgq_chan(struct gh_msgq *msgq)
  55. {
  56. return &msgq->mbox.chans[0];
  57. }
  58. /******************************************************************************/
  59. /* Common arch-independent definitions for Gunyah hypercalls */
  60. #define GH_CAPID_INVAL U64_MAX
  61. #define GH_VMID_ROOT_VM 0xff
  62. enum gh_error {
  63. GH_ERROR_OK = 0,
  64. GH_ERROR_UNIMPLEMENTED = -1,
  65. GH_ERROR_RETRY = -2,
  66. GH_ERROR_ARG_INVAL = 1,
  67. GH_ERROR_ARG_SIZE = 2,
  68. GH_ERROR_ARG_ALIGN = 3,
  69. GH_ERROR_NOMEM = 10,
  70. GH_ERROR_ADDR_OVFL = 20,
  71. GH_ERROR_ADDR_UNFL = 21,
  72. GH_ERROR_ADDR_INVAL = 22,
  73. GH_ERROR_DENIED = 30,
  74. GH_ERROR_BUSY = 31,
  75. GH_ERROR_IDLE = 32,
  76. GH_ERROR_IRQ_BOUND = 40,
  77. GH_ERROR_IRQ_UNBOUND = 41,
  78. GH_ERROR_CSPACE_CAP_NULL = 50,
  79. GH_ERROR_CSPACE_CAP_REVOKED = 51,
  80. GH_ERROR_CSPACE_WRONG_OBJ_TYPE = 52,
  81. GH_ERROR_CSPACE_INSUF_RIGHTS = 53,
  82. GH_ERROR_CSPACE_FULL = 54,
  83. GH_ERROR_MSGQUEUE_EMPTY = 60,
  84. GH_ERROR_MSGQUEUE_FULL = 61,
  85. };
  86. /**
  87. * gh_error_remap() - Remap Gunyah hypervisor errors into a Linux error code
  88. * @gh_error: Gunyah hypercall return value
  89. */
  90. static inline int gh_error_remap(enum gh_error gh_error)
  91. {
  92. switch (gh_error) {
  93. case GH_ERROR_OK:
  94. return 0;
  95. case GH_ERROR_NOMEM:
  96. return -ENOMEM;
  97. case GH_ERROR_DENIED:
  98. case GH_ERROR_CSPACE_CAP_NULL:
  99. case GH_ERROR_CSPACE_CAP_REVOKED:
  100. case GH_ERROR_CSPACE_WRONG_OBJ_TYPE:
  101. case GH_ERROR_CSPACE_INSUF_RIGHTS:
  102. case GH_ERROR_CSPACE_FULL:
  103. return -EACCES;
  104. case GH_ERROR_BUSY:
  105. case GH_ERROR_IDLE:
  106. return -EBUSY;
  107. case GH_ERROR_IRQ_BOUND:
  108. case GH_ERROR_IRQ_UNBOUND:
  109. case GH_ERROR_MSGQUEUE_FULL:
  110. case GH_ERROR_MSGQUEUE_EMPTY:
  111. return -EIO;
  112. case GH_ERROR_UNIMPLEMENTED:
  113. case GH_ERROR_RETRY:
  114. return -EOPNOTSUPP;
  115. default:
  116. return -EINVAL;
  117. }
  118. }
  119. enum gh_api_feature {
  120. GH_FEATURE_DOORBELL = 1,
  121. GH_FEATURE_MSGQUEUE = 2,
  122. GH_FEATURE_VCPU = 5,
  123. GH_FEATURE_MEMEXTENT = 6,
  124. };
  125. bool arch_is_gh_guest(void);
  126. #define GH_API_V1 1
  127. /* Other bits reserved for future use and will be zero */
  128. #define GH_API_INFO_API_VERSION_MASK GENMASK_ULL(13, 0)
  129. #define GH_API_INFO_BIG_ENDIAN BIT_ULL(14)
  130. #define GH_API_INFO_IS_64BIT BIT_ULL(15)
  131. #define GH_API_INFO_VARIANT_MASK GENMASK_ULL(63, 56)
  132. struct gh_hypercall_hyp_identify_resp {
  133. u64 api_info;
  134. u64 flags[3];
  135. };
  136. static inline u16 gh_api_version(const struct gh_hypercall_hyp_identify_resp *gh_api)
  137. {
  138. return FIELD_GET(GH_API_INFO_API_VERSION_MASK, gh_api->api_info);
  139. }
  140. void gh_hypercall_hyp_identify(struct gh_hypercall_hyp_identify_resp *hyp_identity);
  141. enum gh_error gh_hypercall_bell_send(u64 capid, u64 new_flags, u64 *old_flags);
  142. enum gh_error gh_hypercall_bell_set_mask(u64 capid, u64 enable_mask, u64 ack_mask);
  143. #define GH_HYPERCALL_MSGQ_TX_FLAGS_PUSH BIT(0)
  144. enum gh_error gh_hypercall_msgq_send(u64 capid, size_t size, void *buff, u64 tx_flags, bool *ready);
  145. enum gh_error gh_hypercall_msgq_recv(u64 capid, void *buff, size_t size, size_t *recv_size,
  146. bool *ready);
  147. struct gh_hypercall_vcpu_run_resp {
  148. union {
  149. enum {
  150. /* VCPU is ready to run */
  151. GH_VCPU_STATE_READY = 0,
  152. /* VCPU is sleeping until an interrupt arrives */
  153. GH_VCPU_STATE_EXPECTS_WAKEUP = 1,
  154. /* VCPU is powered off */
  155. GH_VCPU_STATE_POWERED_OFF = 2,
  156. /* VCPU is blocked in EL2 for unspecified reason */
  157. GH_VCPU_STATE_BLOCKED = 3,
  158. /* VCPU has returned for MMIO READ */
  159. GH_VCPU_ADDRSPACE_VMMIO_READ = 4,
  160. /* VCPU has returned for MMIO WRITE */
  161. GH_VCPU_ADDRSPACE_VMMIO_WRITE = 5,
  162. } state;
  163. u64 sized_state;
  164. };
  165. u64 state_data[3];
  166. };
  167. enum gh_error gh_hypercall_vcpu_run(u64 capid, u64 *resume_data,
  168. struct gh_hypercall_vcpu_run_resp *resp);
  169. #endif