diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2017-02-14 22:39:43 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2017-02-19 11:00:46 -0500 |
commit | 38e9484f9ffabd98962a00bb4403261f0c58b1ab (patch) | |
tree | 4fa8cc453403d86b077d3d333d60a9325b349c94 /src/generic/armcm_irq.c | |
parent | fec12030a9c63490ef357e71e2430133a64bbe34 (diff) | |
download | kutter-38e9484f9ffabd98962a00bb4403261f0c58b1ab.tar.gz kutter-38e9484f9ffabd98962a00bb4403261f0c58b1ab.tar.xz kutter-38e9484f9ffabd98962a00bb4403261f0c58b1ab.zip |
armcm_irq: Move ARM Cortex-M irq handling to new file
The irq handling in sam3x8e isn't specific to the sam3x8e proccessor -
it's generic for all armcm type machines. So, move the definitions
into a new file generic/armcm-irq.c
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src/generic/armcm_irq.c')
-rw-r--r-- | src/generic/armcm_irq.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/generic/armcm_irq.c b/src/generic/armcm_irq.c new file mode 100644 index 00000000..64acdd89 --- /dev/null +++ b/src/generic/armcm_irq.c @@ -0,0 +1,58 @@ +// Definitions for irq enable/disable on ARM Cortex-M processors +// +// Copyright (C) 2017 Kevin O'Connor <kevin@koconnor.net> +// +// This file may be distributed under the terms of the GNU GPLv3 license. + +#include "irq.h" // irqstatus_t +#include "sched.h" // DECL_SHUTDOWN + +void +irq_disable(void) +{ + asm volatile("cpsid i" ::: "memory"); +} + +void +irq_enable(void) +{ + asm volatile("cpsie i" ::: "memory"); +} + +irqstatus_t +irq_save(void) +{ + irqstatus_t flag; + asm volatile("mrs %0, primask" : "=r" (flag) :: "memory"); + irq_disable(); + return flag; +} + +void +irq_restore(irqstatus_t flag) +{ + asm volatile("msr primask, %0" :: "r" (flag) : "memory"); +} + +// Clear the active irq if a shutdown happened in an irq handler +static void +clear_active_irq(void) +{ + uint32_t psr; + asm volatile("mrs %0, psr" : "=r" (psr)); + if (!(psr & 0x1ff)) + // Shutdown did not occur in an irq - nothing to do. + return; + // Clear active irq status + psr = 1<<24; // T-bit + uint32_t temp; + asm volatile( + " push { %1 }\n" + " adr %0, 1f\n" + " push { %0 }\n" + " push { r0, r1, r2, r3, r12, lr }\n" + " bx %2\n" + "1:\n" + : "=&r"(temp) : "r"(psr), "r"(0xfffffff9) : "cc"); +} +DECL_SHUTDOWN(clear_active_irq); |