sdei_private.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #ifndef SDEI_PRIVATE_H
  7. #define SDEI_PRIVATE_H
  8. #include <errno.h>
  9. #include <stdbool.h>
  10. #include <stdint.h>
  11. #include <arch_helpers.h>
  12. #include <bl31/interrupt_mgmt.h>
  13. #include <common/debug.h>
  14. #include <context.h>
  15. #include <lib/el3_runtime/context_mgmt.h>
  16. #include <lib/spinlock.h>
  17. #include <lib/utils_def.h>
  18. #include <plat/common/platform.h>
  19. #include <services/sdei.h>
  20. #include <setjmp.h>
  21. #ifndef __aarch64__
  22. # error SDEI is implemented only for AArch64 systems
  23. #endif
  24. #ifndef PLAT_SDEI_CRITICAL_PRI
  25. # error Platform must define SDEI critical priority value
  26. #endif
  27. #ifndef PLAT_SDEI_NORMAL_PRI
  28. # error Platform must define SDEI normal priority value
  29. #endif
  30. /* Output SDEI logs as verbose */
  31. #define SDEI_LOG(...) VERBOSE("SDEI: " __VA_ARGS__)
  32. /* SDEI handler unregistered state. This is the default state. */
  33. #define SDEI_STATE_UNREGISTERED 0U
  34. /* SDE event status values in bit position */
  35. #define SDEI_STATF_REGISTERED 0U
  36. #define SDEI_STATF_ENABLED 1U
  37. #define SDEI_STATF_RUNNING 2U
  38. /* SDEI SMC error codes */
  39. #define SDEI_EINVAL (-2)
  40. #define SDEI_EDENY (-3)
  41. #define SDEI_EPEND (-5)
  42. #define SDEI_ENOMEM (-10)
  43. /*
  44. * 'info' parameter to SDEI_EVENT_GET_INFO SMC.
  45. *
  46. * Note that the SDEI v1.0 specification mistakenly enumerates the
  47. * SDEI_INFO_EV_SIGNALED as SDEI_INFO_SIGNALED. This will be corrected in a
  48. * future version.
  49. */
  50. #define SDEI_INFO_EV_TYPE 0
  51. #define SDEI_INFO_EV_NOT_SIGNALED 1
  52. #define SDEI_INFO_EV_PRIORITY 2
  53. #define SDEI_INFO_EV_ROUTING_MODE 3
  54. #define SDEI_INFO_EV_ROUTING_AFF 4
  55. #define SDEI_PRIVATE_MAPPING() (&sdei_global_mappings[SDEI_MAP_IDX_PRIV_])
  56. #define SDEI_SHARED_MAPPING() (&sdei_global_mappings[SDEI_MAP_IDX_SHRD_])
  57. #define for_each_mapping_type(_i, _mapping) \
  58. for ((_i) = 0, (_mapping) = &sdei_global_mappings[(_i)]; \
  59. (_i) < SDEI_MAP_IDX_MAX_; \
  60. (_i)++, (_mapping) = &sdei_global_mappings[(_i)])
  61. #define iterate_mapping(_mapping, _i, _map) \
  62. for ((_map) = (_mapping)->map, (_i) = 0; \
  63. (_i) < (_mapping)->num_maps; \
  64. (_i)++, (_map)++)
  65. #define for_each_private_map(_i, _map) \
  66. iterate_mapping(SDEI_PRIVATE_MAPPING(), _i, _map)
  67. #define for_each_shared_map(_i, _map) \
  68. iterate_mapping(SDEI_SHARED_MAPPING(), _i, _map)
  69. /* SDEI_FEATURES */
  70. #define SDEI_FEATURE_BIND_SLOTS 0U
  71. #define BIND_SLOTS_MASK 0xffffU
  72. #define FEATURES_SHARED_SLOTS_SHIFT 16U
  73. #define FEATURES_PRIVATE_SLOTS_SHIFT 0U
  74. #define FEATURE_BIND_SLOTS(_priv, _shrd) \
  75. (((((uint64_t) (_priv)) & BIND_SLOTS_MASK) << FEATURES_PRIVATE_SLOTS_SHIFT) | \
  76. ((((uint64_t) (_shrd)) & BIND_SLOTS_MASK) << FEATURES_SHARED_SLOTS_SHIFT))
  77. #define GET_EV_STATE(_e, _s) get_ev_state_bit(_e, SDEI_STATF_##_s)
  78. #define SET_EV_STATE(_e, _s) clr_ev_state_bit(_e->state, SDEI_STATF_##_s)
  79. static inline bool is_event_private(sdei_ev_map_t *map)
  80. {
  81. return ((map->map_flags & BIT_32(SDEI_MAPF_PRIVATE_SHIFT_)) != 0U);
  82. }
  83. static inline bool is_event_shared(sdei_ev_map_t *map)
  84. {
  85. return !is_event_private(map);
  86. }
  87. static inline bool is_event_critical(sdei_ev_map_t *map)
  88. {
  89. return ((map->map_flags & BIT_32(SDEI_MAPF_CRITICAL_SHIFT_)) != 0U);
  90. }
  91. static inline bool is_event_normal(sdei_ev_map_t *map)
  92. {
  93. return !is_event_critical(map);
  94. }
  95. static inline bool is_event_signalable(sdei_ev_map_t *map)
  96. {
  97. return ((map->map_flags & BIT_32(SDEI_MAPF_SIGNALABLE_SHIFT_)) != 0U);
  98. }
  99. static inline bool is_map_dynamic(sdei_ev_map_t *map)
  100. {
  101. return ((map->map_flags & BIT_32(SDEI_MAPF_DYNAMIC_SHIFT_)) != 0U);
  102. }
  103. /*
  104. * Checks whether an event is associated with an interrupt. Static events always
  105. * return true, and dynamic events return whether SDEI_INTERRUPT_BIND had been
  106. * called on them. This can be used on both static or dynamic events to check
  107. * for an associated interrupt.
  108. */
  109. static inline bool is_map_bound(sdei_ev_map_t *map)
  110. {
  111. return ((map->map_flags & BIT_32(SDEI_MAPF_BOUND_SHIFT_)) != 0U);
  112. }
  113. static inline void set_map_bound(sdei_ev_map_t *map)
  114. {
  115. map->map_flags |= BIT_32(SDEI_MAPF_BOUND_SHIFT_);
  116. }
  117. static inline bool is_map_explicit(sdei_ev_map_t *map)
  118. {
  119. return ((map->map_flags & BIT_32(SDEI_MAPF_EXPLICIT_SHIFT_)) != 0U);
  120. }
  121. static inline void clr_map_bound(sdei_ev_map_t *map)
  122. {
  123. map->map_flags &= ~BIT_32(SDEI_MAPF_BOUND_SHIFT_);
  124. }
  125. static inline bool is_secure_sgi(unsigned int intr)
  126. {
  127. return ((plat_ic_is_sgi(intr) != 0) &&
  128. (plat_ic_get_interrupt_type(intr) == INTR_TYPE_EL3));
  129. }
  130. /*
  131. * Determine EL of the client. If EL2 is implemented (hence the enabled HCE
  132. * bit), deem EL2; otherwise, deem EL1.
  133. */
  134. static inline unsigned int sdei_client_el(void)
  135. {
  136. cpu_context_t *ns_ctx = cm_get_context(NON_SECURE);
  137. el3_state_t *el3_ctx = get_el3state_ctx(ns_ctx);
  138. return ((read_ctx_reg(el3_ctx, CTX_SCR_EL3) & SCR_HCE_BIT) != 0U) ?
  139. MODE_EL2 : MODE_EL1;
  140. }
  141. static inline unsigned int sdei_event_priority(sdei_ev_map_t *map)
  142. {
  143. return (unsigned int) (is_event_critical(map) ? PLAT_SDEI_CRITICAL_PRI :
  144. PLAT_SDEI_NORMAL_PRI);
  145. }
  146. static inline bool get_ev_state_bit(sdei_entry_t *se, unsigned int bit_no)
  147. {
  148. return ((se->state & BIT_32(bit_no)) != 0U);
  149. }
  150. static inline void clr_ev_state_bit(sdei_entry_t *se, unsigned int bit_no)
  151. {
  152. se->state &= ~BIT_32(bit_no);
  153. }
  154. /* SDEI actions for state transition */
  155. typedef enum {
  156. /*
  157. * Actions resulting from client requests. These directly map to SMC
  158. * calls. Note that the state table columns are listed in this order
  159. * too.
  160. */
  161. DO_REGISTER = 0,
  162. DO_RELEASE = 1,
  163. DO_ENABLE = 2,
  164. DO_DISABLE = 3,
  165. DO_UNREGISTER = 4,
  166. DO_ROUTING = 5,
  167. DO_CONTEXT = 6,
  168. DO_COMPLETE = 7,
  169. DO_COMPLETE_RESUME = 8,
  170. /* Action for event dispatch */
  171. DO_DISPATCH = 9,
  172. DO_MAX,
  173. } sdei_action_t;
  174. typedef enum {
  175. SDEI_NORMAL,
  176. SDEI_CRITICAL
  177. } sdei_class_t;
  178. static inline void sdei_map_lock(sdei_ev_map_t *map)
  179. {
  180. spin_lock(&map->lock);
  181. }
  182. static inline void sdei_map_unlock(sdei_ev_map_t *map)
  183. {
  184. spin_unlock(&map->lock);
  185. }
  186. extern const sdei_mapping_t sdei_global_mappings[];
  187. extern sdei_entry_t sdei_private_event_table[];
  188. extern sdei_entry_t sdei_shared_event_table[];
  189. void init_sdei_state(void);
  190. sdei_ev_map_t *find_event_map_by_intr(unsigned int intr_num, bool shared);
  191. sdei_ev_map_t *find_event_map(int ev_num);
  192. sdei_entry_t *get_event_entry(sdei_ev_map_t *map);
  193. int64_t sdei_event_context(void *handle, unsigned int param);
  194. int sdei_event_complete(bool resume, uint64_t pc);
  195. void sdei_pe_unmask(void);
  196. int64_t sdei_pe_mask(void);
  197. int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
  198. void *cookie);
  199. bool can_sdei_state_trans(sdei_entry_t *se, sdei_action_t act);
  200. void begin_sdei_synchronous_dispatch(jmp_buf *buffer);
  201. #endif /* SDEI_PRIVATE_H */