sbi_trap.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2019 Western Digital Corporation or its affiliates.
  5. *
  6. * Authors:
  7. * Anup Patel <anup.patel@wdc.com>
  8. */
  9. #ifndef __SBI_TRAP_H__
  10. #define __SBI_TRAP_H__
  11. #include <sbi/riscv_encoding.h>
  12. /* clang-format off */
  13. /** Index of zero member in sbi_trap_regs */
  14. #define SBI_TRAP_REGS_zero 0
  15. /** Index of ra member in sbi_trap_regs */
  16. #define SBI_TRAP_REGS_ra 1
  17. /** Index of sp member in sbi_trap_regs */
  18. #define SBI_TRAP_REGS_sp 2
  19. /** Index of gp member in sbi_trap_regs */
  20. #define SBI_TRAP_REGS_gp 3
  21. /** Index of tp member in sbi_trap_regs */
  22. #define SBI_TRAP_REGS_tp 4
  23. /** Index of t0 member in sbi_trap_regs */
  24. #define SBI_TRAP_REGS_t0 5
  25. /** Index of t1 member in sbi_trap_regs */
  26. #define SBI_TRAP_REGS_t1 6
  27. /** Index of t2 member in sbi_trap_regs */
  28. #define SBI_TRAP_REGS_t2 7
  29. /** Index of s0 member in sbi_trap_regs */
  30. #define SBI_TRAP_REGS_s0 8
  31. /** Index of s1 member in sbi_trap_regs */
  32. #define SBI_TRAP_REGS_s1 9
  33. /** Index of a0 member in sbi_trap_regs */
  34. #define SBI_TRAP_REGS_a0 10
  35. /** Index of a1 member in sbi_trap_regs */
  36. #define SBI_TRAP_REGS_a1 11
  37. /** Index of a2 member in sbi_trap_regs */
  38. #define SBI_TRAP_REGS_a2 12
  39. /** Index of a3 member in sbi_trap_regs */
  40. #define SBI_TRAP_REGS_a3 13
  41. /** Index of a4 member in sbi_trap_regs */
  42. #define SBI_TRAP_REGS_a4 14
  43. /** Index of a5 member in sbi_trap_regs */
  44. #define SBI_TRAP_REGS_a5 15
  45. /** Index of a6 member in sbi_trap_regs */
  46. #define SBI_TRAP_REGS_a6 16
  47. /** Index of a7 member in sbi_trap_regs */
  48. #define SBI_TRAP_REGS_a7 17
  49. /** Index of s2 member in sbi_trap_regs */
  50. #define SBI_TRAP_REGS_s2 18
  51. /** Index of s3 member in sbi_trap_regs */
  52. #define SBI_TRAP_REGS_s3 19
  53. /** Index of s4 member in sbi_trap_regs */
  54. #define SBI_TRAP_REGS_s4 20
  55. /** Index of s5 member in sbi_trap_regs */
  56. #define SBI_TRAP_REGS_s5 21
  57. /** Index of s6 member in sbi_trap_regs */
  58. #define SBI_TRAP_REGS_s6 22
  59. /** Index of s7 member in sbi_trap_regs */
  60. #define SBI_TRAP_REGS_s7 23
  61. /** Index of s8 member in sbi_trap_regs */
  62. #define SBI_TRAP_REGS_s8 24
  63. /** Index of s9 member in sbi_trap_regs */
  64. #define SBI_TRAP_REGS_s9 25
  65. /** Index of s10 member in sbi_trap_regs */
  66. #define SBI_TRAP_REGS_s10 26
  67. /** Index of s11 member in sbi_trap_regs */
  68. #define SBI_TRAP_REGS_s11 27
  69. /** Index of t3 member in sbi_trap_regs */
  70. #define SBI_TRAP_REGS_t3 28
  71. /** Index of t4 member in sbi_trap_regs */
  72. #define SBI_TRAP_REGS_t4 29
  73. /** Index of t5 member in sbi_trap_regs */
  74. #define SBI_TRAP_REGS_t5 30
  75. /** Index of t6 member in sbi_trap_regs */
  76. #define SBI_TRAP_REGS_t6 31
  77. /** Index of mepc member in sbi_trap_regs */
  78. #define SBI_TRAP_REGS_mepc 32
  79. /** Index of mstatus member in sbi_trap_regs */
  80. #define SBI_TRAP_REGS_mstatus 33
  81. /** Index of mstatusH member in sbi_trap_regs */
  82. #define SBI_TRAP_REGS_mstatusH 34
  83. /** Last member index in sbi_trap_regs */
  84. #define SBI_TRAP_REGS_last 35
  85. /** Index of epc member in sbi_trap_info */
  86. #define SBI_TRAP_INFO_epc 0
  87. /** Index of cause member in sbi_trap_info */
  88. #define SBI_TRAP_INFO_cause 1
  89. /** Index of tval member in sbi_trap_info */
  90. #define SBI_TRAP_INFO_tval 2
  91. /** Index of tval2 member in sbi_trap_info */
  92. #define SBI_TRAP_INFO_tval2 3
  93. /** Index of tinst member in sbi_trap_info */
  94. #define SBI_TRAP_INFO_tinst 4
  95. /** Index of gva member in sbi_trap_info */
  96. #define SBI_TRAP_INFO_gva 5
  97. /** Last member index in sbi_trap_info */
  98. #define SBI_TRAP_INFO_last 6
  99. /* clang-format on */
  100. /** Get offset of member with name 'x' in sbi_trap_regs */
  101. #define SBI_TRAP_REGS_OFFSET(x) ((SBI_TRAP_REGS_##x) * __SIZEOF_POINTER__)
  102. /** Size (in bytes) of sbi_trap_regs */
  103. #define SBI_TRAP_REGS_SIZE SBI_TRAP_REGS_OFFSET(last)
  104. /** Get offset of member with name 'x' in sbi_trap_info */
  105. #define SBI_TRAP_INFO_OFFSET(x) ((SBI_TRAP_INFO_##x) * __SIZEOF_POINTER__)
  106. /** Size (in bytes) of sbi_trap_info */
  107. #define SBI_TRAP_INFO_SIZE SBI_TRAP_INFO_OFFSET(last)
  108. #ifndef __ASSEMBLER__
  109. #include <sbi/sbi_types.h>
  110. /** Representation of register state at time of trap/interrupt */
  111. struct sbi_trap_regs {
  112. /** zero register state */
  113. unsigned long zero;
  114. /** ra register state */
  115. unsigned long ra;
  116. /** sp register state */
  117. unsigned long sp;
  118. /** gp register state */
  119. unsigned long gp;
  120. /** tp register state */
  121. unsigned long tp;
  122. /** t0 register state */
  123. unsigned long t0;
  124. /** t1 register state */
  125. unsigned long t1;
  126. /** t2 register state */
  127. unsigned long t2;
  128. /** s0 register state */
  129. unsigned long s0;
  130. /** s1 register state */
  131. unsigned long s1;
  132. /** a0 register state */
  133. unsigned long a0;
  134. /** a1 register state */
  135. unsigned long a1;
  136. /** a2 register state */
  137. unsigned long a2;
  138. /** a3 register state */
  139. unsigned long a3;
  140. /** a4 register state */
  141. unsigned long a4;
  142. /** a5 register state */
  143. unsigned long a5;
  144. /** a6 register state */
  145. unsigned long a6;
  146. /** a7 register state */
  147. unsigned long a7;
  148. /** s2 register state */
  149. unsigned long s2;
  150. /** s3 register state */
  151. unsigned long s3;
  152. /** s4 register state */
  153. unsigned long s4;
  154. /** s5 register state */
  155. unsigned long s5;
  156. /** s6 register state */
  157. unsigned long s6;
  158. /** s7 register state */
  159. unsigned long s7;
  160. /** s8 register state */
  161. unsigned long s8;
  162. /** s9 register state */
  163. unsigned long s9;
  164. /** s10 register state */
  165. unsigned long s10;
  166. /** s11 register state */
  167. unsigned long s11;
  168. /** t3 register state */
  169. unsigned long t3;
  170. /** t4 register state */
  171. unsigned long t4;
  172. /** t5 register state */
  173. unsigned long t5;
  174. /** t6 register state */
  175. unsigned long t6;
  176. /** mepc register state */
  177. unsigned long mepc;
  178. /** mstatus register state */
  179. unsigned long mstatus;
  180. /** mstatusH register state (only for 32-bit) */
  181. unsigned long mstatusH;
  182. };
  183. /** Representation of trap details */
  184. struct sbi_trap_info {
  185. /** epc Trap program counter */
  186. unsigned long epc;
  187. /** cause Trap exception cause */
  188. unsigned long cause;
  189. /** tval Trap value */
  190. unsigned long tval;
  191. /** tval2 Trap value 2 */
  192. unsigned long tval2;
  193. /** tinst Trap instruction */
  194. unsigned long tinst;
  195. /** gva Guest virtual address in tval flag */
  196. unsigned long gva;
  197. };
  198. static inline unsigned long sbi_regs_gva(const struct sbi_trap_regs *regs)
  199. {
  200. /*
  201. * If the hypervisor extension is not implemented, mstatus[h].GVA is a
  202. * WPRI field, which is guaranteed to read as zero. In addition, in this
  203. * case we don't read mstatush and instead pretend it is zero, which
  204. * handles privileged spec version < 1.12.
  205. */
  206. #if __riscv_xlen == 32
  207. return (regs->mstatusH & MSTATUSH_GVA) ? 1 : 0;
  208. #else
  209. return (regs->mstatus & MSTATUS_GVA) ? 1 : 0;
  210. #endif
  211. }
  212. int sbi_trap_redirect(struct sbi_trap_regs *regs,
  213. struct sbi_trap_info *trap);
  214. struct sbi_trap_regs *sbi_trap_handler(struct sbi_trap_regs *regs);
  215. void __noreturn sbi_trap_exit(const struct sbi_trap_regs *regs);
  216. #endif
  217. #endif