[da215ded] | 1 | /** |
---|
[78623bce] | 2 | * @file |
---|
| 3 | * |
---|
| 4 | * @ingroup ScoreCPU |
---|
| 5 | * |
---|
| 6 | * @brief ARM architecture support API. |
---|
[da215ded] | 7 | */ |
---|
| 8 | |
---|
[4f0b287] | 9 | /* |
---|
[6c63598] | 10 | * $Id$ |
---|
[fa237002] | 11 | * |
---|
[4f0b287] | 12 | * This include file contains information pertaining to the ARM |
---|
[08330bf] | 13 | * processor. |
---|
| 14 | * |
---|
[c5ed148] | 15 | * Copyright (c) 2009-2011 embedded brains GmbH. |
---|
[39c8fdb] | 16 | * |
---|
[a3ff693] | 17 | * Copyright (c) 2007 Ray Xu <Rayx.cn@gmail.com> |
---|
| 18 | * |
---|
[6a07436] | 19 | * Copyright (c) 2006 OAR Corporation |
---|
| 20 | * |
---|
[fa237002] | 21 | * Copyright (c) 2002 Advent Networks, Inc. |
---|
[4f0b287] | 22 | * Jay Monkman <jmonkman@adventnetworks.com> |
---|
| 23 | * |
---|
[08330bf] | 24 | * COPYRIGHT (c) 2000 Canon Research Centre France SA. |
---|
| 25 | * Emmanuel Raguet, mailto:raguet@crf.canon.fr |
---|
| 26 | * |
---|
| 27 | * The license and distribution terms for this file may be |
---|
| 28 | * found in the file LICENSE in this distribution or at |
---|
[57b8a7b6] | 29 | * http://www.rtems.com/license/LICENSE. |
---|
[08330bf] | 30 | * |
---|
| 31 | */ |
---|
| 32 | |
---|
[7f70d1b7] | 33 | #ifndef _RTEMS_SCORE_CPU_H |
---|
| 34 | #define _RTEMS_SCORE_CPU_H |
---|
[08330bf] | 35 | |
---|
[89b85e51] | 36 | #include <rtems/score/types.h> |
---|
[632e4306] | 37 | #include <rtems/score/arm.h> |
---|
[08330bf] | 38 | |
---|
[c5ed148] | 39 | #if defined(ARM_MULTILIB_ARCH_V4) |
---|
| 40 | |
---|
[78623bce] | 41 | /** |
---|
| 42 | * @defgroup ScoreCPUARM ARM Specific Support |
---|
| 43 | * |
---|
| 44 | * @ingroup ScoreCPU |
---|
| 45 | * |
---|
| 46 | * @brief ARM specific support. |
---|
| 47 | * |
---|
| 48 | * @{ |
---|
| 49 | */ |
---|
| 50 | |
---|
[632e4306] | 51 | #ifdef __thumb__ |
---|
[39c8fdb] | 52 | #define ARM_SWITCH_REGISTERS uint32_t arm_switch_reg |
---|
| 53 | #define ARM_SWITCH_TO_ARM ".align 2\nbx pc\n.arm\n" |
---|
| 54 | #define ARM_SWITCH_BACK "add %[arm_switch_reg], pc, #1\nbx %[arm_switch_reg]\n.thumb\n" |
---|
| 55 | #define ARM_SWITCH_OUTPUT [arm_switch_reg] "=&r" (arm_switch_reg) |
---|
| 56 | #define ARM_SWITCH_ADDITIONAL_OUTPUT , ARM_SWITCH_OUTPUT |
---|
[248e29a] | 57 | #else |
---|
[39c8fdb] | 58 | #define ARM_SWITCH_REGISTERS |
---|
| 59 | #define ARM_SWITCH_TO_ARM |
---|
| 60 | #define ARM_SWITCH_BACK |
---|
| 61 | #define ARM_SWITCH_OUTPUT |
---|
| 62 | #define ARM_SWITCH_ADDITIONAL_OUTPUT |
---|
[248e29a] | 63 | #endif |
---|
[08330bf] | 64 | |
---|
[78623bce] | 65 | /** |
---|
| 66 | * @name Program Status Register |
---|
| 67 | * |
---|
| 68 | * @{ |
---|
| 69 | */ |
---|
| 70 | |
---|
[39c8fdb] | 71 | #define ARM_PSR_N (1 << 31) |
---|
| 72 | #define ARM_PSR_Z (1 << 30) |
---|
| 73 | #define ARM_PSR_C (1 << 29) |
---|
| 74 | #define ARM_PSR_V (1 << 28) |
---|
| 75 | #define ARM_PSR_Q (1 << 27) |
---|
| 76 | #define ARM_PSR_J (1 << 24) |
---|
| 77 | #define ARM_PSR_GE_SHIFT 16 |
---|
| 78 | #define ARM_PSR_GE_MASK (0xf << ARM_PSR_GE_SHIFT) |
---|
| 79 | #define ARM_PSR_E (1 << 9) |
---|
| 80 | #define ARM_PSR_A (1 << 8) |
---|
| 81 | #define ARM_PSR_I (1 << 7) |
---|
| 82 | #define ARM_PSR_F (1 << 6) |
---|
| 83 | #define ARM_PSR_T (1 << 5) |
---|
| 84 | #define ARM_PSR_M_SHIFT 0 |
---|
| 85 | #define ARM_PSR_M_MASK (0x1f << ARM_PSR_M_SHIFT) |
---|
| 86 | #define ARM_PSR_M_USR 0x10 |
---|
| 87 | #define ARM_PSR_M_FIQ 0x11 |
---|
| 88 | #define ARM_PSR_M_IRQ 0x12 |
---|
| 89 | #define ARM_PSR_M_SVC 0x13 |
---|
| 90 | #define ARM_PSR_M_ABT 0x17 |
---|
| 91 | #define ARM_PSR_M_UND 0x1b |
---|
| 92 | #define ARM_PSR_M_SYS 0x1f |
---|
| 93 | |
---|
[78623bce] | 94 | /** @} */ |
---|
| 95 | |
---|
| 96 | /** @} */ |
---|
| 97 | |
---|
[c5ed148] | 98 | #endif /* defined(ARM_MULTILIB_ARCH_V4) */ |
---|
| 99 | |
---|
[78623bce] | 100 | /** |
---|
| 101 | * @addtogroup ScoreCPU |
---|
| 102 | * |
---|
| 103 | * @{ |
---|
| 104 | */ |
---|
| 105 | |
---|
[632e4306] | 106 | /* If someone uses THUMB we assume she wants minimal code size */ |
---|
| 107 | #ifdef __thumb__ |
---|
| 108 | #define CPU_INLINE_ENABLE_DISPATCH FALSE |
---|
| 109 | #else |
---|
| 110 | #define CPU_INLINE_ENABLE_DISPATCH TRUE |
---|
| 111 | #endif |
---|
[08330bf] | 112 | |
---|
[632e4306] | 113 | #if defined(__ARMEL__) |
---|
| 114 | #define CPU_BIG_ENDIAN FALSE |
---|
| 115 | #define CPU_LITTLE_ENDIAN TRUE |
---|
| 116 | #elif defined(__ARMEB__) |
---|
| 117 | #define CPU_BIG_ENDIAN TRUE |
---|
| 118 | #define CPU_LITTLE_ENDIAN FALSE |
---|
| 119 | #else |
---|
| 120 | #error "unknown endianness" |
---|
| 121 | #endif |
---|
[08330bf] | 122 | |
---|
[632e4306] | 123 | #define CPU_UNROLL_ENQUEUE_PRIORITY TRUE |
---|
[08330bf] | 124 | |
---|
| 125 | #define CPU_HAS_SOFTWARE_INTERRUPT_STACK FALSE |
---|
| 126 | |
---|
[c5ed148] | 127 | #define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE |
---|
[08330bf] | 128 | |
---|
[fa237002] | 129 | #define CPU_ALLOCATE_INTERRUPT_STACK FALSE |
---|
[08330bf] | 130 | |
---|
| 131 | #define CPU_ISR_PASSES_FRAME_POINTER 0 |
---|
| 132 | |
---|
| 133 | #if ( ARM_HAS_FPU == 1 ) |
---|
[632e4306] | 134 | #define CPU_HARDWARE_FP TRUE |
---|
[08330bf] | 135 | #else |
---|
[632e4306] | 136 | #define CPU_HARDWARE_FP FALSE |
---|
[08330bf] | 137 | #endif |
---|
| 138 | |
---|
[632e4306] | 139 | #define CPU_SOFTWARE_FP FALSE |
---|
[08330bf] | 140 | |
---|
[632e4306] | 141 | #define CPU_ALL_TASKS_ARE_FP FALSE |
---|
[08330bf] | 142 | |
---|
[632e4306] | 143 | #define CPU_IDLE_TASK_IS_FP FALSE |
---|
[08330bf] | 144 | |
---|
[632e4306] | 145 | #define CPU_USE_DEFERRED_FP_SWITCH FALSE |
---|
[08330bf] | 146 | |
---|
[632e4306] | 147 | #define CPU_PROVIDES_IDLE_THREAD_BODY FALSE |
---|
[08330bf] | 148 | |
---|
[632e4306] | 149 | #define CPU_STACK_GROWS_UP FALSE |
---|
[08330bf] | 150 | |
---|
[632e4306] | 151 | /* XXX Why 32? */ |
---|
| 152 | #define CPU_STRUCTURE_ALIGNMENT __attribute__ ((aligned (32))) |
---|
[08330bf] | 153 | |
---|
[d0630763] | 154 | #define CPU_TIMESTAMP_USE_INT64_INLINE TRUE |
---|
| 155 | |
---|
[08330bf] | 156 | /* |
---|
[632e4306] | 157 | * The interrupt mask disables only normal interrupts (IRQ). |
---|
[08330bf] | 158 | * |
---|
[632e4306] | 159 | * In order to support fast interrupts (FIQ) such that they can do something |
---|
| 160 | * useful, we have to disable the operating system support for FIQs. Having |
---|
| 161 | * operating system support for them would require that FIQs are disabled |
---|
| 162 | * during critical sections of the operating system and application. At this |
---|
| 163 | * level IRQs and FIQs would be equal. It is true that FIQs could interrupt |
---|
| 164 | * the non critical sections of IRQs, so here they would have a small |
---|
| 165 | * advantage. Without operating system support, the FIQs can execute at any |
---|
| 166 | * time (of course not during the service of another FIQ). If someone needs |
---|
| 167 | * operating system support for a FIQ, she can trigger a software interrupt and |
---|
| 168 | * service the request in a two-step process. |
---|
[08330bf] | 169 | */ |
---|
[632e4306] | 170 | #define CPU_MODES_INTERRUPT_MASK 0x80 |
---|
[08330bf] | 171 | |
---|
| 172 | #define CPU_CONTEXT_FP_SIZE sizeof( Context_Control_fp ) |
---|
| 173 | |
---|
| 174 | #define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0 |
---|
| 175 | |
---|
[632e4306] | 176 | #define CPU_INTERRUPT_NUMBER_OF_VECTORS 8 |
---|
[08330bf] | 177 | |
---|
[632e4306] | 178 | #define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1) |
---|
[4db30283] | 179 | |
---|
| 180 | #define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE |
---|
| 181 | |
---|
[632e4306] | 182 | #define CPU_STACK_MINIMUM_SIZE (1024 * 4) |
---|
[08330bf] | 183 | |
---|
[71c8457] | 184 | /* AAPCS, section 4.1, Fundamental Data Types */ |
---|
| 185 | #define CPU_ALIGNMENT 8 |
---|
[08330bf] | 186 | |
---|
[632e4306] | 187 | #define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT |
---|
[08330bf] | 188 | |
---|
[86820eda] | 189 | /* AAPCS, section 4.3.1, Aggregates */ |
---|
| 190 | #define CPU_PARTITION_ALIGNMENT 4 |
---|
[08330bf] | 191 | |
---|
[71c8457] | 192 | /* AAPCS, section 5.2.1.2, Stack constraints at a public interface */ |
---|
| 193 | #define CPU_STACK_ALIGNMENT 8 |
---|
[08330bf] | 194 | |
---|
| 195 | /* |
---|
[632e4306] | 196 | * Bitfield handler macros. |
---|
[08330bf] | 197 | * |
---|
[632e4306] | 198 | * If we had a particularly fast function for finding the first |
---|
| 199 | * bit set in a word, it would go here. Since we don't (*), we'll |
---|
| 200 | * just use the universal macros. |
---|
[08330bf] | 201 | * |
---|
[632e4306] | 202 | * (*) On ARM V5 and later, there's a CLZ function which could be |
---|
| 203 | * used to implement much quicker than the default macro. |
---|
[08330bf] | 204 | */ |
---|
| 205 | |
---|
[632e4306] | 206 | #define CPU_USE_GENERIC_BITFIELD_CODE TRUE |
---|
[08330bf] | 207 | |
---|
[632e4306] | 208 | #define CPU_USE_GENERIC_BITFIELD_DATA TRUE |
---|
[08330bf] | 209 | |
---|
[78623bce] | 210 | /** @} */ |
---|
| 211 | |
---|
[632e4306] | 212 | #ifndef ASM |
---|
[2d877aa] | 213 | |
---|
[632e4306] | 214 | #ifdef __cplusplus |
---|
| 215 | extern "C" { |
---|
| 216 | #endif |
---|
[2d877aa] | 217 | |
---|
[78623bce] | 218 | /** |
---|
| 219 | * @addtogroup ScoreCPU |
---|
| 220 | * |
---|
| 221 | * @{ |
---|
| 222 | */ |
---|
[661e5de4] | 223 | |
---|
[632e4306] | 224 | typedef struct { |
---|
[c5ed148] | 225 | #if defined(ARM_MULTILIB_ARCH_V4) |
---|
[632e4306] | 226 | uint32_t register_cpsr; |
---|
| 227 | uint32_t register_r4; |
---|
| 228 | uint32_t register_r5; |
---|
| 229 | uint32_t register_r6; |
---|
| 230 | uint32_t register_r7; |
---|
| 231 | uint32_t register_r8; |
---|
| 232 | uint32_t register_r9; |
---|
| 233 | uint32_t register_r10; |
---|
| 234 | uint32_t register_fp; |
---|
| 235 | uint32_t register_sp; |
---|
| 236 | uint32_t register_lr; |
---|
| 237 | uint32_t register_pc; |
---|
[c5ed148] | 238 | #elif defined(ARM_MULTILIB_ARCH_V7M) |
---|
| 239 | uint32_t register_r4; |
---|
| 240 | uint32_t register_r5; |
---|
| 241 | uint32_t register_r6; |
---|
| 242 | uint32_t register_r7; |
---|
| 243 | uint32_t register_r8; |
---|
| 244 | uint32_t register_r9; |
---|
| 245 | uint32_t register_r10; |
---|
| 246 | uint32_t register_r11; |
---|
| 247 | void *register_lr; |
---|
| 248 | void *register_sp; |
---|
| 249 | uint32_t isr_nest_level; |
---|
| 250 | #endif |
---|
[632e4306] | 251 | } Context_Control; |
---|
[661e5de4] | 252 | |
---|
[632e4306] | 253 | typedef struct { |
---|
| 254 | /* Not supported */ |
---|
| 255 | } Context_Control_fp; |
---|
[661e5de4] | 256 | |
---|
[632e4306] | 257 | SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context; |
---|
[661e5de4] | 258 | |
---|
[78623bce] | 259 | extern uint32_t arm_cpu_mode; |
---|
| 260 | |
---|
[632e4306] | 261 | static inline uint32_t arm_interrupt_disable( void ) |
---|
| 262 | { |
---|
[c5ed148] | 263 | #if defined(ARM_MULTILIB_ARCH_V4) |
---|
[39c8fdb] | 264 | uint32_t arm_switch_reg; |
---|
[632e4306] | 265 | uint32_t level; |
---|
| 266 | |
---|
[9f9371f] | 267 | __asm__ volatile ( |
---|
[39c8fdb] | 268 | ARM_SWITCH_TO_ARM |
---|
| 269 | "mrs %[level], cpsr\n" |
---|
| 270 | "orr %[arm_switch_reg], %[level], #0x80\n" |
---|
| 271 | "msr cpsr, %[arm_switch_reg]\n" |
---|
| 272 | ARM_SWITCH_BACK |
---|
| 273 | : [arm_switch_reg] "=&r" (arm_switch_reg), [level] "=&r" (level) |
---|
[632e4306] | 274 | ); |
---|
| 275 | |
---|
| 276 | return level; |
---|
[c5ed148] | 277 | #elif defined(ARM_MULTILIB_ARCH_V7M) |
---|
| 278 | uint32_t level; |
---|
| 279 | uint32_t basepri = 0x80; |
---|
| 280 | |
---|
| 281 | __asm__ volatile ( |
---|
| 282 | "mrs %[level], basepri\n" |
---|
| 283 | "msr basepri_max, %[basepri]\n" |
---|
| 284 | : [level] "=&r" (level) |
---|
| 285 | : [basepri] "r" (basepri) |
---|
| 286 | ); |
---|
| 287 | |
---|
| 288 | return level; |
---|
| 289 | #endif |
---|
[632e4306] | 290 | } |
---|
[08330bf] | 291 | |
---|
[632e4306] | 292 | static inline void arm_interrupt_enable( uint32_t level ) |
---|
| 293 | { |
---|
[c5ed148] | 294 | #if defined(ARM_MULTILIB_ARCH_V4) |
---|
[39c8fdb] | 295 | ARM_SWITCH_REGISTERS; |
---|
| 296 | |
---|
[9f9371f] | 297 | __asm__ volatile ( |
---|
[39c8fdb] | 298 | ARM_SWITCH_TO_ARM |
---|
| 299 | "msr cpsr, %[level]\n" |
---|
| 300 | ARM_SWITCH_BACK |
---|
| 301 | : ARM_SWITCH_OUTPUT |
---|
| 302 | : [level] "r" (level) |
---|
| 303 | ); |
---|
[c5ed148] | 304 | #elif defined(ARM_MULTILIB_ARCH_V7M) |
---|
| 305 | __asm__ volatile ( |
---|
| 306 | "msr basepri, %[level]\n" |
---|
| 307 | : |
---|
| 308 | : [level] "r" (level) |
---|
| 309 | ); |
---|
| 310 | #endif |
---|
[632e4306] | 311 | } |
---|
[08330bf] | 312 | |
---|
[632e4306] | 313 | static inline void arm_interrupt_flash( uint32_t level ) |
---|
| 314 | { |
---|
[c5ed148] | 315 | #if defined(ARM_MULTILIB_ARCH_V4) |
---|
[39c8fdb] | 316 | uint32_t arm_switch_reg; |
---|
[632e4306] | 317 | |
---|
[9f9371f] | 318 | __asm__ volatile ( |
---|
[39c8fdb] | 319 | ARM_SWITCH_TO_ARM |
---|
| 320 | "mrs %[arm_switch_reg], cpsr\n" |
---|
| 321 | "msr cpsr, %[level]\n" |
---|
| 322 | "msr cpsr, %[arm_switch_reg]\n" |
---|
| 323 | ARM_SWITCH_BACK |
---|
| 324 | : [arm_switch_reg] "=&r" (arm_switch_reg) |
---|
| 325 | : [level] "r" (level) |
---|
[632e4306] | 326 | ); |
---|
[c5ed148] | 327 | #elif defined(ARM_MULTILIB_ARCH_V7M) |
---|
| 328 | uint32_t basepri; |
---|
| 329 | |
---|
| 330 | __asm__ volatile ( |
---|
| 331 | "mrs %[basepri], basepri\n" |
---|
| 332 | "msr basepri, %[level]\n" |
---|
| 333 | "msr basepri, %[basepri]\n" |
---|
| 334 | : [basepri] "=&r" (basepri) |
---|
| 335 | : [level] "r" (level) |
---|
| 336 | ); |
---|
| 337 | #endif |
---|
[632e4306] | 338 | } |
---|
[4f0b287] | 339 | |
---|
[632e4306] | 340 | #define _CPU_ISR_Disable( _isr_cookie ) \ |
---|
| 341 | do { \ |
---|
| 342 | _isr_cookie = arm_interrupt_disable(); \ |
---|
| 343 | } while (0) |
---|
[08330bf] | 344 | |
---|
[632e4306] | 345 | #define _CPU_ISR_Enable( _isr_cookie ) \ |
---|
| 346 | arm_interrupt_enable( _isr_cookie ) |
---|
[08330bf] | 347 | |
---|
[632e4306] | 348 | #define _CPU_ISR_Flash( _isr_cookie ) \ |
---|
| 349 | arm_interrupt_flash( _isr_cookie ) |
---|
[08330bf] | 350 | |
---|
[632e4306] | 351 | void _CPU_ISR_Set_level( uint32_t level ); |
---|
| 352 | |
---|
| 353 | uint32_t _CPU_ISR_Get_level( void ); |
---|
[08330bf] | 354 | |
---|
[4f0b287] | 355 | void _CPU_Context_Initialize( |
---|
[632e4306] | 356 | Context_Control *the_context, |
---|
[c5ed148] | 357 | void *stack_area_begin, |
---|
| 358 | size_t stack_area_size, |
---|
[632e4306] | 359 | uint32_t new_level, |
---|
[c5ed148] | 360 | void (*entry_point)( void ), |
---|
[632e4306] | 361 | bool is_fp |
---|
[4f0b287] | 362 | ); |
---|
[08330bf] | 363 | |
---|
[632e4306] | 364 | #define _CPU_Context_Get_SP( _context ) \ |
---|
| 365 | (_context)->register_sp |
---|
[08330bf] | 366 | |
---|
| 367 | #define _CPU_Context_Restart_self( _the_context ) \ |
---|
| 368 | _CPU_Context_restore( (_the_context) ); |
---|
| 369 | |
---|
| 370 | #define _CPU_Context_Fp_start( _base, _offset ) \ |
---|
| 371 | ( (void *) _Addresses_Add_offset( (_base), (_offset) ) ) |
---|
| 372 | |
---|
| 373 | #define _CPU_Context_Initialize_fp( _destination ) \ |
---|
[632e4306] | 374 | do { \ |
---|
| 375 | *(*(_destination)) = _CPU_Null_fp_context; \ |
---|
| 376 | } while (0) |
---|
[08330bf] | 377 | |
---|
[5e61c80] | 378 | #define _CPU_Fatal_halt( _err ) \ |
---|
[fa237002] | 379 | do { \ |
---|
[5e61c80] | 380 | uint32_t _level; \ |
---|
| 381 | uint32_t _error = _err; \ |
---|
[fa237002] | 382 | _CPU_ISR_Disable( _level ); \ |
---|
[9f9371f] | 383 | __asm__ volatile ("mov r0, %0\n" \ |
---|
[fa237002] | 384 | : "=r" (_error) \ |
---|
| 385 | : "0" (_error) \ |
---|
| 386 | : "r0" ); \ |
---|
[632e4306] | 387 | while (1); \ |
---|
| 388 | } while (0); |
---|
[08330bf] | 389 | |
---|
[632e4306] | 390 | void _CPU_Initialize( void ); |
---|
[08330bf] | 391 | |
---|
[632e4306] | 392 | #define _CPU_Initialize_vectors() |
---|
[08330bf] | 393 | |
---|
| 394 | void _CPU_ISR_install_vector( |
---|
[632e4306] | 395 | uint32_t vector, |
---|
| 396 | proc_ptr new_handler, |
---|
| 397 | proc_ptr *old_handler |
---|
[08330bf] | 398 | ); |
---|
| 399 | |
---|
[632e4306] | 400 | void _CPU_Context_switch( Context_Control *run, Context_Control *heir ); |
---|
[08330bf] | 401 | |
---|
[db0df7b] | 402 | void _CPU_Context_restore( Context_Control *new_context ) |
---|
[c5ed148] | 403 | RTEMS_COMPILER_NO_RETURN_ATTRIBUTE; |
---|
| 404 | |
---|
| 405 | #if defined(ARM_MULTILIB_ARCH_V7M) |
---|
| 406 | void _ARMV7M_Start_multitasking( Context_Control *bsp, Context_Control *heir ); |
---|
| 407 | void _ARMV7M_Stop_multitasking( Context_Control *bsp ) |
---|
| 408 | RTEMS_COMPILER_NO_RETURN_ATTRIBUTE; |
---|
| 409 | #define _CPU_Start_multitasking _ARMV7M_Start_multitasking |
---|
| 410 | #define _CPU_Stop_multitasking _ARMV7M_Stop_multitasking |
---|
| 411 | #endif |
---|
[08330bf] | 412 | |
---|
[632e4306] | 413 | void _CPU_Context_save_fp( Context_Control_fp **fp_context_ptr ); |
---|
[08330bf] | 414 | |
---|
[632e4306] | 415 | void _CPU_Context_restore_fp( Context_Control_fp **fp_context_ptr ); |
---|
[08330bf] | 416 | |
---|
[632e4306] | 417 | static inline uint32_t CPU_swap_u32( uint32_t value ) |
---|
[08330bf] | 418 | { |
---|
[c5ed148] | 419 | #if defined(__thumb2__) |
---|
| 420 | __asm__ volatile ( |
---|
| 421 | "rev %0, %0" |
---|
| 422 | : "=r" (value) |
---|
| 423 | : "0" (value) |
---|
| 424 | ); |
---|
| 425 | return value; |
---|
| 426 | #elif defined(__thumb__) |
---|
[1c62f169] | 427 | uint32_t byte1, byte2, byte3, byte4, swapped; |
---|
[632e4306] | 428 | |
---|
[1c62f169] | 429 | byte4 = (value >> 24) & 0xff; |
---|
| 430 | byte3 = (value >> 16) & 0xff; |
---|
| 431 | byte2 = (value >> 8) & 0xff; |
---|
[632e4306] | 432 | byte1 = value & 0xff; |
---|
| 433 | |
---|
[1c62f169] | 434 | swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4; |
---|
| 435 | return swapped; |
---|
| 436 | #else |
---|
[632e4306] | 437 | uint32_t tmp = value; /* make compiler warnings go away */ |
---|
[9f9371f] | 438 | __asm__ volatile ("EOR %1, %0, %0, ROR #16\n" |
---|
[632e4306] | 439 | "BIC %1, %1, #0xff0000\n" |
---|
| 440 | "MOV %0, %0, ROR #8\n" |
---|
| 441 | "EOR %0, %0, %1, LSR #8\n" |
---|
| 442 | : "=r" (value), "=r" (tmp) |
---|
[1c62f169] | 443 | : "0" (value), "1" (tmp)); |
---|
| 444 | return value; |
---|
| 445 | #endif |
---|
[08330bf] | 446 | } |
---|
| 447 | |
---|
[632e4306] | 448 | static inline uint16_t CPU_swap_u16( uint16_t value ) |
---|
[fa237002] | 449 | { |
---|
[c5ed148] | 450 | #if defined(__thumb2__) |
---|
| 451 | __asm__ volatile ( |
---|
| 452 | "rev16 %0, %0" |
---|
| 453 | : "=r" (value) |
---|
| 454 | : "0" (value) |
---|
| 455 | ); |
---|
| 456 | return value; |
---|
| 457 | #else |
---|
[632e4306] | 458 | return (uint16_t) (((value & 0xffU) << 8) | ((value >> 8) & 0xffU)); |
---|
[c5ed148] | 459 | #endif |
---|
[632e4306] | 460 | } |
---|
[b32fe793] | 461 | |
---|
[78623bce] | 462 | /** @} */ |
---|
[b32fe793] | 463 | |
---|
[c5ed148] | 464 | #if defined(ARM_MULTILIB_ARCH_V4) |
---|
| 465 | |
---|
[78623bce] | 466 | /** |
---|
| 467 | * @addtogroup ScoreCPUARM |
---|
| 468 | * |
---|
| 469 | * @{ |
---|
| 470 | */ |
---|
[632e4306] | 471 | |
---|
[39c8fdb] | 472 | typedef struct { |
---|
| 473 | uint32_t r0; |
---|
| 474 | uint32_t r1; |
---|
| 475 | uint32_t r2; |
---|
| 476 | uint32_t r3; |
---|
| 477 | uint32_t r4; |
---|
| 478 | uint32_t r5; |
---|
| 479 | uint32_t r6; |
---|
| 480 | uint32_t r7; |
---|
| 481 | uint32_t r8; |
---|
| 482 | uint32_t r9; |
---|
| 483 | uint32_t r10; |
---|
| 484 | uint32_t r11; |
---|
| 485 | uint32_t r12; |
---|
| 486 | uint32_t sp; |
---|
| 487 | uint32_t lr; |
---|
| 488 | uint32_t pc; |
---|
| 489 | uint32_t cpsr; |
---|
| 490 | } arm_cpu_context; |
---|
| 491 | |
---|
| 492 | typedef void arm_exc_abort_handler( arm_cpu_context *context ); |
---|
| 493 | |
---|
[78623bce] | 494 | typedef enum { |
---|
| 495 | ARM_EXCEPTION_RESET = 0, |
---|
| 496 | ARM_EXCEPTION_UNDEF = 1, |
---|
| 497 | ARM_EXCEPTION_SWI = 2, |
---|
| 498 | ARM_EXCEPTION_PREF_ABORT = 3, |
---|
| 499 | ARM_EXCEPTION_DATA_ABORT = 4, |
---|
| 500 | ARM_EXCEPTION_RESERVED = 5, |
---|
| 501 | ARM_EXCEPTION_IRQ = 6, |
---|
| 502 | ARM_EXCEPTION_FIQ = 7, |
---|
| 503 | MAX_EXCEPTIONS = 8 |
---|
| 504 | } Arm_symbolic_exception_name; |
---|
| 505 | |
---|
| 506 | static inline uint32_t arm_status_irq_enable( void ) |
---|
| 507 | { |
---|
| 508 | uint32_t arm_switch_reg; |
---|
| 509 | uint32_t psr; |
---|
| 510 | |
---|
| 511 | RTEMS_COMPILER_MEMORY_BARRIER(); |
---|
| 512 | |
---|
[9f9371f] | 513 | __asm__ volatile ( |
---|
[78623bce] | 514 | ARM_SWITCH_TO_ARM |
---|
| 515 | "mrs %[psr], cpsr\n" |
---|
| 516 | "bic %[arm_switch_reg], %[psr], #0x80\n" |
---|
| 517 | "msr cpsr, %[arm_switch_reg]\n" |
---|
| 518 | ARM_SWITCH_BACK |
---|
| 519 | : [arm_switch_reg] "=&r" (arm_switch_reg), [psr] "=&r" (psr) |
---|
| 520 | ); |
---|
| 521 | |
---|
| 522 | return psr; |
---|
| 523 | } |
---|
| 524 | |
---|
| 525 | static inline void arm_status_restore( uint32_t psr ) |
---|
| 526 | { |
---|
| 527 | ARM_SWITCH_REGISTERS; |
---|
| 528 | |
---|
[9f9371f] | 529 | __asm__ volatile ( |
---|
[78623bce] | 530 | ARM_SWITCH_TO_ARM |
---|
| 531 | "msr cpsr, %[psr]\n" |
---|
| 532 | ARM_SWITCH_BACK |
---|
| 533 | : ARM_SWITCH_OUTPUT |
---|
| 534 | : [psr] "r" (psr) |
---|
| 535 | ); |
---|
| 536 | |
---|
| 537 | RTEMS_COMPILER_MEMORY_BARRIER(); |
---|
| 538 | } |
---|
| 539 | |
---|
[39c8fdb] | 540 | void arm_exc_data_abort_set_handler( arm_exc_abort_handler handler ); |
---|
| 541 | |
---|
| 542 | void arm_exc_data_abort( void ); |
---|
| 543 | |
---|
| 544 | void arm_exc_prefetch_abort_set_handler( arm_exc_abort_handler handler ); |
---|
| 545 | |
---|
| 546 | void arm_exc_prefetch_abort( void ); |
---|
[632e4306] | 547 | |
---|
[39c8fdb] | 548 | void bsp_interrupt_dispatch( void ); |
---|
[632e4306] | 549 | |
---|
| 550 | void arm_exc_interrupt( void ); |
---|
| 551 | |
---|
| 552 | void arm_exc_undefined( void ); |
---|
| 553 | |
---|
[78623bce] | 554 | /** @} */ |
---|
| 555 | |
---|
| 556 | /* XXX This is out of date */ |
---|
| 557 | typedef struct { |
---|
| 558 | uint32_t register_r0; |
---|
| 559 | uint32_t register_r1; |
---|
| 560 | uint32_t register_r2; |
---|
| 561 | uint32_t register_r3; |
---|
| 562 | uint32_t register_ip; |
---|
| 563 | uint32_t register_lr; |
---|
| 564 | } CPU_Exception_frame; |
---|
| 565 | |
---|
| 566 | typedef CPU_Exception_frame CPU_Interrupt_frame; |
---|
| 567 | |
---|
[c5ed148] | 568 | #elif defined(ARM_MULTILIB_ARCH_V7M) |
---|
| 569 | |
---|
| 570 | typedef void CPU_Interrupt_frame; |
---|
| 571 | |
---|
| 572 | #endif /* defined(ARM_MULTILIB_ARCH_V7M) */ |
---|
| 573 | |
---|
[08330bf] | 574 | #ifdef __cplusplus |
---|
| 575 | } |
---|
| 576 | #endif |
---|
| 577 | |
---|
[632e4306] | 578 | #endif /* ASM */ |
---|
| 579 | |
---|
| 580 | #endif /* _RTEMS_SCORE_CPU_H */ |
---|