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