RTEMS 6.1-rc5
Loading...
Searching...
No Matches
irq-generic.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-2-Clause */
2
12/*
13 * Copyright (C) 2016 Chris Johns <chrisj@rtems.org>
14 *
15 * Copyright (C) 2008, 2024 embedded brains GmbH & Co. KG
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39/*
40 * The API is based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
41 */
42
43#ifndef LIBBSP_SHARED_IRQ_GENERIC_H
44#define LIBBSP_SHARED_IRQ_GENERIC_H
45
46#include <stdbool.h>
47
48#include <rtems/irq-extension.h>
49#include <rtems/score/assert.h>
51
52#ifdef RTEMS_SMP
53 #include <rtems/score/atomic.h>
54#endif
55
56#include <bsp/irq.h>
57
58#ifdef __cplusplus
59extern "C" {
60#endif /* __cplusplus */
61
62#if !defined(BSP_INTERRUPT_VECTOR_COUNT)
63 #error "BSP_INTERRUPT_VECTOR_COUNT shall be defined"
64#endif
65
66#if defined(BSP_INTERRUPT_USE_INDEX_TABLE) && !defined(BSP_INTERRUPT_DISPATCH_TABLE_SIZE)
67 #error "if you define BSP_INTERRUPT_USE_INDEX_TABLE, you have to define BSP_INTERRUPT_DISPATCH_TABLE_SIZE etc. as well"
68#endif
69
70#ifndef BSP_INTERRUPT_DISPATCH_TABLE_SIZE
71 #define BSP_INTERRUPT_DISPATCH_TABLE_SIZE BSP_INTERRUPT_VECTOR_COUNT
72#endif
73
74#if !defined(BSP_IRQ_HAVE_GET_SET_AFFINITY) && defined(RTEMS_SMP)
75 #define BSP_IRQ_HAVE_GET_SET_AFFINITY
76#endif
77
78#define bsp_interrupt_assert(e) _Assert(e)
79
85
86#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
87 #if BSP_INTERRUPT_DISPATCH_TABLE_SIZE < 0x100
88 typedef uint8_t bsp_interrupt_dispatch_index_type;
89 #elif BSP_INTERRUPT_DISPATCH_TABLE_SIZE < 0x10000
90 typedef uint16_t bsp_interrupt_dispatch_index_type;
91 #else
92 typedef uint32_t bsp_interrupt_dispatch_index_type;
93 #endif
94 extern bsp_interrupt_dispatch_index_type bsp_interrupt_dispatch_index_table [];
95#endif
96
97static inline rtems_vector_number bsp_interrupt_dispatch_index(
99)
100{
101 #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
102 return bsp_interrupt_dispatch_index_table [vector];
103 #else
104 return vector;
105 #endif
106}
107
158#ifdef BSP_INTERRUPT_CUSTOM_VALID_VECTOR
159 bool bsp_interrupt_is_valid_vector(rtems_vector_number vector);
160#else
165 static inline bool bsp_interrupt_is_valid_vector(rtems_vector_number vector)
166 {
167 return vector < (rtems_vector_number) BSP_INTERRUPT_VECTOR_COUNT;
168 }
169#endif
170
181
194void bsp_interrupt_initialize(void);
195
210
224 rtems_vector_number vector,
226);
227
247 rtems_vector_number vector,
248 bool *enabled
249);
250
273
297
320 rtems_vector_number vector,
321 bool *pending
322);
323
339
340#if defined(RTEMS_SMP)
358rtems_status_code bsp_interrupt_raise_on(
359 rtems_vector_number vector,
360 uint32_t cpu_index
361);
362#endif
363
379
400 rtems_vector_number vector,
401 uint32_t *priority
402);
403
425 rtems_vector_number vector,
426 uint32_t priority
427);
428
448 rtems_vector_number vector,
449 Processor_mask *affinity
450);
451
474 rtems_vector_number vector,
475 const Processor_mask *affinity
476);
477
478#if defined(RTEMS_SMP)
484void bsp_interrupt_spurious( rtems_vector_number vector );
485#endif
486
494static inline rtems_interrupt_entry *bsp_interrupt_entry_load_acquire(
495 rtems_interrupt_entry * const *ptr
496)
497{
498#if defined(RTEMS_SMP)
499 return (rtems_interrupt_entry *) _Atomic_Load_uintptr(
500 (const Atomic_Uintptr *) ptr,
501 ATOMIC_ORDER_ACQUIRE
502 );
503#else
504 return *ptr;
505#endif
506}
507
515static inline void bsp_interrupt_entry_store_release(
518)
519{
520#if defined(RTEMS_SMP)
521 _Atomic_Store_uintptr(
522 (Atomic_Uintptr *) ptr,
523 (uintptr_t) value,
524 ATOMIC_ORDER_RELEASE
525 );
526#else
528
530 *ptr = value;
532#endif
533}
534
542static inline rtems_interrupt_entry *bsp_interrupt_entry_load_first(
544)
545{
547
548 index = bsp_interrupt_dispatch_index( vector );
549
550 return bsp_interrupt_entry_load_acquire(
552 );
553}
554
566static inline void bsp_interrupt_dispatch_entries(
568)
569{
570 do {
571 ( *entry->handler )( entry->arg );
572 entry = bsp_interrupt_entry_load_acquire( &entry->next );
573 } while ( RTEMS_PREDICT_FALSE( entry != NULL ) );
574}
575
592static inline void bsp_interrupt_handler_dispatch_unlikely(
594)
595{
597
598 entry = bsp_interrupt_entry_load_first( vector );
599
600 if ( RTEMS_PREDICT_FALSE( entry != NULL ) ) {
601 bsp_interrupt_dispatch_entries( entry );
602 }
603}
604
618static inline void bsp_interrupt_handler_dispatch_unchecked(
620)
621{
623
624 entry = bsp_interrupt_entry_load_first( vector );
625
626 if ( RTEMS_PREDICT_TRUE( entry != NULL ) ) {
627 bsp_interrupt_dispatch_entries( entry );
628 } else {
629#if defined(RTEMS_SMP)
630 bsp_interrupt_spurious( vector );
631#else
633#endif
634 }
635}
636
651static inline void bsp_interrupt_handler_dispatch( rtems_vector_number vector )
652{
653 if ( bsp_interrupt_is_valid_vector( vector ) ) {
654 bsp_interrupt_handler_dispatch_unchecked( vector );
655 } else {
657 }
658}
659
668void bsp_interrupt_lock(void);
669
675void bsp_interrupt_unlock(void);
676
698 rtems_vector_number vector,
700);
701
702/* For internal use only */
703rtems_interrupt_entry *bsp_interrupt_entry_find(
704 rtems_vector_number vector,
706 void *arg,
707 rtems_interrupt_entry ***previous_next
708);
709
710/* For internal use only */
711void bsp_interrupt_entry_remove(
712 rtems_vector_number vector,
714 rtems_interrupt_entry **previous_next
715);
716
727
737static inline bool bsp_interrupt_is_handler_unique( rtems_vector_number index )
738{
739 rtems_vector_number table_index;
740 uint8_t bit;
741
742 table_index = index / 8;
743 bit = (uint8_t) ( 1U << ( index % 8 ) );
744
745 return ( bsp_interrupt_handler_unique_table[ table_index ] & bit ) != 0;
746}
747
755static inline void bsp_interrupt_set_handler_unique(
757 bool unique
758)
759{
760 rtems_vector_number table_index;
761 uint8_t bit;
762
763 table_index = index / 8;
764 bit = (uint8_t) ( 1U << ( index % 8 ) );
765
766 if (unique) {
767 bsp_interrupt_handler_unique_table[ table_index ] |= bit;
768 } else {
769 bsp_interrupt_handler_unique_table[ table_index ] &= ~bit;
770 }
771}
772
779static inline bool bsp_interrupt_is_initialized( void )
780{
781 return bsp_interrupt_is_handler_unique( BSP_INTERRUPT_DISPATCH_TABLE_SIZE );
782}
783
793);
794
795#ifdef __cplusplus
796}
797#endif /* __cplusplus */
798
799#endif /* LIBBSP_SHARED_IRQ_GENERIC_H */
This header file provides the interfaces of the Assert Handler.
#define RTEMS_PREDICT_FALSE(_exp)
Evaluates the integral expression and tells the compiler that the predicted value is false (0).
Definition: basedefs.h:732
#define RTEMS_PREDICT_TRUE(_exp)
Evaluates the integral expression and tells the compiler that the predicted value is true (1).
Definition: basedefs.h:751
ISR_Vector_number rtems_vector_number
This integer type represents interrupt vector numbers.
Definition: intr.h:102
#define rtems_interrupt_local_disable(_isr_cookie)
Disables the maskable interrupts on the current processor.
Definition: intr.h:427
ISR_Level rtems_interrupt_level
This integer type represents interrupt levels.
Definition: intr.h:111
void(* rtems_interrupt_handler)(void *)
Interrupt handler routines shall have this type.
Definition: intr.h:1030
#define rtems_interrupt_local_enable(_isr_cookie)
Restores the previous interrupt level on the current processor.
Definition: intr.h:468
rtems_status_code
This enumeration provides status codes for directives of the Classic API.
Definition: status.h:85
rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
Disables the interrupt vector.
Definition: irq.c:153
rtems_status_code bsp_interrupt_set_priority(rtems_vector_number vector, uint32_t priority)
Sets the priority of the interrupt vector.
Definition: irq.c:166
rtems_status_code bsp_interrupt_vector_is_enabled(rtems_vector_number vector, bool *enabled)
Checks if the interrupt is enabled.
Definition: irq.c:129
void bsp_interrupt_handler_default(rtems_vector_number vector)
Default interrupt handler.
Definition: irq.c:250
rtems_status_code bsp_interrupt_get_affinity(rtems_vector_number vector, Processor_mask *affinity)
Gets the processor affinity set of the interrupt vector.
Definition: irq.c:426
rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
Enables the interrupt vector.
Definition: irq.c:140
void bsp_interrupt_facility_initialize(void)
BSP specific initialization.
Definition: irq.c:185
rtems_status_code bsp_interrupt_get_priority(rtems_vector_number vector, uint32_t *priority)
Gets the priority of the interrupt vector.
Definition: irq.c:175
rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
Causes the interrupt vector.
Definition: irq.c:117
rtems_status_code bsp_interrupt_is_pending(rtems_vector_number vector, bool *pending)
Checks if the interrupt is pending.
Definition: irq.c:106
rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
Clears the interrupt vector.
Definition: irq.c:123
rtems_status_code bsp_interrupt_get_attributes(rtems_vector_number vector, rtems_interrupt_attributes *attributes)
Gets the attributes of the interrupt vector.
Definition: irq.c:98
void bsp_interrupt_initialize(void)
Initialize Interrupt Manager implementation.
Definition: irq-generic.c:163
rtems_status_code bsp_interrupt_set_affinity(rtems_vector_number vector, const Processor_mask *affinity)
Sets the processor affinity set of the interrupt vector.
Definition: irq.c:406
This header file provides the interfaces of the Atomic Operations.
This header file is provided for backward compatiblility.
uint8_t bsp_interrupt_handler_unique_table[]
This table contains a bit map which indicates if an entry is unique or shared.
Definition: irq-generic.c:58
rtems_interrupt_entry ** bsp_interrupt_get_dispatch_table_slot(rtems_vector_number index)
Gets a reference to the interrupt handler table slot associated with the index.
Definition: irq-generic.c:49
rtems_interrupt_entry * bsp_interrupt_dispatch_table[]
Each member of this table references the first installed entry at the corresponding interrupt vector ...
Definition: irq-generic.c:47
void bsp_interrupt_lock(void)
Acquires the interrupt support lock.
Definition: irq-lock.c:42
void bsp_interrupt_unlock(void)
Releases the interrupt support lock.
Definition: irq-lock.c:49
rtems_status_code bsp_interrupt_check_and_lock(rtems_vector_number vector, rtems_interrupt_handler handler)
Checks the vector and routine. When the checks were successful, the interrupt support lock will be ob...
Definition: irq-generic.c:110
This header file provides the interfaces of the Processor Mask.
Definition: mmu-config.c:53
This structure provides the attributes of an interrupt vector.
Definition: intr.h:2076
This structure represents an interrupt entry.
Definition: intr.h:1070