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 <Masayuki.Ishikawa@jp.sony.com>
This commit is contained in:
Masayuki Ishikawa 2020-10-22 10:06:05 +09:00 committed by David Sidrane
parent d550e39b9e
commit 6e12f3c782
3 changed files with 21 additions and 24 deletions

View File

@ -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.
*/

View File

@ -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

View File

@ -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