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