Jelajahi Sumber

interrupt-allocator: reject vector allocation if its marked as not-implemented. and search to next available

Felipe Neves 5 tahun lalu
induk
melakukan
544a3f7df5

+ 15 - 10
components/esp_system/intr_alloc.c

@@ -48,7 +48,7 @@ Define this to debug the choices made when allocating the interrupt. This leads
 output within a critical region, which can lead to weird effects like e.g. the interrupt watchdog
 being triggered, that is why it is separate from the normal LOG* scheme.
 */
-//define DEBUG_INT_ALLOC_DECISIONS
+//#define DEBUG_INT_ALLOC_DECISIONS
 #ifdef DEBUG_INT_ALLOC_DECISIONS
 # define ALCHLOG(...) ESP_EARLY_LOGD(TAG, __VA_ARGS__)
 #else
@@ -238,13 +238,14 @@ static bool is_vect_desc_usable(vector_desc_t *vd, int flags, int cpu, int force
         return false;
     }
     //Check if the interrupt level is acceptable
-    if (!(flags&(1<<interrupt_controller_hal_get_level(x)))) {
+    if (!(flags&(1<<interrupt_controller_hal_get_level(x))) && 
+            (interrupt_controller_hal_get_type(x)!=INTTP_ANY)) {
         ALCHLOG("....Unusable: incompatible level");
-        return false;
+    return false;
     }
     //check if edge/level type matches what we want
-    if (((flags&ESP_INTR_FLAG_EDGE) && (interrupt_controller_hal_get_type(x)==INTTP_LEVEL)) ||
-            (((!(flags&ESP_INTR_FLAG_EDGE)) && (interrupt_controller_hal_get_type(x)==INTTP_EDGE)))) {
+    if (((flags&ESP_INTR_FLAG_EDGE) && (interrupt_controller_hal_get_type(x)==INTTP_LEVEL) && (interrupt_controller_hal_get_type(x)!= INTTP_ANY)) ||
+            (((!(flags&ESP_INTR_FLAG_EDGE)) && (interrupt_controller_hal_get_type(x)==INTTP_EDGE)&& (interrupt_controller_hal_get_type(x)!= INTTP_ANY)))) {
         ALCHLOG("....Unusable: incompatible trigger type");
         return false;
     }
@@ -582,12 +583,16 @@ esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusre
         esp_intr_disable(ret);
     }
 
-    //Set the level and type at controller level if needed:
-    interrupt_controller_hal_set_int_level(intr,
-                            interrupt_controller_hal_desc_level(intr));
+    //Extract the level from the interrupt passed flags
+    int level = (__builtin_ffs((flags >> 1) & ESP_INTR_FLAG_LEVELMASK)) + 1;
+
+    interrupt_controller_hal_set_int_level(intr,level);
 
-    interrupt_controller_hal_set_int_type(intr,
-                            interrupt_controller_hal_desc_type(intr));
+    if (flags & ESP_INTR_FLAG_EDGE) {
+        interrupt_controller_hal_set_int_type(intr,INTTP_EDGE);
+    } else {
+        interrupt_controller_hal_set_int_type(intr,INTTP_LEVEL);
+    }
 
     portEXIT_CRITICAL(&spinlock);
 

+ 0 - 2
components/freertos/port/riscv/include/freertos/xtensa_api.h

@@ -1,2 +0,0 @@
-/* Just a placeholder since this file is exposed in some top-level apps */
-#pragma once

+ 1 - 1
components/freertos/port/riscv/portasm.S

@@ -73,7 +73,7 @@ rtos_int_exit:
     la t2, uxInterruptNesting
     lw t3, 0x0(t2)
 
-    /* Already zero, protect againts underflow */
+    /* Already zero, protect against underflow */
     beq t3, zero, isr_skip_decrement
     addi t3,t3, -1
     sw  t3, 0x0(t2)

+ 1 - 5
components/hal/esp32c3/include/hal/interrupt_controller_ll.h

@@ -122,8 +122,7 @@ static inline void intr_cntrl_ll_enable_int_mask(uint32_t newmask)
  */
 static inline void intr_cntrl_ll_edge_int_acknowledge (int intr)
 {
-    intr_cntrl_ll_disable_interrupts(1 << intr);
-    esprv_intc_int_set_priority(intr, 0);
+    esprv_intc_set_interrupt_clear(intr);
 }
 
 /**
@@ -145,9 +144,6 @@ static inline void intr_cntrl_ll_set_int_level(int intr, int level)
  */
 static inline void intr_cntrl_ll_set_int_type(int intr, int_type_t type)
 {
-    /* Not needed currently for xtensa platforms since the type is already set
-     *  in interrupt table
-     */
     esprv_intc_int_set_type(BIT(intr), type);
 }
 

+ 32 - 32
components/hal/esp32c3/interrupt_descriptor_table.c

@@ -18,38 +18,38 @@
 
 //This is basically a software-readable version of the interrupt usage table in include/soc/soc.h
 const int_desc_t interrupt_descriptor_table[32] = {
-    { 1, INTTP_LEVEL, {INTDESC_RESVD } }, //0
-    { 1, INTTP_LEVEL, {INTDESC_SPECIAL } }, //1
-    { 1, INTTP_LEVEL, {INTDESC_NORMAL } }, //2
-    { 1, INTTP_LEVEL, {INTDESC_NORMAL } }, //3
-    { 1, INTTP_LEVEL, {INTDESC_NORMAL } }, //4
-    { 1, INTTP_LEVEL, {INTDESC_SPECIAL } }, //5
-    { 1, INTTP_NA,    {INTDESC_NORMAL } }, //6
-    { 1, INTTP_NA,    {INTDESC_NORMAL } }, //7
-    { 1, INTTP_LEVEL, {INTDESC_SPECIAL } }, //8
-    { 1, INTTP_LEVEL, {INTDESC_SPECIAL } }, //9
-    { 1, INTTP_EDGE,  {INTDESC_NORMAL } },  //10
-    { 3, INTTP_NA,    {INTDESC_NORMAL } }, //11
-    { 1, INTTP_LEVEL, {INTDESC_SPECIAL } }, //12
-    { 1, INTTP_LEVEL, {INTDESC_NORMAL } }, //13
-    { 7, INTTP_LEVEL, {INTDESC_NORMAL } }, //14
-    { 3, INTTP_NA,    {INTDESC_NORMAL } }, //15
-    { 5, INTTP_NA,    {INTDESC_NORMAL } }, //16
-    { 1, INTTP_LEVEL, {INTDESC_NORMAL } }, //17
-    { 1, INTTP_LEVEL, {INTDESC_NORMAL } }, //18
-    { 2, INTTP_LEVEL, {INTDESC_NORMAL } }, //19
-    { 2, INTTP_LEVEL, {INTDESC_NORMAL } }, //20
-    { 2, INTTP_LEVEL, {INTDESC_NORMAL } }, //21
-    { 3, INTTP_EDGE,  {INTDESC_NORMAL } }, //22
-    { 3, INTTP_LEVEL, {INTDESC_NORMAL } }, //23
-    { 4, INTTP_LEVEL, {INTDESC_RESVD } }, //24
-    { 4, INTTP_LEVEL, {INTDESC_RESVD } }, //25
-    { 5, INTTP_LEVEL, {INTDESC_NORMAL } }, //26
-    { 3, INTTP_LEVEL, {INTDESC_NORMAL } }, //27
-    { 4, INTTP_EDGE,  {INTDESC_NORMAL } }, //28
-    { 3, INTTP_NA,    {INTDESC_NORMAL } }, //29
-    { 4, INTTP_EDGE,  {INTDESC_NORMAL } }, //30
-    { 5, INTTP_LEVEL, {INTDESC_NORMAL } }, //31
+    { 1, INTTP_ANY, {INTDESC_RESVD } }, //0
+    { 1, INTTP_ANY, {INTDESC_SPECIAL } }, //1
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //2
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //3
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //4
+    { 1, INTTP_ANY, {INTDESC_SPECIAL } }, //5
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //6
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //7
+    { 1, INTTP_ANY, {INTDESC_SPECIAL } }, //8
+    { 1, INTTP_ANY, {INTDESC_SPECIAL } }, //9
+    { 1, INTTP_ANY, {INTDESC_NORMAL } },  //10
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //11
+    { 1, INTTP_ANY, {INTDESC_SPECIAL } }, //12
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //13
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //14
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //15
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //16
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //17
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //18
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //19
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //20
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //21
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //22
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //23
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //24
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //25
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //26
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //27
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //28
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //29
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //30
+    { 1, INTTP_ANY, {INTDESC_NORMAL } }, //31
 };
 
 const int_desc_t *interrupt_controller_hal_desc_table(void)

+ 2 - 2
components/hal/include/hal/interrupt_controller_types.h

@@ -24,13 +24,13 @@ extern "C" {
 typedef enum {
     INTDESC_NORMAL=0,
     INTDESC_RESVD,
-    INTDESC_SPECIAL
+    INTDESC_SPECIAL,
 } int_desc_flag_t;
 
 typedef enum {
     INTTP_LEVEL=0,
     INTTP_EDGE,
-    INTTP_NA
+    INTTP_ANY,
 } int_type_t;
 
 typedef struct {

+ 7 - 0
components/riscv/include/riscv/interrupt.h

@@ -110,6 +110,13 @@ void esprv_intc_set_threshold(int priority_threshold);
  */
 uint32_t esprv_intc_get_interrupt_unmask(void);
 
+/**
+ * @brief Set a bit in int clear register
+ * @param intr bit to set from 0 to 31
+ * @return none
+ */
+void esprv_intc_set_interrupt_clear(int intr); 
+
 #ifdef __cplusplus
 }
 #endif

+ 6 - 0
components/riscv/interrupt.c

@@ -89,6 +89,12 @@ uint32_t esprv_intc_get_interrupt_unmask(void)
     return REG_READ(INTERRUPT_CORE0_CPU_INT_ENABLE_REG);
 }
 
+void esprv_intc_set_interrupt_clear(int intr)
+{
+    REG_SET_BIT(INTERRUPT_CORE0_CPU_INT_CLEAR_REG, intr);
+}
+
+
 /*************************** Exception names. Used in .gdbinit file. ***************************/
 
 const char *riscv_excp_names[16] __attribute__((used)) = {