cpuport.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2011-01-13 weety modified from mini2440
  9. * 2015-04-15 ArdaFu Add code for IAR
  10. */
  11. #include <rthw.h>
  12. #include <rtthread.h>
  13. #define ICACHE_MASK (rt_uint32_t)(1 << 12)
  14. #define DCACHE_MASK (rt_uint32_t)(1 << 2)
  15. extern void machine_reset(void);
  16. extern void machine_shutdown(void);
  17. #if defined(__GNUC__) || defined(__ICCARM__)
  18. rt_inline rt_uint32_t cp15_rd(void)
  19. {
  20. rt_uint32_t i;
  21. __asm volatile("mrc p15, 0, %0, c1, c0, 0":"=r"(i));
  22. return i;
  23. }
  24. rt_inline void cache_enable(rt_uint32_t bit)
  25. {
  26. __asm volatile(\
  27. "mrc p15,0,r0,c1,c0,0\n\t" \
  28. "orr r0,r0,%0\n\t" \
  29. "mcr p15,0,r0,c1,c0,0" \
  30. : \
  31. : "r"(bit) \
  32. : "memory");
  33. }
  34. rt_inline void cache_disable(rt_uint32_t bit)
  35. {
  36. __asm volatile(\
  37. "mrc p15,0,r0,c1,c0,0\n\t" \
  38. "bic r0,r0,%0\n\t" \
  39. "mcr p15,0,r0,c1,c0,0" \
  40. : \
  41. : "r"(bit) \
  42. : "memory");
  43. }
  44. #endif
  45. #if defined(__CC_ARM)
  46. rt_inline rt_uint32_t cp15_rd(void)
  47. {
  48. rt_uint32_t i;
  49. __asm volatile
  50. {
  51. mrc p15, 0, i, c1, c0, 0
  52. }
  53. return i;
  54. }
  55. rt_inline void cache_enable(rt_uint32_t bit)
  56. {
  57. rt_uint32_t value;
  58. __asm volatile
  59. {
  60. mrc p15, 0, value, c1, c0, 0
  61. orr value, value, bit
  62. mcr p15, 0, value, c1, c0, 0
  63. }
  64. }
  65. rt_inline void cache_disable(rt_uint32_t bit)
  66. {
  67. rt_uint32_t value;
  68. __asm volatile
  69. {
  70. mrc p15, 0, value, c1, c0, 0
  71. bic value, value, bit
  72. mcr p15, 0, value, c1, c0, 0
  73. }
  74. }
  75. #endif
  76. /**
  77. * enable I-Cache
  78. *
  79. */
  80. void rt_hw_cpu_icache_enable()
  81. {
  82. cache_enable(ICACHE_MASK);
  83. }
  84. /**
  85. * disable I-Cache
  86. *
  87. */
  88. void rt_hw_cpu_icache_disable()
  89. {
  90. cache_disable(ICACHE_MASK);
  91. }
  92. /**
  93. * return the status of I-Cache
  94. *
  95. */
  96. rt_base_t rt_hw_cpu_icache_status()
  97. {
  98. return (cp15_rd() & ICACHE_MASK);
  99. }
  100. /**
  101. * enable D-Cache
  102. *
  103. */
  104. void rt_hw_cpu_dcache_enable()
  105. {
  106. cache_enable(DCACHE_MASK);
  107. }
  108. /**
  109. * disable D-Cache
  110. *
  111. */
  112. void rt_hw_cpu_dcache_disable()
  113. {
  114. cache_disable(DCACHE_MASK);
  115. }
  116. /**
  117. * return the status of D-Cache
  118. *
  119. */
  120. rt_base_t rt_hw_cpu_dcache_status()
  121. {
  122. return (cp15_rd() & DCACHE_MASK);
  123. }
  124. /**
  125. * reset cpu by dog's time-out
  126. *
  127. */
  128. RT_WEAK void rt_hw_cpu_reset()
  129. {
  130. rt_kprintf("Restarting system...\n");
  131. machine_reset();
  132. while (1); /* loop forever and wait for reset to happen */
  133. /* NEVER REACHED */
  134. }
  135. /**
  136. * shutdown CPU
  137. *
  138. */
  139. RT_WEAK void rt_hw_cpu_shutdown()
  140. {
  141. rt_uint32_t level;
  142. rt_kprintf("shutdown...\n");
  143. level = rt_hw_interrupt_disable();
  144. machine_shutdown();
  145. while (level)
  146. {
  147. RT_ASSERT(0);
  148. }
  149. }
  150. #ifdef RT_USING_CPU_FFS
  151. /**
  152. * This function finds the first bit set (beginning with the least significant bit)
  153. * in value and return the index of that bit.
  154. *
  155. * Bits are numbered starting at 1 (the least significant bit). A return value of
  156. * zero from any of these functions means that the argument was zero.
  157. *
  158. * @return return the index of the first bit set. If value is 0, then this function
  159. * shall return 0.
  160. */
  161. #if defined(__CC_ARM)
  162. int __rt_ffs(int value)
  163. {
  164. register rt_uint32_t x;
  165. if (value == 0)
  166. return value;
  167. __asm
  168. {
  169. rsb x, value, #0
  170. and x, x, value
  171. clz x, x
  172. rsb x, x, #32
  173. }
  174. return x;
  175. }
  176. #elif defined(__GNUC__) || defined(__ICCARM__)
  177. int __rt_ffs(int value)
  178. {
  179. return __builtin_ffs(value);
  180. }
  181. #endif
  182. #endif
  183. /*@}*/