From 38e9484f9ffabd98962a00bb4403261f0c58b1ab Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Tue, 14 Feb 2017 22:39:43 -0500 Subject: 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 --- src/generic/armcm_irq.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/generic/armcm_irq.c (limited to 'src/generic/armcm_irq.c') 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 +// +// 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); -- cgit v1.2.3-70-g09d2