26 #include <bsp/fatal.h> 33 #ifdef BSP_INTERRUPT_USE_INDEX_TABLE 34 bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table
35 [BSP_INTERRUPT_VECTOR_NUMBER];
39 [BSP_INTERRUPT_HANDLER_TABLE_SIZE];
42 static uint8_t bsp_interrupt_handler_unique_table
43 [(BSP_INTERRUPT_HANDLER_TABLE_SIZE + 7 + 1) / 8];
45 static void bsp_interrupt_handler_empty(
void *arg)
53 static void bsp_interrupt_handler_do_nothing(
void *arg)
63 return (bsp_interrupt_handler_unique_table [i] >> s) & 0x1;
66 static inline void bsp_interrupt_set_handler_unique(
74 bsp_interrupt_handler_unique_table [i] |= (uint8_t) (0x1U << s);
76 bsp_interrupt_handler_unique_table [i] &= (uint8_t) ~(0x1U << s);
80 static inline bool bsp_interrupt_is_initialized(
void)
82 return bsp_interrupt_is_handler_unique(BSP_INTERRUPT_HANDLER_TABLE_SIZE);
85 static inline void bsp_interrupt_set_initialized(
void)
87 bsp_interrupt_set_handler_unique(BSP_INTERRUPT_HANDLER_TABLE_SIZE,
true);
90 static inline bool bsp_interrupt_is_empty_handler_entry(
94 return e->handler == bsp_interrupt_handler_empty;
97 static inline void bsp_interrupt_clear_handler_entry(
102 e->handler = bsp_interrupt_handler_empty;
103 bsp_interrupt_fence(ATOMIC_ORDER_RELEASE);
104 e->arg = (
void *) (uintptr_t) vector;
109 static inline bool bsp_interrupt_allocate_handler_index(
114 #ifdef BSP_INTERRUPT_USE_INDEX_TABLE 118 for (i = 1; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i) {
120 if (bsp_interrupt_is_empty_handler_entry(e)) {
128 *index = bsp_interrupt_handler_index(vector);
137 #ifdef BSP_INTERRUPT_NO_HEAP_USAGE 140 if (bsp_interrupt_allocate_handler_index(0, &index)) {
141 e = &bsp_interrupt_handler_table [index];
154 #ifdef BSP_INTERRUPT_NO_HEAP_USAGE 155 bsp_interrupt_clear_handler_entry(e, 0);
167 for (i = 0; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i) {
168 bsp_interrupt_handler_table [i].handler = bsp_interrupt_handler_empty;
169 bsp_interrupt_handler_table [i].arg = (
void *) i;
174 bsp_fatal(BSP_FATAL_INTERRUPT_INITIALIZATION);
177 bsp_interrupt_set_initialized();
204 bool enable_vector =
false;
208 if (!bsp_interrupt_is_initialized()) {
212 }
else if (handler == NULL) {
219 bsp_interrupt_lock();
222 index = bsp_interrupt_handler_index(vector);
225 head = &bsp_interrupt_handler_table [index];
227 if (bsp_interrupt_is_empty_handler_entry(head)) {
230 bsp_interrupt_unlock();
238 if (bsp_interrupt_allocate_handler_index(vector, &index)) {
239 bsp_interrupt_disable(level);
240 bsp_interrupt_handler_table [index].arg = arg;
241 bsp_interrupt_fence(ATOMIC_ORDER_RELEASE);
242 bsp_interrupt_handler_table [index].handler = handler;
243 #ifdef BSP_INTERRUPT_USE_INDEX_TABLE 244 bsp_interrupt_handler_index_table [vector] = index;
246 bsp_interrupt_enable(level);
247 bsp_interrupt_handler_table [index].info = info;
250 bsp_interrupt_unlock();
255 enable_vector =
true;
265 || bsp_interrupt_is_handler_unique(index))
271 bsp_interrupt_unlock();
282 && (current->handler == handler || replace)
283 && current->arg == arg
288 current = current->next;
289 }
while (current != NULL);
294 bsp_interrupt_unlock();
304 bsp_interrupt_unlock();
309 current = bsp_interrupt_allocate_handler_entry();
310 if (current == NULL) {
312 bsp_interrupt_unlock();
318 current->handler = handler;
319 current->info = info;
324 current->next = NULL;
327 bsp_interrupt_disable(level);
328 bsp_interrupt_fence(ATOMIC_ORDER_RELEASE);
329 tail->next = current;
330 bsp_interrupt_enable(level);
343 bsp_interrupt_unlock();
372 if (!bsp_interrupt_is_initialized()) {
376 }
else if (handler == NULL) {
383 bsp_interrupt_lock();
386 index = bsp_interrupt_handler_index(vector);
389 head = &bsp_interrupt_handler_table [index];
394 if (current->handler == handler && current->arg == arg) {
399 current = current->next;
400 }
while (current != NULL);
404 if (match->next != NULL) {
410 current = match->next;
412 bsp_interrupt_disable(level);
414 match->handler = bsp_interrupt_handler_do_nothing;
415 bsp_interrupt_fence(ATOMIC_ORDER_RELEASE);
417 match->arg = current->arg;
418 bsp_interrupt_fence(ATOMIC_ORDER_RELEASE);
419 match->handler = current->handler;
420 match->info = current->info;
421 match->next = current->next;
422 bsp_interrupt_enable(level);
424 bsp_interrupt_free_handler_entry(current);
425 }
else if (match == head) {
437 bsp_interrupt_disable(level);
438 bsp_interrupt_clear_handler_entry(head, vector);
439 #ifdef BSP_INTERRUPT_USE_INDEX_TABLE 440 bsp_interrupt_handler_index_table [vector] = 0;
442 bsp_interrupt_enable(level);
445 bsp_interrupt_set_handler_unique(index,
false);
451 bsp_interrupt_disable(level);
452 previous->next = NULL;
453 bsp_interrupt_fence(ATOMIC_ORDER_RELEASE);
454 bsp_interrupt_enable(level);
456 bsp_interrupt_free_handler_entry(match);
460 bsp_interrupt_unlock();
465 bsp_interrupt_unlock();
491 if (!bsp_interrupt_is_initialized()) {
500 bsp_interrupt_lock();
503 index = bsp_interrupt_handler_index(vector);
504 current = &bsp_interrupt_handler_table [index];
505 if (!bsp_interrupt_is_empty_handler_entry(current)) {
507 options = bsp_interrupt_is_handler_unique(index) ?
509 routine(arg, current->info, options, current->handler, current->arg);
510 current = current->next;
511 }
while (current != NULL);
515 bsp_interrupt_unlock();
558 index = bsp_interrupt_handler_index(vector);
561 head = &bsp_interrupt_handler_table [index];
563 empty = bsp_interrupt_is_empty_handler_entry(head);
570 size_t affinity_size,
571 const cpu_set_t *affinity
575 Processor_mask_Copy_status status;
582 if (status != PROCESSOR_MASK_COPY_LOSSLESS) {
586 #if defined(RTEMS_SMP) 587 bsp_interrupt_set_affinity(vector, &
set);
594 size_t affinity_size,
599 Processor_mask_Copy_status status;
605 #if defined(RTEMS_SMP) 606 bsp_interrupt_get_affinity(vector, &
set);
612 if (status != PROCESSOR_MASK_COPY_LOSSLESS) {
This status code indicates you have attempted to create too many instances of a particular object cla...
RTEMS_INLINE_ROUTINE Processor_mask_Copy_status _Processor_mask_From_cpu_set_t(Processor_mask *dst, size_t src_size, const cpu_set_t *src)
Copies one mask to another.
Generic BSP interrupt support API.
void * rtems_malloc(size_t size) RTEMS_MALLOCLIKE RTEMS_ALLOC_SIZE(1) RTEMS_WARN_UNUSED_RESULT
Allocates a memory area of the specified size from the heap.
uint32_t rtems_option
This type is used to represent an option set.
#define RTEMS_INTERRUPT_SHARED
Allows that this interrupt handler may share a common interrupt vector with other handler...
static rtems_status_code bsp_interrupt_handler_remove(rtems_vector_number vector, rtems_interrupt_handler handler, void *arg)
Removes an interrupt handler.
This status code indicates that the object still had resources in use.
This status code indicates that the request was not satisfied.
RTEMS_INLINE_ROUTINE Processor_mask_Copy_status _Processor_mask_To_cpu_set_t(const Processor_mask *src, size_t dst_size, cpu_set_t *dst)
Copies one mask to another.
rtems_status_code rtems_interrupt_handler_remove(rtems_vector_number vector, rtems_interrupt_handler handler, void *arg)
Removes the interrupt handler routine handler with argument arg for the interrupt vector with number ...
#define rtems_interrupt_is_in_progress()
%
void bsp_interrupt_vector_disable(rtems_vector_number vector)
Disables the interrupt vector with number vector.
bool bsp_interrupt_handler_is_empty(rtems_vector_number vector)
Is interrupt handler empty.
rtems_status_code rtems_interrupt_handler_install(rtems_vector_number vector, const char *info, rtems_option options, rtems_interrupt_handler handler, void *arg)
Installs the interrupt handler routine handler for the interrupt vector with number vector...
static rtems_status_code bsp_interrupt_handler_install(rtems_vector_number vector, const char *info, rtems_option options, rtems_interrupt_handler handler, void *arg)
Installs an interrupt handler.
This status code indicates successful completion.
ISR_Level rtems_interrupt_level
%
rtems_status_code rtems_interrupt_get_affinity(rtems_vector_number vector, size_t affinity_size, cpu_set_t *affinity)
Gets the processor affinity set of an interrupt vector.
rtems_status_code
This enumeration provides status codes for directives of the Classic API.
#define RTEMS_INTERRUPT_IS_REPLACE(options)
Returns true if the interrupt handler replace option is set.
#define RTEMS_INTERRUPT_UNIQUE
Makes the interrupt handler unique. Prevents other handler from using the same interrupt vector...
void bsp_interrupt_handler_default(rtems_vector_number vector)
Default interrupt handler.
RTEMS_INLINE_ROUTINE void _Processor_mask_From_index(Processor_mask *mask, uint32_t index)
Creates a processor set from the specified index.
This status code indicates that a specified address was invalid.
static bool bsp_interrupt_is_valid_vector(rtems_vector_number vector)
Returns true if the interrupt vector with number vector is valid.
void(* rtems_interrupt_per_handler_routine)(void *, const char *, rtems_option, rtems_interrupt_handler, void *)
Interrupt handler iteration routine type.
This status code indicates that the operation should not be called from this execution environment...
This status code indicates that an object identifier was invalid.
static rtems_status_code bsp_interrupt_handler_iterate(rtems_vector_number vector, rtems_interrupt_per_handler_routine routine, void *arg)
Iterates over all installed interrupt handler of a vector.
void(* rtems_interrupt_handler)(void *)
Interrupt handler routine type.
This status code indicates that the directive attempted to allocate memory but was unable to do so...
void bsp_interrupt_initialize(void)
Initialize BSP interrupt support.
This status code indicates that an internal RTEMS inconsistency was detected.
rtems_status_code rtems_interrupt_set_affinity(rtems_vector_number vector, size_t affinity_size, const cpu_set_t *affinity)
Sets the processor affinity set of an interrupt vector.
ISR_Vector_number rtems_vector_number
%
rtems_status_code bsp_interrupt_facility_initialize(void)
BSP specific initialization.
rtems_status_code rtems_interrupt_handler_iterate(rtems_vector_number vector, rtems_interrupt_per_handler_routine routine, void *arg)
Iterates over all installed interrupt handler of the interrupt vector with number vector...
void bsp_interrupt_vector_enable(rtems_vector_number vector)
Enables the interrupt vector with number vector.
#define RTEMS_INTERRUPT_IS_UNIQUE(options)
Returns true if the interrupt handler unique option is set.
This status code indicates that a specified size was invalid.