From bb88f8d0bbc59b3d8783e37ef7e90e5f570d18f8 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 21 Jun 2018 10:59:58 -0600 Subject: [PATCH] Squashed commit of the following: A few bugfixes in initial testing on the i.MX6. Behavior seems a little more stable, but there are still memory corruption issues. Also print CPU number on assertion. Add a file missed in the last big commit. arch/arm/src/armv7a and imx6: Add support for per-CPU IRQ and FIQ interrupt stacks (bugfix). Add support so that up_assert will print the correct interrupt stack on an assertion (FIQ stack is still not printed). arch/arm/src/lc823450: Combine the content of smp_macros.h into chip.h. Add support so that up_assert will print the correct interrupt stack on an assertion. --- TODO | 11 +- arch/arm/src/a1x/chip.h | 20 +-- arch/arm/src/armv7-a/arm_assert.c | 36 ++++- arch/arm/src/armv7-a/arm_vectors.S | 113 +++++++++++++--- arch/arm/src/armv7-m/gnu/up_exception.S | 16 ++- arch/arm/src/armv7-m/gnu/up_lazyexception.S | 17 ++- arch/arm/src/armv7-m/up_assert.c | 24 +++- arch/arm/src/imx6/chip.h | 127 +++++++++++++++++- arch/arm/src/imx6/imx_irq.c | 51 ++++++- arch/arm/src/imx6/imx_irq.h | 95 +++++++++++++ arch/arm/src/lc823450/chip.h | 94 +++++++++++-- arch/arm/src/lc823450/lc823450_irq.c | 30 ++--- .../lc823450/{smp_macros.h => lc823450_irq.h} | 76 ++++++----- arch/arm/src/sama5/chip.h | 7 +- configs/sabre-6quad/README.txt | 4 +- 15 files changed, 598 insertions(+), 123 deletions(-) create mode 100644 arch/arm/src/imx6/imx_irq.h rename arch/arm/src/lc823450/{smp_macros.h => lc823450_irq.h} (70%) diff --git a/TODO b/TODO index 8d4a244215..ef4d193a35 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ -NuttX TODO List (Last updated June 20, 2018) +NuttX TODO List (Last updated June 21, 2018) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This file summarizes known NuttX bugs, limitations, inconsistencies with @@ -10,7 +10,7 @@ issues related to each board port. nuttx/: (15) Task/Scheduler (sched/) - (4) SMP + (3) SMP (1) Memory Management (mm/) (0) Power Management (drivers/pm) (3) Signals (sched/signal, arch/) @@ -482,13 +482,6 @@ o SMP simplification in the design and permit commonality with other, non-GIC imoplementations. - Title: BAD INTERRUPTSTACK LOGIC FOR ARMv7-A IN SMP CONFIGURATION - Description: The handler at arch/arm/src/armv7-a/arm_vectors.S supports - only a single interrupt stack. In SMP mode, that same - interrupt stack is used for all CPUs. That cannot work. - Status: Open - Priority: High - o Memory Management (mm/) ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/arch/arm/src/a1x/chip.h b/arch/arm/src/a1x/chip.h index c86af8e0c7..31521e2d0a 100644 --- a/arch/arm/src/a1x/chip.h +++ b/arch/arm/src/a1x/chip.h @@ -36,28 +36,28 @@ #ifndef __ARCH_ARM_SRC_A1X_CHIP_H #define __ARCH_ARM_SRC_A1X_CHIP_H -/************************************************************************************ +/***************************************************************************** * Included Files - ************************************************************************************/ + ****************************************************************************/ #include #include "chip/a1x_memorymap.h" -/************************************************************************************ +/**************************************************************************** * Pre-processor Definitions - ************************************************************************************/ + ****************************************************************************/ -/************************************************************************************ +/**************************************************************************** * Public Types - ************************************************************************************/ + ****************************************************************************/ -/************************************************************************************ +/**************************************************************************** * Public Data - ************************************************************************************/ + ****************************************************************************/ -/************************************************************************************ +/**************************************************************************** * Public Functions - ************************************************************************************/ + ****************************************************************************/ #endif /* __ARCH_ARM_SRC_A1X_CHIP_H */ diff --git a/arch/arm/src/armv7-a/arm_assert.c b/arch/arm/src/armv7-a/arm_assert.c index b8019df7d0..75b94bdb46 100644 --- a/arch/arm/src/armv7-a/arm_assert.c +++ b/arch/arm/src/armv7-a/arm_assert.c @@ -52,14 +52,17 @@ #include -#include "up_arch.h" #include "sched/sched.h" #include "irq/irq.h" + +#include "up_arch.h" #include "up_internal.h" +#include "chip.h" /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ + /* USB trace dumping */ #ifndef CONFIG_USBDEV_TRACE @@ -210,7 +213,7 @@ static void up_dumpstate(void) uint32_t sp = up_getsp(); uint32_t ustackbase; uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 +#if CONFIG_ARCH_INTERRUPTSTACK > 7 uint32_t istackbase; uint32_t istacksize; #endif @@ -233,11 +236,15 @@ static void up_dumpstate(void) _alert("Current sp: %08x\n", sp); -#if CONFIG_ARCH_INTERRUPTSTACK > 3 +#if CONFIG_ARCH_INTERRUPTSTACK > 7 /* Get the limits on the interrupt stack memory */ +#ifdef CONFIG_SMP + istackbase = (uint32_t)up_intstack_base(); +#else istackbase = (uint32_t)&g_intstackbase; - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); +#endif + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~7); /* Show interrupt stack info */ @@ -271,11 +278,13 @@ static void up_dumpstate(void) } #endif -#if CONFIG_ARCH_INTERRUPTSTACK > 3 +#if CONFIG_ARCH_INTERRUPTSTACK > 7 /* Does the current stack pointer lie within the interrupt stack? */ if (sp > istackbase - istacksize && sp < istackbase) { + uint32_t *stackbase; + /* Yes.. dump the interrupt stack */ _alert("Interrupt Stack\n", sp); @@ -285,7 +294,12 @@ static void up_dumpstate(void) * at the base of the interrupt stack. */ - sp = g_intstackbase; +#ifdef CONFIG_SMP + stackbase = (uint32_t *)up_intstack_base(); +#else + stackbase = (uint32_t *)&g_intstackbase; +#endif + sp = *stackbase; _alert("User sp: %08x\n", sp); } #endif @@ -399,12 +413,22 @@ void up_assert(const uint8_t *filename, int lineno) (void)syslog_flush(); +#ifdef CONFIG_SMP +#if CONFIG_TASK_NAME_SIZE > 0 + _alert("Assertion failed CPU%d at file:%s line: %d task: %s\n", + up_cpu_index(), filename, lineno, rtcb->name); +#else + _alert("Assertion failed CPU%d at file:%s line: %d\n", + up_cpu_index(), filename, lineno); +#endif +#else #if CONFIG_TASK_NAME_SIZE > 0 _alert("Assertion failed at file:%s line: %d task: %s\n", filename, lineno, rtcb->name); #else _alert("Assertion failed at file:%s line: %d\n", filename, lineno); +#endif #endif up_dumpstate(); diff --git a/arch/arm/src/armv7-a/arm_vectors.S b/arch/arm/src/armv7-a/arm_vectors.S index 8a76e000b5..4157f25457 100644 --- a/arch/arm/src/armv7-a/arm_vectors.S +++ b/arch/arm/src/armv7-a/arm_vectors.S @@ -1,7 +1,7 @@ /************************************************************************************ * arch/arm/src/armv7-a/arm_vectors.S * - * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2014, 2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -42,6 +42,7 @@ #include "arm.h" #include "cp15.h" +#include "chip.h" .file "arm_vectors.S" @@ -53,22 +54,83 @@ g_irqtmp: .word 0 /* Saved lr */ .word 0 /* Saved spsr */ + g_undeftmp: .word 0 /* Saved lr */ .word 0 /* Saved spsr */ + g_aborttmp: .word 0 /* Saved lr */ .word 0 /* Saved spsr */ + #ifdef CONFIG_ARMV7A_DECODEFIQ g_fiqtmp: .word 0 /* Saved lr */ .word 0 /* Saved spsr */ #endif -#if CONFIG_ARCH_INTERRUPTSTACK > 3 && defined(CONFIG_ARMV7A_HAVE_GICv2) + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 && defined(CONFIG_ARMV7A_HAVE_GICv2) + g_nestlevel: +#ifdef CONFIG_SMP + .rept CONFIG_SMP_NCPUS + .word 0 /* CPUn Interrupt nesting level */ + .endr +#else .word 0 /* Interrupt nesting level */ #endif +#endif /* CONFIG_ARCH_INTERRUPTSTACK > 7 && CONFIG_ARMV7A_HAVE_GICv2 */ + +/************************************************************************************ + * Macro Definitions + ************************************************************************************/ + +/************************************************************************************ + * Name: cpuindex + * + * Description: + * Return an index idenifying the current CPU. Single CPU case. Must be + * provided by MCU-specific logic in chip.h for the SMP case. + * + ************************************************************************************/ + +#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 + .macro cpuindex, index + .mov \index, #0 + .endm +#endif + +/************************************************************************************ + * Name: setirqstack + * + * Description: + * Set the current stack pointer to the "top" of the IRQ interrupt stack. Single + * CPU case. Must be provided by MCU-specific logic in chip.h for the SMP case. + * + ************************************************************************************/ + +#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 + .macro setirqstack, tmp1, tmp2 + ldr sp, .Lirqstackbase /* SP = IRQ stack top */ + .endm +#endif + +/************************************************************************************ + * Name: setfiqstack + * + * Description: + * Set the current stack pointer to the "top" of the FIQ interrupt stack. Single + * CPU case. Must be provided by MCU-specific logic in chip.h for the SMP case. + * + ************************************************************************************/ + +#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 + .macro setfiqstack, tmp1, tmp2 + ldr sp, .Lfiqstackbase /* SP = FIQ stack top */ + .endm +#endif + /************************************************************************************ * Private Functions ************************************************************************************/ @@ -175,14 +237,19 @@ arm_vectorirq: mov fp, #0 /* Init frame pointer */ mov r0, sp /* Get r0=xcp */ -#if CONFIG_ARCH_INTERRUPTSTACK > 3 +#if CONFIG_ARCH_INTERRUPTSTACK > 7 #ifdef CONFIG_ARMV7A_HAVE_GICv2 /* We will switch to the interrupt stack, UNLESS we are processing a * nested interrupt in which case we are already using the interrupt * stack. SGI interrupts may be nested because they are non-maskable. */ - ldr r5, .Lirqnestlevel /* r1=Points to interrupt nesting level */ + ldr r5, .Lirqnestlevel /* r5=Points to interrupt nesting level */ +#ifdef CONFIG_SMP + cpuindex r1 /* r1=cpu index */ + lsls r1, r1, #2 /* r1=array byte offset */ + add r5, r5, r1 /* Indexed interrupt nesting level */ +#endif ldr r1, [r5] /* Get r1= nesting level */ add r1, r1, #1 /* Increment nesting level */ str r1, [r5] /* Save r1= nesting level */ @@ -193,7 +260,7 @@ arm_vectorirq: /* Call arm_decodeirq() on the interrupt stack */ - ldr sp, .Lirqstackbase /* SP = interrupt stack base */ + setirqstack r1, r5 /* SP = IRQ stack top */ str r0, [sp] /* Save the user stack pointer */ mov r4, sp /* Save the SP in a preserved register */ bic sp, sp, #7 /* Force 8-byte alignment */ @@ -268,14 +335,19 @@ arm_vectorirq: .Lirqtmp: .word g_irqtmp -#if CONFIG_ARCH_INTERRUPTSTACK > 3 + +#if CONFIG_ARCH_INTERRUPTSTACK > 7 +#ifndef CONFIG_SMP .Lirqstackbase: .word g_intstackbase +#endif + #ifdef CONFIG_ARMV7A_HAVE_GICv2 .Lirqnestlevel: .word g_nestlevel #endif -#endif +#endif /* CONFIG_ARCH_INTERRUPTSTACK > 7 */ + .size arm_vectorirq, . - arm_vectorirq .align 5 @@ -930,8 +1002,8 @@ arm_vectorfiq: mov fp, #0 /* Init frame pointer */ mov r0, sp /* Get r0=xcp */ -#if CONFIG_ARCH_INTERRUPTSTACK > 3 - ldr sp, .Lfiqstackbase /* SP = interrupt stack base */ +#if CONFIG_ARCH_INTERRUPTSTACK > 7 + setfiqstack r1, r4 /* SP = FIQ stack top */ str r0, [sp] /* Save the user stack pointer */ mov r4, sp /* Save the SP in a preserved register */ bic sp, sp, #7 /* Force 8-byte alignment */ @@ -983,7 +1055,8 @@ arm_vectorfiq: .Lfiqtmp: .word g_fiqtmp -#if CONFIG_ARCH_INTERRUPTSTACK > 3 + +#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 .Lfiqstackbase: .word g_fiqstackbase #endif @@ -997,7 +1070,7 @@ arm_vectorfiq: * Name: g_intstackalloc/g_intstackbase ************************************************************************************/ -#if CONFIG_ARCH_INTERRUPTSTACK > 3 +#if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 .bss .align 4 @@ -1007,27 +1080,27 @@ arm_vectorfiq: .type g_intstackbase, object g_intstackalloc: - .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4) + .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~7) - 4) g_intstackbase: .skip 4 .size g_intstackbase, 4 - .size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3) + .size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~7) + +/************************************************************************************ + * Name: g_fiqstackalloc/g_fiqstackbase + ************************************************************************************/ .globl g_fiqstackalloc .type g_fiqstackalloc, object .globl g_fiqstackbase .type g_fiqstackbase, object -/************************************************************************************ - * Name: g_fiqstackalloc/g_fiqstackbase - ************************************************************************************/ - g_fiqstackalloc: - .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4) + .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~7) - 4) g_fiqstackbase: .skip 4 .size g_fiqstackbase, 4 - .size g_fiqstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~3) + .size g_fiqstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~7) -#endif /* CONFIG_ARCH_INTERRUPTSTACK > 3 */ +#endif /* !CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 7 */ .end diff --git a/arch/arm/src/armv7-m/gnu/up_exception.S b/arch/arm/src/armv7-m/gnu/up_exception.S index f829105ae1..1629dc99bb 100644 --- a/arch/arm/src/armv7-m/gnu/up_exception.S +++ b/arch/arm/src/armv7-m/gnu/up_exception.S @@ -44,9 +44,6 @@ #include "exc_return.h" #include "chip.h" -#ifdef CONFIG_SMP -# include "smp_macros.h" -#endif /************************************************************************************ * Pre-processor Definitions @@ -96,8 +93,17 @@ * Macro Definitions ************************************************************************************/ +/************************************************************************************ + * Name: setintstack + * + * Description: + * Set the current stack pointer to the "top" the interrupt stack. Single CPU + * case. Must be provided by MCU-specific logic in the SMP case. + * + ************************************************************************************/ + #if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 - .macro setintstack, tmp + .macro setintstack, tmp1, tmp2 ldr sp, =g_intstackbase .endm #endif @@ -206,7 +212,7 @@ exception_common: * here prohibits nested interrupts without some additional logic! */ - setintstack r2 + setintstack r2, r3 #else /* Otherwise, we will re-use the interrupted thread's stack. That may diff --git a/arch/arm/src/armv7-m/gnu/up_lazyexception.S b/arch/arm/src/armv7-m/gnu/up_lazyexception.S index 28f0d320d7..54625cffde 100644 --- a/arch/arm/src/armv7-m/gnu/up_lazyexception.S +++ b/arch/arm/src/armv7-m/gnu/up_lazyexception.S @@ -43,13 +43,11 @@ #include "exc_return.h" #include "chip.h" -#ifdef CONFIG_SMP -# include "smp_macros.h" -#endif /************************************************************************************************ * Pre-processor Definitions ************************************************************************************************/ + /* Configuration ********************************************************************************/ #ifdef CONFIG_ARCH_HIPRI_INTERRUPT @@ -93,8 +91,17 @@ * Macro Definitions ************************************************************************************************/ +/************************************************************************************************ + * Name: setintstack + * + * Description: + * Set the current stack pointer to the "top" the interrupt stack. Single CPU case. Must be + * provided by MCU-specific logic in chip.h for the SMP case. + * + ************************************************************************************************/ + #if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 - .macro setintstack, tmp + .macro setintstack, tmp1, tmp2 ldr sp, =g_intstackbase .endm #endif @@ -214,7 +221,7 @@ exception_common: * here prohibits nested interrupts without some additional logic! */ - setintstack r2 + setintstack r2, r3 #else /* Otherwise, we will re-use the interrupted thread's stack. That may diff --git a/arch/arm/src/armv7-m/up_assert.c b/arch/arm/src/armv7-m/up_assert.c index 0bbb5a5eab..549f3042ce 100644 --- a/arch/arm/src/armv7-m/up_assert.c +++ b/arch/arm/src/armv7-m/up_assert.c @@ -53,10 +53,12 @@ #include -#include "up_arch.h" #include "sched/sched.h" #include "irq/irq.h" + +#include "up_arch.h" #include "up_internal.h" +#include "chip.h" /**************************************************************************** * Pre-processor Definitions @@ -224,7 +226,7 @@ static void up_dumpstate(void) uint32_t sp = up_getsp(); uint32_t ustackbase; uint32_t ustacksize; -#if CONFIG_ARCH_INTERRUPTSTACK > 3 +#if CONFIG_ARCH_INTERRUPTSTACK > 7 uint32_t istackbase; uint32_t istacksize; #endif @@ -242,11 +244,15 @@ static void up_dumpstate(void) ustacksize = (uint32_t)rtcb->adj_stack_size; } -#if CONFIG_ARCH_INTERRUPTSTACK > 3 +#if CONFIG_ARCH_INTERRUPTSTACK > 7 /* Get the limits on the interrupt stack memory */ +#ifdef CONFIG_SMP + istackbase = (uint32_t)up_intstack_base(); +#else istackbase = (uint32_t)&g_intstackbase; - istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3); +#endif + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~7); /* Show interrupt stack info */ @@ -404,12 +410,22 @@ void up_assert(const uint8_t *filename, int lineno) (void)syslog_flush(); +#ifdef CONFIG_SMP +#if CONFIG_TASK_NAME_SIZE > 0 + _alert("Assertion failed CPU%d at file:%s line: %d task: %s\n", + up_cpu_index(), filename, lineno, rtcb->name); +#else + _alert("Assertion failed CPU%d at file:%s line: %d\n", + up_cpu_index(), filename, lineno); +#endif +#else #if CONFIG_TASK_NAME_SIZE > 0 _alert("Assertion failed at file:%s line: %d task: %s\n", filename, lineno, rtcb->name); #else _alert("Assertion failed at file:%s line: %d\n", filename, lineno); +#endif #endif up_dumpstate(); diff --git a/arch/arm/src/imx6/chip.h b/arch/arm/src/imx6/chip.h index 504e1ee4d2..7ffb923c0f 100644 --- a/arch/arm/src/imx6/chip.h +++ b/arch/arm/src/imx6/chip.h @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/imx6/chip.h * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2016, 2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -41,7 +41,13 @@ ****************************************************************************/ #include + +#ifndef __ASSEMBLY__ +# include +#endif + #include "chip/imx_memorymap.h" +#include "imx_irq.h" /**************************************************************************** * Pre-processor Definitions @@ -63,6 +69,125 @@ * Public Data ****************************************************************************/ +#ifdef __ASSEMBLY__ + +#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 + .globl g_irqstack_top + .globl g_fiqstack_top +#endif /* CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 7 */ + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Macro Definitions + ****************************************************************************/ + +#ifdef __ASSEMBLY__ + +/*************************************************************************** + * Name: cpuindex + * + * Description: + * Return an index idenifying the current CPU. + * + ****************************************************************************/ + +#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 + .macro cpuindex, index + mrc p15, 0, \index, c0, c0, 5 /* Read the MPIDR */ + and \index, \index, #3 /* Bits 0-1=CPU ID */ + .endm +#endif + +/*************************************************************************** + * Name: setirqstack + * + * Description: + * Set the current stack pointer to the -"top" of the IRQ interrupt + * stack for the current CPU. + * + ***************************************************************************/ + +#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 + .macro setirqstack, tmp1, tmp2 + mrc p15, 0, \tmp1, c0, c0, 5 /* tmp1=MPIDR */ + and \tmp1, \tmp1, #3 /* Bits 0-1=CPU ID */ + ldr \tmp2, =g_irqstack_top /* tmp2=Array of IRQ stack pointers */ + lsls \tmp1, \tmp1, #2 /* tmp1=Array byte offset */ + add \tmp2, \tmp2, \tmp1 /* tmp2=Offset address into array */ + ldr sp, [\tmp2, #0] /* sp=Address in stack allocation */ + .endm +#endif + +/**************************************************************************** + * Name: setfiqstack + * + * Description: + * Set the current stack pointer to the -"top" of the FIQ interrupt + * stack for the current CPU. + * + ****************************************************************************/ + +#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 + .macro setfiqstack, tmp1, tmp2 + mrc p15, 0, \tmp1, c0, c0, 5 /* tmp1=MPIDR */ + and \tmp1, \tmp1, #3 /* Bits 0-1=CPU ID */ + ldr \tmp2, =g_fiqstack_top /* tmp2=Array of FIQ stack pointers */ + lsls \tmp1, \tmp1, #2 /* tmp1=Array byte offset */ + add \tmp2, \tmp2, \tmp1 /* tmp2=Offset address into array */ + ldr sp, [\tmp2, #0] /* sp=Address in stack allocation */ + .endm +#endif + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Name: up_intstack_base + * + * Description: + * Return a pointer to the "base" the correct interrupt stack for the + * current CPU. + * + ****************************************************************************/ + +#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 +static inline uintptr_t up_intstack_base(void) +{ + uintptr_t base = (uintptr_t)g_irqstack_alloc; +#if CONFIG_SMP_NCPUS > 1 + uint32_t cpu = up_cpu_index(); + + base += cpu * INTSTACK_SIZE; +#endif + + return base; +} +#endif + +/**************************************************************************** + * Name: up_intstack_top + * + * Description: + * Return a pointer to the "top" the correct interrupt stack for the + * current CPU. + * + ****************************************************************************/ + +#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 +static inline uintptr_t up_intstack_top(void) +{ + return up_intstack_base() + INTSTACK_SIZE; +} +#endif + +#endif /* !__ASSEMBLY__ */ + /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/arch/arm/src/imx6/imx_irq.c b/arch/arm/src/imx6/imx_irq.c index d5248ef40f..4b172aa566 100644 --- a/arch/arm/src/imx6/imx_irq.c +++ b/arch/arm/src/imx6/imx_irq.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/imx6/imx_irq.c * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2016, 2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,15 @@ #include "up_internal.h" #include "sctlr.h" #include "gic.h" +#include "imx_irq.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Size of the interrupt stack allocation */ + +#define INTSTACK_ALLOC (CONFIG_SMP_NCPUS * INTSTACK_SIZE) /**************************************************************************** * Public Data @@ -67,6 +76,46 @@ volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS]; volatile uint32_t *g_current_regs[1]; #endif +#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 +/* In the SMP configuration, we will need custom IRQ and FIQ stacks. + * These definitions provide the aligned stack allocations. + */ + +uint64_t g_irqstack_alloc[INTSTACK_ALLOC >> 3]; +uint64_t g_fiqstack_alloc[INTSTACK_ALLOC >> 3]; + +/* These are arrays that point to the top of each interrupt stack */ + +uintptr_t g_irqstack_top[CONFIG_SMP_NCPUS] = +{ + (uintptr_t)g_irqstack_alloc + INTSTACK_SIZE, +#if CONFIG_SMP_NCPUS > 1 + (uintptr_t)g_irqstack_alloc + 2 * INTSTACK_SIZE, +#endif +#if CONFIG_SMP_NCPUS > 2 + (uintptr_t)g_irqstack_alloc + 3 * INTSTACK_SIZE, +#endif +#if CONFIG_SMP_NCPUS > 3 + (uintptr_t)g_irqstack_alloc + 4 * INTSTACK_SIZE +#endif +}; + +uintptr_t g_fiqstack_top[CONFIG_SMP_NCPUS] = +{ + (uintptr_t)g_fiqstack_alloc + INTSTACK_SIZE, +#if CONFIG_SMP_NCPUS > 1 + (uintptr_t)g_fiqstack_alloc + 2 * INTSTACK_SIZE, +#endif +#if CONFIG_SMP_NCPUS > 2 + (uintptr_t)g_fiqstack_alloc + 3 * INTSTACK_SIZE, +#endif +#if CONFIG_SMP_NCPUS > 3 + (uintptr_t)g_fiqstack_alloc + 4 * INTSTACK_SIZE +#endif +}; + +#endif + /* Symbols defined via the linker script */ extern uint32_t _vector_start; /* Beginning of vector block */ diff --git a/arch/arm/src/imx6/imx_irq.h b/arch/arm/src/imx6/imx_irq.h new file mode 100644 index 0000000000..4751ced0fd --- /dev/null +++ b/arch/arm/src/imx6/imx_irq.h @@ -0,0 +1,95 @@ +/**************************************************************************** + * arch/arm/src/imx6/imx_irq.h + * + * Copyright (C) 2018 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_IMX6_IMX_IRQ_H +#define __ARCH_ARM_SRC_IMX6_IMX_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The size of one interrupt stack. This is the configured value aligned + * the 8-bytes as required by the ARM EABI. + */ + +#define INTSTACK_SIZE (CONFIG_ARCH_INTERRUPTSTACK & ~7) + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 +/* In the SMP configuration, we will need custom IRQ and FIQ stacks. + * These definitions provide the aligned stack allocations. + */ + +EXTERN uint64_t g_irqstack_alloc[]; +EXTERN uint64_t g_fiqstack_alloc[]; + +/* These are arrays that point to the top of each interrupt stack */ + +EXTERN uintptr_t g_irqstack_top[CONFIG_SMP_NCPUS]; +EXTERN uintptr_t g_irqstack_top[CONFIG_SMP_NCPUS]; + +#endif /* CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 7 */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_IMX6_IMX_IRQ_H */ diff --git a/arch/arm/src/lc823450/chip.h b/arch/arm/src/lc823450/chip.h index 7232afef70..5e31052e2d 100644 --- a/arch/arm/src/lc823450/chip.h +++ b/arch/arm/src/lc823450/chip.h @@ -41,9 +41,12 @@ * Included Files ****************************************************************************/ -#include -#include -#include +#ifndef __ASSEMBLY__ +# include +# include +# include +# include "lc823450_irq.h" +#endif /**************************************************************************** * Pre-processor Definitions @@ -56,16 +59,70 @@ #define ARMV7M_PERIPHERAL_INTERRUPTS LC823450_IRQ_NEXTINT +/* Access to COREID register */ + +#define LC823450_CORE_BASE 0xe00fe000 +#define CORE_COREID (LC823450_CORE_BASE + 0) +#define CORE_COREID_ID (1 << 0) + /**************************************************************************** * Public Types ****************************************************************************/ -#ifndef __ASSEMBLY__ - /**************************************************************************** * Public Data ****************************************************************************/ +#ifdef __ASSEMBLY__ + +#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 + .globl g_instack_alloc +#endif /* CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 7 */ + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Macro Definitions + ****************************************************************************/ + +#ifdef __ASSEMBLY__ + +/**************************************************************************** + * Name: setintstack + * + * Description: + * Set the current stack pointer to the "top" the correct interrupt stack + * for the current CPU. + * + ****************************************************************************/ + +#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 + .macro setintstack, tmp1, tmp2 +#if CONFIG_SMP_NCPUS > 1 + ldr \tmp1, =CORE_COREID + ldr \tmp1, [\tmp1, 0] /* \tmp = getreg32(coreid_reg) */ + and \tmp1, \tmp1, 1 /* \tmp = COREID */ + cmp \tmp1, #0 + bne 1f + ldr sp, =g_cpu0_instack_base + b 2f +1: + ldr sp, =g_cpu1_instack_base +2: +#else + ldr sp, =g_cpu0_instack_base +#endif + .endm +#endif /* CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 7 */ + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + #ifdef __cplusplus #define EXTERN extern "C" extern "C" @@ -75,19 +132,40 @@ extern "C" #endif /**************************************************************************** - * Inline Functions + * Name: up_intstack_base + * + * Description: + * Set the current stack pointer to the "top" the correct interrupt stack + * for the current CPU. + * ****************************************************************************/ +#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 +static inline uintptr_t up_intstack_base(void) +{ + uintptr_t base = (uintptr_t)g_instack_alloc; +#if CONFIG_SMP_NCPUS > 1 + uint32_t coreid = getreg32(CORE_COREID); + + if ((coreid & CORE_COREID_ID) != 0) + { + base += INTSTACK_SIZE; + } +#endif + + return base; +} +#endif /**************************************************************************** * Public Function Prototypes ****************************************************************************/ - #if defined(__cplusplus) } #endif #undef EXTERN -#endif /* __ASSEMBLY__ */ +#endif /* !__ASSEMBLY__ */ + #endif /* _ARCH_ARM_SRC_LC823450_CHIP_H */ diff --git a/arch/arm/src/lc823450/lc823450_irq.c b/arch/arm/src/lc823450/lc823450_irq.c index c111bc10aa..3b16bcc064 100644 --- a/arch/arm/src/lc823450/lc823450_irq.c +++ b/arch/arm/src/lc823450/lc823450_irq.c @@ -80,20 +80,9 @@ #define NVIC_ENA_OFFSET (0) #define NVIC_CLRENA_OFFSET (NVIC_IRQ0_31_CLEAR - NVIC_IRQ0_31_ENABLE) -/**************************************************************************** - * Private Data - ****************************************************************************/ +/* Size of the interrupt stack allocation */ -#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 -/* In the SMP configuration, we will need two custom interrupt stacks. - * These definitions provide the aligned stack allocations. - */ - -static uint64_t g_cpu0_instack_alloc[CONFIG_ARCH_INTERRUPTSTACK >> 3]; -#if CONFIG_SMP_NCPUS > 1 -static uint64_t g_cpu1_instack_alloc[CONFIG_ARCH_INTERRUPTSTACK >> 3]; -#endif -#endif +#define INTSTACK_ALLOC (CONFIG_SMP_NCPUS * INTSTACK_SIZE) /**************************************************************************** * Public Data @@ -111,14 +100,19 @@ volatile uint32_t *g_current_regs[1]; #if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 /* In the SMP configuration, we will need two custom interrupt stacks. - * These defintions provide the "top" of the push-down stacks. + * These definitions provide the aligned stack allocations. */ -const uint32_t g_cpu0_instack_base = (uint32_t)g_cpu0_instack_alloc + - sizeof(g_cpu0_instack_alloc); +uint64_t g_instack_alloc[INTSTACK_ALLOC >> 3]; + +/* These definitions provide the "top" of the push-down stacks. */ + +const uint32_t g_cpu0_instack_base = + (uint32_t)g_instack_alloc + INTSTACK_SIZE) + #if CONFIG_SMP_NCPUS > 1 -const uint32_t g_cpu1_instack_base = (uint32_t)g_cpu1_instack_alloc + - sizeof(g_cpu1_instack_alloc); +const uint32_t g_cpu1_instack_base = + (uint32_t)g_instack_alloc + 2 * INTSTACK_SIZE) #endif #endif diff --git a/arch/arm/src/lc823450/smp_macros.h b/arch/arm/src/lc823450/lc823450_irq.h similarity index 70% rename from arch/arm/src/lc823450/smp_macros.h rename to arch/arm/src/lc823450/lc823450_irq.h index c8685ff788..caea743c19 100644 --- a/arch/arm/src/lc823450/smp_macros.h +++ b/arch/arm/src/lc823450/lc823450_irq.h @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/lc823450/smp_macros.h + * arch/arm/src/lc823450/lc823450_irq.h * * Copyright (C) 2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -33,8 +33,8 @@ * ****************************************************************************/ -#ifndef __ARCH_ARM_SRC_LC823450_SMP_MACROS_H -#define __ARCH_ARM_SRC_LC823450_SMP_MACROS_H +#ifndef __ARCH_ARM_SRC_LC823450_LC823450_IRQ_H +#define __ARCH_ARM_SRC_LC823450_LC823450_IRQ_H /**************************************************************************** * Included Files @@ -42,45 +42,55 @@ #include -#if defined(__ASSEMBLY__) && defined(CONFIG_SMP) - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -#define COREID_REG 0xe00fe000 +/* The size of one interrupt stack. This is the configured value aligned + * the 8-bytes as required by the ARM EABI. + */ + +#define INTSTACK_SIZE (CONFIG_ARCH_INTERRUPTSTACK & ~7) /**************************************************************************** - * Imported Public Data + * Public Data ****************************************************************************/ -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - .globl g_cpu0_instack_base - .globl g_cpu1_instack_base -#endif +#ifndef __ASSEMBLY__ -/**************************************************************************** - * Macro Definitions - ****************************************************************************/ - -#if CONFIG_ARCH_INTERRUPTSTACK > 7 - .macro setintstack, tmp -#if CONFIG_SMP_NCPUS > 1 - ldr \tmp, =COREID_REG - ldr \tmp, [\tmp, 0] /* \tmp = getreg32(coreid_reg) */ - and \tmp, \tmp, 1 /* \tmp = COREID */ - cmp \tmp, #0 - bne 1f - ldr sp, =g_cpu0_instack_base - b 2f -1: - ldr sp, =g_cpu1_instack_base -2: +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ #else - ldr sp, =g_cpu0_instack_base -#endif - .endm +#define EXTERN extern #endif -#endif /* __ASSEMBLY__ && CONFIG_SMP */ -#endif /* __ARCH_ARM_SRC_LC823450_SMP_MACROS_H */ +#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 +/* In the SMP configuration, we will need two custom interrupt stacks. + * These definitions provide the aligned stack allocations. + */ + +EXTERN uint64_t g_instack_alloc[]; + +/* These definitions provide the "top" of the push-down stacks. */ + +EXTERN const uint32_t g_cpu0_instack_base; +#if CONFIG_SMP_NCPUS > 1 +EXTERN const uint32_t g_cpu1_instack_base; +#endif + +#endif /* CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 7 */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_LC823450_LC823450_IRQ_H */ diff --git a/arch/arm/src/sama5/chip.h b/arch/arm/src/sama5/chip.h index 6534257c7c..ab2bd4d681 100644 --- a/arch/arm/src/sama5/chip.h +++ b/arch/arm/src/sama5/chip.h @@ -1,7 +1,7 @@ /************************************************************************************ * arch/arm/src/sama5/chip.h * - * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2014, 2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -41,7 +41,10 @@ ************************************************************************************/ #include -#include + +#ifndef __ASSEMBLY__ +# include +#endif #include "chip/sam_memorymap.h" diff --git a/configs/sabre-6quad/README.txt b/configs/sabre-6quad/README.txt index f07582b62c..a187ded885 100644 --- a/configs/sabre-6quad/README.txt +++ b/configs/sabre-6quad/README.txt @@ -165,7 +165,9 @@ Status 2018-06-20: There is a problem with the Interrupt Stack for SMP in arch/arm/src/armv7-a/arm_vectors.S: There is only one interrupt stack for - all CPUs! + all CPUs! A fix for this was put in place on 2018-06-21. Big Improvement! + Bit this does not completely eliminate instabilities which seem to be + related to memory corruption -- mm_mallinfo() asserts. Platform Features =================