You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/09/16 02:32:44 UTC

[incubator-nuttx] branch master updated (44cbba2 -> cdb441c)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


    from 44cbba2  drivers/sdmmc: Remove rwbuffer to avoid panic
     new 583dce0  arch:xtensa: remove WSBITS/WBBITS to core.h
     new 3acdbef  xtensa:arch: force up_getsp to inline
     new 6e0f84d  arch:xtensa: add up_backtrace support
     new cdb441c  arch:xtensa:dumpstate: use sched_dumpstack

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 arch/xtensa/include/arch.h                  |   1 +
 arch/xtensa/include/xtensa/core.h           |   6 +
 arch/xtensa/src/common/xtensa_backtrace.c   | 287 ++++++++++++++++++++++++++++
 arch/xtensa/src/common/xtensa_dumpstate.c   | 123 +-----------
 arch/xtensa/src/common/xtensa_windowspill.S |   3 +-
 5 files changed, 305 insertions(+), 115 deletions(-)
 create mode 100644 arch/xtensa/src/common/xtensa_backtrace.c

[incubator-nuttx] 04/04: arch:xtensa:dumpstate: use sched_dumpstack

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit cdb441cc3ff78f4c6dbc2268f2acbc66dcbc8196
Author: zhuyanlin <zh...@xiaomi.com>
AuthorDate: Wed Sep 15 15:01:34 2021 +0800

    arch:xtensa:dumpstate: use sched_dumpstack
    
    Use sched_dumpstack instead. The backtrace infomation like
    
    xtensa_user_panic: User Exception: EXCCAUSE=0009 task: hello
    xtensa_registerdump:    PC: 202b32b8    PS: 00060030
    xtensa_registerdump:    A0: a02acb87    A1: 20998d10    A2: ffffaaaa    A3: 12345678
    xtensa_registerdump:    A4: a02ba26c    A5: 209949c0    A6: 20990994    A7: 00000258
    xtensa_registerdump:    A8: a02b32af    A9: 20998cb0   A10: 0000000f   A11: 209949a0
    xtensa_registerdump:   A12: a02be95c   A13: 20994980   A14: 00000003   A15: 209949d0
    xtensa_registerdump:   SAR: 00000000 CAUSE: 00000009 VADDR: ffffaaaa
    xtensa_registerdump:  LBEG: 00000000  LEND: 00000000  LCNT: 00000000
    xtensa_registerdump:  TMP0: 202b1512  TMP1: 20998af0
    sched_dumpstack: [BackTrace| 3|0]:  0x202acbae 0x202b232e 0x202b1912 0x202b19f5 0x202b24f1 0x202b152f    0x40023 0x202b32b0
    sched_dumpstack: [BackTrace| 3|1]:  0x202acb87 0x202a86a4
    
    Signed-off-by: zhuyanlin <zh...@xiaomi.com>
---
 arch/xtensa/src/common/xtensa_dumpstate.c | 123 +++---------------------------
 1 file changed, 10 insertions(+), 113 deletions(-)

diff --git a/arch/xtensa/src/common/xtensa_dumpstate.c b/arch/xtensa/src/common/xtensa_dumpstate.c
index fc93f9c..6627556 100644
--- a/arch/xtensa/src/common/xtensa_dumpstate.c
+++ b/arch/xtensa/src/common/xtensa_dumpstate.c
@@ -69,6 +69,13 @@ static void up_taskdump(FAR struct tcb_s *tcb, FAR void *arg)
         tcb->pid, (unsigned long)up_check_tcbstack(tcb),
         (unsigned long)tcb->adj_stack_size);
 #endif
+
+  /* Dump the backtrace */
+
+#if defined(CONFIG_XTENSA_DUMPBT_ON_ASSERT) && \
+    defined(CONFIG_SCHED_BACKTRACE)
+  sched_dumpstack(rtcb->pid);
+#endif
 }
 #endif
 
@@ -150,117 +157,6 @@ static inline void xtensa_registerdump(void)
 #endif
 }
 
