This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 909e63b63bad4dd87aa26addf5110d9713427958 Author: zhangyu117 <[email protected]> AuthorDate: Mon Dec 16 11:28:03 2024 +0800 arch/tricore: upcsa/lowcsa process && dumpinfo tricore csa is not continuous. when assert prints information, we need to handle the regs specially in order to dump all the registers. Signed-off-by: zhangyu117 <[email protected]> --- arch/Kconfig | 7 ++ arch/tricore/include/irq.h | 16 ++--- arch/tricore/include/tc3xx/irq.h | 5 +- arch/tricore/src/common/tricore_csa.c | 4 +- arch/tricore/src/common/tricore_registerdump.c | 82 ++++++++++++++++++++--- arch/tricore/src/common/tricore_saveusercontext.c | 31 ++++++++- arch/tricore/src/common/tricore_trapcall.c | 11 +++ include/nuttx/arch.h | 10 +++ sched/misc/assert.c | 6 +- 9 files changed, 148 insertions(+), 24 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index ea801c57f5c..597a0490de8 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -200,6 +200,7 @@ config ARCH_TRICORE select ARCH_HAVE_STACKCHECK select ARCH_HAVE_CUSTOMOPT select ARCH_HAVE_TCBINFO + select ARCH_HAVE_REGCPY ---help--- Infineon 32-bit AURIX TriCore architectures @@ -1134,6 +1135,12 @@ config ARCH_STACKDUMP ---help--- Enable to do stack dumps after assertions +config ARCH_HAVE_REGCPY + bool "common copy of cpu regs" + default n + ---help--- + Supports context data copying with different architectures + config ARCH_STACKDUMP_MAX_LENGTH int "The maximum length for dump stack on assertions" depends on ARCH_STACKDUMP diff --git a/arch/tricore/include/irq.h b/arch/tricore/include/irq.h index f1018dcb667..9f357334229 100644 --- a/arch/tricore/include/irq.h +++ b/arch/tricore/include/irq.h @@ -196,18 +196,18 @@ static inline_function bool up_interrupt_context(void) static inline_function uintptr_t up_getusrsp(void *regs) { - uintptr_t *csa = regs; - uintptr_t pcxi = tricore_addr2csa(csa); + uintptr_t *csaregs = regs; - while ((pcxi & PCXI_UL) == 0) + if (csaregs[REG_LPCXI] & PCXI_UL) { - csa = tricore_csa2addr(csa[REG_UPCXI]); - pcxi = csa[REG_UPCXI]; + csaregs = tricore_csa2addr(csaregs[REG_LPCXI]); + } + else + { + csaregs += TC_CONTEXT_REGS; } - csa = tricore_csa2addr(pcxi); - - return csa[REG_SP]; + return csaregs[REG_SP]; } #endif /* __ASSEMBLY__ */ diff --git a/arch/tricore/include/tc3xx/irq.h b/arch/tricore/include/tc3xx/irq.h index d7b7b399540..a9b76965b68 100644 --- a/arch/tricore/include/tc3xx/irq.h +++ b/arch/tricore/include/tc3xx/irq.h @@ -83,9 +83,10 @@ #define REG_LPC REG_LA11 #define TC_CONTEXT_REGS (16) +#define TC_CONTEXT_SIZE (sizeof(void *) * TC_CONTEXT_REGS) -#define XCPTCONTEXT_REGS (TC_CONTEXT_REGS) -#define XCPTCONTEXT_SIZE (sizeof(void *) * TC_CONTEXT_REGS) +#define XCPTCONTEXT_REGS (TC_CONTEXT_REGS * 2) +#define XCPTCONTEXT_SIZE (sizeof(void *) * XCPTCONTEXT_REGS) #define NR_IRQS (255) diff --git a/arch/tricore/src/common/tricore_csa.c b/arch/tricore/src/common/tricore_csa.c index d1c782ec2ed..d68ea4ae215 100644 --- a/arch/tricore/src/common/tricore_csa.c +++ b/arch/tricore/src/common/tricore_csa.c @@ -64,8 +64,8 @@ uintptr_t *tricore_alloc_csa(uintptr_t pc, uintptr_t sp, __isync(); - memset(pucsa, 0, XCPTCONTEXT_SIZE); - memset(plcsa, 0, XCPTCONTEXT_SIZE); + memset(pucsa, 0, TC_CONTEXT_SIZE); + memset(plcsa, 0, TC_CONTEXT_SIZE); pucsa[REG_SP] = sp; pucsa[REG_PSW] = psw; diff --git a/arch/tricore/src/common/tricore_registerdump.c b/arch/tricore/src/common/tricore_registerdump.c index 36c65628940..116cac3046c 100644 --- a/arch/tricore/src/common/tricore_registerdump.c +++ b/arch/tricore/src/common/tricore_registerdump.c @@ -39,6 +39,60 @@ * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: tricore_upcsa_register + ****************************************************************************/ + +void tricore_upcsa_register(volatile uint32_t *regs) +{ + _alert("UPCXI:%08x PSW:%08x SP:%08x PC:%08x\n", + regs[REG_UPCXI], regs[REG_PSW], regs[REG_A10], regs[REG_UA11]); + _alert("D8:%08x D9:%08x D10:%08x D11:%08x\n", + regs[REG_D8], regs[REG_D9], regs[REG_D10], regs[REG_D11]); + _alert("A12:%08x A13:%08x A14:%08x A15:%08x\n", + regs[REG_A12], regs[REG_A13], regs[REG_A14], regs[REG_A15]); + _alert("D12:%08x D13:%08x D14:%08x D15:%08x\n\n", + regs[REG_D12], regs[REG_D13], regs[REG_D14], regs[REG_D15]); +} + +/**************************************************************************** + * Name: tricore_lowcsa_register + ****************************************************************************/ + +void tricore_lowcsa_register(volatile uint32_t *regs) +{ + _alert("LPCXI:%08x A11:%08x A2:%08x A3:%08x\n", + regs[REG_LPCXI] | PCXI_UL, regs[REG_LA11], + regs[REG_A2], regs[REG_A3]); + _alert("D0:%08x D1:%08x D2:%08x D3:%08x\n", + regs[REG_D0], regs[REG_D1], regs[REG_D2], regs[REG_D3]); + _alert("A4:%08x A5:%08x A6:%08x A7:%08x\n", + regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]); + _alert("D4:%08x D5:%08x D6:%08x D7:%08x\n\n", + regs[REG_D4], regs[REG_D5], regs[REG_D6], regs[REG_D7]); +} + +/**************************************************************************** + * Name: tricore_csachain_dump + ****************************************************************************/ + +void tricore_csachain_dump(uintptr_t pcxi) +{ + while (pcxi & FCX_FREE) + { + if (pcxi & PCXI_UL) + { + tricore_upcsa_register(tricore_csa2addr(pcxi)); + } + else + { + tricore_lowcsa_register(tricore_csa2addr(pcxi)); + } + + pcxi = tricore_csa2addr(pcxi)[0]; + } +} + /**************************************************************************** * Name: up_dump_register ****************************************************************************/ @@ -47,12 +101,24 @@ void up_dump_register(void *dumpregs) { volatile uint32_t *regs = dumpregs; - _alert("PCXI:%08x PSW:%08x SP:%08x PC:%08x\n", - regs[REG_UPCXI], regs[REG_PSW], regs[REG_A10], regs[REG_UA11]); - _alert("D8:%08x D9:%08x D10:%08x D11:%08x\n", - regs[REG_D8], regs[REG_D9], regs[REG_D10], regs[REG_D11]); - _alert("A12:%08x A13:%08x A14:%08x A15:%08x\n", - regs[REG_A12], regs[REG_A13], regs[REG_A14], regs[REG_A15]); - _alert("D12:%08x D13:%08x D14:%08x D15:%08x\n\n", - regs[REG_D12], regs[REG_D13], regs[REG_D14], regs[REG_D15]); + tricore_lowcsa_register(regs); + + tricore_upcsa_register(regs + TC_CONTEXT_REGS); +} + +/**************************************************************************** + * Name: up_regs_memcpy + ****************************************************************************/ + +void up_regs_memcpy(FAR void *dest, FAR void *src, size_t count) +{ + int csa_size = TC_CONTEXT_REGS * sizeof(uintptr_t); + int csa_num = count / csa_size; + + while (csa_num--) + { + memcpy(dest, src, csa_size); + dest = (char *)dest + csa_size; + src = tricore_csa2addr(((uintptr_t *)src)[REG_LPCXI]); + } } diff --git a/arch/tricore/src/common/tricore_saveusercontext.c b/arch/tricore/src/common/tricore_saveusercontext.c index c2b6152305b..25a46f82017 100644 --- a/arch/tricore/src/common/tricore_saveusercontext.c +++ b/arch/tricore/src/common/tricore_saveusercontext.c @@ -32,6 +32,10 @@ * Pre-processor Definitions ****************************************************************************/ +/**************************************************************************** + * Public Data + ****************************************************************************/ + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -46,7 +50,30 @@ int up_saveusercontext(void *saveregs) { - uintptr_t *regs = tricore_csa2addr(__mfcr(CPU_PCXI)); - memcpy(saveregs, regs, XCPTCONTEXT_SIZE); + uintptr_t *regs; + uintptr_t pcxi; + int csa_size = TC_CONTEXT_REGS * sizeof(uintptr_t); + + pcxi = __mfcr(CPU_PCXI); + regs = tricore_csa2addr(pcxi); + memcpy((char *)saveregs + csa_size, regs, csa_size); + + /* to unify the trap processing, extra save lowcsa */ + + __asm("svlcx"); + + regs = tricore_csa2addr(__mfcr(CPU_PCXI)); + memcpy(saveregs, regs, csa_size); + + /* lowcsa[REG_LPCXI] saves the upcsa's pcxi, but if lowcsa and upcsa is + * stored at continuous addresses, pcxi has no meaning. Use PCXI_UL + * without marking whether it is lowcsa or upcsa, but to mark whether + * lowcsa and upcsa is stored at continuous addresses. + */ + + ((uintptr_t *)saveregs)[REG_LPCXI] = pcxi & (~PCXI_UL); + + __asm("rslcx"); + return 0; } diff --git a/arch/tricore/src/common/tricore_trapcall.c b/arch/tricore/src/common/tricore_trapcall.c index 5420020c900..d6b8d1a2663 100644 --- a/arch/tricore/src/common/tricore_trapcall.c +++ b/arch/tricore/src/common/tricore_trapcall.c @@ -282,11 +282,22 @@ int tricore_assertiontrap(uint32_t tid, void *context, void *arg) void tricore_trapcall(volatile void *trap) { uintptr_t *regs; + uintptr_t pcxi; + IfxCpu_Trap *ctrap = (IfxCpu_Trap *)trap; IfxCpu_Trap_Class tclass = (IfxCpu_Trap_Class)ctrap->tClass; unsigned int tid = ctrap->tId; regs = tricore_csa2addr(__mfcr(CPU_PCXI)); + pcxi = regs[REG_UPCXI]; + regs = tricore_csa2addr(pcxi); + + if (!up_interrupt_context()) + { + /* Update the current task's regs */ + + g_running_tasks[this_cpu()]->xcp.regs = regs; + } up_set_interrupt_context(true); diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 7f5d39a7bab..8e645423382 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -2913,6 +2913,16 @@ bool up_fpucmp(FAR const void *saveregs1, FAR const void *saveregs2); #define up_fpucmp(r1, r2) (true) #endif +/**************************************************************************** + * Name: up_regs_memcpy + ****************************************************************************/ + +#ifdef CONFIG_ARCH_HAVE_REGCPY +void up_regs_memcpy(FAR void *dest, FAR void *src, size_t count); +#else +#define up_regs_memcpy(dest, src, count) memcpy(dest, src, count) +#endif + #ifdef CONFIG_ARCH_HAVE_DEBUG /**************************************************************************** diff --git a/sched/misc/assert.c b/sched/misc/assert.c index 0c89d62a7df..a5cd333d697 100644 --- a/sched/misc/assert.c +++ b/sched/misc/assert.c @@ -611,7 +611,8 @@ static void dump_deadlock(void) static noreturn_function int pause_cpu_handler(FAR void *arg) { - memcpy(g_last_regs[this_cpu()], running_regs(), sizeof(g_last_regs[0])); + up_regs_memcpy(g_last_regs[this_cpu()], running_regs(), + sizeof(g_last_regs[0])); g_cpu_paused[this_cpu()] = true; up_flush_dcache_all(); while (1); @@ -877,7 +878,8 @@ void _assert(FAR const char *filename, int linenum, } else { - memcpy(g_last_regs[this_cpu()], regs, sizeof(g_last_regs[0])); + up_regs_memcpy(g_last_regs[this_cpu()], regs, sizeof(g_last_regs[0])); + regs = g_last_regs[this_cpu()]; } notifier_data.rtcb = rtcb;
