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