summaryrefslogtreecommitdiffstats
path: root/bsps/arm
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2023-12-21 15:16:47 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2024-01-15 10:33:01 +0100
commita6482ebfaa6f25307c098aaa1ad9d5e393cbdbc0 (patch)
tree9ba7074f541e37c821a24e49c7f27935ea88326a /bsps/arm
parentbsp/tms570: Avoid errno for debug console (diff)
downloadrtems-a6482ebfaa6f25307c098aaa1ad9d5e393cbdbc0.tar.bz2
bsp/tms570: Implement set/get interrupt priority
Update #4982.
Diffstat (limited to 'bsps/arm')
-rw-r--r--bsps/arm/tms570/include/bsp/irq.h61
-rw-r--r--bsps/arm/tms570/irq/irq.c132
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) */