diff options
author | Ricardo Salveti <ricardo.salveti@linaro.org> | 2016-10-05 19:43:36 -0300 |
---|---|---|
committer | Anas Nashif <nashif@linux.intel.com> | 2016-10-22 01:25:53 +0000 |
commit | ffacae20d0d3c022be57d897cde590d3309960e2 (patch) | |
tree | 996f7aa20c805c2995467edcce6f6206da4c5fed /include | |
parent | 6249c567f5c79627cca3489a80e293aaec6d8f36 (diff) |
arch/arm: add initial support for Cortex-M0/M0+
Not disabling SysTick as it is optional by the spec.
SVC not used as there is no priority-based interrupt masking (only
PendSV is used).
Largely based on a previous work done by Euan Mutch <euan@abelon.com>.
Jira: ZEP-783
Change-Id: I38e29bfcf0624c1aea5f9fd7a74230faa1b59e8b
Signed-off-by: Ricardo Salveti <ricardo.salveti@linaro.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/arch/arm/cortex_m/asm_inline_gcc.h | 48 | ||||
-rw-r--r-- | include/arch/arm/cortex_m/gdb_stub.h | 6 | ||||
-rw-r--r-- | include/arch/arm/cortex_m/memory_map.h | 2 | ||||
-rw-r--r-- | include/arch/arm/cortex_m/nvic.h | 2 | ||||
-rw-r--r-- | include/arch/arm/cortex_m/scb.h | 5 |
5 files changed, 38 insertions, 25 deletions
diff --git a/include/arch/arm/cortex_m/asm_inline_gcc.h b/include/arch/arm/cortex_m/asm_inline_gcc.h index 85a4a1c91..ccce5f08e 100644 --- a/include/arch/arm/cortex_m/asm_inline_gcc.h +++ b/include/arch/arm/cortex_m/asm_inline_gcc.h @@ -57,17 +57,11 @@ extern "C" { static ALWAYS_INLINE unsigned int find_msb_set(uint32_t op) { - unsigned int bit; + if (!op) { + return 0; + } - __asm__ volatile( - "cmp %1, #0;\n\t" - "itt ne;\n\t" - " clzne %1, %1;\n\t" - " rsbne %0, %1, #32;\n\t" - : "=r"(bit) - : "r"(op)); - - return bit; + return 32 - __builtin_clz(op); } @@ -85,18 +79,7 @@ static ALWAYS_INLINE unsigned int find_msb_set(uint32_t op) static ALWAYS_INLINE unsigned int find_lsb_set(uint32_t op) { - unsigned int bit; - - __asm__ volatile( - "rsb %0, %1, #0;\n\t" - "ands %0, %0, %1;\n\t" /* r0 = x & (-x): only LSB set */ - "itt ne;\n\t" - " clzne %0, %0;\n\t" /* count leading zeroes */ - " rsbne %0, %0, #32;\n\t" - : "=&r"(bit) - : "r"(op)); - - return bit; + return __builtin_ffs(op); } @@ -135,12 +118,21 @@ static ALWAYS_INLINE unsigned int find_lsb_set(uint32_t op) * * On Cortex-M3/M4, this function prevents exceptions of priority lower than * the two highest priorities from interrupting the CPU. + * + * On Cortex-M0/M0+, this function reads the value of PRIMASK which shows + * if interrupts are enabled, then disables all interrupts except NMI. + * */ static ALWAYS_INLINE unsigned int _arch_irq_lock(void) { unsigned int key; +#if defined(CONFIG_CPU_CORTEX_M0_M0PLUS) + __asm__ volatile("mrs %0, PRIMASK;\n\t" + "cpsid i;\n\t" + : "=r" (key)); +#else /* CONFIG_CPU_CORTEX_M3_M4 */ __asm__ volatile( "movs.n %%r1, %1;\n\t" "mrs %0, BASEPRI;\n\t" @@ -148,6 +140,7 @@ static ALWAYS_INLINE unsigned int _arch_irq_lock(void) : "=r"(key) : "i"(_EXC_IRQ_DEFAULT_PRIO) : "r1"); +#endif return key; } @@ -166,11 +159,22 @@ static ALWAYS_INLINE unsigned int _arch_irq_lock(void) * @param key architecture-dependent lock-out key * * @return N/A + * + * On Cortex-M0/M0+, this enables all interrupts if they were not + * previously disabled. + * */ static ALWAYS_INLINE void _arch_irq_unlock(unsigned int key) { +#if defined(CONFIG_CPU_CORTEX_M0_M0PLUS) + if (key) { + return; + } + __asm__ volatile("cpsie i;\n\t"); +#else /* CONFIG_CPU_CORTEX_M3_M4 */ __asm__ volatile("msr BASEPRI, %0;\n\t" : : "r"(key)); +#endif } diff --git a/include/arch/arm/cortex_m/gdb_stub.h b/include/arch/arm/cortex_m/gdb_stub.h index 37c30ae6d..744a990be 100644 --- a/include/arch/arm/cortex_m/gdb_stub.h +++ b/include/arch/arm/cortex_m/gdb_stub.h @@ -40,7 +40,8 @@ _GDB_STUB_EXC_ENTRY : .macro bl irq_lock bl _GdbStubExcEntry bl irq_unlock - pop {lr} + pop {r1} + move lr, r1 .endm GTEXT(_GdbStubExcExit) @@ -49,7 +50,8 @@ _GDB_STUB_EXC_EXIT : .macro bl irq_lock bl _GdbStubExcExit bl irq_unlock - pop {lr} + pop {r1} + move lr, r1 .endm GTEXT(_irq_vector_table_entry_with_gdb_stub) diff --git a/include/arch/arm/cortex_m/memory_map.h b/include/arch/arm/cortex_m/memory_map.h index 6f1f3da0d..eb0edadf4 100644 --- a/include/arch/arm/cortex_m/memory_map.h +++ b/include/arch/arm/cortex_m/memory_map.h @@ -57,7 +57,7 @@ /* 0xe0000000 -> 0xffffffff: varies by processor (see below) */ -#if defined(CONFIG_CPU_CORTEX_M3_M4) +#if defined(CONFIG_CPU_CORTEX_M0_M0PLUS) || defined(CONFIG_CPU_CORTEX_M3_M4) /* 0xe0000000 -> 0xe00fffff: private peripheral bus */ /* 0xe0000000 -> 0xe003ffff: internal [256KB] */ diff --git a/include/arch/arm/cortex_m/nvic.h b/include/arch/arm/cortex_m/nvic.h index 0ed2fbafb..64e63d739 100644 --- a/include/arch/arm/cortex_m/nvic.h +++ b/include/arch/arm/cortex_m/nvic.h @@ -204,6 +204,7 @@ static inline uint32_t _NvicIrqPrioGet(unsigned int irq) return __scs.nvic.ipr[irq]; } +#if !defined(CONFIG_CPU_CORTEX_M0_M0PLUS) /** * * @brief Trigger an interrupt via software @@ -224,6 +225,7 @@ static inline void _NvicSwInterruptTrigger(unsigned int irq) __scs.stir = irq; #endif } +#endif /* !CONFIG_CPU_CORTEX_M0_M0PLUS */ #endif /* !_ASMLANGUAGE */ diff --git a/include/arch/arm/cortex_m/scb.h b/include/arch/arm/cortex_m/scb.h index 79f1f215c..6c5284cc7 100644 --- a/include/arch/arm/cortex_m/scb.h +++ b/include/arch/arm/cortex_m/scb.h @@ -597,6 +597,8 @@ static inline void _ScbExcPrioSet(uint8_t exc, uint8_t pri) __scs.scb.shpr[exc - 4] = pri; } +#if !defined(CONFIG_CPU_CORTEX_M0_M0PLUS) + /** * * @brief Enable usage fault exceptions @@ -1204,6 +1206,9 @@ static inline void _ScbUsageFaultAllFaultsReset(void) { __scs.scb.cfsr.byte.ufsr.val = 0xffff; } + +#endif /* !CONFIG_CPU_CORTEX_M0_M0PLUS */ + #endif /* _ASMLANGUAGE */ #ifdef __cplusplus |