[PATCH 11/47] bsp/tms570: Implement set/get interrupt priority

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Dec 21 14:37:44 UTC 2023


---
 bsps/arm/tms570/include/bsp/irq.h |  61 +++++++++-----
 bsps/arm/tms570/irq/irq.c         | 132 ++++++++++++++++++++++--------
 2 files changed, 140 insertions(+), 53 deletions(-)

diff --git a/bsps/arm/tms570/include/bsp/irq.h b/bsps/arm/tms570/include/bsp/irq.h
index 3c7170eb2a..d0eb130a92 100644
--- a/bsps/arm/tms570/include/bsp/irq.h
+++ b/bsps/arm/tms570/include/bsp/irq.h
@@ -140,33 +140,56 @@
 #ifndef ASM
 
 /**
- * @brief Set priority of the interrupt vector.
- *
- * This function is here because of compability. It should set
- * priority of the interrupt vector.
- * @warning It does not set any priority at HW layer. It is nearly imposible to
- * @warning set priority of the interrupt on TMS570 in a nice way.
- * @param[in] vector vector of isr
- * @param[in] priority new priority assigned to the vector
- * @return Void
+ * @brief Sets the priority of the interrupt vector.
+ *
+ * The priority is defined by the VIM interrupt channel.  Firstly, the VIM
+ * Interrupt Control (CHANCTRL) registers are searched to get the current
+ * channel associated with the interrupt vector.  The interrupt vector of the
+ * channel associated with the priority is assigned to this channel.  The
+ * specified interrupt vector is assigned to the channel associated with the
+ * priority.  So, this function swaps the channels of two interrupt vectors.
+ *
+ * @param vector is the number of the interrupt vector to set the priority.
+ *
+ * @param priority is the priority to set.
+ *
+ * @retval ::RTEMS_SUCCESSFUL The requested operation was successful.
+ *
+ * @retval ::RTEMS_INVALID_ID There was no interrupt vector associated with the
+ *   number specified by ``vector``.
+ *
+ * @retval ::RTEMS_INVALID_PRIORITY The interrupt priority specified in
+ *   ``priority`` was invalid.
  */
