Przeglądaj źródła

esp32: Dis interrupts up to 5 lvl for DPORT

Disable interrupts for both DPORT workarounds up to 5 lvl.

Closes: https://esp32.com/viewtopic.php?f=2&t=10981&sid=d125cec233070ed4d2c5410bf5d3d74a
Closes: IDF-728
Konstantin Kondrashov 7 lat temu
rodzic
commit
2e9904556f

+ 7 - 1
components/esp32/Kconfig

@@ -1038,6 +1038,13 @@ menu "ESP32-specific"
             This option depends on the CONFIG_FREERTOS_UNICORE option because RTC fast memory
             can be accessed only by PRO_CPU core.
 
+    config ESP32_DPORT_DIS_INTERRUPT_LVL
+        int "Disable the interrupt level for the DPORT workarounds"
+        default 5
+        help
+            To prevent interrupting DPORT workarounds,
+            need to disable interrupt with a maximum used level in the system.
+
 endmenu  # ESP32-Specific
 
 menu Wi-Fi
@@ -1406,7 +1413,6 @@ menu PHY
 
 endmenu  # PHY
 
-
 menu "Power Management"
 
     config PM_ENABLE

+ 1 - 1
components/esp32/dport_access.c

@@ -256,7 +256,7 @@ uint32_t IRAM_ATTR esp_dport_access_reg_read(uint32_t reg)
     unsigned int intLvl;
     __asm__ __volatile__ (\
                   "movi %[APB], "XTSTR(0x3ff40078)"\n"\
-                  "rsil %[LVL], "XTSTR(3)"\n"\
+                  "rsil %[LVL], "XTSTR(CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL)"\n"\
                   "l32i %[APB], %[APB], 0\n"\
                   "l32i %[REG], %[REG], 0\n"\
                   "wsr  %[LVL], "XTSTR(PS)"\n"\

+ 7 - 2
components/esp32/dport_panic_highint_hdl.S

@@ -31,9 +31,10 @@ Interrupt , a high-priority interrupt, is used for several things:
 
 */
 
-#define L4_INTR_STACK_SIZE  8
+#define L4_INTR_STACK_SIZE  12
 #define L4_INTR_A2_OFFSET   0
 #define L4_INTR_A3_OFFSET   4
+#define L4_INTR_A4_OFFSET   8
     .data
 _l4_intr_stack:
     .space      L4_INTR_STACK_SIZE
@@ -145,10 +146,11 @@ xt_highint4:
     movi    a0, (1<<ETS_DPORT_INUM)
     wsr     a0, INTCLEAR
 
-    /* Save A2, A3 so we can use those registers */
+    /* Save A2, A3, A4 so we can use those registers */
     movi    a0, _l4_intr_stack
     s32i    a2, a0, L4_INTR_A2_OFFSET
     s32i    a3, a0, L4_INTR_A3_OFFSET
+    s32i    a4, a0, L4_INTR_A4_OFFSET
 
     /* handle dport interrupt */
     /* get CORE_ID */
@@ -168,6 +170,7 @@ xt_highint4:
     s32i    a2, a0, 0   /* clear intr */
     movi    a0, 1       /* other cpu id */
 3:
+    rsil    a4, CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL /* disable nested iterrupt */
     /* set and wait flag */
     movi    a2, dport_access_start
     addx4   a2, a0, a2
@@ -180,10 +183,12 @@ xt_highint4:
     l32i    a3, a2, 0
     beqz    a3, .check_dport_access_end
 
+    wsr     a4, PS                                   /* restore iterrupt level */
     /* Done. Restore registers and return. */
     movi    a0, _l4_intr_stack
     l32i    a2, a0, L4_INTR_A2_OFFSET
     l32i    a3, a0, L4_INTR_A3_OFFSET
+    l32i    a4, a0, L4_INTR_A4_OFFSET
     rsync                                   /* ensure register restored */
 
     rsr     a0, EXCSAVE_4                   /* restore a0 */

+ 1 - 1
components/esp32/include/esp_dport_access.h

@@ -41,7 +41,7 @@ void esp_dport_access_int_abort(void);
 #else
 #define DPORT_STALL_OTHER_CPU_START()   esp_dport_access_stall_other_cpu_start()
 #define DPORT_STALL_OTHER_CPU_END()     esp_dport_access_stall_other_cpu_end()
-#define DPORT_INTERRUPT_DISABLE()       unsigned int intLvl = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL)
+#define DPORT_INTERRUPT_DISABLE()       unsigned int intLvl = XTOS_SET_INTLEVEL(CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL)
 #define DPORT_INTERRUPT_RESTORE()       XTOS_RESTORE_JUST_INTLEVEL(intLvl)
 #endif