summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRicardo Salveti <ricardo.salveti@linaro.org>2016-10-05 19:43:36 -0300
committerAnas Nashif <nashif@linux.intel.com>2016-10-22 01:25:53 +0000
commitffacae20d0d3c022be57d897cde590d3309960e2 (patch)
tree996f7aa20c805c2995467edcce6f6206da4c5fed /include
parent6249c567f5c79627cca3489a80e293aaec6d8f36 (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.h48
-rw-r--r--include/arch/arm/cortex_m/gdb_stub.h6
-rw-r--r--include/arch/arm/cortex_m/memory_map.h2
-rw-r--r--include/arch/arm/cortex_m/nvic.h2
-rw-r--r--include/arch/arm/cortex_m/scb.h5
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