]> granicus.if.org Git - esp-idf/commitdiff
esp32: Dis interrupts up to 5 lvl for DPORT
authorKonstantin Kondrashov <konstantin@espressif.com>
Tue, 25 Jun 2019 11:23:10 +0000 (19:23 +0800)
committerbot <bot@espressif.com>
Tue, 16 Jul 2019 05:54:45 +0000 (05:54 +0000)
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
components/esp32/Kconfig
components/esp32/dport_access.c
components/esp32/dport_panic_highint_hdl.S
components/esp32/include/esp32/dport_access.h

index 6fdfcc3e2a3235db12fa813cb583b880f299e1a2..847560fe054201327235e7fd387d2745d3283979 100644 (file)
@@ -741,6 +741,13 @@ menu "ESP32-specific"
             Please note that the actual length will be reduced by BT_RESERVE_DRAM if Bluetooth
             controller is enabled.
 
+    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 "Power Management"
index de828eb06113358b6a9ca255028043ede294143b..2c83583350601ed304878df9e2feff40f46806a6 100644 (file)
@@ -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"\
index 924d77b2f03a5693a2465532a5f60e1a339377e4..72916286351f7f0c959e007a8706ded575e4adeb 100644 (file)
@@ -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 */
index adbb8282012ea4039bc08946d4bb7e7d12abe9ae..f91c563e6bb459354084ad085006953efbca343a 100644 (file)
@@ -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