cpu.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. //*****************************************************************************
  2. //
  3. // cpu.c
  4. //
  5. // Instruction wrappers for special CPU instructions needed by the
  6. // drivers.
  7. //
  8. // Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
  9. //
  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. // Redistributions of source code must retain the above copyright
  16. // notice, this list of conditions and the following disclaimer.
  17. //
  18. // Redistributions in binary form must reproduce the above copyright
  19. // notice, this list of conditions and the following disclaimer in the
  20. // documentation and/or other materials provided with the
  21. // distribution.
  22. //
  23. // Neither the name of Texas Instruments Incorporated nor the names of
  24. // its contributors may be used to endorse or promote products derived
  25. // from this software without specific prior written permission.
  26. //
  27. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  28. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  29. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  30. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  31. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  32. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  33. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  34. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  35. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  37. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. //
  39. //*****************************************************************************
  40. #include "cpu.h"
  41. //*****************************************************************************
  42. //
  43. // Wrapper function for the CPSID instruction. Returns the state of PRIMASK
  44. // on entry.
  45. //
  46. //*****************************************************************************
  47. #if defined(gcc)
  48. unsigned long __attribute__((naked))
  49. CPUcpsid(void)
  50. {
  51. unsigned long ulRet;
  52. //
  53. // Read PRIMASK and disable interrupts.
  54. //
  55. __asm(" mrs r0, PRIMASK\n"
  56. " cpsid i\n"
  57. " dsb \n"
  58. " isb \n"
  59. " bx lr\n"
  60. : "=r" (ulRet));
  61. //
  62. // The return is handled in the inline assembly, but the compiler will
  63. // still complain if there is not an explicit return here (despite the fact
  64. // that this does not result in any code being produced because of the
  65. // naked attribute).
  66. //
  67. return(ulRet);
  68. }
  69. #endif
  70. #if defined(ewarm)
  71. unsigned long
  72. CPUcpsid(void)
  73. {
  74. //
  75. // Read PRIMASK and disable interrupts.
  76. //
  77. __asm(" mrs r0, PRIMASK\n"
  78. " cpsid i\n"
  79. " dsb \n"
  80. " isb \n");
  81. //
  82. // "Warning[Pe940]: missing return statement at end of non-void function"
  83. // is suppressed here to avoid putting a "bx lr" in the inline assembly
  84. // above and a superfluous return statement here.
  85. //
  86. #pragma diag_suppress=Pe940
  87. }
  88. #pragma diag_default=Pe940
  89. #endif
  90. #if defined(ccs)
  91. unsigned long
  92. CPUcpsid(void)
  93. {
  94. //
  95. // Read PRIMASK and disable interrupts.
  96. //
  97. __asm(" mrs r0, PRIMASK\n"
  98. " cpsid i\n"
  99. " dsb \n"
  100. " isb \n"
  101. " bx lr\n");
  102. //
  103. // The following keeps the compiler happy, because it wants to see a
  104. // return value from this function. It will generate code to return
  105. // a zero. However, the real return is the "bx lr" above, so the
  106. // return(0) is never executed and the function returns with the value
  107. // you expect in R0.
  108. //
  109. return(0);
  110. }
  111. #endif
  112. //*****************************************************************************
  113. //
  114. // Wrapper function returning the state of PRIMASK (indicating whether
  115. // interrupts are enabled or disabled).
  116. //
  117. //*****************************************************************************
  118. #if defined(gcc)
  119. unsigned long __attribute__((naked))
  120. CPUprimask(void)
  121. {
  122. unsigned long ulRet;
  123. //
  124. // Read PRIMASK and disable interrupts.
  125. //
  126. __asm(" mrs r0, PRIMASK\n"
  127. " bx lr\n"
  128. : "=r" (ulRet));
  129. //
  130. // The return is handled in the inline assembly, but the compiler will
  131. // still complain if there is not an explicit return here (despite the fact
  132. // that this does not result in any code being produced because of the
  133. // naked attribute).
  134. //
  135. return(ulRet);
  136. }
  137. #endif
  138. #if defined(ewarm)
  139. unsigned long
  140. CPUprimask(void)
  141. {
  142. //
  143. // Read PRIMASK and disable interrupts.
  144. //
  145. __asm(" mrs r0, PRIMASK\n");
  146. //
  147. // "Warning[Pe940]: missing return statement at end of non-void function"
  148. // is suppressed here to avoid putting a "bx lr" in the inline assembly
  149. // above and a superfluous return statement here.
  150. //
  151. #pragma diag_suppress=Pe940
  152. }
  153. #pragma diag_default=Pe940
  154. #endif
  155. #if defined(ccs)
  156. unsigned long
  157. CPUprimask(void)
  158. {
  159. //
  160. // Read PRIMASK and disable interrupts.
  161. //
  162. __asm(" mrs r0, PRIMASK\n"
  163. " bx lr\n");
  164. //
  165. // The following keeps the compiler happy, because it wants to see a
  166. // return value from this function. It will generate code to return
  167. // a zero. However, the real return is the "bx lr" above, so the
  168. // return(0) is never executed and the function returns with the value
  169. // you expect in R0.
  170. //
  171. return(0);
  172. }
  173. #endif
  174. //*****************************************************************************
  175. //
  176. // Wrapper function for the CPSIE instruction. Returns the state of PRIMASK
  177. // on entry.
  178. //
  179. //*****************************************************************************
  180. #if defined(gcc)
  181. unsigned long __attribute__((naked))
  182. CPUcpsie(void)
  183. {
  184. unsigned long ulRet;
  185. //
  186. // Read PRIMASK and enable interrupts.
  187. //
  188. __asm(" mrs r0, PRIMASK\n"
  189. " cpsie i\n"
  190. " dsb \n"
  191. " isb \n"
  192. " bx lr\n"
  193. : "=r" (ulRet));
  194. //
  195. // The return is handled in the inline assembly, but the compiler will
  196. // still complain if there is not an explicit return here (despite the fact
  197. // that this does not result in any code being produced because of the
  198. // naked attribute).
  199. //
  200. return(ulRet);
  201. }
  202. #endif
  203. #if defined(ewarm)
  204. unsigned long
  205. CPUcpsie(void)
  206. {
  207. //
  208. // Read PRIMASK and enable interrupts.
  209. //
  210. __asm(" mrs r0, PRIMASK\n"
  211. " cpsie i\n"
  212. " dsb \n"
  213. " isb \n");
  214. //
  215. // "Warning[Pe940]: missing return statement at end of non-void function"
  216. // is suppressed here to avoid putting a "bx lr" in the inline assembly
  217. // above and a superfluous return statement here.
  218. //
  219. #pragma diag_suppress=Pe940
  220. }
  221. #pragma diag_default=Pe940
  222. #endif
  223. #if defined(ccs)
  224. unsigned long
  225. CPUcpsie(void)
  226. {
  227. //
  228. // Read PRIMASK and enable interrupts.
  229. //
  230. __asm(" mrs r0, PRIMASK\n"
  231. " cpsie i\n"
  232. " dsb \n"
  233. " isb \n"
  234. " bx lr\n");
  235. //
  236. // The following keeps the compiler happy, because it wants to see a
  237. // return value from this function. It will generate code to return
  238. // a zero. However, the real return is the "bx lr" above, so the
  239. // return(0) is never executed and the function returns with the value
  240. // you expect in R0.
  241. //
  242. return(0);
  243. }
  244. #endif
  245. //*****************************************************************************
  246. //
  247. // Wrapper function for the WFI instruction.
  248. //
  249. //*****************************************************************************
  250. #if defined(gcc)
  251. void __attribute__((naked))
  252. CPUwfi(void)
  253. {
  254. //
  255. // Wait for the next interrupt.
  256. //
  257. __asm(" dsb \n"
  258. " isb \n"
  259. " wfi \n"
  260. " bx lr\n");
  261. }
  262. #endif
  263. #if defined(ewarm)
  264. void
  265. CPUwfi(void)
  266. {
  267. //
  268. // Wait for the next interrupt.
  269. //
  270. __asm(" dsb \n"
  271. " isb \n"
  272. " wfi \n");
  273. }
  274. #endif
  275. #if defined(ccs)
  276. void
  277. CPUwfi(void)
  278. {
  279. //
  280. // Wait for the next interrupt.
  281. //
  282. __asm(" dsb \n"
  283. " isb \n"
  284. " wfi \n");
  285. }
  286. #endif
  287. //*****************************************************************************
  288. //
  289. // Wrapper function for writing the BASEPRI register.
  290. //
  291. //*****************************************************************************
  292. #if defined(gcc)
  293. void __attribute__((naked))
  294. CPUbasepriSet(unsigned long ulNewBasepri)
  295. {
  296. //
  297. // Set the BASEPRI register
  298. //
  299. __asm(" msr BASEPRI, r0\n"
  300. " dsb \n"
  301. " isb \n"
  302. " bx lr\n");
  303. }
  304. #endif
  305. #if defined(ewarm)
  306. void
  307. CPUbasepriSet(unsigned long ulNewBasepri)
  308. {
  309. //
  310. // Set the BASEPRI register
  311. //
  312. __asm(" msr BASEPRI, r0\n"
  313. " dsb \n"
  314. " isb \n");
  315. }
  316. #endif
  317. #if defined(ccs)
  318. void
  319. CPUbasepriSet(unsigned long ulNewBasepri)
  320. {
  321. //
  322. // Set the BASEPRI register
  323. //
  324. __asm(" msr BASEPRI, r0\n"
  325. " dsb \n"
  326. " isb \n");
  327. }
  328. #endif
  329. //*****************************************************************************
  330. //
  331. // Wrapper function for reading the BASEPRI register.
  332. //
  333. //*****************************************************************************
  334. #if defined(gcc)
  335. unsigned long __attribute__((naked))
  336. CPUbasepriGet(void)
  337. {
  338. unsigned long ulRet;
  339. //
  340. // Read BASEPRI
  341. //
  342. __asm(" mrs r0, BASEPRI\n"
  343. " bx lr\n"
  344. : "=r" (ulRet));
  345. //
  346. // The return is handled in the inline assembly, but the compiler will
  347. // still complain if there is not an explicit return here (despite the fact
  348. // that this does not result in any code being produced because of the
  349. // naked attribute).
  350. //
  351. return(ulRet);
  352. }
  353. #endif
  354. #if defined(ewarm)
  355. unsigned long
  356. CPUbasepriGet(void)
  357. {
  358. //
  359. // Read BASEPRI
  360. //
  361. __asm(" mrs r0, BASEPRI\n");
  362. //
  363. // "Warning[Pe940]: missing return statement at end of non-void function"
  364. // is suppressed here to avoid putting a "bx lr" in the inline assembly
  365. // above and a superfluous return statement here.
  366. //
  367. #pragma diag_suppress=Pe940
  368. }
  369. #pragma diag_default=Pe940
  370. #endif
  371. #if defined(ccs)
  372. unsigned long
  373. CPUbasepriGet(void)
  374. {
  375. //
  376. // Read BASEPRI
  377. //
  378. __asm(" mrs r0, BASEPRI\n"
  379. " bx lr\n");
  380. //
  381. // The following keeps the compiler happy, because it wants to see a
  382. // return value from this function. It will generate code to return
  383. // a zero. However, the real return is the "bx lr" above, so the
  384. // return(0) is never executed and the function returns with the value
  385. // you expect in R0.
  386. //
  387. return(0);
  388. }
  389. #endif