diff --git a/arch/arm/src/common/up_internal.h b/arch/arm/src/common/up_internal.h index 1be47932475..489f13679de 100644 --- a/arch/arm/src/common/up_internal.h +++ b/arch/arm/src/common/up_internal.h @@ -135,11 +135,14 @@ # endif # define up_restorestate(regs) (current_regs = regs) -/* The Cortex-A5 supports the same mechanism, but only lazy floating point - * register save/restore. +/* The Cortex-A and Cortex-R supports the same mechanism, but only lazy + * floating point register save/restore. */ -#elif defined(CONFIG_ARCH_CORTEXA5) || defined(CONFIG_ARCH_CORTEXA8) +#elif defined(CONFIG_ARCH_CORTEXA5) || defined(CONFIG_ARCH_CORTEXA8) || \ + defined(CONFIG_ARCH_CORTEXR4) || defined(CONFIG_ARCH_CORTEXR4F) || \ + defined(CONFIG_ARCH_CORTEXR5) || defined(CONFIG_ARCH_CORTEXR5F) || \ + defined(CONFIG_ARCH_CORTEXR7) || defined(CONFIG_ARCH_CORTEXR7F) /* If the floating point unit is present and enabled, then save the * floating point registers as well as normal ARM registers. @@ -348,11 +351,14 @@ int up_memfault(int irq, FAR void *context); # endif /* CONFIG_ARCH_CORTEXM3,4,7 */ -/* Exception handling logic unique to the Cortex-A family (but should be - * back-ported to the ARM7 and ARM9 families). +/* Exception handling logic unique to the Cortex-A and Cortex-R families +* (but should be back-ported to the ARM7 and ARM9 families). */ -#elif defined(CONFIG_ARCH_CORTEXA5) || defined(CONFIG_ARCH_CORTEXA8) +#elif defined(CONFIG_ARCH_CORTEXA5) || defined(CONFIG_ARCH_CORTEXA8) || \ + defined(CONFIG_ARCH_CORTEXR4) || defined(CONFIG_ARCH_CORTEXR4F) || \ + defined(CONFIG_ARCH_CORTEXR5) || defined(CONFIG_ARCH_CORTEXR5F) || \ + defined(CONFIG_ARCH_CORTEXR7) || defined(CONFIG_ARCH_CORTEXR7F) /* Interrupt acknowledge and dispatch */ diff --git a/arch/arm/src/common/up_vfork.c b/arch/arm/src/common/up_vfork.c index 655619d8de2..bf738fa464f 100644 --- a/arch/arm/src/common/up_vfork.c +++ b/arch/arm/src/common/up_vfork.c @@ -248,6 +248,16 @@ pid_t up_vfork(const struct vfork_s *context) child->cmn.xcp.syscall[index].cpsr = parent->xcp.syscall[index].cpsr; +# endif + +#elif defined(CONFIG_ARCH_CORTEXR4) || defined(CONFIG_ARCH_CORTEXR4F) || \ + defined(CONFIG_ARCH_CORTEXR5) || defined(CONFIG_ARCH_CORTEXR5F) || \ + defined(CONFIG_ARCH_CORTEXR7) || defined(CONFIG_ARCH_CORTEXR7F) +# ifdef CONFIG_BUILD_PROTECTED + + child->cmn.xcp.syscall[index].cpsr = + parent->xcp.syscall[index].cpsr; + # endif #elif defined(CONFIG_ARCH_CORTEXM3) || defined(CONFIG_ARCH_CORTEXM4) || \ defined(CONFIG_ARCH_CORTEXM0) || defined(CONFIG_ARCH_CORTEXM7) diff --git a/arch/arm/src/tms570/chip/tms570_vim.h b/arch/arm/src/tms570/chip/tms570_vim.h index 9caf42cea03..9b30c33374c 100644 --- a/arch/arm/src/tms570/chip/tms570_vim.h +++ b/arch/arm/src/tms570/chip/tms570_vim.h @@ -159,9 +159,13 @@ #define VIM_FBPARERR_ /* IRQ Index Offset Vector Register */ -#define VIM_IRQINDEX_ + +#define VIM_IRQINDEX_MASK (0x000000ff) /* IRQ index vector */ + /* FIQ Index Offset Vector Register */ -#define VIM_FIQINDEX_ + +#define VIM_FIQINDEX_MASK (0x000000ff) /* FIQ index vector */ + /* FIQ/IRQ Program Control Register 0 */ #define VIM_FIRQPR0_ /* FIQ/IRQ Program Control Register 1 */ diff --git a/arch/arm/src/tms570/tms570_boot.h b/arch/arm/src/tms570/tms570_boot.h index a674095d11a..09ce644727b 100644 --- a/arch/arm/src/tms570/tms570_boot.h +++ b/arch/arm/src/tms570/tms570_boot.h @@ -1,5 +1,5 @@ /************************************************************************************ - * arch/arm/src/samv7/tms570_start.h + * arch/arm/src/tms570/tms570_boot.h * * Copyright (C) 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -33,8 +33,8 @@ * ************************************************************************************/ -#ifndef __ARCH_ARM_SRC_SAMV7_SAM_START_H -#define __ARCH_ARM_SRC_SAMV7_SAM_START_H +#ifndef __ARCH_ARM_SRC_TMS570_SAM_BOOT_H +#define __ARCH_ARM_SRC_TMS570_SAM_BOOT_H /************************************************************************************ * Included Files @@ -139,4 +139,4 @@ void tms570_board_initialize(void); #endif #endif /* __ASSEMBLY__ */ -#endif /* __ARCH_ARM_SRC_SAMV7_SAM_START_H */ +#endif /* __ARCH_ARM_SRC_TMS570_SAM_BOOT_H */ diff --git a/arch/arm/src/tms570/tms570_irq.c b/arch/arm/src/tms570/tms570_irq.c index 6db60a33a16..24af3895c6f 100644 --- a/arch/arm/src/tms570/tms570_irq.c +++ b/arch/arm/src/tms570/tms570_irq.c @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -51,6 +52,7 @@ #include "up_internal.h" #include "chip/tms570_vim.h" +#include "tms570_irq.h" /**************************************************************************** * Pre-processor Definitions @@ -66,29 +68,75 @@ volatile uint32_t *current_regs; +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_error_handler + ****************************************************************************/ + +static void tms570_error_handler(void) +{ + PANIC(); +} + /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: up_irqinitialize + + * The device supports three different possibilities for software to handle + * interrupts: + * + * 1. Index interrupts mode (compatible with TMS470R1x legacy code), + * 2. Register vectored interrupts (automatically provide vector address + * to application) + * 3. Hardware vectored interrupts (automatically dispatch to ISR, IRQ + * only) + * + * Only the indexed mode is supported here: After the interrupt is received + * by the CPU, the CPU branches to 0x18 (IRQ) or 0x1C (FIQ) to execute the + * main ISR. The main ISR routine reads the offset register (IRQINDEX, + * FIQINDEX) to determine the source of the interrupt. + * + * To use mode 2), it would only be necessary to initialize the VIM_RAM. + * To use mode 3), it would be necessary to initialize the VIM_RAM and also + * to set the vector enable (VE) bit in the CP15 R1 register. This bit is + * zero on reset so that the default state after reset is backward + * compatible to earlier ARM CPU. + * ****************************************************************************/ void up_irqinitialize(void) { - /* Disable all interrupts. */ -#warning Missing logic + FAR uintptr_t *vimram; + int i; /* Colorize the interrupt stack for debug purposes */ #if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 - { - size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); - up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), - intstack_size); - } + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); + up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), + intstack_size); #endif + /* Initialize VIM RAM vectors. These vectors are not used in the current + * interrupt handler logic. + */ + + vimram = (FAR uintptr_t *)TMS570_VIMRAM_BASE; + for (i = 0; i < (TMS570_IRQ_NCHANNELS + 1); i++) + { + *vimram++ = (uintptr_t)tms570_error_handler; + } + + /* Set Fall-Back Address Parity Error Register (also not used) */ + + putreg32((uint32_t)tms570_error_handler, TMS570_VIM_FBPARERR); + /* Assign all channels to IRQs */ putreg32(0, TMS570_VIM_FIRQPR0); @@ -111,12 +159,22 @@ void up_irqinitialize(void) current_regs = NULL; +#ifdef CONFIG_ARMV7R_HAVE_DECODEFIQ + /* By default, interrupt CHAN0 is mapped to ESM (Error Signal Module) + * high level interrupt and CHAN1 is reserved for other NMI. For safety + * reasons, these two channels are mapped to FIQ only and can NOT be + * disabled through ENABLE registers. + */ + +#warning Missing Logic +#endif + #ifndef CONFIG_SUPPRESS_INTERRUPTS +#ifdef CONFIG_TMS570_GPIO_IRQ /* Initialize logic to support a second level of interrupt decoding for * GPIO pins. */ -#ifdef CONFIG_TMS570_GPIO_IRQ tms570_gpioirqinitialize(); #endif @@ -126,6 +184,27 @@ void up_irqinitialize(void) #endif } +/**************************************************************************** + * Name: tms570_vim_channel + * + * Description: + * Allocate a VIM channel and assign it to the 'request'. + * + * Input Parameters: + * request - The interrupt request to be mapped to a channel + * + * Returned Value: + * One sucess, the allocated channel number is returned. A negated errno + * value is returned on any failure. + * + ****************************************************************************/ + +int tms570_vim_channel(int request) +{ +#warning Missing logic + return -ENOSYS; +} + /**************************************************************************** * Name: arm_decodeirq * @@ -136,15 +215,38 @@ void up_irqinitialize(void) * the irq number of the interrupt and then to call arm_doirq to dispatch * the interrupt. * - * Input parameters: + * Input parameters: * regs - A pointer to the register save area on the stack. * ****************************************************************************/ uint32_t *arm_decodeirq(uint32_t *regs) { -#warning Missing Logic - return 0; + int vector; + + /* Check for a VRAM parity error. This is not to critical in this + * implementatin since VIM RAM is not used. + */ +#warning Missing logic + + /* Get the interrupting vector number from the IRQINDEX register. Zero, + * the "phantom" vector will returned. + */ + + vector = getreg32(TMS570_VIM_IRQINDEX) & VIM_IRQINDEX_MASK; + if (vector > 0) + { + /* Dispatch the interrupt. NOTE that the IRQ number is the vector + * number offset by one to skip over the "phantom" vector. + */ + + regs = arm_doirq(vector - 1, regs); + } + + /* Acknowledge interrupt */ +#warning Verify not needed + + return regs; } /**************************************************************************** @@ -165,8 +267,31 @@ uint32_t *arm_decodeirq(uint32_t *regs) #ifdef CONFIG_ARMV7R_HAVE_DECODEFIQ uint32_t *arm_decodefiq(FAR uint32_t *regs) { -#warning Missing Logic - return 0; + int vector; + + /* Check for a VRAM parity error. This is not to critical in this + * implementatin since VIM RAM is not used. + */ +#warning Missing logic + + /* Get the interrupting vector number from the FIQINDEX register. Zero, + * the "phantom" vector will returned. + */ + + vector = getreg32(TMS570_VIM_FIQINDEX) & VIM_FIQINDEX_MASK; + if (vector > 0) + { + /* Dispatch the interrupt. NOTE that the IRQ number is the vector + * number offset by one to skip over the "phantom" vector. + */ + + regs = arm_doirq(vector - 1, regs) + } + + /* Acknowledge interrupt */ +#warning Verify not needed + + return regs; } #endif diff --git a/arch/arm/src/tms570/tms570_irq.h b/arch/arm/src/tms570/tms570_irq.h new file mode 100644 index 00000000000..fd899e2a24f --- /dev/null +++ b/arch/arm/src/tms570/tms570_irq.h @@ -0,0 +1,99 @@ +/**************************************************************************** + * arch/arm/src/tms570/tms570_irq.h + * + * Copyright (C) 2015 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. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_TMS570_SAM_IRQ_H +#define __ARCH_ARM_SRC_TMS570_SAM_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: tms570_vim_channel + * + * Description: + * Allocate a VIM channel and assign it to the 'request'. + * + * Input Parameters: + * request - The interrupt request to be mapped to a channel + * + * Returned Value: + * One sucess, the allocated channel number is returned. A negated errno + * value is returned on any failure. + * + ****************************************************************************/ + +int tms570_vim_channel(int request); + +/**************************************************************************** + * Name: up_enable_fiq + * + * Description: + * Enable the FIQ specified by 'channel' + * + ****************************************************************************/ + +#ifdef CONFIG_ARMV7R_HAVE_DECODEFIQ +void up_enable_fiq(int channel); +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_TMS570_SAM_IRQ_H */