diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2014-03-01 10:20:47 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-03-11 05:52:41 +0000 |
commit | 0f73a129b42acfcad843203b602fbbcc8894c614 (patch) | |
tree | 9531fae7a8d9c3290973fe5b5ee47e57cd485546 /core/cortex-m0/irq_handler.h | |
parent | 7aab81edce830e15134b52256ad3186e08951b10 (diff) | |
download | chrome-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.h | 65 |
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 */ |