From 6e12f3c78288f5ed4d3f7d82c1cccc06c31b50ac Mon Sep 17 00:00:00 2001 From: Masayuki Ishikawa Date: Thu, 22 Oct 2020 10:06:05 +0900 Subject: [PATCH] armv7-a, imx6: Refactor interrupt stack related code Summary: - Remove -4/-8 offset coding in imx_irq.c and arm_vectors.S - Instead, add SP adjustment after calling setirqstack/setfiqstack - Fix off-by-one irq/fiq stack allocation in 8-byte aligned arch - Fix comments on the user stack pointer in arm_vectors.S - Also, fix up_dumpstate() to extract the user stack pointer - NOTE: stack pointer alignment is 8-byte Impact: - Affects armv7-a with interrupt stack enabled Testing: - Tested with sabre-6quad:smp with QEMU - Tested with sabre-6quad:nsh with QEMU Signed-off-by: Masayuki Ishikawa --- arch/arm/src/armv7-a/arm_assert.c | 25 +++++++++++-------------- arch/arm/src/armv7-a/arm_vectors.S | 10 +++++----- arch/arm/src/imx6/imx_irq.c | 10 +++++----- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/arch/arm/src/armv7-a/arm_assert.c b/arch/arm/src/armv7-a/arm_assert.c index 07a2decbf7..f04eaa0012 100644 --- a/arch/arm/src/armv7-a/arm_assert.c +++ b/arch/arm/src/armv7-a/arm_assert.c @@ -265,24 +265,10 @@ static void up_dumpstate(void) if (sp > istackbase - istacksize && sp < istackbase) { - uint32_t *stackbase; - /* Yes.. dump the interrupt stack */ _alert("Interrupt Stack\n", sp); up_stackdump(sp, istackbase); - - /* Extract the user stack pointer which should lie - * at the base of the interrupt stack. - */ - -#ifdef CONFIG_SMP - stackbase = (uint32_t *)arm_intstack_base(); -#else - stackbase = (uint32_t *)&g_intstackbase; -#endif - sp = *stackbase; - _alert("User sp: %08x\n", sp); } else if (CURRENT_REGS) { @@ -291,6 +277,17 @@ static void up_dumpstate(void) } #endif + /* Extract the user stack pointer if we are in an interrupt handler. + * If we are not in an interrupt handler. Then sp is the user stack + * pointer (and the above range check should have failed). + */ + + if (CURRENT_REGS) + { + sp = CURRENT_REGS[REG_R13]; + _alert("User sp: %08x\n", sp); + } + /* Dump the user stack if the stack pointer lies within the allocated user * stack memory. */ diff --git a/arch/arm/src/armv7-a/arm_vectors.S b/arch/arm/src/armv7-a/arm_vectors.S index 6df8755c4c..e055904816 100644 --- a/arch/arm/src/armv7-a/arm_vectors.S +++ b/arch/arm/src/armv7-a/arm_vectors.S @@ -261,7 +261,7 @@ arm_vectorirq: /* Call arm_decodeirq() on the interrupt stack */ setirqstack r1, r3 /* SP = IRQ stack top */ - str r0, [sp] /* Save the user stack pointer */ + str r0, [sp, #-4]! /* Save the xcp address at SP-4 then update SP */ mov r4, sp /* Save the SP in a preserved register */ bic sp, sp, #7 /* Force 8-byte alignment */ bl arm_decodeirq /* Call the handler */ @@ -1004,7 +1004,7 @@ arm_vectorfiq: #if CONFIG_ARCH_INTERRUPTSTACK > 7 setfiqstack r1, r4 /* SP = FIQ stack top */ - str r0, [sp] /* Save the user stack pointer */ + str r0, [sp, #-4]! /* Save the xcp address at SP-4 then update SP */ mov r4, sp /* Save the SP in a preserved register */ bic sp, sp, #7 /* Force 8-byte alignment */ bl arm_decodefiq /* Call the handler */ @@ -1072,7 +1072,7 @@ arm_vectorfiq: #if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 .bss - .align 4 + .balign 8 .globl g_intstackalloc .type g_intstackalloc, object @@ -1080,7 +1080,7 @@ arm_vectorfiq: .type g_intstackbase, object g_intstackalloc: - .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~7) - 4) + .skip ((CONFIG_ARCH_INTERRUPTSTACK + 4) & ~7) g_intstackbase: .skip 4 .size g_intstackbase, 4 @@ -1096,7 +1096,7 @@ g_intstackbase: .type g_fiqstackbase, object g_fiqstackalloc: - .skip ((CONFIG_ARCH_INTERRUPTSTACK & ~7) - 4) + .skip ((CONFIG_ARCH_INTERRUPTSTACK + 4) & ~7) g_fiqstackbase: .skip 4 .size g_fiqstackbase, 4 diff --git a/arch/arm/src/imx6/imx_irq.c b/arch/arm/src/imx6/imx_irq.c index 1f7738f9a0..7d3b76033e 100644 --- a/arch/arm/src/imx6/imx_irq.c +++ b/arch/arm/src/imx6/imx_irq.c @@ -88,15 +88,15 @@ uint64_t g_fiqstack_alloc[INTSTACK_ALLOC >> 3]; uintptr_t g_irqstack_top[CONFIG_SMP_NCPUS] = { - (uintptr_t)g_irqstack_alloc + INTSTACK_SIZE - 8, + (uintptr_t)g_irqstack_alloc + INTSTACK_SIZE, #if CONFIG_SMP_NCPUS > 1 - (uintptr_t)g_irqstack_alloc + (2 * INTSTACK_SIZE) - 8, + (uintptr_t)g_irqstack_alloc + (2 * INTSTACK_SIZE), #endif #if CONFIG_SMP_NCPUS > 2 - (uintptr_t)g_irqstack_alloc + (3 * INTSTACK_SIZE) - 8, + (uintptr_t)g_irqstack_alloc + (3 * INTSTACK_SIZE), #endif #if CONFIG_SMP_NCPUS > 3 - (uintptr_t)g_irqstack_alloc + (4 * INTSTACK_SIZE) - 8 + (uintptr_t)g_irqstack_alloc + (4 * INTSTACK_SIZE) #endif }; @@ -215,6 +215,6 @@ uintptr_t arm_intstack_base(void) #if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 7 uintptr_t arm_intstack_alloc(void) { - return g_irqstack_top[up_cpu_index()] - (INTSTACK_SIZE - 8); + return g_irqstack_top[up_cpu_index()] - INTSTACK_SIZE; } #endif