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 8fb8c2dca50212277b19e531022af3f7c5ff5396
Author: Filipe Cavalcanti <[email protected]>
AuthorDate: Fri Apr 10 09:27:07 2026 -0300

    arch/xtensa: register Wi-Fi IRQs in non_iram mask for SPI flash
    
    Wi-Fi used a locally allocated vector_desc, so those CPU interrupt lines
    were never recorded in the HAL non_iram_int_mask.
    During SPI flash, esp_intr_noniram_disable() therefore did not mask them,
    and Wi-Fi ISRs could still run with the cache off.
    Now, Wi-Fi IRQs are treated as non-IRAM and get masked while flash/cache is 
suspended.
    
    Signed-off-by: Filipe Cavalcanti <[email protected]>
---
 arch/xtensa/src/esp32/esp32_wifi_adapter.c     | 20 +++++++++++++++++++-
 arch/xtensa/src/esp32s2/esp32s2_wifi_adapter.c | 26 +++++++++++++++++++-------
 arch/xtensa/src/esp32s3/esp32s3_wifi_adapter.c | 23 ++++++++++++++++++++++-
 3 files changed, 60 insertions(+), 9 deletions(-)

diff --git a/arch/xtensa/src/esp32/esp32_wifi_adapter.c 
b/arch/xtensa/src/esp32/esp32_wifi_adapter.c
index 5a6659919bb..fddae265cc0 100644
--- a/arch/xtensa/src/esp32/esp32_wifi_adapter.c
+++ b/arch/xtensa/src/esp32/esp32_wifi_adapter.c
@@ -49,6 +49,7 @@
 #include "esp32_wifi_adapter.h"
 #include "esp_hr_timer.h"
 #include "esp_irq.h"
+#include "esp_intr_alloc.h"
 #include "esp_cpu.h"
 #include "espressif/esp_wireless.h"
 #include "espressif/esp_wifi_utils.h"
@@ -1752,7 +1753,9 @@ static bool wifi_env_is_chip(void)
  * Name: set_intr_wrapper
  *
  * Description:
- *   Do nothing
+ *   Route the Wi-Fi interrupt source and attach a handle that uses the HAL
+ *   global vector descriptor list. Mark the CPU line as non-IRAM so
+ *   esp_intr_noniram_disable() masks it while SPI flash holds the cache off.
  *
  * Input Parameters:
  *     cpu_no      - The CPU which the interrupt number belongs.
