diff --git a/arch/arm/include/armv7-a/irq.h b/arch/arm/include/armv7-a/irq.h index 81eea542ab..761d46e8d9 100755 --- a/arch/arm/include/armv7-a/irq.h +++ b/arch/arm/include/armv7-a/irq.h @@ -175,21 +175,40 @@ struct xcptcontext #ifndef __ASSEMBLY__ -/* Save the current interrupt enable state & disable IRQs */ +/* Disable IRQs and return the previous IRQ state */ static inline irqstate_t irqsave(void) { - unsigned int flags; - unsigned int temp; + unsigned int cpsr; + __asm__ __volatile__ ( - "\tmrs %0, cpsr\n" - "\torr %1, %0, #128\n" - "\tmsr cpsr_c, %1" - : "=r" (flags), "=r" (temp) - : - : "memory"); - return flags; + "\tmrs %0, cpsr\n" + "\tcpsid i\n" + : "=r" (cpsr) + : + : "memory" + ); + + return cpsr; +} + +/* Enable IRQs and return the previous IRQ state */ + +static inline irqstate_t irqenable(void) +{ + unsigned int cpsr; + + __asm__ __volatile__ + ( + "\tmrs %0, cpsr\n" + "\tcpsie i\n" + : "=r" (cpsr) + : + : "memory" + ); + + return cpsr; } /* Restore saved IRQ & FIQ state */ @@ -198,11 +217,13 @@ static inline void irqrestore(irqstate_t flags) { __asm__ __volatile__ ( - "msr cpsr_c, %0" - : - : "r" (flags) - : "memory"); + "msr cpsr_c, %0" + : + : "r" (flags) + : "memory" + ); } + #endif /* __ASSEMBLY__ */ /**************************************************************************** diff --git a/arch/arm/src/armv7-a/fpu.h b/arch/arm/src/armv7-a/fpu.h index 1a22371d12..9ec290c2cd 100644 --- a/arch/arm/src/armv7-a/fpu.h +++ b/arch/arm/src/armv7-a/fpu.h @@ -34,13 +34,15 @@ * ****************************************************************************/ -#ifndef __ARCH_ARM_SRC_ARMV7_A_CPSR_H -#define __ARCH_ARM_SRC_ARMV7_A_CPSR_H +#ifndef __ARCH_ARM_SRC_ARMV7_A_FPU_H +#define __ARCH_ARM_SRC_ARMV7_A_FPU_H /**************************************************************************** * Included Files ****************************************************************************/ +#include + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -87,4 +89,4 @@ void arm_fpuconfig(void); #endif #endif /* __ASSEMBLY__ */ -#endif /* __ARCH_ARM_SRC_ARMV7_A_CPSR_H */ +#endif /* __ARCH_ARM_SRC_ARMV7_A_FPU_H */ diff --git a/arch/arm/src/sama5/Make.defs b/arch/arm/src/sama5/Make.defs index 31b70c29ff..64b8076c99 100644 --- a/arch/arm/src/sama5/Make.defs +++ b/arch/arm/src/sama5/Make.defs @@ -61,4 +61,4 @@ endif CHIP_ASRCS = -CHIP_CSRCS = sam_boot.c sam_timerisr.c +CHIP_CSRCS = sam_boot.c sam_irq.c sam_timerisr.c diff --git a/arch/arm/src/sama5/sam_irq.c b/arch/arm/src/sama5/sam_irq.c new file mode 100644 index 0000000000..2c8cb1f3a1 --- /dev/null +++ b/arch/arm/src/sama5/sam_irq.c @@ -0,0 +1,224 @@ +/**************************************************************************** + * arch/arm/src/sama5/sam_irq.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "os_internal.h" +#include "up_internal.h" + +#ifdef CONFIG_GPIO_IRQ +# include "sam_gpio.h" +#endif + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/* Enable NVIC debug features that are probably only desireable during + * bringup + */ + +#undef SAM_IRQ_DEBUG + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint32_t *current_regs; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_dumpaic + * + * Description: + * Dump some interesting AIC registers + * + ****************************************************************************/ + +#if defined(SAM_IRQ_DEBUG) && defined (CONFIG_DEBUG) +static void sam_dumpaic(const char *msg, int irq) +{ + irqstate_t flags; + + flags = irqsave(); +#warning Missing logic + slldbg("AIC (%s, irq=%d):\n", msg, irq); +#warning Missing logic + irqrestore(flags); +} +#else +# define sam_dumpaic(msg, irq) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* Disable all interrupts */ +#warning Missing logic + + /* Set all interrupts to the default priority */ +#warning Missing logic + + /* currents_regs is non-NULL only while processing an interrupt */ + + current_regs = NULL; + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + /* Initialize logic to support a second level of interrupt decoding for + * GPIO pins. + */ + +#ifdef CONFIG_GPIO_IRQ + sam_gpioirqinitialize(); +#endif + + /* And finally, enable interrupts */ + + (void)irqenable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + if (irq < SAM_IRQ_NINT) + { +#warning Missing logic + } +#ifdef CONFIG_GPIO_IRQ + else + { + /* Maybe it is a (derived) GPIO IRQ */ + + sam_gpioirqdisable(irq); + } +#endif + sam_dumpaic("disable", irq); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + if (irq < SAM_IRQ_NINT) + { +#warning Missing logic + } +#ifdef CONFIG_GPIO_IRQ + else + { + /* Maybe it is a (derived) GPIO IRQ */ + + sam_gpioirqenable(irq); + } +#endif + sam_dumpaic("enable", irq); +} + +/**************************************************************************** + * Name: up_maskack_irq + * + * Description: + * Mask the IRQ and acknowledge it + * + ****************************************************************************/ + +void up_maskack_irq(int irq) +{ + up_disable_irq(irq); +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ + if (irq < SAM_IRQ_NINT) + { +#warning Missing logic + } + + sam_dumpaic("prioritize", irq); + return OK; +} +#endif diff --git a/arch/arm/src/sama5/sam_timerisr.c b/arch/arm/src/sama5/sam_timerisr.c index 99b4d5df32..6ba87074c5 100644 --- a/arch/arm/src/sama5/sam_timerisr.c +++ b/arch/arm/src/sama5/sam_timerisr.c @@ -145,6 +145,7 @@ void up_timerinit(void) */ regval = PIT_PIV | PIT_MR_PITEN | PIT_MR_PITIEN; + putreg32(regval, SAM_PIT_MR); /* And enable the timer interrupt */