ft_aarch32_asm.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2.  * @ : Copyright (c) 2021 Phytium Information Technology, Inc.
  3.  *
  4.  * SPDX-License-Identifier: Apache-2.0.
  5.  *
  6. * @Date: 2021-01-22 16:30:56
  7. * @LastEditTime: 2021-05-24 14:35:53
  8. * @LastEditors: Please set LastEditors
  9. * @Description: In User Settings Edit
  10. * @FilePath: \project_freertos\devices\ft2004\bsp\core\ft_asm.h
  11. */
  12. #ifndef FT_AARCH32_ASM_H
  13. #define FT_AARCH32_ASM_H
  14. #ifdef __cplusplus
  15. extern "C"
  16. {
  17. #endif
  18. #include "ft_types.h"
  19. #define __ASM __asm
  20. #define __STRINGIFY(x) #x
  21. /* C语言实现MCR指令 */
  22. #define __MCR(coproc, opcode_1, src, CRn, CRm, opcode_2) \
  23. __ASM volatile("MCR " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \
  24. "%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " __STRINGIFY(opcode_2) \
  25. : \
  26. : "r"(src) \
  27. : "memory");
  28. /* C语言实现MRC指令 */
  29. #define __MRC(coproc, opcode_1, CRn, CRm, opcode_2) \
  30. ({ \
  31. u32 __dst; \
  32. __ASM volatile("MRC " __STRINGIFY(p##coproc) ", " __STRINGIFY(opcode_1) ", " \
  33. "%0, " __STRINGIFY(c##CRn) ", " __STRINGIFY(c##CRm) ", " __STRINGIFY(opcode_2) \
  34. : "=r"(__dst)::"memory"); \
  35. __dst; \
  36. })
  37. __attribute__((always_inline)) __STATIC_INLINE u32 __get_VBAR(void)
  38. {
  39. return __MRC(15, 0, 12, 0, 0);
  40. }
  41. __attribute__((always_inline)) __STATIC_INLINE void __set_VBAR(u32 vbar)
  42. {
  43. __MCR(15, 0, vbar, 12, 0, 0);
  44. }
  45. __attribute__((always_inline)) __STATIC_INLINE void sys_icc_igrpen0_set(u32 value)
  46. {
  47. __MCR(15, 0, value, 12, 12, 6);
  48. }
  49. __attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_igrpen0_get(void)
  50. {
  51. return __MRC(15, 0, 12, 12, 6);
  52. }
  53. __attribute__((always_inline)) __STATIC_INLINE void sys_icc_igrpen1_set(u32 value)
  54. {
  55. __MCR(15, 0, value, 12, 12, 7);
  56. }
  57. __attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_igrpen1_get(void)
  58. {
  59. return __MRC(15, 0, 12, 12, 7);
  60. }
  61. __attribute__((always_inline)) __STATIC_INLINE void sys_icc_ctlr_set(u32 value)
  62. {
  63. __MCR(15, 0, value, 12, 12, 4);
  64. }
  65. __attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_ctlr_get(void)
  66. {
  67. return __MRC(15, 0, 12, 12, 4);
  68. }
  69. __attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_hppir0_get(void)
  70. {
  71. return __MRC(15, 0, 12, 8, 2);
  72. }
  73. __attribute__((always_inline)) __STATIC_INLINE void sys_icc_bpr_set(u32 value)
  74. {
  75. __MCR(15, 0, value, 12, 12, 3);
  76. }
  77. __attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_bpr_get(void)
  78. {
  79. return __MRC(15, 0, 12, 12, 3);
  80. }
  81. __attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_hppir1_get(void)
  82. {
  83. return __MRC(15, 0, 12, 12, 2);
  84. }
  85. __attribute__((always_inline)) __STATIC_INLINE void sys_icc_eoir0_set(u32 value)
  86. {
  87. __MCR(15, 0, value, 12, 8, 1);
  88. }
  89. __attribute__((always_inline)) __STATIC_INLINE void sys_icc_eoir1_set(u32 value)
  90. {
  91. __MCR(15, 0, value, 12, 12, 1);
  92. }
  93. __attribute__((always_inline)) __STATIC_INLINE void sys_icc_pmr_set(u32 value)
  94. {
  95. __MCR(15, 0, value, 4, 6, 0);
  96. }
  97. __attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_pmr_get(void)
  98. {
  99. return __MRC(15, 0, 4, 6, 0);
  100. }
  101. __attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_iar1_get(void)
  102. {
  103. return __MRC(15, 0, 12, 12, 0);
  104. }
  105. __attribute__((always_inline)) __STATIC_INLINE void sys_icc_sre_set(u32 value)
  106. {
  107. __MCR(15, 0, value, 12, 12, 5);
  108. }
  109. __attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_sre_get(void)
  110. {
  111. return __MRC(15, 0, 12, 12, 5);
  112. }
  113. __attribute__((always_inline)) __STATIC_INLINE u32 sys_icc_rpr_get(void)
  114. {
  115. return __MRC(15, 0, 12, 11, 3);
  116. }
  117. /* Generic Timer registers */
  118. /**
  119. * @name: arm_aarch32_cntfrq_get
  120. * @msg: This register is provided so that software can discover the frequency of the system counter.
  121. * @return {__STATIC_INLINEu32}: frequency of the system counter
  122. */
  123. __attribute__((always_inline)) __STATIC_INLINE u32 arm_aarch32_cntfrq_get(void)
  124. {
  125. return __MRC(15, 0, 14, 0, 0);
  126. }
  127. /**
  128. * @name: arm_aarch32_cnthv_tval_get
  129. * @msg: Provides AArch32 access to the timer value for the EL2 virtual timer.
  130. * @return {__STATIC_INLINEu32}: EL2 virtual timer Cnt.
  131. */
  132. __attribute__((always_inline)) __STATIC_INLINE u32 arm_aarch32_cnthv_tval_get(void)
  133. {
  134. return __MRC(15, 0, 14, 3, 0);
  135. }
  136. /**
  137. * @name: arm_aarch32_cnthv_ctl_set
  138. * @msg: Provides AArch32 access to the control register for the EL2 virtual timer.
  139. * @in param {u32}: RegValue;ENABLE: bit [0] 0 Timer disabled,1 Timer enabled.
  140. * IMASK,bit [1]: 0 Timer interrupt is not masked by the IMASK bit. 1 Timer interrupt is masked by the IMASK bit.
  141. * ISTATUS, bit [2]: 0 Timer condition is not met. 1 Timer condition is met. rea-only
  142. */
  143. __attribute__((always_inline)) __STATIC_INLINE void arm_aarch32_cnthv_ctl_set(u32 RegValue)
  144. {
  145. __MCR(15, 0, RegValue, 14, 3, 1);
  146. }
  147. /**
  148. * @name: arm_aarch32_cnthv_ctl_get
  149. * @msg: Provides AArch32 access to the control register for the EL2 virtual timer.
  150. * @return {__STATIC_INLINEu32}: RegValue;ENABLE: bit [0] 0 Timer disabled,1 Timer enabled.
  151. * IMASK,bit [1]: 0 Timer interrupt is not masked by the IMASK bit. 1 Timer interrupt is masked by the IMASK bit.
  152. * ISTATUS, bit [2]: 0 Timer condition is not met. 1 Timer condition is met. read-only
  153. */
  154. __attribute__((always_inline)) __STATIC_INLINE u32 arm_aarch32_cnthv_ctl_get(void)
  155. {
  156. return __MRC(15, 0, 14, 3, 1);
  157. }
  158. /**
  159. * @name: arm_aarch32_cnthv_tval_set
  160. * @msg: Provides AArch32 access to the timer value for the EL2 virtual timer.
  161. * @in param {u32}: TimerValue, bits [31:0] The TimerValue view of the EL2 virtual timer.
  162. */
  163. __attribute__((always_inline)) __STATIC_INLINE void arm_aarch32_cnthv_tval_set(u32 RegValue)
  164. {
  165. __MCR(15, 0, RegValue, 14, 3, 0);
  166. }
  167. /**
  168. * @name: arm_aarch32_cntvct_get
  169. * @msg: Read the register that holds the 64-bit virtual count value. The virtual count value is equal to the physical count value visible in CNTPCT minus the virtual offset visible in CNTVOFF.
  170. * @return {__STATIC_INLINEu64}Bits [63:0] Virtual count value.
  171. */
  172. __attribute__((always_inline)) __STATIC_INLINE u64 arm_aarch32_cntvct_get(void)
  173. {
  174. /* "r0" --- low,
  175. "r1" --- hi
  176. */
  177. u32 low;
  178. u32 hi;
  179. __asm__ volatile(
  180. ".word 0xec510f1e \n" /* mrrc p15, 1, r0, r1, c14 */
  181. "mov %0, r0 \n"
  182. "mov %1, r1 \n"
  183. : "=&r"(low), "=&r"(hi));
  184. return (((u64)hi) << 32) | low;
  185. }
  186. /* physical */
  187. /**
  188. * @name: arm_aarch32_cntp_tval_get
  189. * @msg: Read the register that holds the timer value for the EL1 physical timer.
  190. * @return {__STATIC_INLINEu32}: TimerValue, bits [31:0] The TimerValue view of the EL1 physical timer.
  191. */
  192. __attribute__((always_inline)) __STATIC_INLINE u32 arm_aarch32_cntp_tval_get(void)
  193. {
  194. return __MRC(15, 0, 14, 2, 0);
  195. }
  196. /**
  197. * @name: arm_aarch32_cntp_tval_set
  198. * @msg: write the register that control register for the EL1 physical timer.
  199. * @in param {u32}: TimerValue, bits [31:0] The TimerValue view of the EL1 physical timer.
  200. */
  201. __attribute__((always_inline)) __STATIC_INLINE void arm_aarch32_cntp_tval_set(u32 RegValue)
  202. {
  203. __MCR(15, 0, RegValue, 14, 2, 0);
  204. }
  205. /**
  206. * @name: arm_aarch32_cntp_ctl_set
  207. * @msg: write the register that control register for the EL1 physical timer.
  208. * @in param {u32}: ENABLE, bit[0] Enables the timer ; IMASK, bit [1] Timer interrupt mask bit; ISTATUS, bit [2] The status of the timer.
  209. */
  210. __attribute__((always_inline)) __STATIC_INLINE void arm_aarch32_cntp_ctl_set(u32 RegValue)
  211. {
  212. __MCR(15, 0, RegValue, 14, 2, 1);
  213. }
  214. /**
  215. * @name: arm_aarch32_cntp_ctl_get
  216. * @msg: Read the register that control register for the EL1 physical timer.
  217. * @return {__STATIC_INLINEu32}: ENABLE, bit[0] Enables the timer ; IMASK, bit [1] Timer interrupt mask bit; ISTATUS, bit [2] The status of the timer.
  218. */
  219. __attribute__((always_inline)) __STATIC_INLINE u32 arm_aarch32_cntp_ctl_get(void)
  220. {
  221. return __MRC(15, 0, 14, 2, 1);
  222. }
  223. /**
  224. * @name: arm_aarch32_cntpct_get
  225. * @msg: Read the register that holds the 64-bit physical count value.
  226. * @return {__STATIC_INLINEu64} CompareValue, bits [63:0] Physical count value.
  227. */
  228. __attribute__((always_inline)) __STATIC_INLINE u64 arm_aarch32_cntpct_get(void)
  229. {
  230. /* "r0" --- low,
  231. "r1" --- hi
  232. */
  233. u32 low;
  234. u32 hi;
  235. __asm__ volatile(
  236. ".word 0xec510f0e \n" /* mrrc p15, 0, r0, r1, c14 */
  237. "mov %0, r0 \n"
  238. "mov %1, r1 \n"
  239. : "=&r"(low), "=&r"(hi));
  240. return (((u64)hi) << 32) | low;
  241. }
  242. #define IRQ_DISABLE() \
  243. __asm volatile("CPSID i" :: \
  244. : "memory"); \
  245. __asm volatile("DSB"); \
  246. __asm volatile("ISB");
  247. #define IRQ_ENABLE() \
  248. __asm volatile("CPSIE i" :: \
  249. : "memory"); \
  250. __asm volatile("DSB"); \
  251. __asm volatile("ISB");
  252. /* the exception stack without VFP registers */
  253. struct ft_hw_exp_stack
  254. {
  255. u32 r0;
  256. u32 r1;
  257. u32 r2;
  258. u32 r3;
  259. u32 r4;
  260. u32 r5;
  261. u32 r6;
  262. u32 r7;
  263. u32 r8;
  264. u32 r9;
  265. u32 r10;
  266. u32 fp;
  267. u32 ip;
  268. u32 sp;
  269. u32 lr;
  270. u32 pc;
  271. u32 cpsr;
  272. };
  273. #ifdef __cplusplus
  274. }
  275. #endif
  276. #endif // !