summaryrefslogtreecommitdiff
path: root/core/cortex-m0/irq_handler.h
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2014-03-01 10:20:47 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-03-11 05:52:41 +0000
commit0f73a129b42acfcad843203b602fbbcc8894c614 (patch)
tree9531fae7a8d9c3290973fe5b5ee47e57cd485546 /core/cortex-m0/irq_handler.h
parent7aab81edce830e15134b52256ad3186e08951b10 (diff)
downloadchrome-ec-0f73a129b42acfcad843203b602fbbcc8894c614.tar.gz
Add Cortex-M0 core support
The Cortex-M0 core is based on ARMv6-M instruction set rather than ARMv7-M as Cortex-M3 and M4. Signed-off-by: Vincent Palatin <vpalatin@chromium.org> BRANCH=none BUG=none TEST=run console on STM32F072, and pass all available unit-tests on target. Change-Id: I9bdf6637132ba4a3e739d388580a72b4c84e930e Reviewed-on: https://chromium-review.googlesource.com/188982 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Commit-Queue: Vincent Palatin <vpalatin@chromium.org> Tested-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'core/cortex-m0/irq_handler.h')
-rw-r--r--core/cortex-m0/irq_handler.h65
1 files changed, 65 insertions, 0 deletions
diff --git a/core/cortex-m0/irq_handler.h b/core/cortex-m0/irq_handler.h
new file mode 100644
index 0000000000..4383f3c7ca
--- /dev/null
+++ b/core/cortex-m0/irq_handler.h
@@ -0,0 +1,65 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Helper to declare IRQ handling routines */
+
+#ifndef __IRQ_HANDLER_H
+#define __IRQ_HANDLER_H
+
+#ifdef CONFIG_TASK_PROFILING
+#define bl_task_start_irq_handler "bl task_start_irq_handler\n"
+#else
+#define bl_task_start_irq_handler ""
+#endif
+
+/* Helper macros to build the IRQ handler and priority struct names */
+#define IRQ_HANDLER(irqname) CONCAT3(irq_, irqname, _handler)
+#define IRQ_PRIORITY(irqname) CONCAT2(prio_, irqname)
+
+/* re-scheduling flag */
+extern int need_resched_or_profiling;
+
+/*
+ * Macro to connect the interrupt handler "routine" to the irq number "irq" and
+ * ensure it is enabled in the interrupt controller with the right priority.
+ */
+#define DECLARE_IRQ(irq, routine, priority) \
+ void IRQ_HANDLER(irq)(void) __attribute__((naked)); \
+ void IRQ_HANDLER(irq)(void) \
+ { \
+ asm volatile("mov r0, lr\n" \
+ /* Must push registers in pairs to keep 64-bit aligned*/\
+ /* stack for ARM EABI. */ \
+ "push {r0, %0}\n" \
+ bl_task_start_irq_handler \
+ "bl "#routine"\n" \
+ "pop {r2, r3}\n" \
+ /* read need_resched_or_profiling result after IRQ */ \
+ "ldr r0, [r3]\n" \
+ "mov r1, #8\n" \
+ "cmp r0, #0\n" \
+ /* if we need to go through the re-scheduling, go on */ \
+ "bne 2f\n" \
+ /* else return from exception */ \
+ "1: bx r2\n" \
+ /* check if that's a nested exception */ \
+ "2: tst r1, r2\n" \
+ /* if yes return immediatly */ \
+ "beq 1b\n" \
+ "push {r0, r2}\n" \
+ "mov r0, #0\n" \
+ "mov r1, #0\n" \
+ /* ensure we have priority 0 during re-scheduling */ \
+ "cpsid i\n isb\n" \
+ /* re-schedule the highest priority task */ \
+ "bl svc_handler\n" \
+ /* return from exception */ \
+ "pop {r0,pc}\n" \
+ : : "r"(&need_resched_or_profiling)); \
+ } \
+ const struct irq_priority IRQ_PRIORITY(irq) \
+ __attribute__((section(".rodata.irqprio"))) \
+ = {irq, priority}
+#endif /* __IRQ_HANDLER_H */