-#ifdef CONFIG_XTENSA_DUMPBT_ON_ASSERT
-
-/****************************************************************************
- * Name: xtensa_getcause
- ****************************************************************************/
-
-static inline uint32_t xtensa_getcause(void)
-{
-  uint32_t cause;
-
-  __asm__ __volatile__
-  (
-    "rsr %0, EXCCAUSE"  : "=r"(cause)
-  );
-
-  return cause;
-}
-
-/****************************************************************************
- * Name: stackpc
- ****************************************************************************/
-
-static inline uint32_t stackpc(uint32_t pc)
-{
-  if (pc & 0x80000000)
-    {
-      /* Top two bits of a0 (return address) specify window increment.
-       * Overwrite to map to address space.
-       */
-
-      pc = (pc & 0x3fffffff) | 0x40000000;
-    }
-
-  /* Minus 3 to get PC of previous instruction (i.e. instruction executed
-   * before return address).
-   */
-
-  return pc - 3;
-}
-
-/****************************************************************************
- * Name: corruptedframe
- ****************************************************************************/
-
-static inline bool corruptedframe(uint32_t pc, uint32_t sp)
-{
-  return !(xtensa_ptr_exec((void *)stackpc(pc)) || xtensa_sp_sane(sp));
-}
-
-/****************************************************************************
- * Name: nextframe
- ****************************************************************************/
-
-static bool nextframe(uint32_t *pc, uint32_t *sp, uint32_t *npc)
-{
-  /* Use frame(i - 1)'s base save area located below frame(i)'s sp to get
-   * frame(i - 1)'s sp and frame(i - 2)'s pc. Base save area consists of
-   * 4 words under SP.
-   */
-
-  void *bsa = (void *)*sp;
-
-  *pc  = *npc;
-  *npc = *((uint32_t *)(bsa - 16));
-  *sp  = *((uint32_t *)(bsa - 12));
-
-  return !corruptedframe(*pc, *sp);
-}
-
-/****************************************************************************
- * Name: xtensa_btdump
- ****************************************************************************/
-
-static inline void xtensa_btdump(void)
-{
-  uint32_t pc;
-  uint32_t sp;
-  uint32_t npc;
-  int i;
-  bool corrupted = false;
-
-  uint32_t *regs = (uint32_t *)CURRENT_REGS;
-
-  pc  = regs[REG_PC];
-  npc = regs[REG_A0]; /* return register */
-  sp  = regs[REG_A1]; /* stack pointer */
-
-  _alert("Backtrace0: %x:%x\n", stackpc(pc), sp);
-
-  corrupted = corruptedframe(pc, sp) &&
-              !(xtensa_getcause() == EXCCAUSE_INSTR_PROHIBITED);
-
-  for (i = 1; i <= CONFIG_XTENSA_BTDEPTH && npc != 0 && !corrupted; i++)
-    {
-      if (!nextframe(&pc, &sp, &npc))
-        {
-          corrupted = true;
-        }
-
-      _alert("Backtrace%d: %x:%x\n", i, stackpc(pc), sp);
-    }
-
-  _alert("BACKTRACE %s\n",
-         (corrupted ? "CORRUPTED!" : (npc == 0 ? "Done":"CONTINUES...")));
-}
-#endif /* CONFIG_XTENSA_DUMPBT_ON_ASSERT */
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
 /****************************************************************************
  * Name: xtensa_dumpstate
  ****************************************************************************/
@@ -288,8 +184,9 @@ void xtensa_dumpstate(void)
 
   /* Dump the backtrace */
 
-#ifdef CONFIG_XTENSA_DUMPBT_ON_ASSERT
-  xtensa_btdump();
+#if defined(CONFIG_XTENSA_DUMPBT_ON_ASSERT) && \
+    defined(CONFIG_SCHED_BACKTRACE)
+  sched_dumpstack(rtcb->pid);
 #endif
 
   /* Get the limits on the user stack memory */

[incubator-nuttx] 02/04: xtensa:arch: force up_getsp to inline

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 3acdbef60d23f1196c233352d991f30b69d9714f
Author: zhuyanlin <zh...@xiaomi.com>
AuthorDate: Wed Sep 15 14:55:27 2021 +0800

    xtensa:arch: force up_getsp to inline
    
    Up_getsp may be not inline in gcc, thus get the sp
    is up_getsp function's sp, not the caller function.
    
    Signed-off-by: zhuyanlin <zh...@xiaomi.com>
---
 arch/xtensa/include/arch.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/xtensa/include/arch.h b/arch/xtensa/include/arch.h
