cp15.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. /* ----------------------------------------------------------------------------
  2. * SAM Software Package License
  3. * ----------------------------------------------------------------------------
  4. * Copyright (c) 2011, Atmel Corporation
  5. *
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions are met:
  10. *
  11. * - Redistributions of source code must retain the above copyright notice,
  12. * this list of conditions and the disclaimer below.
  13. *
  14. * Atmel's name may not be used to endorse or promote products derived from
  15. * this software without specific prior written permission.
  16. *
  17. * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  20. * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  22. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  23. * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  24. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  25. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  26. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. * ----------------------------------------------------------------------------
  28. */
  29. //-----------------------------------------------------------------------------
  30. // Reg Reads Writes
  31. //----------------------------------------------------------------------------
  32. // 0 ID code Unpredictable
  33. // 0 cache type Unpredictable
  34. // 0 TCM status Unpredictable
  35. // 1 Control Control
  36. // 2 Translation table base Translation table base
  37. // 3 Domain access control Domain access control
  38. // 4 (Reserved)
  39. // 5 Data fault status Data fault status
  40. // 5 Instruction fault status Instruction fault status
  41. // 6 Fault address Fault address
  42. // 7 cache operations cache operations
  43. // 8 Unpredictable TLB operations
  44. // 9 cache lockdown cache lockdown
  45. // 9 TCM region TCM region
  46. // 10 TLB lockdown TLB lockdown
  47. // 11 (Reserved)
  48. // 12 (Reserved)
  49. // 13 FCSE PID FCSE PID
  50. // 13 Context ID Context ID
  51. // 14 (Reserved)
  52. // 15 Test configuration Test configuration
  53. //-----------------------------------------------------------------------------
  54. /** \page cp15_f CP15 Functions.
  55. *
  56. * \section CP15 function Usage
  57. *
  58. * Methods to manage the Coprocessor 15. Coprocessor 15, or System Control
  59. * Coprocessor CP15, is used to configure and control all the items in the
  60. * list below:
  61. * <ul>
  62. * <li> ARM core
  63. * <li> caches (Icache, Dcache and write buffer)
  64. * <li> TCM
  65. * <li> MMU
  66. * <li> Other system options
  67. * </ul>
  68. * \section Usage
  69. *
  70. * -# Enable or disable D cache with Enable_D_cache and Disable_D_cache
  71. * -# Enable or disable I cache with Enable_I_cache and Disable_I_cache
  72. *
  73. * Related files:\n
  74. * \ref cp15.h\n
  75. * \ref cp15.c.\n
  76. */
  77. /** \file */
  78. /*----------------------------------------------------------------------------
  79. * Headers
  80. *----------------------------------------------------------------------------*/
  81. #include "chip.h"
  82. #if defined(__ICCARM__)
  83. #include <intrinsics.h>
  84. #endif
  85. /*----------------------------------------------------------------------------
  86. * Global functions
  87. *----------------------------------------------------------------------------*/
  88. /**
  89. * \brief Check Instruction cache
  90. * \return 0 if I_cache disable, 1 if I_cache enable
  91. */
  92. unsigned int CP15_IsIcacheEnabled(void)
  93. {
  94. unsigned int control;
  95. control = CP15_ReadControl();
  96. return ((control & (1 << CP15_I_BIT)) != 0);
  97. }
  98. /**
  99. * \brief Enable Instruction cache
  100. */
  101. void CP15_EnableIcache(void)
  102. {
  103. unsigned int control;
  104. control = CP15_ReadControl();
  105. // Check if cache is disabled
  106. if ((control & (1 << CP15_I_BIT)) == 0) {
  107. control |= (1 << CP15_I_BIT);
  108. CP15_WriteControl(control);
  109. TRACE_INFO("I cache enabled.\n\r");
  110. }
  111. else {
  112. TRACE_INFO("I cache is already enabled.\n\r");
  113. }
  114. }
  115. /**
  116. * \brief Disable Instruction cache
  117. */
  118. void CP15_DisableIcache(void)
  119. {
  120. unsigned int control;
  121. control = CP15_ReadControl();
  122. // Check if cache is enabled
  123. if ((control & (1 << CP15_I_BIT)) != 0) {
  124. control &= ~(1ul << CP15_I_BIT);
  125. CP15_WriteControl(control);
  126. TRACE_INFO("I cache disabled.\n\r");
  127. }
  128. else {
  129. TRACE_INFO("I cache is already disabled.\n\r");
  130. }
  131. }
  132. /**
  133. * \brief Check MMU
  134. * \return 0 if MMU disable, 1 if MMU enable
  135. */
  136. unsigned int CP15_IsMMUEnabled(void)
  137. {
  138. unsigned int control;
  139. control = CP15_ReadControl();
  140. return ((control & (1 << CP15_M_BIT)) != 0);
  141. }
  142. /**
  143. * \brief Enable MMU
  144. */
  145. void CP15_EnableMMU(void)
  146. {
  147. unsigned int control;
  148. control = CP15_ReadControl();
  149. // Check if MMU is disabled
  150. if ((control & (1 << CP15_M_BIT)) == 0) {
  151. control |= (1 << CP15_M_BIT);
  152. CP15_WriteControl(control);
  153. TRACE_INFO("MMU enabled.\n\r");
  154. }
  155. else {
  156. TRACE_INFO("MMU is already enabled.\n\r");
  157. }
  158. }
  159. /**
  160. * \brief Disable MMU
  161. */
  162. void CP15_DisableMMU(void)
  163. {
  164. unsigned int control;
  165. control = CP15_ReadControl();
  166. // Check if MMU is enabled
  167. if ((control & (1 << CP15_M_BIT)) != 0) {
  168. control &= ~(1ul << CP15_M_BIT);
  169. control &= ~(1ul << CP15_C_BIT);
  170. CP15_WriteControl(control);
  171. TRACE_INFO("MMU disabled.\n\r");
  172. }
  173. else {
  174. TRACE_INFO("MMU is already disabled.\n\r");
  175. }
  176. }
  177. /**
  178. * \brief Check D_cache
  179. * \return 0 if D_cache disable, 1 if D_cache enable (with MMU of course)
  180. */
  181. unsigned int CP15_IsDcacheEnabled(void)
  182. {
  183. unsigned int control;
  184. control = CP15_ReadControl();
  185. return ((control & ((1 << CP15_C_BIT)||(1 << CP15_M_BIT))) != 0);
  186. }
  187. void CP15_EnableSMP(void)
  188. {
  189. unsigned int control;
  190. control = CP15_ReadACTLRControl();
  191. if ((control & (1 << CP15_SMP_BIT)) == 0) {
  192. control |= (1 << CP15_SMP_BIT);
  193. CP15_WriteACTLRControl(control);
  194. }
  195. }
  196. /**
  197. * \brief Enable Data cache
  198. */
  199. void CP15_EnableDcache(void)
  200. {
  201. unsigned int control;
  202. control = CP15_ReadControl();
  203. if( !CP15_IsMMUEnabled() ) {
  204. TRACE_ERROR("Do nothing: MMU not enabled\n\r");
  205. }
  206. else {
  207. // Check if cache is disabled
  208. if ((control & (1 << CP15_C_BIT)) == 0) {
  209. control |= (1 << CP15_C_BIT);
  210. CP15_WriteControl(control);
  211. TRACE_INFO("D cache enabled.\n\r");
  212. }
  213. else {
  214. TRACE_INFO("D cache is already enabled.\n\r");
  215. }
  216. }
  217. }
  218. /**
  219. * \brief Disable Data cache
  220. */
  221. void CP15_DisableDcache(void)
  222. {
  223. unsigned int control;
  224. control = CP15_ReadControl();
  225. // Check if cache is enabled
  226. if ((control & (1 << CP15_C_BIT)) != 0) {
  227. control &= ~(1ul << CP15_C_BIT);
  228. CP15_WriteControl(control);
  229. TRACE_INFO("D cache disabled.\n\r");
  230. }
  231. else {
  232. TRACE_INFO("D cache is already disabled.\n\r");
  233. }
  234. }
  235. /**
  236. * \brief Invalidate TLB
  237. */
  238. void CP15_InvalidateTLB(void)
  239. {
  240. asm("MCR p15, 0, %0, c8, c3, 0" : : "r"(1));
  241. asm("DSB");
  242. }
  243. /**
  244. * \brief Clean Data cache
  245. */
  246. void CP15_CacheClean(uint8_t CacheType)
  247. {
  248. configASSERT(!CacheType);
  249. CP15_SelectDCache();
  250. CP15_CleanDCacheBySetWay();
  251. asm("DSB");
  252. }
  253. /**
  254. * \brief Invalidate D/Icache
  255. */
  256. void CP15_CacheInvalidate(uint8_t CacheType)
  257. {
  258. if(CacheType)
  259. {
  260. CP15_SelectICache();
  261. CP15_InvalidateIcacheInnerSharable();
  262. asm("DSB");
  263. asm("ISB");
  264. }
  265. else
  266. {
  267. CP15_SelectDCache();
  268. CP15_InvalidateDcacheBySetWay();
  269. asm("DSB");
  270. asm("ISB");
  271. }
  272. }
  273. /**
  274. * \brief Flush(Clean and invalidate) Data cache
  275. */
  276. void CP15_CacheFlush(uint8_t CacheType)
  277. {
  278. configASSERT(!CacheType);
  279. CP15_SelectDCache();
  280. CP15_CleanInvalidateDCacheBySetWay();
  281. asm("DSB");
  282. }
  283. /**
  284. * \brief Invalidate Data cache by address
  285. */
  286. void CP15_InvalidateDCacheByVA(uint32_t S_Add, uint32_t E_Add)
  287. {
  288. CP15_SelectDCache();
  289. CP15_InvalidateDcacheByMva(S_Add, E_Add);
  290. }
  291. /**
  292. * \brief Clean Data cache by address
  293. */
  294. void CP15_CleanDCacheByVA(uint32_t S_Add, uint32_t E_Add)
  295. {
  296. CP15_SelectDCache();
  297. CP15_CleanDCacheByMva(S_Add, E_Add);
  298. }
  299. /**
  300. * \brief Flush Data cache by address
  301. */
  302. void CP15_FlushDCacheByVA(uint32_t S_Add, uint32_t E_Add)
  303. {
  304. CP15_SelectDCache();
  305. CP15_CleanInvalidateDcacheByMva(S_Add, E_Add);
  306. }