msa.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. * Copyright (C) 2013 Imagination Technologies
  3. * Author: Paul Burton <paul.burton@imgtec.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version.
  9. */
  10. #ifndef _ASM_MSA_H
  11. #define _ASM_MSA_H
  12. #include <asm/mipsregs.h>
  13. extern void _save_msa(struct task_struct *);
  14. extern void _restore_msa(struct task_struct *);
  15. static inline void enable_msa(void)
  16. {
  17. if (cpu_has_msa) {
  18. set_c0_config5(MIPS_CONF5_MSAEN);
  19. enable_fpu_hazard();
  20. }
  21. }
  22. static inline void disable_msa(void)
  23. {
  24. if (cpu_has_msa) {
  25. clear_c0_config5(MIPS_CONF5_MSAEN);
  26. disable_fpu_hazard();
  27. }
  28. }
  29. static inline int is_msa_enabled(void)
  30. {
  31. if (!cpu_has_msa)
  32. return 0;
  33. return read_c0_config5() & MIPS_CONF5_MSAEN;
  34. }
  35. static inline int thread_msa_context_live(void)
  36. {
  37. /*
  38. * Check cpu_has_msa only if it's a constant. This will allow the
  39. * compiler to optimise out code for CPUs without MSA without adding
  40. * an extra redundant check for CPUs with MSA.
  41. */
  42. if (__builtin_constant_p(cpu_has_msa) && !cpu_has_msa)
  43. return 0;
  44. return test_thread_flag(TIF_MSA_CTX_LIVE);
  45. }
  46. static inline void save_msa(struct task_struct *t)
  47. {
  48. if (cpu_has_msa)
  49. _save_msa(t);
  50. }
  51. static inline void restore_msa(struct task_struct *t)
  52. {
  53. if (cpu_has_msa)
  54. _restore_msa(t);
  55. }
  56. #ifdef TOOLCHAIN_SUPPORTS_MSA
  57. #define __BUILD_MSA_CTL_REG(name, cs) \
  58. static inline unsigned int read_msa_##name(void) \
  59. { \
  60. unsigned int reg; \
  61. __asm__ __volatile__( \
  62. " .set push\n" \
  63. " .set msa\n" \
  64. " cfcmsa %0, $" #cs "\n" \
  65. " .set pop\n" \
  66. : "=r"(reg)); \
  67. return reg; \
  68. } \
  69. \
  70. static inline void write_msa_##name(unsigned int val) \
  71. { \
  72. __asm__ __volatile__( \
  73. " .set push\n" \
  74. " .set msa\n" \
  75. " ctcmsa $" #cs ", %0\n" \
  76. " .set pop\n" \
  77. : : "r"(val)); \
  78. }
  79. #else /* !TOOLCHAIN_SUPPORTS_MSA */
  80. /*
  81. * Define functions using .word for the c[ft]cmsa instructions in order to
  82. * allow compilation with toolchains that do not support MSA. Once all
  83. * toolchains in use support MSA these can be removed.
  84. */
  85. #ifdef CONFIG_CPU_MICROMIPS
  86. #define CFC_MSA_INSN 0x587e0056
  87. #define CTC_MSA_INSN 0x583e0816
  88. #else
  89. #define CFC_MSA_INSN 0x787e0059
  90. #define CTC_MSA_INSN 0x783e0819
  91. #endif
  92. #define __BUILD_MSA_CTL_REG(name, cs) \
  93. static inline unsigned int read_msa_##name(void) \
  94. { \
  95. unsigned int reg; \
  96. __asm__ __volatile__( \
  97. " .set push\n" \
  98. " .set noat\n" \
  99. " .insn\n" \
  100. " .word #CFC_MSA_INSN | (" #cs " << 11)\n" \
  101. " move %0, $1\n" \
  102. " .set pop\n" \
  103. : "=r"(reg)); \
  104. return reg; \
  105. } \
  106. \
  107. static inline void write_msa_##name(unsigned int val) \
  108. { \
  109. __asm__ __volatile__( \
  110. " .set push\n" \
  111. " .set noat\n" \
  112. " move $1, %0\n" \
  113. " .insn\n" \
  114. " .word #CTC_MSA_INSN | (" #cs " << 6)\n" \
  115. " .set pop\n" \
  116. : : "r"(val)); \
  117. }
  118. #endif /* !TOOLCHAIN_SUPPORTS_MSA */
  119. #define MSA_IR 0
  120. #define MSA_CSR 1
  121. #define MSA_ACCESS 2
  122. #define MSA_SAVE 3
  123. #define MSA_MODIFY 4
  124. #define MSA_REQUEST 5
  125. #define MSA_MAP 6
  126. #define MSA_UNMAP 7
  127. __BUILD_MSA_CTL_REG(ir, 0)
  128. __BUILD_MSA_CTL_REG(csr, 1)
  129. __BUILD_MSA_CTL_REG(access, 2)
  130. __BUILD_MSA_CTL_REG(save, 3)
  131. __BUILD_MSA_CTL_REG(modify, 4)
  132. __BUILD_MSA_CTL_REG(request, 5)
  133. __BUILD_MSA_CTL_REG(map, 6)
  134. __BUILD_MSA_CTL_REG(unmap, 7)
  135. /* MSA Implementation Register (MSAIR) */
  136. #define MSA_IR_REVB 0
  137. #define MSA_IR_REVF (_ULCAST_(0xff) << MSA_IR_REVB)
  138. #define MSA_IR_PROCB 8
  139. #define MSA_IR_PROCF (_ULCAST_(0xff) << MSA_IR_PROCB)
  140. #define MSA_IR_WRPB 16
  141. #define MSA_IR_WRPF (_ULCAST_(0x1) << MSA_IR_WRPB)
  142. /* MSA Control & Status Register (MSACSR) */
  143. #define MSA_CSR_RMB 0
  144. #define MSA_CSR_RMF (_ULCAST_(0x3) << MSA_CSR_RMB)
  145. #define MSA_CSR_RM_NEAREST 0
  146. #define MSA_CSR_RM_TO_ZERO 1
  147. #define MSA_CSR_RM_TO_POS 2
  148. #define MSA_CSR_RM_TO_NEG 3
  149. #define MSA_CSR_FLAGSB 2
  150. #define MSA_CSR_FLAGSF (_ULCAST_(0x1f) << MSA_CSR_FLAGSB)
  151. #define MSA_CSR_FLAGS_IB 2
  152. #define MSA_CSR_FLAGS_IF (_ULCAST_(0x1) << MSA_CSR_FLAGS_IB)
  153. #define MSA_CSR_FLAGS_UB 3
  154. #define MSA_CSR_FLAGS_UF (_ULCAST_(0x1) << MSA_CSR_FLAGS_UB)
  155. #define MSA_CSR_FLAGS_OB 4
  156. #define MSA_CSR_FLAGS_OF (_ULCAST_(0x1) << MSA_CSR_FLAGS_OB)
  157. #define MSA_CSR_FLAGS_ZB 5
  158. #define MSA_CSR_FLAGS_ZF (_ULCAST_(0x1) << MSA_CSR_FLAGS_ZB)
  159. #define MSA_CSR_FLAGS_VB 6
  160. #define MSA_CSR_FLAGS_VF (_ULCAST_(0x1) << MSA_CSR_FLAGS_VB)
  161. #define MSA_CSR_ENABLESB 7
  162. #define MSA_CSR_ENABLESF (_ULCAST_(0x1f) << MSA_CSR_ENABLESB)
  163. #define MSA_CSR_ENABLES_IB 7
  164. #define MSA_CSR_ENABLES_IF (_ULCAST_(0x1) << MSA_CSR_ENABLES_IB)
  165. #define MSA_CSR_ENABLES_UB 8
  166. #define MSA_CSR_ENABLES_UF (_ULCAST_(0x1) << MSA_CSR_ENABLES_UB)
  167. #define MSA_CSR_ENABLES_OB 9
  168. #define MSA_CSR_ENABLES_OF (_ULCAST_(0x1) << MSA_CSR_ENABLES_OB)
  169. #define MSA_CSR_ENABLES_ZB 10
  170. #define MSA_CSR_ENABLES_ZF (_ULCAST_(0x1) << MSA_CSR_ENABLES_ZB)
  171. #define MSA_CSR_ENABLES_VB 11
  172. #define MSA_CSR_ENABLES_VF (_ULCAST_(0x1) << MSA_CSR_ENABLES_VB)
  173. #define MSA_CSR_CAUSEB 12
  174. #define MSA_CSR_CAUSEF (_ULCAST_(0x3f) << MSA_CSR_CAUSEB)
  175. #define MSA_CSR_CAUSE_IB 12
  176. #define MSA_CSR_CAUSE_IF (_ULCAST_(0x1) << MSA_CSR_CAUSE_IB)
  177. #define MSA_CSR_CAUSE_UB 13
  178. #define MSA_CSR_CAUSE_UF (_ULCAST_(0x1) << MSA_CSR_CAUSE_UB)
  179. #define MSA_CSR_CAUSE_OB 14
  180. #define MSA_CSR_CAUSE_OF (_ULCAST_(0x1) << MSA_CSR_CAUSE_OB)
  181. #define MSA_CSR_CAUSE_ZB 15
  182. #define MSA_CSR_CAUSE_ZF (_ULCAST_(0x1) << MSA_CSR_CAUSE_ZB)
  183. #define MSA_CSR_CAUSE_VB 16
  184. #define MSA_CSR_CAUSE_VF (_ULCAST_(0x1) << MSA_CSR_CAUSE_VB)
  185. #define MSA_CSR_CAUSE_EB 17
  186. #define MSA_CSR_CAUSE_EF (_ULCAST_(0x1) << MSA_CSR_CAUSE_EB)
  187. #define MSA_CSR_NXB 18
  188. #define MSA_CSR_NXF (_ULCAST_(0x1) << MSA_CSR_NXB)
  189. #define MSA_CSR_FSB 24
  190. #define MSA_CSR_FSF (_ULCAST_(0x1) << MSA_CSR_FSB)
  191. #endif /* _ASM_MSA_H */