index a96fc1a..7b40c4b 100644
--- a/arch/xtensa/include/arch.h
+++ b/arch/xtensa/include/arch.h
@@ -47,6 +47,7 @@
  * Name: up_getsp
  ****************************************************************************/
 
+static inline uint32_t up_getsp(void) inline_function;
 static inline uint32_t up_getsp(void)
 {
   register uint32_t sp;

[incubator-nuttx] 03/04: arch:xtensa: add up_backtrace support

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 6e0f84dc88b92b5280721c7b7f8bb3e6e6a02289
Author: zhuyanlin <zh...@xiaomi.com>
AuthorDate: Wed Sep 15 15:00:04 2021 +0800

    arch:xtensa: add up_backtrace support
    
    Up_backtrace can be backtrace from task or interrupt.
    
    Signed-off-by: zhuyanlin <zh...@xiaomi.com>
---
 arch/xtensa/src/common/xtensa_backtrace.c | 287 ++++++++++++++++++++++++++++++
 1 file changed, 287 insertions(+)

diff --git a/arch/xtensa/src/common/xtensa_backtrace.c b/arch/xtensa/src/common/xtensa_backtrace.c
new file mode 100644
index 0000000..27efd03
--- /dev/null
+++ b/arch/xtensa/src/common/xtensa_backtrace.c
@@ -0,0 +1,287 @@
+/****************************************************************************
+ * arch/xtensa/src/common/xtensa_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <arch/irq.h>
+#include <arch/xtensa/core.h>
+
+#include "sched/sched.h"
+#include "xtensa.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Convert return address to a valid pc  */
+
+#define MAKE_PC_FROM_RA(ra)    ((ra) & 0x3fffffff)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+#ifndef __XTENSA_CALL0_ABI__
+struct xtensa_windowregs_s
+{
+  uint32_t windowbase;
+  uint32_t windowstart;
+  uint32_t areg[16];
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: get_window_regs
+ *
+ * Description:
+ *  getfp() returns current frame pointer
+ *
+ ****************************************************************************/
+
+#ifndef __XTENSA_CALL0_ABI__
+static void get_window_regs(struct xtensa_windowregs_s *frame)
+inline_function
+{
+  __asm__ __volatile__("\trsr %0, WINDOWSTART\n": "=r"(frame->windowstart));
+  __asm__ __volatile__("\trsr %0, WINDOWBASE\n": "=r"(frame->windowbase));
+
+  __asm__ __volatile__("\tmov %0, a0\n": "=r"(frame->areg[0]));
+  __asm__ __volatile__("\tmov %0, a1\n": "=r"(frame->areg[1]));
+  __asm__ __volatile__("\tmov %0, a2\n": "=r"(frame->areg[2]));
+  __asm__ __volatile__("\tmov %0, a3\n": "=r"(frame->areg[3]));
+  __asm__ __volatile__("\tmov %0, a4\n": "=r"(frame->areg[4]));
+  __asm__ __volatile__("\tmov %0, a5\n": "=r"(frame->areg[5]));
+  __asm__ __volatile__("\tmov %0, a6\n": "=r"(frame->areg[6]));
+  __asm__ __volatile__("\tmov %0, a7\n": "=r"(frame->areg[7]));
+  __asm__ __volatile__("\tmov %0, a8\n": "=r"(frame->areg[8]));
+  __asm__ __volatile__("\tmov %0, a9\n": "=r"(frame->areg[9]));
+  __asm__ __volatile__("\tmov %0, a10\n": "=r"(frame->areg[10]));
+  __asm__ __volatile__("\tmov %0, a11\n": "=r"(frame->areg[11]));
+  __asm__ __volatile__("\tmov %0, a12\n": "=r"(frame->areg[12]));
+  __asm__ __volatile__("\tmov %0, a13\n": "=r"(frame->areg[13]));
+  __asm__ __volatile__("\tmov %0, a14\n": "=r"(frame->areg[14]));
+  __asm__ __volatile__("\tmov %0, a15\n": "=r"(frame->areg[15]));
+}
+#endif
+
+/****************************************************************************
+ * Name: backtrace_window
+ *
+ * Description:
+ *  backtrace_window() parsing the return address in register window
+ *
+ ****************************************************************************/
+
+#ifndef __XTENSA_CALL0_ABI__
+static int backtrace_window(FAR uintptr_t *base, FAR uintptr_t *limit,
+                     struct xtensa_windowregs_s *frame,
+                     FAR void **buffer, int size)
+{
+  uint32_t windowstart;
+  uint32_t ra;
+  uint32_t sp;
+  int index;
+  int i;
+
+  /* Rotate WINDOWSTART to move the bit corresponding to
+   * the current window to the bit #0
+   */
+
+  windowstart = (frame->windowstart << WSBITS | frame->windowstart) >>
+        frame->windowbase;
+
+  /* Look for bits that are set, they correspond to valid windows. */
+
+  for (i = 0, index = WSBITS - 1; (index > 0) && (i < size); index--)
+    {
+      if (windowstart & (1 << index))
+        {
+          ra = frame->areg[index * 4];
+          sp = frame->areg[index * 4 + 1];
+
+          if (sp > limit || sp < base || ra == 0)
+            {
+              continue;
+            }
+
+          buffer[i++] = MAKE_PC_FROM_RA(ra);
+        }
+    }
+
+  return i;
+}
+#endif
+
+/****************************************************************************
+ * Name: backtrace_stack
+ *
+ * Description:
+ * backtrace_stack() parsing the return address in stack
+ *
+ ****************************************************************************/
+
+static int backtrace_stack(FAR uintptr_t *base, FAR uintptr_t *limit,
+                     FAR uintptr_t *sp, FAR uintptr_t *ra,
+                     FAR void **buffer, int size)
+{
+  int i = 0;
+
+  if (ra)
+    {
+      buffer[i++] = MAKE_PC_FROM_RA((uintptr_t)ra);
+    }
+
+  for (; i < size; sp = (FAR uintptr_t *)*(sp - 3), i++)
+    {
+      if (sp > limit || sp < base)
+        {
+          break;
+        }
+
+      ra = (FAR uintptr_t *)*(sp - 4);
+      if (ra == NULL)
+        {
+          break;
+        }
+
+      buffer[i] = MAKE_PC_FROM_RA((uintptr_t)ra);
+    }
+
+  return i;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_backtrace
+ *
+ * Description:
+ *  up_backtrace()  returns  a backtrace for the TCB, in the array
+ *  pointed to by buffer.  A backtrace is the series of currently active
+ *  function calls for the program.  Each item in the array pointed to by
+ *  buffer is of type void *, and is the return address from the
+ *  corresponding stack frame.  The size argument specifies the maximum
+ *  number of addresses that can be stored in buffer.   If  the backtrace is
+ *  larger than size, then the addresses corresponding to the size most
+ *  recent function calls are returned; to obtain the complete backtrace,
+ *  make sure that buffer and size are large enough.
+ *
+ * Input Parameters:
+ *   tcb    - Address of the task's TCB
+ *   buffer - Return address from the corresponding stack frame
+ *   size   - Maximum number of addresses that can be stored in buffer
+ *
+ * Returned Value:
+ *   up_backtrace() returns the number of addresses returned in buffer
+ *
+ ****************************************************************************/
+
+int up_backtrace(FAR struct tcb_s *tcb, FAR void **buffer, int size)
+{
+  FAR struct tcb_s *rtcb = running_task();
+  irqstate_t flags;
+  int ret;
+
+  if (size <= 0 || !buffer)
+    {
+      return 0;
+    }
+
+  if (tcb == NULL || tcb == rtcb)
+    {
+      if (up_interrupt_context())
+        {
+#if CONFIG_ARCH_INTERRUPTSTACK > 15
+          uintptr_t istackbase;
+#ifdef CONFIG_SMP
+          istackbase = xtensa_intstack_alloc();
+#else
+          istackbase = &g_intstackalloc;
+#endif
+          ret = bactrace_stack((FAR void *)istackbase,
+                          (FAR void *)((uint32_t)&g_intstackalloc +
+                                       CONFIG_ARCH_INTERRUPTSTACK),
+                          (FAR void *)up_getsp(), NULL, buffer, size);
+#else
+          ret = backtrace_stack(rtcb->stack_base_ptr,
+                          rtcb->stack_base_ptr + rtcb->adj_stack_size,
+                          (FAR void *)up_getsp(), NULL, buffer, size);
+#endif
+          ret += backtrace_stack(rtcb->stack_base_ptr,
+                          rtcb->stack_base_ptr +
+                          rtcb->adj_stack_size,
+                          (FAR void *)CURRENT_REGS[REG_A1],
+                          (FAR void *)CURRENT_REGS[REG_A0],
+                          &buffer[ret], size - ret);
+        }
+      else
+        {
+          /* Two steps for current task:
+           *
+           * 1. Look through the register window for the
+           * previous PCs in the call trace.
+           *
+           * 2. Look on the stack.
+           */
+
+#ifndef __XTENSA_CALL0_ABI__
+          static struct xtensa_windowregs_s frame;
+
+          xtensa_window_spill();
+
+          get_window_regs(&frame);
+
+          ret = backtrace_window(rtcb->stack_base_ptr,
+                          rtcb->stack_base_ptr + rtcb->adj_stack_size,
+                          &frame, buffer, size);
+#endif
+          ret += backtrace_stack(rtcb->stack_base_ptr,
+                          rtcb->stack_base_ptr + rtcb->adj_stack_size,
+                          (FAR void *)up_getsp(), NULL, buffer, size - ret);
+        }
+    }
+  else
+    {
+      /* For non-current task, only check in stack. */
+
+      flags = enter_critical_section();
+
+      ret = backtrace_stack(tcb->stack_base_ptr,
+                      tcb->stack_base_ptr + tcb->adj_stack_size,
+                      (FAR void *)tcb->xcp.regs[REG_A1],
+                      (FAR void *)tcb->xcp.regs[REG_A0],
+                      buffer, size);
+
+      leave_critical_section(flags);
+    }
+
+  return ret;
+}

[incubator-nuttx] 01/04: arch:xtensa: remove WSBITS/WBBITS to core.h

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 583dce0b981082732a5a4b1a819de3cd72515ed8
Author: zhuyanlin <zh...@xiaomi.com>
AuthorDate: Wed Sep 15 14:50:27 2021 +0800

    arch:xtensa: remove WSBITS/WBBITS to core.h
    
    Remove WSBITS/WBBITS macro to core.h as may be used by
    arch common code.
    
    Signed-off-by: zhuyanlin <zh...@xiaomi.com>
---
 arch/xtensa/include/xtensa/core.h           | 6 ++++++
 arch/xtensa/src/common/xtensa_windowspill.S | 3 +--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/xtensa/include/xtensa/core.h b/arch/xtensa/include/xtensa/core.h
index bf769b9..01112b9 100644
--- a/arch/xtensa/include/xtensa/core.h
+++ b/arch/xtensa/include/xtensa/core.h
@@ -71,6 +71,12 @@
 #  define XCHAL_SEP2                    },{
 #endif
 
+/* WSBITS and WBBITS are the width of the WINDOWSTART and WINDOWBASE
+ * registers
+ */
+#define WSBITS  (XCHAL_NUM_AREGS / 4)      /* width of WINDOWSTART in bits */
+#define WBBITS  (XCHAL_NUM_AREGS_LOG2 - 2) /* width of WINDOWBASE in bits */
+
 /* ISA **********************************************************************/
 
 #if XCHAL_HAVE_BE
diff --git a/arch/xtensa/src/common/xtensa_windowspill.S b/arch/xtensa/src/common/xtensa_windowspill.S
index 9e92ed6..f2d3448 100644
--- a/arch/xtensa/src/common/xtensa_windowspill.S
+++ b/arch/xtensa/src/common/xtensa_windowspill.S
@@ -40,6 +40,7 @@
  ****************************************************************************/
 
 #include <arch/chip/core-isa.h>
+#include <arch/xtensa/core.h>
 #include <arch/xtensa/xtensa_specregs.h>
 #include <arch/xtensa/xtensa_corebits.h>
 
@@ -116,8 +117,6 @@ _xtensa_window_spill:
 	ret
 
 #else /* XCHAL_HAVE_WINDOWED */
-#  define WSBITS  (XCHAL_NUM_AREGS / 4)			/* Width of WINDOWSTART register in bits */
-#  define WBBITS  (XCHAL_NUM_AREGS_LOG2 - 2)	/* Width of WINDOWBASE register in bits */
 
 	/*
 	 * Rearrange (rotate) window start bits relative to the current