cp15.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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 "cp15.h"
  82. #include "uart.h"
  83. #if defined(__ICCARM__)
  84. #include <intrinsics.h>
  85. #endif
  86. /*----------------------------------------------------------------------------
  87. * Global functions
  88. *----------------------------------------------------------------------------*/
  89. /**
  90. * \brief Check Instruction cache
  91. * \return 0 if I_cache disable, 1 if I_cache enable
  92. */
  93. unsigned int CP15_IsIcacheEnabled(void)
  94. {
  95. unsigned int control;
  96. control = CP15_ReadControl();
  97. return ((control & (1 << CP15_I_BIT)) != 0);
  98. }
  99. /**
  100. * \brief Enable Instruction cache
  101. */
  102. void CP15_EnableIcache(void)
  103. {
  104. unsigned int control;
  105. control = CP15_ReadControl();
  106. // Check if cache is disabled
  107. if ((control & (1 << CP15_I_BIT)) == 0) {
  108. control |= (1 << CP15_I_BIT);
  109. CP15_WriteControl(control);
  110. //SendUartString("I cache enabled.\n\r");
  111. }
  112. else {
  113. //SendUartString("I cache is already enabled.\n\r");
  114. }
  115. }
  116. /**
  117. * \brief Disable Instruction cache
  118. */
  119. void CP15_DisableIcache(void)
  120. {
  121. unsigned int control;
  122. control = CP15_ReadControl();
  123. // Check if cache is enabled
  124. if ((control & (1 << CP15_I_BIT)) != 0) {
  125. control &= ~(1ul << CP15_I_BIT);
  126. CP15_WriteControl(control);
  127. //SendUartString("I cache disabled.\n\r");
  128. }
  129. else {
  130. //SendUartString("I cache is already disabled.\n\r");
  131. }
  132. }
  133. /**
  134. * \brief Check MMU
  135. * \return 0 if MMU disable, 1 if MMU enable
  136. */
  137. unsigned int CP15_IsMMUEnabled(void)
  138. {
  139. unsigned int control;
  140. control = CP15_ReadControl();
  141. return ((control & (1 << CP15_M_BIT)) != 0);
  142. }
  143. /**
  144. * \brief Enable MMU
  145. */
  146. void CP15_EnableMMU(void)
  147. {
  148. unsigned int control;
  149. control = CP15_ReadControl();
  150. // Check if MMU is disabled
  151. if ((control & (1 << CP15_M_BIT)) == 0) {
  152. control |= (1 << CP15_M_BIT);
  153. CP15_WriteControl(control);
  154. //SendUartString("MMU enabled.\n\r");
  155. }
  156. else {
  157. //SendUartString("MMU is already enabled.\n\r");
  158. }
  159. }
  160. /**
  161. * \brief Disable MMU
  162. */
  163. void CP15_DisableMMU(void)
  164. {
  165. unsigned int control;
  166. control = CP15_ReadControl();
  167. // Check if MMU is enabled
  168. if ((control & (1 << CP15_M_BIT)) != 0) {
  169. control &= ~(1ul << CP15_M_BIT);
  170. control &= ~(1ul << CP15_C_BIT);
  171. CP15_WriteControl(control);
  172. //SendUartString("MMU disabled.\n\r");
  173. }
  174. else {
  175. //SendUartString("MMU is already disabled.\n\r");
  176. }
  177. }
  178. /**
  179. * \brief Check D_cache
  180. * \return 0 if D_cache disable, 1 if D_cache enable (with MMU of course)
  181. */
  182. unsigned int CP15_IsDcacheEnabled(void)
  183. {
  184. unsigned int control;
  185. control = CP15_ReadControl();
  186. return ((control & ((1 << CP15_C_BIT)||(1 << CP15_M_BIT))) != 0);
  187. }
  188. /**
  189. * \brief Enable Data cache
  190. */
  191. void CP15_EnableDcache(void)
  192. {
  193. unsigned int control;
  194. control = CP15_ReadControl();
  195. if( !CP15_IsMMUEnabled() ) {
  196. //SendUartString("Do nothing: MMU not enabled\r\n");
  197. }
  198. else {
  199. // Check if cache is disabled
  200. if ((control & (1 << CP15_C_BIT)) == 0) {
  201. control |= (1 << CP15_C_BIT);
  202. CP15_WriteControl(control);
  203. //SendUartString("D cache enabled.\r\n");
  204. }
  205. else {
  206. //SendUartString("D cache is already enabled.\r\n");
  207. }
  208. }
  209. }
  210. /**
  211. * \brief Disable Data cache
  212. */
  213. void CP15_DisableDcache(void)
  214. {
  215. unsigned int control;
  216. control = CP15_ReadControl();
  217. // Check if cache is enabled
  218. if ((control & (1 << CP15_C_BIT)) != 0) {
  219. control &= ~(1ul << CP15_C_BIT);
  220. CP15_WriteControl(control);
  221. //SendUartString("D cache disabled.\n\r");
  222. }
  223. else {
  224. //SendUartString("D cache is already disabled.\n\r");
  225. }
  226. }
  227. /**
  228. * \brief Invalidate TLB
  229. */
  230. void CP15_InvalidateTLB(void)
  231. {
  232. asm("MCR p15, 0, %0, c8, c3, 0" : : "r"(1));
  233. asm("DSB");
  234. }
  235. /**
  236. * \brief Clean Data cache
  237. */
  238. void CP15_CacheClean(uint8_t CacheType)
  239. {
  240. //assert(!CacheType);
  241. CP15_SelectDCache();
  242. CP15_CleanDCacheBySetWay();
  243. asm("DSB");
  244. }
  245. /**
  246. * \brief Invalidate D/Icache
  247. */
  248. void CP15_CacheInvalidate(uint8_t CacheType)
  249. {
  250. if(CacheType)
  251. {
  252. CP15_SelectICache();
  253. CP15_InvalidateIcacheInnerSharable();
  254. asm("DSB");
  255. asm("ISB");
  256. }
  257. else
  258. {
  259. CP15_SelectDCache();
  260. CP15_InvalidateDcacheBySetWay();
  261. asm("DSB");
  262. asm("ISB");
  263. }
  264. }
  265. /**
  266. * \brief Flush(Clean and invalidate) Data cache
  267. */
  268. void CP15_CacheFlush(uint8_t CacheType)
  269. {
  270. //assert(!CacheType);
  271. CP15_SelectDCache();
  272. CP15_CleanInvalidateDCacheBySetWay();
  273. asm("DSB");
  274. }
  275. /**
  276. * \brief Invalidate Data cache by address
  277. */
  278. void CP15_InvalidateDCacheByVA(uint32_t S_Add, uint32_t E_Add)
  279. {
  280. CP15_SelectDCache();
  281. CP15_InvalidateDcacheByMva(S_Add, E_Add);
  282. }
  283. /**
  284. * \brief Clean Data cache by address
  285. */
  286. void CP15_CleanDCacheByVA(uint32_t S_Add, uint32_t E_Add)
  287. {
  288. CP15_SelectDCache();
  289. CP15_CleanDCacheByMva(S_Add, E_Add);
  290. }
  291. /**
  292. * \brief Flush Data cache by address
  293. */
  294. void CP15_FlushDCacheByVA(uint32_t S_Add, uint32_t E_Add)
  295. {
  296. CP15_SelectDCache();
  297. CP15_CleanInvalidateDcacheByMva(S_Add, E_Add);
  298. }