cpu.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2006-03-13 Bernard first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include "s3c24x0.h"
  13. /**
  14. * @addtogroup S3C24X0
  15. */
  16. /*@{*/
  17. #define ICACHE_MASK (rt_uint32_t)(1 << 12)
  18. #define DCACHE_MASK (rt_uint32_t)(1 << 2)
  19. #define CACHE_LINE_SIZE 32
  20. #ifdef __GNUC__
  21. rt_inline rt_uint32_t cp15_rd(void)
  22. {
  23. rt_uint32_t i;
  24. asm("mrc p15, 0, %0, c1, c0, 0"
  25. : "=r"(i));
  26. return i;
  27. }
  28. rt_inline void cache_enable(rt_uint32_t bit)
  29. {
  30. __asm__ __volatile__(
  31. "mrc p15,0,r0,c1,c0,0\n\t"
  32. "orr r0,r0,%0\n\t"
  33. "mcr p15,0,r0,c1,c0,0"
  34. :
  35. : "r"(bit)
  36. : "memory");
  37. }
  38. rt_inline void cache_disable(rt_uint32_t bit)
  39. {
  40. __asm__ __volatile__(
  41. "mrc p15,0,r0,c1,c0,0\n\t"
  42. "bic r0,r0,%0\n\t"
  43. "mcr p15,0,r0,c1,c0,0"
  44. :
  45. : "r"(bit)
  46. : "memory");
  47. }
  48. void dcache_clean(rt_uint32_t buffer, rt_uint32_t size)
  49. {
  50. unsigned int ptr;
  51. ptr = buffer & ~(CACHE_LINE_SIZE - 1);
  52. while (ptr < buffer + size)
  53. {
  54. asm volatile("mcr p15, 0, %0, c7, c10, 1": :"r"(ptr));
  55. ptr += CACHE_LINE_SIZE;
  56. }
  57. }
  58. void dcache_invalidate(rt_uint32_t buffer, rt_uint32_t size)
  59. {
  60. unsigned int ptr;
  61. ptr = buffer & ~(CACHE_LINE_SIZE - 1);
  62. while (ptr < buffer + size)
  63. {
  64. asm volatile("mcr p15, 0, %0, c7, c6, 1": :"r"(ptr));
  65. ptr += CACHE_LINE_SIZE;
  66. }
  67. }
  68. void icache_invalidate()
  69. {
  70. asm volatile("mcr p15, 0, %0, c7, c5, 0": :"r"(0));
  71. }
  72. #endif
  73. #ifdef __CC_ARM
  74. rt_inline rt_uint32_t cp15_rd(void)
  75. {
  76. rt_uint32_t i;
  77. __asm
  78. {
  79. mrc p15, 0, i, c1, c0, 0
  80. }
  81. return i;
  82. }
  83. rt_inline void cache_enable(rt_uint32_t bit)
  84. {
  85. rt_uint32_t value;
  86. __asm
  87. {
  88. mrc p15, 0, value, c1, c0, 0
  89. orr value, value, bit
  90. mcr p15, 0, value, c1, c0, 0
  91. }
  92. }
  93. rt_inline void cache_disable(rt_uint32_t bit)
  94. {
  95. rt_uint32_t value;
  96. __asm
  97. {
  98. mrc p15, 0, value, c1, c0, 0
  99. bic value, value, bit
  100. mcr p15, 0, value, c1, c0, 0
  101. }
  102. }
  103. void dcache_clean(rt_uint32_t buffer, rt_uint32_t size)
  104. {
  105. unsigned int ptr;
  106. ptr = buffer & ~(CACHE_LINE_SIZE - 1);
  107. while (ptr < buffer + size)
  108. {
  109. __asm volatile { mcr p15, 0, ptr, c7, c10, 1 }
  110. ptr += CACHE_LINE_SIZE;
  111. }
  112. }
  113. void dcache_invalidate(rt_uint32_t buffer, rt_uint32_t size)
  114. {
  115. unsigned int ptr;
  116. ptr = buffer & ~(CACHE_LINE_SIZE - 1);
  117. while (ptr < buffer + size)
  118. {
  119. __asm volatile { mcr p15, 0, ptr, c7, c6, 1 }
  120. ptr += CACHE_LINE_SIZE;
  121. }
  122. }
  123. void icache_invalidate()
  124. {
  125. register rt_uint32_t value;
  126. value = 0;
  127. __asm volatile { mcr p15, 0, value, c7, c5, 0 }
  128. }
  129. #endif
  130. /**
  131. * enable I-Cache
  132. *
  133. */
  134. void rt_hw_cpu_icache_enable()
  135. {
  136. cache_enable(ICACHE_MASK);
  137. }
  138. /**
  139. * disable I-Cache
  140. *
  141. */
  142. void rt_hw_cpu_icache_disable()
  143. {
  144. cache_disable(ICACHE_MASK);
  145. }
  146. /**
  147. * return the status of I-Cache
  148. *
  149. */
  150. rt_base_t rt_hw_cpu_icache_status()
  151. {
  152. return (cp15_rd() & ICACHE_MASK);
  153. }
  154. /**
  155. * enable D-Cache
  156. *
  157. */
  158. void rt_hw_cpu_dcache_enable()
  159. {
  160. cache_enable(DCACHE_MASK);
  161. }
  162. /**
  163. * disable D-Cache
  164. *
  165. */
  166. void rt_hw_cpu_dcache_disable()
  167. {
  168. cache_disable(DCACHE_MASK);
  169. }
  170. /**
  171. * return the status of D-Cache
  172. *
  173. */
  174. rt_base_t rt_hw_cpu_dcache_status()
  175. {
  176. return (cp15_rd() & DCACHE_MASK);
  177. }
  178. void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
  179. {
  180. if (ops == RT_HW_CACHE_INVALIDATE)
  181. icache_invalidate(); /* TODO: only invalidate an addr range */
  182. }
  183. void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
  184. {
  185. if (ops == RT_HW_CACHE_FLUSH)
  186. dcache_clean(addr, size);
  187. else if (ops == RT_HW_CACHE_INVALIDATE)
  188. dcache_invalidate(addr, size);
  189. }
  190. /**
  191. * reset cpu by dog's time-out
  192. *
  193. */
  194. void rt_hw_cpu_reset()
  195. {
  196. /* Disable all interrupt except the WDT */
  197. INTMSK = (~((rt_uint32_t)1 << INTWDT));
  198. /* Disable watchdog */
  199. WTCON = 0x0000;
  200. /* Initialize watchdog timer count register */
  201. WTCNT = 0x0001;
  202. /* Enable watchdog timer; assert reset at timer timeout */
  203. WTCON = 0x0021;
  204. while (1)
  205. ; /* loop forever and wait for reset to happen */
  206. /* NEVER REACHED */
  207. }
  208. /**
  209. * shutdown CPU
  210. *
  211. */
  212. void rt_hw_cpu_shutdown()
  213. {
  214. rt_uint32_t level;
  215. rt_kprintf("shutdown...\n");
  216. level = rt_hw_interrupt_disable();
  217. while (level)
  218. {
  219. RT_ASSERT(0);
  220. }
  221. }
  222. /*@}*/