-void tms570_irq_set_priority(
+rtems_status_code tms570_irq_set_priority(
   rtems_vector_number vector,
-  unsigned            priority
+  uint32_t            priority
 );
 
 /**
- * @brief Gets priority of the interrupt vector.
+ * @brief Gets the priority of the interrupt vector.
  *
- * This function is here because of compability. It returns priority
- * of the isr vector last set by tms570_irq_set_priority function.
+ * The priority is defined by the VIM interrupt channel.  The VIM Interrupt
+ * Control (CHANCTRL) registers are searched to get the channel associated with
+ * the interrupt vector.
  *
- * @warning It does not return any real priority of the HW layer.
- * @param[in] vector vector of isr
- * @retval 0 vector is invalid.
- * @retval priority priority of the interrupt
+ * @param vector is the number of the interrupt vector to set the priority.
+ *
+ * @param priority is the priority to set.
+ *
+ * @retval ::RTEMS_SUCCESSFUL The requested operation was successful.
+ *
+ * @retval ::RTEMS_INVALID_ADDRESS The ``priority`` parameter was NULL.
+ *
+ * @retval ::RTEMS_INVALID_ID There was no interrupt vector associated with the
+ *   number specified by ``vector``.
+ *
+ * @retval ::RTEMS_NOT_DEFINED The interrupt has no associated priority.
  */
-unsigned tms570_irq_get_priority( rtems_vector_number vector );
+rtems_status_code tms570_irq_get_priority(
+  rtems_vector_number  vector,
+  uint32_t            *priority
+);
 
 #endif /* ASM */
 
diff --git a/bsps/arm/tms570/irq/irq.c b/bsps/arm/tms570/irq/irq.c
index bdc7fb8f0a..c5bdea577b 100644
--- a/bsps/arm/tms570/irq/irq.c
+++ b/bsps/arm/tms570/irq/irq.c
@@ -46,48 +46,112 @@
 #include <bsp/irq.h>
 #include <rtems/score/armv4.h>
 
-unsigned int priorityTable[BSP_INTERRUPT_VECTOR_COUNT];
+#define VIM_CHANCTRL_COUNT 24
+#define VIM_CHANMAP_MASK UINT32_C(0x7f)
+#define VIM_CHANMAP_SHIFT(i) (24 - (8 * (i)))
 
-/**
- * @brief Set priority of the interrupt vector.
- *
- * This function is here because of compability. It should set
- * priority of the interrupt vector.
- * @warning It does not set any priority at HW layer. It is nearly imposible to
- * @warning set priority of the interrupt on TMS570 in a nice way.
- * @param[in] vector vector of isr
- * @param[in] priority new priority assigned to the vector
- * @return Void
- */
-void tms570_irq_set_priority(
+static void vim_set_channel_request(uint32_t channel, uint32_t request)
+{
+  uint32_t chanctrl;
+  int shift;
+
+  chanctrl = TMS570_VIM.CHANCTRL[channel / 4];
+  shift = VIM_CHANMAP_SHIFT(channel % 4);
+  chanctrl &= ~(VIM_CHANMAP_MASK << shift);
+  chanctrl |= request << shift;
+  TMS570_VIM.CHANCTRL[channel / 4] = chanctrl;
+}
+
+rtems_status_code tms570_irq_set_priority(
   rtems_vector_number vector,
-  unsigned priority
+  uint32_t            priority
 )
 {
-  if ( bsp_interrupt_is_valid_vector(vector) ) {
-    priorityTable[vector] = priority;
+  rtems_interrupt_level level;
+  uint32_t current_channel;
+  uint32_t chanctrl;
+  size_t i;
+  size_t j;
+
+  if (!bsp_interrupt_is_valid_vector(vector)) {
+   return RTEMS_INVALID_ID;
+  }
+
+  if (priority < 2) {
+    return RTEMS_INVALID_PRIORITY;
+  }
+
+  if (priority >= BSP_INTERRUPT_VECTOR_COUNT) {
+    return RTEMS_INVALID_PRIORITY;
+  }
+
+  rtems_interrupt_disable(level);
+  current_channel = TMS570_VIM.CHANCTRL[priority / 4];
+  current_channel >>= VIM_CHANMAP_SHIFT(priority % 4);
+  current_channel &= VIM_CHANMAP_MASK;
+
+  for (i = 0; i < VIM_CHANCTRL_COUNT; ++i) {
+    chanctrl = TMS570_VIM.CHANCTRL[i];
+
+    for (j = 0; j < 4; ++j) {
+      uint32_t channel_vector;
+
+      channel_vector = (chanctrl >> VIM_CHANMAP_SHIFT(j)) & VIM_CHANMAP_MASK;
+
+      if (channel_vector == vector) {
+        vim_set_channel_request(i * 4 + j, current_channel);
+        goto set_my_request;
+      }
+    }
   }
+
+set_my_request:
+
+  vim_set_channel_request(priority, vector);
+  rtems_interrupt_enable(level);
+  return RTEMS_SUCCESSFUL;
 }
 
-/**
- * @brief Gets priority of the interrupt vector.
- *
- * This function is here because of compability. It returns priority
- * of the isr vector last set by tms570_irq_set_priority function.
- *
- * @warning It does not return any real priority of the HW layer.
- * @param[in] vector vector of isr
- * @retval 0 vector is invalid.
- * @retval priority priority of the interrupt
- */
-unsigned tms570_irq_get_priority(
-  rtems_vector_number vector
+rtems_status_code tms570_irq_get_priority(
+  rtems_vector_number  vector,
+  unsigned            *priority
 )
 {
-  if ( bsp_interrupt_is_valid_vector(vector) ) {
-   return priorityTable[vector];
- }
- return 0;
+  rtems_interrupt_level level;
+  size_t i;
+  size_t j;
+
+  if (priority == NULL) {
+    return RTEMS_INVALID_ADDRESS;
+  }
+
+  if (!bsp_interrupt_is_valid_vector(vector)) {
+   return RTEMS_INVALID_ID;
+  }
+
+  rtems_interrupt_disable(level);
+
+  for (i = 0; i < VIM_CHANCTRL_COUNT; ++i) {
+    uint32_t chanctrl;
+
+    chanctrl = TMS570_VIM.CHANCTRL[i];
+
+    for (j = 0; j < 4; ++j) {
+      uint32_t channel_vector;
+
+      channel_vector = (chanctrl >> VIM_CHANMAP_SHIFT(j)) & VIM_CHANMAP_MASK;
+
+      if (channel_vector == vector) {
+        rtems_interrupt_enable(level);
+        *priority = i * 4 + j;
+        return RTEMS_SUCCESSFUL;
+      }
+    }
+  }
+
+  rtems_interrupt_enable(level);
+  *priority = UINT32_MAX;
+  return RTEMS_NOT_DEFINED;
 }
 
 /**
@@ -204,7 +268,7 @@ void bsp_interrupt_facility_initialize(void)
     TMS570_VIM.REQENACLR[i] = 0xffffffff;
   }
   /* Map default events on interrupt vectors */
-  for ( i = 0; i < 24; i += 1, value += 0x04040404) {
+  for ( i = 0; i < VIM_CHANCTRL_COUNT; i += 1, value += 0x04040404) {
     TMS570_VIM.CHANCTRL[i] = value;
   }
   /* Set all vectors as IRQ (not FIR) */
-- 
2.35.3



More information about the devel mailing list