rtems_status_code qoriq_pic_set_priority( rtems_vector_number vector, int new_priority, int *old_priority ) { rtems_status_code sc = RTEMS_SUCCESSFUL; uint32_t old_vpr = 0; if (bsp_interrupt_is_valid_vector(vector)) { volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector); if (QORIQ_PIC_PRIORITY_IS_VALID(new_priority)) { rtems_interrupt_lock_context lock_context; rtems_interrupt_lock_acquire(&lock, &lock_context); old_vpr = src_cfg->vpr; src_cfg->vpr = VPR_PRIORITY_SET(old_vpr, (uint32_t) new_priority); rtems_interrupt_lock_release(&lock, &lock_context); } else if (new_priority < 0) { old_vpr = src_cfg->vpr; } else { sc = RTEMS_INVALID_PRIORITY; } } else { sc = RTEMS_INVALID_ID; } if (old_priority != NULL) { *old_priority = (int) VPR_PRIORITY_GET(old_vpr); } return sc; }
rtems_status_code qoriq_pic_set_priority( rtems_vector_number vector, int new_priority, int *old_priority ) { rtems_status_code sc = RTEMS_SUCCESSFUL; uint32_t old_vpr = 0; if (bsp_interrupt_is_valid_vector(vector)) { int offs = vpr_and_dr_offsets [vector] << 2; volatile uint32_t *vpr = (volatile uint32_t *) &qoriq.pic + offs; if (QORIQ_PIC_PRIORITY_IS_VALID(new_priority)) { rtems_interrupt_level level; rtems_interrupt_disable(level); old_vpr = *vpr; *vpr = VPR_PRIORITY_SET(old_vpr, (uint32_t) new_priority); rtems_interrupt_enable(level); } else if (new_priority < 0) { old_vpr = *vpr; } else { sc = RTEMS_INVALID_PRIORITY; } } else { sc = RTEMS_INVALID_ID; } if (old_priority != NULL) { *old_priority = (int) VPR_PRIORITY_GET(old_vpr); } return sc; }
void bsp_interrupt_vector_disable(rtems_vector_number vector) { volatile gic_dist *dist = ARM_GIC_DIST; bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); gic_id_disable(dist, vector); }
rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) { rtems_status_code sc = RTEMS_SUCCESSFUL; if (bsp_interrupt_is_valid_vector(vector)) { volatile gic_dist *dist = ARM_GIC_DIST; gic_id_disable(dist, vector); } else { sc = RTEMS_INVALID_ID; } return sc; }
static rtems_status_code pic_vector_enable(rtems_vector_number vector, uint32_t msk) { rtems_status_code sc = RTEMS_SUCCESSFUL; if (bsp_interrupt_is_valid_vector(vector)) { volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector); rtems_interrupt_lock_context lock_context; rtems_interrupt_lock_acquire(&lock, &lock_context); src_cfg->vpr = (src_cfg->vpr & ~VPR_MSK) | msk; rtems_interrupt_lock_release(&lock, &lock_context); } return sc; }
static rtems_status_code pic_vector_enable(rtems_vector_number vector, uint32_t msk) { rtems_status_code sc = RTEMS_SUCCESSFUL; if (bsp_interrupt_is_valid_vector(vector)) { int offs = vpr_and_dr_offsets [vector] << 2; volatile uint32_t *vpr = (volatile uint32_t *) &qoriq.pic + offs; rtems_interrupt_level level; rtems_interrupt_disable(level); *vpr = (*vpr & ~VPR_MSK) | msk; rtems_interrupt_enable(level); } return sc; }
rtems_status_code arm_gic_irq_set_affinity( rtems_vector_number vector, uint8_t targets ) { rtems_status_code sc = RTEMS_SUCCESSFUL; if (bsp_interrupt_is_valid_vector(vector)) { volatile gic_dist *dist = ARM_GIC_DIST; gic_id_set_targets(dist, vector, targets); } else { sc = RTEMS_INVALID_ID; } return sc; }
rtems_status_code arm_gic_irq_get_priority( rtems_vector_number vector, uint8_t *priority ) { rtems_status_code sc = RTEMS_SUCCESSFUL; if (bsp_interrupt_is_valid_vector(vector)) { volatile gic_dist *dist = ARM_GIC_DIST; *priority = gic_id_get_priority(dist, vector); } else { sc = RTEMS_INVALID_ID; } return sc; }
rtems_status_code qoriq_pic_set_affinities( rtems_vector_number vector, uint32_t processor_affinities ) { rtems_status_code sc = RTEMS_SUCCESSFUL; if (bsp_interrupt_is_valid_vector(vector)) { volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector); src_cfg->dr = processor_affinities; } else { sc = RTEMS_INVALID_ID; } return sc; }
/** * @brief Iterates over all installed interrupt handler of a vector. * * @ingroup bsp_interrupt * * @return In addition to the standard status codes this function returns * RTEMS_INTERNAL_ERROR if the BSP interrupt support is not initialized. * * @see rtems_interrupt_handler_iterate(). */ static rtems_status_code bsp_interrupt_handler_iterate( rtems_vector_number vector, rtems_interrupt_per_handler_routine routine, void *arg ) { rtems_status_code sc = RTEMS_SUCCESSFUL; bsp_interrupt_handler_entry *current = NULL; rtems_option options = 0; rtems_vector_number index = 0; /* Check parameters and system state */ if (!bsp_interrupt_is_initialized()) { return RTEMS_INTERNAL_ERROR; } else if (!bsp_interrupt_is_valid_vector(vector)) { return RTEMS_INVALID_ID; } else if (rtems_interrupt_is_in_progress()) { return RTEMS_CALLED_FROM_ISR; } /* Lock */ sc = bsp_interrupt_lock(); if (sc != RTEMS_SUCCESSFUL) { return sc; } /* Interate */ index = bsp_interrupt_handler_index(vector); current = &bsp_interrupt_handler_table [index]; if (!bsp_interrupt_is_empty_handler_entry(current)) { do { options = bsp_interrupt_is_handler_unique(index) ? RTEMS_INTERRUPT_UNIQUE : RTEMS_INTERRUPT_SHARED; routine(arg, current->info, options, current->handler, current->arg); current = current->next; } while (current != NULL); } /* Unlock */ sc = bsp_interrupt_unlock(); if (sc != RTEMS_SUCCESSFUL) { return sc; } return RTEMS_SUCCESSFUL; }
rtems_status_code arm_gic_irq_get_group( rtems_vector_number vector, gic_group *group ) { rtems_status_code sc = RTEMS_SUCCESSFUL; if (bsp_interrupt_is_valid_vector(vector)) { volatile gic_dist *dist = ARM_GIC_DIST; *group = gic_id_get_group(dist, vector); } else { sc = RTEMS_INVALID_ID; } return sc; }
rtems_status_code qoriq_pic_set_affinity( rtems_vector_number vector, uint32_t processor_index ) { rtems_status_code sc = RTEMS_SUCCESSFUL; if (bsp_interrupt_is_valid_vector(vector)) { if (processor_index <= 1) { int offs = (vpr_and_dr_offsets [vector] << 2) + 4; volatile uint32_t *dr = (volatile uint32_t *) &qoriq.pic + offs; *dr = BSP_BIT32(processor_index); } else { sc = RTEMS_INVALID_NUMBER; } } else { sc = RTEMS_INVALID_ID; } return sc; }
/** * @brief Removes an interrupt handler. * * @ingroup bsp_interrupt * * @return In addition to the standard status codes this function returns * RTEMS_INTERNAL_ERROR if the BSP interrupt support is not initialized. * * @see rtems_interrupt_handler_remove(). */ static rtems_status_code bsp_interrupt_handler_remove( rtems_vector_number vector, rtems_interrupt_handler handler, void *arg ) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_interrupt_level level; rtems_vector_number index = 0; bsp_interrupt_handler_entry *head = NULL; bsp_interrupt_handler_entry *current = NULL; bsp_interrupt_handler_entry *previous = NULL; bsp_interrupt_handler_entry *match = NULL; /* Check parameters and system state */ if (!bsp_interrupt_is_initialized()) { return RTEMS_INTERNAL_ERROR; } else if (!bsp_interrupt_is_valid_vector(vector)) { return RTEMS_INVALID_ID; } else if (handler == NULL) { return RTEMS_INVALID_ADDRESS; } else if (rtems_interrupt_is_in_progress()) { return RTEMS_CALLED_FROM_ISR; } /* Lock */ sc = bsp_interrupt_lock(); if (sc != RTEMS_SUCCESSFUL) { return sc; } /* Get handler table index */ index = bsp_interrupt_handler_index(vector); /* Get head entry of the handler list for current vector */ head = &bsp_interrupt_handler_table [index]; /* Search for a matching entry */ current = head; do { if (current->handler == handler && current->arg == arg) { match = current; break; } previous = current; current = current->next; } while (current != NULL); /* Remove the matching entry */ if (match != NULL) { if (match->next != NULL) { /* * The match has a successor. A successor is always * allocated. So replace the match with its successor * and free the successor entry. */ current = match->next; rtems_interrupt_disable(level); *match = *current; rtems_interrupt_enable(level); bsp_interrupt_free_handler_entry(current); } else if (match == head) { /* * The match is the list head and has no successor. * The list head is stored in a static table so clear * this entry. Since now the list is empty disable the * vector. */ /* Disable the vector */ sc = bsp_interrupt_vector_disable(vector); /* Clear entry */ rtems_interrupt_disable(level); bsp_interrupt_clear_handler_entry(head); #ifdef BSP_INTERRUPT_USE_INDEX_TABLE bsp_interrupt_handler_index_table [vector] = 0; #endif rtems_interrupt_enable(level); /* Allow shared handlers */ bsp_interrupt_set_handler_unique(index, false); /* Check status code */ if (sc != RTEMS_SUCCESSFUL) { bsp_interrupt_unlock(); return sc; } } else { /* * The match is the list tail and has a predecessor. * So terminate the predecessor and free the match. */ rtems_interrupt_disable(level); previous->next = NULL; rtems_interrupt_enable(level); bsp_interrupt_free_handler_entry(match); } } else { /* No matching entry found */ bsp_interrupt_unlock(); return RTEMS_UNSATISFIED; } /* Unlock */ sc = bsp_interrupt_unlock(); if (sc != RTEMS_SUCCESSFUL) { return sc; } return RTEMS_SUCCESSFUL; }
/** * @brief Installs an interrupt handler. * * @ingroup bsp_interrupt * * @return In addition to the standard status codes this function returns: * - If the BSP interrupt support is not initialized RTEMS_INTERNAL_ERROR will * be returned. * - If not enough memory for a new handler is available RTEMS_NO_MEMORY will * be returned * * @see rtems_interrupt_handler_install() */ static rtems_status_code bsp_interrupt_handler_install( rtems_vector_number vector, const char *info, rtems_option options, rtems_interrupt_handler handler, void *arg ) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_interrupt_level level; rtems_vector_number index = 0; bsp_interrupt_handler_entry *head = NULL; bsp_interrupt_handler_entry *tail = NULL; bsp_interrupt_handler_entry *current = NULL; bsp_interrupt_handler_entry *match = NULL; bool enable_vector = false; /* Check parameters and system state */ if (!bsp_interrupt_is_initialized()) { return RTEMS_INTERNAL_ERROR; } else if (!bsp_interrupt_is_valid_vector(vector)) { return RTEMS_INVALID_ID; } else if (handler == NULL) { return RTEMS_INVALID_ADDRESS; } else if (rtems_interrupt_is_in_progress()) { return RTEMS_CALLED_FROM_ISR; } /* Lock */ sc = bsp_interrupt_lock(); if (sc != RTEMS_SUCCESSFUL) { return sc; } /* Get handler table index */ index = bsp_interrupt_handler_index(vector); /* Get head entry of the handler list for current vector */ head = &bsp_interrupt_handler_table [index]; if (bsp_interrupt_is_empty_handler_entry(head)) { /* * No real handler installed yet. So allocate a new index in * the handler table and fill the entry with life. */ if (bsp_interrupt_allocate_handler_index(vector, &index)) { rtems_interrupt_disable(level); bsp_interrupt_handler_table [index].handler = handler; bsp_interrupt_handler_table [index].arg = arg; #ifdef BSP_INTERRUPT_USE_INDEX_TABLE bsp_interrupt_handler_index_table [vector] = index; #endif rtems_interrupt_enable(level); bsp_interrupt_handler_table [index].info = info; } else { /* Handler table is full */ bsp_interrupt_unlock(); return RTEMS_NO_MEMORY; } /* This is the first handler so enable the vector later */ enable_vector = true; } else { /* Ensure that a unique handler remains unique */ if ( RTEMS_INTERRUPT_IS_UNIQUE(options) || bsp_interrupt_is_handler_unique(index) ) { /* * Tried to install a unique handler on a not empty * list or there is already a unique handler installed. */ bsp_interrupt_unlock(); return RTEMS_RESOURCE_IN_USE; } /* * Search for the list tail and check if the handler is already * installed. */ current = head; do { if (current->handler == handler && current->arg == arg) { match = current; } tail = current; current = current->next; } while (current != NULL); /* Ensure the handler is not already installed */ if (match != NULL) { /* The handler is already installed */ bsp_interrupt_unlock(); return RTEMS_TOO_MANY; } /* Allocate a new entry */ current = bsp_interrupt_allocate_handler_entry(); if (current == NULL) { /* Not enough memory */ bsp_interrupt_unlock(); return RTEMS_NO_MEMORY; } /* Set entry */ current->handler = handler; current->arg = arg; current->info = info; current->next = NULL; /* Link to list tail */ rtems_interrupt_disable(level); tail->next = current; rtems_interrupt_enable(level); } /* Make the handler unique if necessary */ bsp_interrupt_set_handler_unique(index, RTEMS_INTERRUPT_IS_UNIQUE(options)); /* Enable the vector if necessary */ if (enable_vector) { sc = bsp_interrupt_vector_enable(vector); if (sc != RTEMS_SUCCESSFUL) { bsp_interrupt_unlock(); return sc; } } /* Unlock */ sc = bsp_interrupt_unlock(); if (sc != RTEMS_SUCCESSFUL) { return sc; } return RTEMS_SUCCESSFUL; }
void bsp_interrupt_vector_disable(rtems_vector_number vector) { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); }
void bsp_interrupt_vector_disable( rtems_vector_number irqnum) { /* FIXME: do something */ bsp_interrupt_assert(bsp_interrupt_is_valid_vector(irqnum)); }