mips-extns.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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. * NOTE: Do not save/restore flags around write_c0_eimr().
  44. * On non-R2 platforms the flags has part of EIMR that is shadowed in STATUS
  45. * register. Restoring flags will overwrite the lower 8 bits of EIMR.
  46. *
  47. * Call with interrupts disabled.
  48. */
  49. #define write_c0_eimr(val) \
  50. do { \
  51. if (sizeof(unsigned long) == 4) { \
  52. __asm__ __volatile__( \
  53. ".set\tmips64\n\t" \
  54. "dsll\t%L0, %L0, 32\n\t" \
  55. "dsrl\t%L0, %L0, 32\n\t" \
  56. "dsll\t%M0, %M0, 32\n\t" \
  57. "or\t%L0, %L0, %M0\n\t" \
  58. "dmtc0\t%L0, $9, 7\n\t" \
  59. ".set\tmips0" \
  60. : : "r" (val)); \
  61. } else \
  62. __write_64bit_c0_register($9, 7, (val)); \
  63. } while (0)
  64. /*
  65. * Handling the 64 bit EIMR and EIRR registers in 32-bit mode with
  66. * standard functions will be very inefficient. This provides
  67. * optimized functions for the normal operations on the registers.
  68. *
  69. * Call with interrupts disabled.
  70. */
  71. static inline void ack_c0_eirr(int irq)
  72. {
  73. __asm__ __volatile__(
  74. ".set push\n\t"
  75. ".set mips64\n\t"
  76. ".set noat\n\t"
  77. "li $1, 1\n\t"
  78. "dsllv $1, $1, %0\n\t"
  79. "dmtc0 $1, $9, 6\n\t"
  80. ".set pop"
  81. : : "r" (irq));
  82. }
  83. static inline void set_c0_eimr(int irq)
  84. {
  85. __asm__ __volatile__(
  86. ".set push\n\t"
  87. ".set mips64\n\t"
  88. ".set noat\n\t"
  89. "li $1, 1\n\t"
  90. "dsllv %0, $1, %0\n\t"
  91. "dmfc0 $1, $9, 7\n\t"
  92. "or $1, %0\n\t"
  93. "dmtc0 $1, $9, 7\n\t"
  94. ".set pop"
  95. : "+r" (irq));
  96. }
  97. static inline void clear_c0_eimr(int irq)
  98. {
  99. __asm__ __volatile__(
  100. ".set push\n\t"
  101. ".set mips64\n\t"
  102. ".set noat\n\t"
  103. "li $1, 1\n\t"
  104. "dsllv %0, $1, %0\n\t"
  105. "dmfc0 $1, $9, 7\n\t"
  106. "or $1, %0\n\t"
  107. "xor $1, %0\n\t"
  108. "dmtc0 $1, $9, 7\n\t"
  109. ".set pop"
  110. : "+r" (irq));
  111. }
  112. /*
  113. * Read c0 eimr and c0 eirr, do AND of the two values, the result is
  114. * the interrupts which are raised and are not masked.
  115. */
  116. static inline uint64_t read_c0_eirr_and_eimr(void)
  117. {
  118. uint64_t val;
  119. #ifdef CONFIG_64BIT
  120. val = read_c0_eimr() & read_c0_eirr();
  121. #else
  122. __asm__ __volatile__(
  123. ".set push\n\t"
  124. ".set mips64\n\t"
  125. ".set noat\n\t"
  126. "dmfc0 %M0, $9, 6\n\t"
  127. "dmfc0 %L0, $9, 7\n\t"
  128. "and %M0, %L0\n\t"
  129. "dsll %L0, %M0, 32\n\t"
  130. "dsra %M0, %M0, 32\n\t"
  131. "dsra %L0, %L0, 32\n\t"
  132. ".set pop"
  133. : "=r" (val));
  134. #endif
  135. return val;
  136. }
  137. static inline int hard_smp_processor_id(void)
  138. {
  139. return __read_32bit_c0_register($15, 1) & 0x3ff;
  140. }
  141. static inline int nlm_nodeid(void)
  142. {
  143. return (__read_32bit_c0_register($15, 1) >> 5) & 0x3;
  144. }
  145. static inline unsigned int nlm_core_id(void)
  146. {
  147. return (read_c0_ebase() & 0x1c) >> 2;
  148. }
  149. static inline unsigned int nlm_thread_id(void)
  150. {
  151. return read_c0_ebase() & 0x3;
  152. }
  153. #define __read_64bit_c2_split(source, sel) \
  154. ({ \
  155. unsigned long long __val; \
  156. unsigned long __flags; \
  157. \
  158. local_irq_save(__flags); \
  159. if (sel == 0) \
  160. __asm__ __volatile__( \
  161. ".set\tmips64\n\t" \
  162. "dmfc2\t%M0, " #source "\n\t" \
  163. "dsll\t%L0, %M0, 32\n\t" \
  164. "dsra\t%M0, %M0, 32\n\t" \
  165. "dsra\t%L0, %L0, 32\n\t" \
  166. ".set\tmips0\n\t" \
  167. : "=r" (__val)); \
  168. else \
  169. __asm__ __volatile__( \
  170. ".set\tmips64\n\t" \
  171. "dmfc2\t%M0, " #source ", " #sel "\n\t" \
  172. "dsll\t%L0, %M0, 32\n\t" \
  173. "dsra\t%M0, %M0, 32\n\t" \
  174. "dsra\t%L0, %L0, 32\n\t" \
  175. ".set\tmips0\n\t" \
  176. : "=r" (__val)); \
  177. local_irq_restore(__flags); \
  178. \
  179. __val; \
  180. })
  181. #define __write_64bit_c2_split(source, sel, val) \
  182. do { \
  183. unsigned long __flags; \
  184. \
  185. local_irq_save(__flags); \
  186. if (sel == 0) \
  187. __asm__ __volatile__( \
  188. ".set\tmips64\n\t" \
  189. "dsll\t%L0, %L0, 32\n\t" \
  190. "dsrl\t%L0, %L0, 32\n\t" \
  191. "dsll\t%M0, %M0, 32\n\t" \
  192. "or\t%L0, %L0, %M0\n\t" \
  193. "dmtc2\t%L0, " #source "\n\t" \
  194. ".set\tmips0\n\t" \
  195. : : "r" (val)); \
  196. else \
  197. __asm__ __volatile__( \
  198. ".set\tmips64\n\t" \
  199. "dsll\t%L0, %L0, 32\n\t" \
  200. "dsrl\t%L0, %L0, 32\n\t" \
  201. "dsll\t%M0, %M0, 32\n\t" \
  202. "or\t%L0, %L0, %M0\n\t" \
  203. "dmtc2\t%L0, " #source ", " #sel "\n\t" \
  204. ".set\tmips0\n\t" \
  205. : : "r" (val)); \
  206. local_irq_restore(__flags); \
  207. } while (0)
  208. #define __read_32bit_c2_register(source, sel) \
  209. ({ uint32_t __res; \
  210. if (sel == 0) \
  211. __asm__ __volatile__( \
  212. ".set\tmips32\n\t" \
  213. "mfc2\t%0, " #source "\n\t" \
  214. ".set\tmips0\n\t" \
  215. : "=r" (__res)); \
  216. else \
  217. __asm__ __volatile__( \
  218. ".set\tmips32\n\t" \
  219. "mfc2\t%0, " #source ", " #sel "\n\t" \
  220. ".set\tmips0\n\t" \
  221. : "=r" (__res)); \
  222. __res; \
  223. })
  224. #define __read_64bit_c2_register(source, sel) \
  225. ({ unsigned long long __res; \
  226. if (sizeof(unsigned long) == 4) \
  227. __res = __read_64bit_c2_split(source, sel); \
  228. else if (sel == 0) \
  229. __asm__ __volatile__( \
  230. ".set\tmips64\n\t" \
  231. "dmfc2\t%0, " #source "\n\t" \
  232. ".set\tmips0\n\t" \
  233. : "=r" (__res)); \
  234. else \
  235. __asm__ __volatile__( \
  236. ".set\tmips64\n\t" \
  237. "dmfc2\t%0, " #source ", " #sel "\n\t" \
  238. ".set\tmips0\n\t" \
  239. : "=r" (__res)); \
  240. __res; \
  241. })
  242. #define __write_64bit_c2_register(register, sel, value) \
  243. do { \
  244. if (sizeof(unsigned long) == 4) \
  245. __write_64bit_c2_split(register, sel, value); \
  246. else if (sel == 0) \
  247. __asm__ __volatile__( \
  248. ".set\tmips64\n\t" \
  249. "dmtc2\t%z0, " #register "\n\t" \
  250. ".set\tmips0\n\t" \
  251. : : "Jr" (value)); \
  252. else \
  253. __asm__ __volatile__( \
  254. ".set\tmips64\n\t" \
  255. "dmtc2\t%z0, " #register ", " #sel "\n\t" \
  256. ".set\tmips0\n\t" \
  257. : : "Jr" (value)); \
  258. } while (0)
  259. #define __write_32bit_c2_register(reg, sel, value) \
  260. ({ \
  261. if (sel == 0) \
  262. __asm__ __volatile__( \
  263. ".set\tmips32\n\t" \
  264. "mtc2\t%z0, " #reg "\n\t" \
  265. ".set\tmips0\n\t" \
  266. : : "Jr" (value)); \
  267. else \
  268. __asm__ __volatile__( \
  269. ".set\tmips32\n\t" \
  270. "mtc2\t%z0, " #reg ", " #sel "\n\t" \
  271. ".set\tmips0\n\t" \
  272. : : "Jr" (value)); \
  273. })
  274. #endif /*_ASM_NLM_MIPS_EXTS_H */