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;

Reply via email to