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/nuttx.git

commit cdeb720bf8a3b7fd29693c40e36e11cd9633b209
Author: Tiago Medicci Serrano <[email protected]>
AuthorDate: Wed Sep 4 16:25:57 2024 -0300

    xtensa/esp32[|s2|s3]: Fix task backtrace dump
    
    - Fix `MAKE_PC_FROM_RA` macro to consider the instruction region
    base address;
    - Add sanity check for calculated PC and SP registers;
    - Check if the stack pointer is within the interrupt stack to
    enable backtrace dump if an exception occurs during the ISR;
---
 arch/risc-v/src/common/espressif/Make.defs         |  2 +-
 arch/xtensa/include/irq.h                          |  2 +-
 arch/xtensa/src/common/xtensa_backtrace.c          | 28 ++++++++++++++++---
 arch/xtensa/src/common/xtensa_macros.S             | 29 +++++++++++++++++---
 arch/xtensa/src/esp32/Make.defs                    |  4 +--
 arch/xtensa/src/esp32/chip_macros.h                | 31 +++++++++++++++++++---
 arch/xtensa/src/esp32/chip_memory.h                |  8 +++++-
 arch/xtensa/src/esp32s2/Make.defs                  |  4 +--
 arch/xtensa/src/esp32s2/chip_memory.h              |  8 +++++-
 arch/xtensa/src/esp32s3/Make.defs                  |  4 +--
 arch/xtensa/src/esp32s3/chip_macros.h              | 31 +++++++++++++++++++---
 arch/xtensa/src/esp32s3/chip_memory.h              |  8 +++++-
 .../esp32/esp32-wrover-kit/configs/gpio/defconfig  |  1 -
 13 files changed, 133 insertions(+), 27 deletions(-)

diff --git a/arch/risc-v/src/common/espressif/Make.defs 
b/arch/risc-v/src/common/espressif/Make.defs
index 7002bd2b5b..97b24aa1c2 100644
--- a/arch/risc-v/src/common/espressif/Make.defs
+++ b/arch/risc-v/src/common/espressif/Make.defs
@@ -136,7 +136,7 @@ endif
 
 ESP_HAL_3RDPARTY_REPO   = esp-hal-3rdparty
 ifndef ESP_HAL_3RDPARTY_VERSION
-       ESP_HAL_3RDPARTY_VERSION = 20690e67695f0a8170a19ec99e2e9a13b620e94d
+       ESP_HAL_3RDPARTY_VERSION = b4c723a119344b4b71d69819019d55637fb570fd
 endif
 
 ifndef ESP_HAL_3RDPARTY_URL
diff --git a/arch/xtensa/include/irq.h b/arch/xtensa/include/irq.h
index 21ce8f20f4..1d299f428e 100644
--- a/arch/xtensa/include/irq.h
+++ b/arch/xtensa/include/irq.h
@@ -250,7 +250,7 @@ noinstrument_function static inline void 
xtensa_setps(uint32_t ps)
 
 /* Return the current value of the stack pointer */
 