@@ -1770,6 +1773,7 @@ static void set_intr_wrapper(int32_t cpu_no, uint32_t 
intr_source,
 {
   intr_handle_t handle;
   int irq = ESP_SOURCE2IRQ(intr_source);
+  esp_err_t err;
 
   wlinfo("cpu_no=%" PRId32 ", intr_source=%" PRIu32
          ", intr_num=%" PRIu32 ", intr_prio=%" PRId32 "\n",
@@ -1785,11 +1789,25 @@ static void set_intr_wrapper(int32_t cpu_no, uint32_t 
intr_source,
     }
 
   handle->vector_desc = get_desc_for_int(intr_num, cpu_no);
+  if (handle->vector_desc == NULL)
+    {
+      wlerr("get_desc_for_int failed\n");
+      kmm_free(handle);
+      return;
+    }
+
   handle->vector_desc->source = intr_source;
+  handle->shared_vector_desc = NULL;
 
   /* Register the handle - it contains all needed information (cpuint, cpu) */
 
   esp_set_handle(cpu_no, irq, handle);
+
+  err = esp_intr_set_in_iram(handle, false);
+  if (err != OK)
+    {
+      wlerr("esp_intr_set_in_iram failed: %d\n", err);
+    }
 }
 
 /****************************************************************************
diff --git a/arch/xtensa/src/esp32s2/esp32s2_wifi_adapter.c 
b/arch/xtensa/src/esp32s2/esp32s2_wifi_adapter.c
index 6f30680a3ca..bb8a3deb8aa 100644
--- a/arch/xtensa/src/esp32s2/esp32s2_wifi_adapter.c
+++ b/arch/xtensa/src/esp32s2/esp32s2_wifi_adapter.c
@@ -44,6 +44,7 @@
 #include "xtensa.h"
 #include "esp_attr.h"
 #include "esp_irq.h"
+#include "esp_intr_alloc.h"
 #include "esp_cpu.h"
 #include "hardware/esp32s2_system.h"
 #include "soc/rtc_cntl_reg.h"
@@ -95,6 +96,12 @@ struct vector_desc_t
   vector_desc_t *next;
 };
 
+/* From esp_hw_support/intr_alloc.c: returns a pointer to a HAL-owned
+ * vector descriptor for some intno and cpu.
+ */
+
+extern vector_desc_t *get_desc_for_int(int intno, int cpu);
+
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
@@ -1604,7 +1611,9 @@ static bool wifi_env_is_chip(void)
  * Name: set_intr_wrapper
  *
  * Description:
- *   Do nothing
+ *   Route the Wi-Fi interrupt source and attach a handle that uses the HAL
+ *   global vector descriptor list. Mark the CPU line as non-IRAM so
+ *   esp_intr_noniram_disable() masks it while SPI flash holds the cache off.
  *
  * Input Parameters:
  *     cpu_no      - The CPU which the interrupt number belongs.
@@ -1622,6 +1631,7 @@ static void set_intr_wrapper(int32_t cpu_no, uint32_t 
intr_source,
 {
   intr_handle_t handle;
   int irq = ESP_SOURCE2IRQ(intr_source);
+  esp_err_t err;
 
   wlinfo("cpu_no=%" PRId32 ", intr_source=%" PRIu32
          ", intr_num=%" PRIu32 ", intr_prio=%" PRId32 "\n",
@@ -1636,24 +1646,26 @@ static void set_intr_wrapper(int32_t cpu_no, uint32_t 
intr_source,
       return;
     }
 
-  handle->vector_desc = kmm_calloc(1, sizeof(vector_desc_t));
+  handle->vector_desc = get_desc_for_int(intr_num, cpu_no);
   if (handle->vector_desc == NULL)
     {
-      wlerr("Failed to kmm_calloc\n");
+      wlerr("get_desc_for_int failed\n");
       kmm_free(handle);
       return;
     }
 
-  handle->vector_desc->intno = intr_num;
-  handle->vector_desc->cpu = cpu_no;
   handle->vector_desc->source = intr_source;
-  handle->vector_desc->shared_vec_info = NULL;
-  handle->vector_desc->next = NULL;
   handle->shared_vector_desc = NULL;
 
   /* Register the handle - it contains all needed information (cpuint, cpu) */
 
   esp_set_handle(cpu_no, irq, handle);
+
+  err = esp_intr_set_in_iram(handle, false);
+  if (err != OK)
+    {
+      wlerr("esp_intr_set_in_iram failed: %d\n", err);
+    }
 }
 
 /****************************************************************************
diff --git a/arch/xtensa/src/esp32s3/esp32s3_wifi_adapter.c 
b/arch/xtensa/src/esp32s3/esp32s3_wifi_adapter.c
index 61f72f9beeb..3d9d5339b53 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_wifi_adapter.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_wifi_adapter.c
@@ -44,6 +44,7 @@
 #include "xtensa.h"
 #include "esp_attr.h"
 #include "esp_irq.h"
+#include "esp_intr_alloc.h"
 #include "esp_cpu.h"
 #include "hardware/esp32s3_system.h"
 #include "soc/rtc_cntl_reg.h"
@@ -267,6 +268,10 @@ static int coex_schm_flexible_period_set_wrapper(uint8_t 
period);
 static uint8_t coex_schm_flexible_period_get_wrapper(void);
 static void * coex_schm_get_phase_by_idx_wrapper(int phase_idx);
 
+/* From esp_hw_support/intr_alloc.c: returns a pointer to a HAL-owned
+ * vector descriptor for some intno and cpu.
+ */
+
 extern vector_desc_t *get_desc_for_int(int intno, int cpu);
 
 /****************************************************************************
@@ -1738,7 +1743,9 @@ static bool wifi_env_is_chip(void)
  * Name: set_intr_wrapper
  *
  * Description:
- *   Do nothing
+ *   Route the Wi-Fi interrupt source and attach a handle that uses the HAL
+ *   global vector descriptor list. Mark the CPU line as non-IRAM so
+ *   esp_intr_noniram_disable() masks it while SPI flash holds the cache off.
  *
  * Input Parameters:
  *     cpu_no      - The CPU which the interrupt number belongs.
@@ -1756,6 +1763,7 @@ static void set_intr_wrapper(int32_t cpu_no, uint32_t 
intr_source,
 {
   intr_handle_t handle;
   int irq = ESP_SOURCE2IRQ(intr_source);
+  esp_err_t err;
 
   wlinfo("cpu_no=%" PRId32 ", intr_source=%" PRIu32
          ", intr_num=%" PRIu32 ", intr_prio=%" PRId32 "\n",
@@ -1771,12 +1779,25 @@ static void set_intr_wrapper(int32_t cpu_no, uint32_t 
intr_source,
     }
 
   handle->vector_desc = get_desc_for_int(intr_num, cpu_no);
+  if (handle->vector_desc == NULL)
+    {
+      wlerr("get_desc_for_int failed\n");
+      kmm_free(handle);
+      return;
+    }
 
   handle->vector_desc->source = intr_source;
+  handle->shared_vector_desc = NULL;
 
   /* Register the handle - it contains all needed information (cpuint, cpu) */
 
   esp_set_handle(cpu_no, irq, handle);
+
+  err = esp_intr_set_in_iram(handle, false);
+  if (err != OK)
+    {
+      wlerr("esp_intr_set_in_iram failed: %d\n", err);
+    }
 }
 
 /****************************************************************************

Reply via email to