cpu.c 12 KB

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