mips-extns.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
  3. * reserved.
  4. *
  5. * This software is available to you under a choice of one of two
  6. * licenses. You may choose to be licensed under the terms of the GNU
  7. * General Public License (GPL) Version 2, available from the file
  8. * COPYING in the main directory of this source tree, or the NetLogic
  9. * license below:
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. *
  15. * 1. Redistributions of source code must retain the above copyright
  16. * notice, this list of conditions and the following disclaimer.
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in
  19. * the documentation and/or other materials provided with the
  20. * distribution.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
  23. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
  26. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  29. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  30. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  31. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  32. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #ifndef _ASM_NLM_MIPS_EXTS_H
  35. #define _ASM_NLM_MIPS_EXTS_H
  36. /*
  37. * XLR and XLP interrupt request and interrupt mask registers
  38. */
  39. #define read_c0_eirr() __read_64bit_c0_register($9, 6)
  40. #define read_c0_eimr() __read_64bit_c0_register($9, 7)
  41. #define write_c0_eirr(val) __write_64bit_c0_register($9, 6, val)
  42. /*
  43. * Writing EIMR in 32 bit is a special case, the lower 8 bit of the
  44. * EIMR is shadowed in the status register, so we cannot save and
  45. * restore status register for split read.
  46. */
  47. #define write_c0_eimr(val) \
  48. do { \
  49. if (sizeof(unsigned long) == 4) { \
  50. unsigned long __flags; \
  51. \
  52. local_irq_save(__flags); \
  53. __asm__ __volatile__( \
  54. ".set\tmips64\n\t" \
  55. "dsll\t%L0, %L0, 32\n\t" \
  56. "dsrl\t%L0, %L0, 32\n\t" \
  57. "dsll\t%M0, %M0, 32\n\t" \
  58. "or\t%L0, %L0, %M0\n\t" \
  59. "dmtc0\t%L0, $9, 7\n\t" \
  60. ".set\tmips0" \
  61. : : "r" (val)); \
  62. __flags = (__flags & 0xffff00ff) | (((val) & 0xff) << 8);\
  63. local_irq_restore(__flags); \
  64. } else \
  65. __write_64bit_c0_register($9, 7, (val)); \
  66. } while (0)
  67. static inline int hard_smp_processor_id(void)
  68. {
  69. return __read_32bit_c0_register($15, 1) & 0x3ff;
  70. }
  71. static inline int nlm_nodeid(void)
  72. {
  73. return (__read_32bit_c0_register($15, 1) >> 5) & 0x3;
  74. }
  75. static inline unsigned int nlm_core_id(void)
  76. {
  77. return (read_c0_ebase() & 0x1c) >> 2;
  78. }
  79. static inline unsigned int nlm_thread_id(void)
  80. {
  81. return read_c0_ebase() & 0x3;
  82. }
  83. #define __read_64bit_c2_split(source, sel) \
  84. ({ \
  85. unsigned long long __val; \
  86. unsigned long __flags; \
  87. \
  88. local_irq_save(__flags); \
  89. if (sel == 0) \
  90. __asm__ __volatile__( \
  91. ".set\tmips64\n\t" \
  92. "dmfc2\t%M0, " #source "\n\t" \
  93. "dsll\t%L0, %M0, 32\n\t" \
  94. "dsra\t%M0, %M0, 32\n\t" \
  95. "dsra\t%L0, %L0, 32\n\t" \
  96. ".set\tmips0\n\t" \
  97. : "=r" (__val)); \
  98. else \
  99. __asm__ __volatile__( \
  100. ".set\tmips64\n\t" \
  101. "dmfc2\t%M0, " #source ", " #sel "\n\t" \
  102. "dsll\t%L0, %M0, 32\n\t" \
  103. "dsra\t%M0, %M0, 32\n\t" \
  104. "dsra\t%L0, %L0, 32\n\t" \
  105. ".set\tmips0\n\t" \
  106. : "=r" (__val)); \
  107. local_irq_restore(__flags); \
  108. \
  109. __val; \
  110. })
  111. #define __write_64bit_c2_split(source, sel, val) \
  112. do { \
  113. unsigned long __flags; \
  114. \
  115. local_irq_save(__flags); \
  116. if (sel == 0) \
  117. __asm__ __volatile__( \
  118. ".set\tmips64\n\t" \
  119. "dsll\t%L0, %L0, 32\n\t" \
  120. "dsrl\t%L0, %L0, 32\n\t" \
  121. "dsll\t%M0, %M0, 32\n\t" \
  122. "or\t%L0, %L0, %M0\n\t" \
  123. "dmtc2\t%L0, " #source "\n\t" \
  124. ".set\tmips0\n\t" \
  125. : : "r" (val)); \
  126. else \
  127. __asm__ __volatile__( \
  128. ".set\tmips64\n\t" \
  129. "dsll\t%L0, %L0, 32\n\t" \
  130. "dsrl\t%L0, %L0, 32\n\t" \
  131. "dsll\t%M0, %M0, 32\n\t" \
  132. "or\t%L0, %L0, %M0\n\t" \
  133. "dmtc2\t%L0, " #source ", " #sel "\n\t" \
  134. ".set\tmips0\n\t" \
  135. : : "r" (val)); \
  136. local_irq_restore(__flags); \
  137. } while (0)
  138. #define __read_32bit_c2_register(source, sel) \
  139. ({ uint32_t __res; \
  140. if (sel == 0) \
  141. __asm__ __volatile__( \
  142. ".set\tmips32\n\t" \
  143. "mfc2\t%0, " #source "\n\t" \
  144. ".set\tmips0\n\t" \
  145. : "=r" (__res)); \
  146. else \
  147. __asm__ __volatile__( \
  148. ".set\tmips32\n\t" \
  149. "mfc2\t%0, " #source ", " #sel "\n\t" \
  150. ".set\tmips0\n\t" \
  151. : "=r" (__res)); \
  152. __res; \
  153. })
  154. #define __read_64bit_c2_register(source, sel) \
  155. ({ unsigned long long __res; \
  156. if (sizeof(unsigned long) == 4) \
  157. __res = __read_64bit_c2_split(source, sel); \
  158. else if (sel == 0) \
  159. __asm__ __volatile__( \
  160. ".set\tmips64\n\t" \
  161. "dmfc2\t%0, " #source "\n\t" \
  162. ".set\tmips0\n\t" \
  163. : "=r" (__res)); \
  164. else \
  165. __asm__ __volatile__( \
  166. ".set\tmips64\n\t" \
  167. "dmfc2\t%0, " #source ", " #sel "\n\t" \
  168. ".set\tmips0\n\t" \
  169. : "=r" (__res)); \
  170. __res; \
  171. })
  172. #define __write_64bit_c2_register(register, sel, value) \
  173. do { \
  174. if (sizeof(unsigned long) == 4) \
  175. __write_64bit_c2_split(register, sel, value); \
  176. else if (sel == 0) \
  177. __asm__ __volatile__( \
  178. ".set\tmips64\n\t" \
  179. "dmtc2\t%z0, " #register "\n\t" \
  180. ".set\tmips0\n\t" \
  181. : : "Jr" (value)); \
  182. else \
  183. __asm__ __volatile__( \
  184. ".set\tmips64\n\t" \
  185. "dmtc2\t%z0, " #register ", " #sel "\n\t" \
  186. ".set\tmips0\n\t" \
  187. : : "Jr" (value)); \
  188. } while (0)
  189. #define __write_32bit_c2_register(reg, sel, value) \
  190. ({ \
  191. if (sel == 0) \
  192. __asm__ __volatile__( \
  193. ".set\tmips32\n\t" \
  194. "mtc2\t%z0, " #reg "\n\t" \
  195. ".set\tmips0\n\t" \
  196. : : "Jr" (value)); \
  197. else \
  198. __asm__ __volatile__( \
  199. ".set\tmips32\n\t" \
  200. "mtc2\t%z0, " #reg ", " #sel "\n\t" \
  201. ".set\tmips0\n\t" \
  202. : : "Jr" (value)); \
  203. })
  204. #endif /*_ASM_NLM_MIPS_EXTS_H */