mips-extns.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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() & PRID_IMP_MASK;
  141. if ((prid == PRID_IMP_NETLOGIC_XLP9XX) ||
  142. (prid == PRID_IMP_NETLOGIC_XLP5XX))
  143. return (__read_32bit_c0_register($15, 1) >> 7) & 0x7;
  144. else
  145. return (__read_32bit_c0_register($15, 1) >> 5) & 0x3;
  146. }
  147. static inline unsigned int nlm_core_id(void)
  148. {
  149. return (read_c0_ebase() & 0x1c) >> 2;
  150. }
  151. static inline unsigned int nlm_thread_id(void)
  152. {
  153. return read_c0_ebase() & 0x3;
  154. }
  155. #define __read_64bit_c2_split(source, sel) \
  156. ({ \
  157. unsigned long long __val; \
  158. unsigned long __flags; \
  159. \
  160. local_irq_save(__flags); \
  161. if (sel == 0) \
  162. __asm__ __volatile__( \
  163. ".set\tmips64\n\t" \
  164. "dmfc2\t%M0, " #source "\n\t" \
  165. "dsll\t%L0, %M0, 32\n\t" \
  166. "dsra\t%M0, %M0, 32\n\t" \
  167. "dsra\t%L0, %L0, 32\n\t" \
  168. ".set\tmips0\n\t" \
  169. : "=r" (__val)); \
  170. else \
  171. __asm__ __volatile__( \
  172. ".set\tmips64\n\t" \
  173. "dmfc2\t%M0, " #source ", " #sel "\n\t" \
  174. "dsll\t%L0, %M0, 32\n\t" \
  175. "dsra\t%M0, %M0, 32\n\t" \
  176. "dsra\t%L0, %L0, 32\n\t" \
  177. ".set\tmips0\n\t" \
  178. : "=r" (__val)); \
  179. local_irq_restore(__flags); \
  180. \
  181. __val; \
  182. })
  183. #define __write_64bit_c2_split(source, sel, val) \
  184. do { \
  185. unsigned long __flags; \
  186. \
  187. local_irq_save(__flags); \
  188. if (sel == 0) \
  189. __asm__ __volatile__( \
  190. ".set\tmips64\n\t" \
  191. "dsll\t%L0, %L0, 32\n\t" \
  192. "dsrl\t%L0, %L0, 32\n\t" \
  193. "dsll\t%M0, %M0, 32\n\t" \
  194. "or\t%L0, %L0, %M0\n\t" \
  195. "dmtc2\t%L0, " #source "\n\t" \
  196. ".set\tmips0\n\t" \
  197. : : "r" (val)); \
  198. else \
  199. __asm__ __volatile__( \
  200. ".set\tmips64\n\t" \
  201. "dsll\t%L0, %L0, 32\n\t" \
  202. "dsrl\t%L0, %L0, 32\n\t" \
  203. "dsll\t%M0, %M0, 32\n\t" \
  204. "or\t%L0, %L0, %M0\n\t" \
  205. "dmtc2\t%L0, " #source ", " #sel "\n\t" \
  206. ".set\tmips0\n\t" \
  207. : : "r" (val)); \
  208. local_irq_restore(__flags); \
  209. } while (0)
  210. #define __read_32bit_c2_register(source, sel) \
  211. ({ uint32_t __res; \
  212. if (sel == 0) \
  213. __asm__ __volatile__( \
  214. ".set\tmips32\n\t" \
  215. "mfc2\t%0, " #source "\n\t" \
  216. ".set\tmips0\n\t" \
  217. : "=r" (__res)); \
  218. else \
  219. __asm__ __volatile__( \
  220. ".set\tmips32\n\t" \
  221. "mfc2\t%0, " #source ", " #sel "\n\t" \
  222. ".set\tmips0\n\t" \
  223. : "=r" (__res)); \
  224. __res; \
  225. })
  226. #define __read_64bit_c2_register(source, sel) \
  227. ({ unsigned long long __res; \
  228. if (sizeof(unsigned long) == 4) \
  229. __res = __read_64bit_c2_split(source, sel); \
  230. else if (sel == 0) \
  231. __asm__ __volatile__( \
  232. ".set\tmips64\n\t" \
  233. "dmfc2\t%0, " #source "\n\t" \
  234. ".set\tmips0\n\t" \
  235. : "=r" (__res)); \
  236. else \
  237. __asm__ __volatile__( \
  238. ".set\tmips64\n\t" \
  239. "dmfc2\t%0, " #source ", " #sel "\n\t" \
  240. ".set\tmips0\n\t" \
  241. : "=r" (__res)); \
  242. __res; \
  243. })
  244. #define __write_64bit_c2_register(register, sel, value) \
  245. do { \
  246. if (sizeof(unsigned long) == 4) \
  247. __write_64bit_c2_split(register, sel, value); \
  248. else if (sel == 0) \
  249. __asm__ __volatile__( \
  250. ".set\tmips64\n\t" \
  251. "dmtc2\t%z0, " #register "\n\t" \
  252. ".set\tmips0\n\t" \
  253. : : "Jr" (value)); \
  254. else \
  255. __asm__ __volatile__( \
  256. ".set\tmips64\n\t" \
  257. "dmtc2\t%z0, " #register ", " #sel "\n\t" \
  258. ".set\tmips0\n\t" \
  259. : : "Jr" (value)); \
  260. } while (0)
  261. #define __write_32bit_c2_register(reg, sel, value) \
  262. ({ \
  263. if (sel == 0) \
  264. __asm__ __volatile__( \
  265. ".set\tmips32\n\t" \
  266. "mtc2\t%z0, " #reg "\n\t" \
  267. ".set\tmips0\n\t" \
  268. : : "Jr" (value)); \
  269. else \
  270. __asm__ __volatile__( \
  271. ".set\tmips32\n\t" \
  272. "mtc2\t%z0, " #reg ", " #sel "\n\t" \
  273. ".set\tmips0\n\t" \
  274. : : "Jr" (value)); \
  275. })
  276. #endif /*_ASM_NLM_MIPS_EXTS_H */