diff options
Diffstat (limited to 'cpukit/score/cpu/arm/rtems/score/cpu.h')
-rw-r--r-- | cpukit/score/cpu/arm/rtems/score/cpu.h | 169 |
1 files changed, 105 insertions, 64 deletions
diff --git a/cpukit/score/cpu/arm/rtems/score/cpu.h b/cpukit/score/cpu/arm/rtems/score/cpu.h index d7eca1527c..de452e8cb4 100644 --- a/cpukit/score/cpu/arm/rtems/score/cpu.h +++ b/cpukit/score/cpu/arm/rtems/score/cpu.h @@ -8,6 +8,8 @@ * This include file contains information pertaining to the ARM * processor. * + * Copyright (c) 2009 embedded brains GmbH. + * * Copyright (c) 2007 Ray Xu <Rayx.cn@gmail.com> * * Copyright (c) 2006 OAR Corporation @@ -44,13 +46,42 @@ #endif #ifdef __thumb__ - #define ARM_TO_THUMB "add %0, pc, #1\nbx %0\n.thumb\n" - #define THUMB_TO_ARM ".align 2\nbx pc\n.arm\n" + #define ARM_SWITCH_REGISTERS uint32_t arm_switch_reg + #define ARM_SWITCH_TO_ARM ".align 2\nbx pc\n.arm\n" + #define ARM_SWITCH_BACK "add %[arm_switch_reg], pc, #1\nbx %[arm_switch_reg]\n.thumb\n" + #define ARM_SWITCH_OUTPUT [arm_switch_reg] "=&r" (arm_switch_reg) + #define ARM_SWITCH_ADDITIONAL_OUTPUT , ARM_SWITCH_OUTPUT #else - #define ARM_TO_THUMB - #define THUMB_TO_ARM + #define ARM_SWITCH_REGISTERS + #define ARM_SWITCH_TO_ARM + #define ARM_SWITCH_BACK + #define ARM_SWITCH_OUTPUT + #define ARM_SWITCH_ADDITIONAL_OUTPUT #endif +#define ARM_PSR_N (1 << 31) +#define ARM_PSR_Z (1 << 30) +#define ARM_PSR_C (1 << 29) +#define ARM_PSR_V (1 << 28) +#define ARM_PSR_Q (1 << 27) +#define ARM_PSR_J (1 << 24) +#define ARM_PSR_GE_SHIFT 16 +#define ARM_PSR_GE_MASK (0xf << ARM_PSR_GE_SHIFT) +#define ARM_PSR_E (1 << 9) +#define ARM_PSR_A (1 << 8) +#define ARM_PSR_I (1 << 7) +#define ARM_PSR_F (1 << 6) +#define ARM_PSR_T (1 << 5) +#define ARM_PSR_M_SHIFT 0 +#define ARM_PSR_M_MASK (0x1f << ARM_PSR_M_SHIFT) +#define ARM_PSR_M_USR 0x10 +#define ARM_PSR_M_FIQ 0x11 +#define ARM_PSR_M_IRQ 0x12 +#define ARM_PSR_M_SVC 0x13 +#define ARM_PSR_M_ABT 0x17 +#define ARM_PSR_M_UND 0x1b +#define ARM_PSR_M_SYS 0x1f + /* If someone uses THUMB we assume she wants minimal code size */ #ifdef __thumb__ #define CPU_INLINE_ENABLE_DISPATCH FALSE @@ -205,16 +236,16 @@ SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context; static inline uint32_t arm_interrupt_disable( void ) { - uint32_t reg; + uint32_t arm_switch_reg; uint32_t level; asm volatile ( - THUMB_TO_ARM - "mrs %1, cpsr\n" - "orr %0, %1, #0x80\n" - "msr cpsr, %0\n" - ARM_TO_THUMB - : "=r" (reg), "=r" (level) + ARM_SWITCH_TO_ARM + "mrs %[level], cpsr\n" + "orr %[arm_switch_reg], %[level], #0x80\n" + "msr cpsr, %[arm_switch_reg]\n" + ARM_SWITCH_BACK + : [arm_switch_reg] "=&r" (arm_switch_reg), [level] "=&r" (level) ); return level; @@ -222,54 +253,46 @@ static inline uint32_t arm_interrupt_disable( void ) static inline void arm_interrupt_enable( uint32_t level ) { - #ifdef __thumb__ - uint32_t reg; - - asm volatile ( - THUMB_TO_ARM - "msr cpsr, %1\n" - ARM_TO_THUMB - : "=r" (reg) - : "r" (level) - ); - #else - asm volatile ( - "msr cpsr, %0" - : - : "r" (level) - ); - #endif + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "msr cpsr, %[level]\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [level] "r" (level) + ); } static inline void arm_interrupt_flash( uint32_t level ) { - uint32_t reg; + uint32_t arm_switch_reg; asm volatile ( - THUMB_TO_ARM - "mrs %0, cpsr\n" - "msr cpsr, %1\n" - "msr cpsr, %0\n" - ARM_TO_THUMB - : "=r" (reg) - : "r" (level) + ARM_SWITCH_TO_ARM + "mrs %[arm_switch_reg], cpsr\n" + "msr cpsr, %[level]\n" + "msr cpsr, %[arm_switch_reg]\n" + ARM_SWITCH_BACK + : [arm_switch_reg] "=&r" (arm_switch_reg) + : [level] "r" (level) ); } static inline uint32_t arm_status_irq_enable( void ) { - uint32_t reg; + uint32_t arm_switch_reg; uint32_t psr; RTEMS_COMPILER_MEMORY_BARRIER(); asm volatile ( - THUMB_TO_ARM - "mrs %1, cpsr\n" - "bic %0, %1, #0x80\n" - "msr cpsr, %0\n" - ARM_TO_THUMB - : "=r" (reg), "=r" (psr) + ARM_SWITCH_TO_ARM + "mrs %[psr], cpsr\n" + "bic %[arm_switch_reg], %[psr], #0x80\n" + "msr cpsr, %[arm_switch_reg]\n" + ARM_SWITCH_BACK + : [arm_switch_reg] "=&r" (arm_switch_reg), [psr] "=&r" (psr) ); return psr; @@ -277,23 +300,15 @@ static inline uint32_t arm_status_irq_enable( void ) static inline void arm_status_restore( uint32_t psr ) { - #ifdef __thumb__ - uint32_t reg; - - asm volatile ( - THUMB_TO_ARM - "msr cpsr, %1\n" - ARM_TO_THUMB - : "=r" (reg) - : "r" (psr) - ); - #else - asm volatile ( - "msr cpsr, %0" - : - : "r" (psr) - ); - #endif + ARM_SWITCH_REGISTERS; + + asm volatile ( + ARM_SWITCH_TO_ARM + "msr cpsr, %[psr]\n" + ARM_SWITCH_BACK + : ARM_SWITCH_OUTPUT + : [psr] "r" (psr) + ); RTEMS_COMPILER_MEMORY_BARRIER(); } @@ -402,16 +417,42 @@ static inline uint16_t CPU_swap_u16( uint16_t value ) extern uint32_t arm_cpu_mode; -void arm_exc_abort_data( void ); +typedef struct { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; + uint32_t r12; + uint32_t sp; + uint32_t lr; + uint32_t pc; + uint32_t cpsr; +} arm_cpu_context; + +typedef void arm_exc_abort_handler( arm_cpu_context *context ); + +void arm_exc_data_abort_set_handler( arm_exc_abort_handler handler ); + +void arm_exc_data_abort( void ); + +void arm_exc_prefetch_abort_set_handler( arm_exc_abort_handler handler ); + +void arm_exc_prefetch_abort( void ); -void arm_exc_abort_prefetch( void ); +void bsp_interrupt_dispatch( void ); void arm_exc_interrupt( void ); void arm_exc_undefined( void ); -void bsp_interrupt_dispatch( void ); - #ifdef __cplusplus } #endif |