-static inline uint32_t up_getsp(void)
+static inline_function uint32_t up_getsp(void)
 {
   register uint32_t sp;
 
diff --git a/arch/xtensa/src/common/xtensa_backtrace.c 
b/arch/xtensa/src/common/xtensa_backtrace.c
index 8029eba2c8..fb6da7a144 100644
--- a/arch/xtensa/src/common/xtensa_backtrace.c
+++ b/arch/xtensa/src/common/xtensa_backtrace.c
@@ -30,14 +30,29 @@
 
 #include "sched/sched.h"
 #include "xtensa.h"
+#include "chip.h"
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
+/* When the Windowed Register Option is configured, the register-window call
+ * instructions only store the low 30 bits of the return address, enabling
+ * addressing instructions within a 1GB region. To convert the return address
+ * to a valid PC, we need to add the base address of the instruction region.
+ * The following macro is used to define the base address of the 1GB region,
+ * which may not start in 0x00000000. This macro can be overriden in
+ * `chip_memory.h` of the chip directory.
+ */
+
+#ifndef XTENSA_INSTUCTION_REGION
+#  define XTENSA_INSTUCTION_REGION 0x00000000
+#endif
+
 /* Convert return address to a valid pc  */
 
-#define MAKE_PC_FROM_RA(ra)   (uintptr_t *)((ra) & 0x3fffffff)
+#define MAKE_PC_FROM_RA(ra) \
+  (uintptr_t *)(((ra) & 0x3fffffff) | XTENSA_INSTUCTION_REGION)
 
 /****************************************************************************
  * Private Types
@@ -173,17 +188,21 @@ static int backtrace_stack(uintptr_t *base, uintptr_t 
*limit,
 
   while (i < size)
     {
-      ra = (uintptr_t *)*(sp - 4);
+      ra = MAKE_PC_FROM_RA((uintptr_t)(*(sp - 4)));
       sp = (uintptr_t *)*(sp - 3);
 
-      if (sp >= limit || sp < base || ra == NULL)
+      if (!(xtensa_ptr_exec(ra) && xtensa_sp_sane((uintptr_t)sp))
+#if CONFIG_ARCH_INTERRUPTSTACK < 15
+          || sp >= limit || sp < base
+#endif
+         )
         {
           break;
         }
 
       if ((*skip)-- <= 0)
         {
-          buffer[i++] = MAKE_PC_FROM_RA((uintptr_t)ra);
+          buffer[i++] = ra;
         }
     }
 
@@ -250,6 +269,7 @@ int up_backtrace(struct tcb_s *tcb, void **buffer, int 
size, int skip)
                                 (void *)up_getsp(), NULL,
                                 buffer, size, &skip);
 #else
+          xtensa_window_spill();
           ret = backtrace_stack(rtcb->stack_base_ptr,
                                 rtcb->stack_base_ptr + rtcb->adj_stack_size,
                                 (void *)up_getsp(), NULL,
diff --git a/arch/xtensa/src/common/xtensa_macros.S 
b/arch/xtensa/src/common/xtensa_macros.S
index 7b531dc131..de73d49195 100644
--- a/arch/xtensa/src/common/xtensa_macros.S
+++ b/arch/xtensa/src/common/xtensa_macros.S
@@ -42,9 +42,32 @@
  ****************************************************************************/
 
 #if !defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 15
-       .macro  setintstack tmp1 tmp2
-       movi            a1, g_intstacktop
-       .endm
+    .macro     setintstack tmp1 tmp2
+
+       /* Load g_intstacktop (the start of the interrupt stack) */
+
+       movi    \tmp1, g_intstacktop
+
+    /* If a1 < g_intstackalloc (outside the interrupt stack boundary),
+        * set a1 (sp) to g_intstacktop (switch to the interrupt stack).
+        */
+
+       movi    \tmp2, g_intstackalloc  /* Load the end (low address) of the 
interrupt stack */
+    sub                \tmp2, a1, \tmp2
+    movltz     a1, \tmp1, \tmp2
+
+    /* If a1 >= g_intstacktop, sp is outside the interrupt stack boundaries */
+
+       movi    \tmp2, g_intstacktop   /* Load the start (high address) of the 
interrupt stack */
+    sub                \tmp2, a1, \tmp2
+    movgez     a1, \tmp1, \tmp2
+
+       /* If neither movltz and movgez moved g_intstacktop (on /tmp1) to a1,
+        * it means that the stack pointer was already pointing to the interrupt
+        * stack and no action is required.
+        */
+
+    .endm
 #endif
 
 /****************************************************************************
diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs
index 983e6d7aac..740b9de033 100644
--- a/arch/xtensa/src/esp32/Make.defs
+++ b/arch/xtensa/src/esp32/Make.defs
@@ -213,7 +213,7 @@ endif
 
 ESP_HAL_3RDPARTY_REPO   = esp-hal-3rdparty
 ifndef ESP_HAL_3RDPARTY_VERSION
-       ESP_HAL_3RDPARTY_VERSION = 20690e67695f0a8170a19ec99e2e9a13b620e94d
+       ESP_HAL_3RDPARTY_VERSION = b4c723a119344b4b71d69819019d55637fb570fd
 endif
 
 ifndef ESP_HAL_3RDPARTY_URL
@@ -246,7 +246,7 @@ chip/$(ESP_HAL_3RDPARTY_REPO):
 
 # Silent preprocessor warnings
 
-CFLAGS += -Wno-undef -Wno-unused-variable
+CFLAGS += -Wno-undef -Wno-unused-variable -fno-jump-tables 
-fno-tree-switch-conversion
 
 # Enable strict volatile bitfield access
 
diff --git a/arch/xtensa/src/esp32/chip_macros.h 
b/arch/xtensa/src/esp32/chip_macros.h
index 2a68cedf45..d7a06e424c 100644
--- a/arch/xtensa/src/esp32/chip_macros.h
+++ b/arch/xtensa/src/esp32/chip_macros.h
@@ -120,10 +120,33 @@
 
 #if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 15
     .macro setintstack tmp1 tmp2
-    getcoreid \tmp1                   /* tmp1 = Core ID (0 or 1) */
-    movi  \tmp2, g_cpu_intstack_top   /* tmp2 = Array of stack pointers */
-    addx4 \tmp2, \tmp1, \tmp2         /* tmp2 = tmp2 + (tmp1 << 2) */
-    l32i  a1, \tmp2, 0                /* a1   = *tmp2 */
+    getcoreid \tmp1                     /* tmp1 = Core ID (0 or 1) */
+    movi  \tmp2, g_cpu_intstack_top     /* tmp2 = Array of stack pointers */
+    addx4 \tmp2, \tmp1, \tmp2           /* tmp2 = tmp2 + (tmp1 << 2) */
+    l32i  \tmp1, \tmp2, 0               /* Load the top of the interrupt stack 
for this core */
+
+  /* tmp1 represents the top of the interrupt stack for this core
+   * If a1 >= tmp1, sp is outside the interrupt stack boundaries.
+   */
+
+    l32i    \tmp2, \tmp2, 0             /* Load the top of the interrupt stack 
for this core */
+    sub     \tmp2, a1, \tmp2
+    movgez  a1, \tmp1, \tmp2
+
+  /* If a1 < (tmp1 - INTSTACK_SIZE), sp is outside the interrupt stack
+   * boundaries.
+   */
+
+    movi    \tmp2, CONFIG_ARCH_INTERRUPTSTACK
+    sub     \tmp2, \tmp1, \tmp2
+    sub     \tmp2, a1, \tmp2
+    movltz  a1, \tmp1, \tmp2
+
+  /* If neither movltz and movgez moved the top of the interrupt stack to
+   * a1, it means that the stack pointer was already pointing to the
+   * interrupt stack and no action is required.
+   */
+
     .endm
 #endif
 
diff --git a/arch/xtensa/src/esp32/chip_memory.h 
b/arch/xtensa/src/esp32/chip_memory.h
index 91b513d862..0636213ef1 100644
--- a/arch/xtensa/src/esp32/chip_memory.h
+++ b/arch/xtensa/src/esp32/chip_memory.h
@@ -29,6 +29,12 @@
 #include "hardware/esp32_soc.h"
 #endif
 
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define XTENSA_INSTUCTION_REGION 0x40000000
+
 /****************************************************************************
  * Inline Functions
  ****************************************************************************/
@@ -48,7 +54,7 @@ extern "C"
 
 static inline bool xtensa_sp_sane(uint32_t sp)
 {
-  return (esp32_sp_dram(sp) && ((sp & 0x0f) == 0));
+  return esp32_sp_dram(sp);
 }
 
 /****************************************************************************
diff --git a/arch/xtensa/src/esp32s2/Make.defs 
b/arch/xtensa/src/esp32s2/Make.defs
index 29b74def1f..840ea0cdcf 100644
--- a/arch/xtensa/src/esp32s2/Make.defs
+++ b/arch/xtensa/src/esp32s2/Make.defs
@@ -145,7 +145,7 @@ endif
 
 ESP_HAL_3RDPARTY_REPO   = esp-hal-3rdparty
 ifndef ESP_HAL_3RDPARTY_VERSION
-       ESP_HAL_3RDPARTY_VERSION = 20690e67695f0a8170a19ec99e2e9a13b620e94d
+       ESP_HAL_3RDPARTY_VERSION = b4c723a119344b4b71d69819019d55637fb570fd
 endif
 
 ifndef ESP_HAL_3RDPARTY_URL
@@ -171,7 +171,7 @@ chip/$(ESP_HAL_3RDPARTY_REPO):
 
 # Silent preprocessor warnings
 
-CFLAGS += -Wno-undef -Wno-unused-variable
+CFLAGS += -Wno-undef -Wno-unused-variable -fno-jump-tables 
-fno-tree-switch-conversion
 
 # Enable strict volatile bitfield access
 
diff --git a/arch/xtensa/src/esp32s2/chip_memory.h 
b/arch/xtensa/src/esp32s2/chip_memory.h
index b4d42826f3..f3180cb6f4 100644
--- a/arch/xtensa/src/esp32s2/chip_memory.h
+++ b/arch/xtensa/src/esp32s2/chip_memory.h
@@ -29,6 +29,12 @@
 #include "hardware/esp32s2_soc.h"
 #endif
 
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define XTENSA_INSTUCTION_REGION 0x40000000
+
 /****************************************************************************
  * Inline Functions
  ****************************************************************************/
@@ -48,7 +54,7 @@ extern "C"
 
 static inline bool xtensa_sp_sane(uint32_t sp)
 {
-  return (esp32s2_sp_dram(sp) && ((sp & 0x0f) == 0));
+  return esp32s2_sp_dram(sp);
 }
 
 /****************************************************************************
diff --git a/arch/xtensa/src/esp32s3/Make.defs 
b/arch/xtensa/src/esp32s3/Make.defs
index 5fed43a911..6fadf64279 100644
--- a/arch/xtensa/src/esp32s3/Make.defs
+++ b/arch/xtensa/src/esp32s3/Make.defs
@@ -211,7 +211,7 @@ endif
 
 ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty
 ifndef ESP_HAL_3RDPARTY_VERSION
-       ESP_HAL_3RDPARTY_VERSION = 20690e67695f0a8170a19ec99e2e9a13b620e94d
+       ESP_HAL_3RDPARTY_VERSION = b4c723a119344b4b71d69819019d55637fb570fd
 endif
 
 ifndef ESP_HAL_3RDPARTY_URL
@@ -244,7 +244,7 @@ chip/$(ESP_HAL_3RDPARTY_REPO):
 
 # Silent preprocessor warnings
 
-CFLAGS += -Wno-undef -Wno-unused-variable
+CFLAGS += -Wno-undef -Wno-unused-variable -fno-jump-tables 
-fno-tree-switch-conversion
 CFLAGS += ${DEFINE_PREFIX}_RETARGETABLE_LOCKING
 
 # Enable strict volatile bitfield access
diff --git a/arch/xtensa/src/esp32s3/chip_macros.h 
b/arch/xtensa/src/esp32s3/chip_macros.h
index 658789489f..652d95a3a3 100644
--- a/arch/xtensa/src/esp32s3/chip_macros.h
+++ b/arch/xtensa/src/esp32s3/chip_macros.h
@@ -104,10 +104,33 @@
 
 #if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 15
     .macro setintstack tmp1 tmp2
-    getcoreid \tmp1                   /* tmp1 = Core ID (0 or 1) */
-    movi  \tmp2, g_cpu_intstack_top   /* tmp2 = Array of stack pointers */
-    addx4 \tmp2, \tmp1, \tmp2         /* tmp2 = tmp2 + (tmp1 << 2) */
-    l32i  a1, \tmp2, 0                /* a1   = *tmp2 */
+    getcoreid \tmp1                     /* tmp1 = Core ID (0 or 1) */
+    movi  \tmp2, g_cpu_intstack_top     /* tmp2 = Array of stack pointers */
+    addx4 \tmp2, \tmp1, \tmp2           /* tmp2 = tmp2 + (tmp1 << 2) */
+    l32i  \tmp1, \tmp2, 0               /* Load the top of the interrupt stack 
for this core */
+
+  /* tmp1 represents the top of the interrupt stack for this core
+   * If a1 >= tmp1, sp is outside the interrupt stack boundaries.
+   */
+
+    l32i    \tmp2, \tmp2, 0             /* Load the top of the interrupt stack 
for this core */
+    sub     \tmp2, a1, \tmp2
+    movgez  a1, \tmp1, \tmp2
+
+  /* If a1 < (tmp1 - INTSTACK_SIZE), sp is outside the interrupt stack
+   * boundaries.
+   */
+
+    movi    \tmp2, CONFIG_ARCH_INTERRUPTSTACK
+    sub     \tmp2, \tmp1, \tmp2
+    sub     \tmp2, a1, \tmp2
+    movltz  a1, \tmp1, \tmp2
+
+  /* If neither movltz and movgez moved the top of the interrupt stack to
+   * a1, it means that the stack pointer was already pointing to the
+   * interrupt stack and no action is required.
+   */
+
     .endm
 #endif
 
diff --git a/arch/xtensa/src/esp32s3/chip_memory.h 
b/arch/xtensa/src/esp32s3/chip_memory.h
index 4df97a4d0c..4c745c1216 100644
--- a/arch/xtensa/src/esp32s3/chip_memory.h
+++ b/arch/xtensa/src/esp32s3/chip_memory.h
@@ -32,6 +32,12 @@
 #include "hardware/esp32s3_soc.h"
 #endif
 
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define XTENSA_INSTUCTION_REGION 0x40000000
+
 /****************************************************************************
  * Inline Functions
  ****************************************************************************/
@@ -51,7 +57,7 @@ extern "C"
 
 static inline bool xtensa_sp_sane(uint32_t sp)
 {
-  return (esp32s3_sp_dram(sp) && ((sp & 0x0f) == 0));
+  return esp32s3_sp_dram(sp);
 }
 
 /****************************************************************************
diff --git a/boards/xtensa/esp32/esp32-wrover-kit/configs/gpio/defconfig 
b/boards/xtensa/esp32/esp32-wrover-kit/configs/gpio/defconfig
index f5fbcae5a2..69fc2e6655 100644
--- a/boards/xtensa/esp32/esp32-wrover-kit/configs/gpio/defconfig
+++ b/boards/xtensa/esp32/esp32-wrover-kit/configs/gpio/defconfig
@@ -48,4 +48,3 @@ CONFIG_START_YEAR=2011
 CONFIG_SYSLOG_BUFFER=y
 CONFIG_SYSTEM_NSH=y
 CONFIG_UART0_SERIAL_CONSOLE=y
-CONFIG_XTENSA_INTBACKTRACE=y

Reply via email to