mirror of
https://github.com/apache/nuttx.git
synced 2026-05-21 04:52:02 +08:00
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 <zhangyu117@xiaomi.com>
This commit is contained in:
committed by
Alan C. Assis
parent
641d52fefa
commit
909e63b63b
@@ -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
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
/****************************************************************************
|
||||
|
||||
+4
-2
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user