msa.h 5.9 KB

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