![]() |
|
|||
File indexing completed on 2025-05-11 08:23:42
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @ingroup RTEMSImplClassicIntr 0007 * 0008 * @brief This header file provides interfaces of the Interrupt Manager 0009 * implementation. 0010 */ 0011 0012 /* 0013 * Copyright (C) 2016 Chris Johns <chrisj@rtems.org> 0014 * 0015 * Copyright (C) 2008, 2024 embedded brains GmbH & Co. KG 0016 * 0017 * Redistribution and use in source and binary forms, with or without 0018 * modification, are permitted provided that the following conditions 0019 * are met: 0020 * 1. Redistributions of source code must retain the above copyright 0021 * notice, this list of conditions and the following disclaimer. 0022 * 2. Redistributions in binary form must reproduce the above copyright 0023 * notice, this list of conditions and the following disclaimer in the 0024 * documentation and/or other materials provided with the distribution. 0025 * 0026 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0027 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0028 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0029 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0030 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0031 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0032 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0033 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0034 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0035 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0036 * POSSIBILITY OF SUCH DAMAGE. 0037 */ 0038 0039 /* 0040 * The API is based on concepts of Pavel Pisa, Till Straumann and Eric Valette. 0041 */ 0042 0043 #ifndef LIBBSP_SHARED_IRQ_GENERIC_H 0044 #define LIBBSP_SHARED_IRQ_GENERIC_H 0045 0046 #include <stdbool.h> 0047 0048 #include <rtems/irq-extension.h> 0049 #include <rtems/score/assert.h> 0050 #include <rtems/score/processormask.h> 0051 0052 #ifdef RTEMS_SMP 0053 #include <rtems/score/atomic.h> 0054 #endif 0055 0056 #include <bsp/irq.h> 0057 0058 #ifdef __cplusplus 0059 extern "C" { 0060 #endif /* __cplusplus */ 0061 0062 #if !defined(BSP_INTERRUPT_VECTOR_COUNT) 0063 #error "BSP_INTERRUPT_VECTOR_COUNT shall be defined" 0064 #endif 0065 0066 #if defined(BSP_INTERRUPT_USE_INDEX_TABLE) && !defined(BSP_INTERRUPT_DISPATCH_TABLE_SIZE) 0067 #error "if you define BSP_INTERRUPT_USE_INDEX_TABLE, you have to define BSP_INTERRUPT_DISPATCH_TABLE_SIZE etc. as well" 0068 #endif 0069 0070 #ifndef BSP_INTERRUPT_DISPATCH_TABLE_SIZE 0071 #define BSP_INTERRUPT_DISPATCH_TABLE_SIZE BSP_INTERRUPT_VECTOR_COUNT 0072 #endif 0073 0074 #if !defined(BSP_IRQ_HAVE_GET_SET_AFFINITY) && defined(RTEMS_SMP) 0075 #define BSP_IRQ_HAVE_GET_SET_AFFINITY 0076 #endif 0077 0078 #define bsp_interrupt_assert(e) _Assert(e) 0079 0080 /** 0081 * @brief Each member of this table references the first installed entry at the 0082 * corresponding interrupt vector or is NULL. 0083 */ 0084 extern rtems_interrupt_entry *bsp_interrupt_dispatch_table[]; 0085 0086 #ifdef BSP_INTERRUPT_USE_INDEX_TABLE 0087 #if BSP_INTERRUPT_DISPATCH_TABLE_SIZE < 0x100 0088 typedef uint8_t bsp_interrupt_dispatch_index_type; 0089 #elif BSP_INTERRUPT_DISPATCH_TABLE_SIZE < 0x10000 0090 typedef uint16_t bsp_interrupt_dispatch_index_type; 0091 #else 0092 typedef uint32_t bsp_interrupt_dispatch_index_type; 0093 #endif 0094 extern bsp_interrupt_dispatch_index_type bsp_interrupt_dispatch_index_table []; 0095 #endif 0096 0097 static inline rtems_vector_number bsp_interrupt_dispatch_index( 0098 rtems_vector_number vector 0099 ) 0100 { 0101 #ifdef BSP_INTERRUPT_USE_INDEX_TABLE 0102 return bsp_interrupt_dispatch_index_table [vector]; 0103 #else 0104 return vector; 0105 #endif 0106 } 0107 0108 /** 0109 * @defgroup RTEMSImplClassicIntr Interrupt Manager 0110 * 0111 * @ingroup RTEMSImplClassic 0112 * 0113 * @brief This group contains the Interrupt Manager implementation. 0114 * 0115 * The Interrupt Manager implementation manages a sequence of interrupt vector 0116 * numbers greater than or equal to zero and less than 0117 * ``BSP_INTERRUPT_VECTOR_COUNT``. It provides methods to install, remove, and 0118 * dispatch interrupt entries for each vector number, see 0119 * bsp_interrupt_dispatch_entries(). 0120 * 0121 * The entry points to a list of interrupt entries are stored in a table 0122 * (= dispatch table). 0123 * 0124 * You have to configure the Interrupt Manager implementation in the <bsp/irq.h> file 0125 * for each BSP. For a minimum configuration you have to provide 0126 * ``BSP_INTERRUPT_VECTOR_COUNT``. 0127 * 0128 * For boards with small memory requirements you can define 0129 * ``BSP_INTERRUPT_USE_INDEX_TABLE``. With an enabled index table the 0130 * dispatch table will be accessed via a small index table. You can define the 0131 * size of the dispatch table with ``BSP_INTERRUPT_DISPATCH_TABLE_SIZE``. 0132 * 0133 * You have to provide some special routines in your BSP (follow the links for 0134 * the details): 0135 * - bsp_interrupt_facility_initialize() 0136 * - bsp_interrupt_vector_enable() 0137 * - bsp_interrupt_vector_disable() 0138 * - bsp_interrupt_handler_default() 0139 * 0140 * Optionally, the BSP may define the following macros to customize the vector 0141 * installation after installing the first entry and the vector removal before 0142 * removing the last entry: 0143 * - bsp_interrupt_vector_install() 0144 * - bsp_interrupt_vector_remove() 0145 * 0146 * The following now deprecated functions are provided for backward 0147 * compatibility: 0148 * - BSP_get_current_rtems_irq_handler() 0149 * - BSP_install_rtems_irq_handler() 0150 * - BSP_install_rtems_shared_irq_handler() 0151 * - BSP_remove_rtems_irq_handler() 0152 * - BSP_rtems_irq_mngt_set() 0153 * - BSP_rtems_irq_mngt_get() 0154 * 0155 * @{ 0156 */ 0157 0158 #ifdef BSP_INTERRUPT_CUSTOM_VALID_VECTOR 0159 bool bsp_interrupt_is_valid_vector(rtems_vector_number vector); 0160 #else 0161 /** 0162 * @brief Returns true if the interrupt vector with number @a vector is 0163 * valid. 0164 */ 0165 static inline bool bsp_interrupt_is_valid_vector(rtems_vector_number vector) 0166 { 0167 return vector < (rtems_vector_number) BSP_INTERRUPT_VECTOR_COUNT; 0168 } 0169 #endif 0170 0171 /** 0172 * @brief Default interrupt handler. 0173 * 0174 * This routine will be called from bsp_interrupt_handler_dispatch() with the 0175 * current vector number @a vector when the handler list for this vector is 0176 * empty or the vector number is out of range. 0177 * 0178 * @note This function must cope with arbitrary vector numbers @a vector. 0179 */ 0180 void bsp_interrupt_handler_default(rtems_vector_number vector); 0181 0182 /** 0183 * @brief Initialize Interrupt Manager implementation. 0184 * 0185 * You must call this function before you can install, remove and dispatch 0186 * interrupt entries. There is no protection against concurrent 0187 * initialization. This function must be called at most once. The BSP 0188 * specific bsp_interrupt_facility_initialize() function will be called after 0189 * all internals are initialized. If the BSP specific initialization fails, 0190 * then this is a fatal error. The fatal error source is 0191 * RTEMS_FATAL_SOURCE_BSP and the fatal error code is 0192 * BSP_FATAL_INTERRUPT_INITIALIZATION. 0193 */ 0194 void bsp_interrupt_initialize(void); 0195 0196 /** 0197 * @brief BSP specific initialization. 0198 * 0199 * This routine will be called form bsp_interrupt_initialize() and shall do the 0200 * following: 0201 * - Initialize the facilities that call bsp_interrupt_handler_dispatch(). For 0202 * example on PowerPC the external exception handler. 0203 * - Initialize the interrupt controller. You shall set the interrupt 0204 * controller in a state such that interrupts are disabled for all vectors. 0205 * The vectors will be enabled with your bsp_interrupt_vector_enable() function 0206 * and disabled via your bsp_interrupt_vector_disable() function. These 0207 * functions have to work afterwards. 0208 */ 0209 void bsp_interrupt_facility_initialize(void); 0210 0211 /** 0212 * @brief Gets the attributes of the interrupt vector. 0213 * 0214 * @param vector is the interrupt vector number. It shall be valid. 0215 * 0216 * @param[out] attributes is the pointer to an rtems_interrupt_attributes 0217 * object. When the function call is successful, the attributes of the 0218 * interrupt vector will be stored in this object. The pointer shall not be 0219 * NULL. The object shall be cleared to zero by the caller. 0220 * 0221 * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. 0222 */ 0223 rtems_status_code bsp_interrupt_get_attributes( 0224 rtems_vector_number vector, 0225 rtems_interrupt_attributes *attributes 0226 ); 0227 0228 /** 0229 * @brief Checks if the interrupt is enabled. 0230 * 0231 * The function checks if the interrupt associated with the interrupt vector 0232 * specified by ``vector`` was enabled for the processor executing the function 0233 * call at some time point during the call. 0234 * 0235 * @param vector is the interrupt vector number. It shall be valid. 0236 * 0237 * @param[out] enabled is the pointer to a ``bool`` object. It shall not be 0238 * ``NULL``. When the function call is successful, the enabled status of 0239 * the interrupt associated with the interrupt vector specified by ``vector`` 0240 * will be stored in this object. When the interrupt was enabled for the 0241 * processor executing the function call at some time point during the call, 0242 * the object will be set to true, otherwise to false. 0243 * 0244 * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. 0245 */ 0246 rtems_status_code bsp_interrupt_vector_is_enabled( 0247 rtems_vector_number vector, 0248 bool *enabled 0249 ); 0250 0251 /** 0252 * @brief Enables the interrupt vector. 0253 * 0254 * This function shall enable the vector at the corresponding facility (in most 0255 * cases the interrupt controller). It will be called then the first entry 0256 * is installed for the vector in rtems_interrupt_entry_install() for example. 0257 * 0258 * @note The implementation should use 0259 * bsp_interrupt_assert( bsp_interrupt_is_valid_vector( vector ) ) to validate 0260 * the vector number in ::RTEMS_DEBUG configurations. 0261 * 0262 * @param vector is the interrupt vector number. 0263 * 0264 * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. 0265 * 0266 * @retval ::RTEMS_UNSATISFIED The request to enable the interrupt vector has 0267 * not been satisfied. The presence of this error condition is 0268 * implementation-defined. The interrupt vector attributes obtained by 0269 * rtems_interrupt_get_attributes() should indicate if it is possible to 0270 * enable a particular interrupt vector. 0271 */ 0272 rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number vector ); 0273 0274 /** 0275 * @brief Disables the interrupt vector. 0276 * 0277 * This function shall disable the vector at the corresponding facility (in 0278 * most cases the interrupt controller). It will be called then the last 0279 * entry is removed for the vector in rtems_interrupt_entry_remove() for 0280 * example. 0281 * 0282 * @note The implementation should use 0283 * bsp_interrupt_assert( bsp_interrupt_is_valid_vector( vector ) ) to validate 0284 * the vector number in ::RTEMS_DEBUG configurations. 0285 * 0286 * @param vector is the interrupt vector number. 0287 * 0288 * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. 0289 * 0290 * @retval ::RTEMS_UNSATISFIED The request to disable the interrupt vector has 0291 * not been satisfied. The presence of this error condition is 0292 * implementation-defined. The interrupt vector attributes obtained by 0293 * rtems_interrupt_get_attributes() should indicate if it is possible to 0294 * disable a particular interrupt vector. 0295 */ 0296 rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector ); 0297 0298 /** 0299 * @brief Checks if the interrupt is pending. 0300 * 0301 * The function checks if the interrupt associated with the interrupt vector 0302 * specified by ``vector`` was pending for the processor executing the function 0303 * call at some time point during the call. 0304 * 0305 * @param vector is the interrupt vector number. It shall be valid. 0306 * 0307 * @param[out] pending is the pointer to a ``bool`` object. It shall not be 0308 * ``NULL``. When the function call is successful, the pending status of 0309 * the interrupt associated with the interrupt vector specified by ``vector`` 0310 * will be stored in this object. When the interrupt was pending for the 0311 * processor executing the function call at some time point during the call, 0312 * the object will be set to true, otherwise to false. 0313 * 0314 * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. 0315 * 0316 * @retval ::RTEMS_UNSATISFIED The request to get the pending status has not 0317 * been satisfied. 0318 */ 0319 rtems_status_code bsp_interrupt_is_pending( 0320 rtems_vector_number vector, 0321 bool *pending 0322 ); 0323 0324 /** 0325 * @brief Causes the interrupt vector. 0326 * 0327 * @param vector is the number of the interrupt vector to cause. It shall be 0328 * valid. 0329 * 0330 * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. 0331 * 0332 * @retval ::RTEMS_UNSATISFIED The request to raise the interrupt vector has 0333 * not been satisfied. The presence of this error condition is 0334 * implementation-defined. The interrupt vector attributes obtained by 0335 * rtems_interrupt_get_attributes() should indicate if it is possible to 0336 * raise a particular interrupt vector. 0337 */ 0338 rtems_status_code bsp_interrupt_raise( rtems_vector_number vector ); 0339 0340 #if defined(RTEMS_SMP) 0341 /** 0342 * @brief Causes the interrupt vector on the processor. 0343 * 0344 * @param vector is the number of the interrupt vector to cause. It shall be 0345 * valid. 0346 * 0347 * @param cpu_index is the index of the target processor of the interrupt 0348 * vector to cause. It shall be valid. 0349 * 0350 * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. 0351 * 0352 * @retval ::RTEMS_UNSATISFIED The request to cause the interrupt vector has 0353 * not been satisfied. The presence of this error condition is 0354 * implementation-defined. The interrupt vector attributes obtained by 0355 * rtems_interrupt_get_attributes() should indicate if it is possible to 0356 * raise a particular interrupt vector on a specific processor. 0357 */ 0358 rtems_status_code bsp_interrupt_raise_on( 0359 rtems_vector_number vector, 0360 uint32_t cpu_index 0361 ); 0362 #endif 0363 0364 /** 0365 * @brief Clears the interrupt vector. 0366 * 0367 * @param vector is the number of the interrupt vector to clear. It shall be 0368 * valid. 0369 * 0370 * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. 0371 * 0372 * @retval ::RTEMS_UNSATISFIED The request to cause the interrupt vector has 0373 * not been satisfied. The presence of this error condition is 0374 * implementation-defined. The interrupt vector attributes obtained by 0375 * rtems_interrupt_get_attributes() should indicate if it is possible to 0376 * clear a particular interrupt vector. 0377 */ 0378 rtems_status_code bsp_interrupt_clear( rtems_vector_number vector ); 0379 0380 /** 0381 * @brief Gets the priority of the interrupt vector. 0382 * 0383 * The return status shall correspond to the 0384 * rtems_interrupt_attributes::can_get_priority value of the interrupt vector. 0385 * 0386 * @param vector is the interrupt vector number. The vector number shall be 0387 * less than BSP_INTERRUPT_VECTOR_COUNT. 0388 * 0389 * @param[out] priority is the pointer to an uint32_t object. When the 0390 * directive call is successful, the priority of the interrupt vector will be 0391 * stored in this object. The pointer shall be valid. 0392 * 0393 * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. 0394 * 0395 * @retval ::RTEMS_UNSATISFIED There is no priority associated with the 0396 * interrupt vector. This status shall be returned if the function is not 0397 * implemented by the BSP. 0398 */ 0399 rtems_status_code bsp_interrupt_get_priority( 0400 rtems_vector_number vector, 0401 uint32_t *priority 0402 ); 0403 0404 /** 0405 * @brief Sets the priority of the interrupt vector. 0406 * 0407 * The return status shall correspond to the 0408 * rtems_interrupt_attributes::can_set_priority value of the interrupt vector. 0409 * 0410 * @param vector is the interrupt vector number. The vector number shall be 0411 * less than BSP_INTERRUPT_VECTOR_COUNT. 0412 * 0413 * @param priority is the new priority for the interrupt vector. 0414 * 0415 * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. 0416 * 0417 * @retval ::RTEMS_INVALID_PRIORITY The priority specified by ``priority`` was 0418 * not a valid new priority for the interrupt vector. 0419 * 0420 * @retval ::RTEMS_UNSATISFIED The request to set the priority of the interrupt 0421 * vector has not been satisfied. This status shall be returned if the 0422 * function is not implemented by the BSP. 0423 */ 0424 rtems_status_code bsp_interrupt_set_priority( 0425 rtems_vector_number vector, 0426 uint32_t priority 0427 ); 0428 0429 /** 0430 * @brief Gets the processor affinity set of the interrupt vector. 0431 * 0432 * The function may have no implementation in uniprocessor configurations. 0433 * 0434 * @param vector is the interrupt vector number. 0435 * 0436 * @param[out] affinity is the pointer to a Processor_mask object. When the 0437 * directive call is successful, the processor affinity set of the interrupt 0438 * vector will be stored in this object. A set bit in the processor set 0439 * means that the corresponding processor is in the processor affinity set of 0440 * the interrupt vector, otherwise the bit is cleared. 0441 * 0442 * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. 0443 * 0444 * @retval ::RTEMS_UNSATISFIED The request to get the processor affinity of the 0445 * interrupt vector has not been satisfied. 0446 */ 0447 rtems_status_code bsp_interrupt_get_affinity( 0448 rtems_vector_number vector, 0449 Processor_mask *affinity 0450 ); 0451 0452 /** 0453 * @brief Sets the processor affinity set of the interrupt vector. 0454 * 0455 * The function may have no implementation in uniprocessor configurations. 0456 * 0457 * @param vector is the interrupt vector number. It shall be valid. 0458 * 0459 * @param affinity is the pointer to a Processor_mask object. The processor set 0460 * defines the new processor affinity set of the interrupt vector. A set bit 0461 * in the processor set means that the corresponding processor shall be in 0462 * the processor affinity set of the interrupt vector, otherwise the bit 0463 * shall be cleared. 0464 * 0465 * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. 0466 * 0467 * @retval ::RTEMS_INVALID_NUMBER The referenced processor set was not a valid 0468 * new processor affinity set for the interrupt vector. 0469 * 0470 * @retval ::RTEMS_UNSATISFIED The request to set the processor affinity of the 0471 * interrupt vector has not been satisfied. 0472 */ 0473 rtems_status_code bsp_interrupt_set_affinity( 0474 rtems_vector_number vector, 0475 const Processor_mask *affinity 0476 ); 0477 0478 #if defined(RTEMS_SMP) 0479 /** 0480 * @brief Handles a spurious interrupt. 0481 * 0482 * @param vector is the vector number. 0483 */ 0484 void bsp_interrupt_spurious( rtems_vector_number vector ); 0485 #endif 0486 0487 /** 0488 * @brief Loads the interrupt entry with atomic acquire semantic. 0489 * 0490 * @param ptr is the pointer to an ::rtems_interrupt_entry pointer. 0491 * 0492 * @return Returns the pointer value. 0493 */ 0494 static inline rtems_interrupt_entry *bsp_interrupt_entry_load_acquire( 0495 rtems_interrupt_entry * const *ptr 0496 ) 0497 { 0498 #if defined(RTEMS_SMP) 0499 return (rtems_interrupt_entry *) _Atomic_Load_uintptr( 0500 (const Atomic_Uintptr *) ptr, 0501 ATOMIC_ORDER_ACQUIRE 0502 ); 0503 #else 0504 return *ptr; 0505 #endif 0506 } 0507 0508 /** 0509 * @brief Stores the interrupt entry with atomic release semantic. 0510 * 0511 * @param[out] ptr is the pointer to an ::rtems_interrupt_entry pointer. 0512 * 0513 * @param value is the pointer value. 0514 */ 0515 static inline void bsp_interrupt_entry_store_release( 0516 rtems_interrupt_entry **ptr, 0517 rtems_interrupt_entry *value 0518 ) 0519 { 0520 #if defined(RTEMS_SMP) 0521 _Atomic_Store_uintptr( 0522 (Atomic_Uintptr *) ptr, 0523 (uintptr_t) value, 0524 ATOMIC_ORDER_RELEASE 0525 ); 0526 #else 0527 rtems_interrupt_level level; 0528 0529 rtems_interrupt_local_disable( level ); 0530 *ptr = value; 0531 rtems_interrupt_local_enable( level ); 0532 #endif 0533 } 0534 0535 /** 0536 * @brief Loads the first interrupt entry installed at the interrupt vector. 0537 * 0538 * @param vector is the vector number. 0539 * 0540 * @return Returns the first entry or NULL. 0541 */ 0542 static inline rtems_interrupt_entry *bsp_interrupt_entry_load_first( 0543 rtems_vector_number vector 0544 ) 0545 { 0546 rtems_vector_number index; 0547 0548 index = bsp_interrupt_dispatch_index( vector ); 0549 0550 return bsp_interrupt_entry_load_acquire( 0551 &bsp_interrupt_dispatch_table[ index ] 0552 ); 0553 } 0554 0555 /** 0556 * @brief Sequentially calls all interrupt handlers of the entry its 0557 * successors. 0558 * 0559 * In uniprocessor configurations, you can call this function within every 0560 * context which can be disabled via rtems_interrupt_local_disable(). 0561 * 0562 * In SMP configurations, you can call this function in every context. 0563 * 0564 * @param entry is the first entry. 0565 */ 0566 static inline void bsp_interrupt_dispatch_entries( 0567 const rtems_interrupt_entry *entry 0568 ) 0569 { 0570 do { 0571 ( *entry->handler )( entry->arg ); 0572 entry = bsp_interrupt_entry_load_acquire( &entry->next ); 0573 } while ( RTEMS_PREDICT_FALSE( entry != NULL ) ); 0574 } 0575 0576 /** 0577 * @brief Sequentially calls all interrupt handlers installed at the vector. 0578 * 0579 * This function does not validate the vector number. If the vector number is 0580 * out of range, then the behaviour is undefined. 0581 * 0582 * The function assumes that no interrupt entries are installed at the vector. 0583 * In this case, no operation is performed. 0584 * 0585 * In uniprocessor configurations, you can call this function within every 0586 * context which can be disabled via rtems_interrupt_local_disable(). 0587 * 0588 * In SMP configurations, you can call this function in every context. 0589 * 0590 * @param vector is the vector number. 0591 */ 0592 static inline void bsp_interrupt_handler_dispatch_unlikely( 0593 rtems_vector_number vector 0594 ) 0595 { 0596 const rtems_interrupt_entry *entry; 0597 0598 entry = bsp_interrupt_entry_load_first( vector ); 0599 0600 if ( RTEMS_PREDICT_FALSE( entry != NULL ) ) { 0601 bsp_interrupt_dispatch_entries( entry ); 0602 } 0603 } 0604 0605 /** 0606 * @brief Sequentially calls all interrupt handlers installed at the vector. 0607 * 0608 * This function does not validate the vector number. If the vector number is 0609 * out of range, then the behaviour is undefined. 0610 * 0611 * In uniprocessor configurations, you can call this function within every 0612 * context which can be disabled via rtems_interrupt_local_disable(). 0613 * 0614 * In SMP configurations, you can call this function in every context. 0615 * 0616 * @param vector is the vector number. 0617 */ 0618 static inline void bsp_interrupt_handler_dispatch_unchecked( 0619 rtems_vector_number vector 0620 ) 0621 { 0622 const rtems_interrupt_entry *entry; 0623 0624 entry = bsp_interrupt_entry_load_first( vector ); 0625 0626 if ( RTEMS_PREDICT_TRUE( entry != NULL ) ) { 0627 bsp_interrupt_dispatch_entries( entry ); 0628 } else { 0629 #if defined(RTEMS_SMP) 0630 bsp_interrupt_spurious( vector ); 0631 #else 0632 bsp_interrupt_handler_default( vector ); 0633 #endif 0634 } 0635 } 0636 0637 /** 0638 * @brief Sequentially calls all interrupt handlers installed at the vector. 0639 * 0640 * If the vector number is out of range or the interrupt entry list is empty, 0641 * then bsp_interrupt_handler_default() will be called with the vector number 0642 * as argument. 0643 * 0644 * In uniprocessor configurations, you can call this function within every 0645 * context which can be disabled via rtems_interrupt_local_disable(). 0646 * 0647 * In SMP configurations, you can call this function in every context. 0648 * 0649 * @param vector is the vector number. 0650 */ 0651 static inline void bsp_interrupt_handler_dispatch( rtems_vector_number vector ) 0652 { 0653 if ( bsp_interrupt_is_valid_vector( vector ) ) { 0654 bsp_interrupt_handler_dispatch_unchecked( vector ); 0655 } else { 0656 bsp_interrupt_handler_default( vector ); 0657 } 0658 } 0659 0660 /** @} */ 0661 0662 /** 0663 * @brief Acquires the interrupt support lock. 0664 * 0665 * The interrupt support lock is a mutex. The mutex is only acquired if the 0666 * system is the ::SYSTEM_STATE_UP state. 0667 */ 0668 void bsp_interrupt_lock(void); 0669 0670 /** 0671 * @brief Releases the interrupt support lock. 0672 * 0673 * The mutex is only released if the system is the ::SYSTEM_STATE_UP state. 0674 */ 0675 void bsp_interrupt_unlock(void); 0676 0677 /** 0678 * @brief Checks the vector and routine. When the checks were successful, the 0679 * interrupt support lock will be obtained. 0680 * 0681 * @param vector is the interrupt vector number to check. 0682 * 0683 * @param routine is the routine to check. 0684 * 0685 * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. 0686 * 0687 * @retval ::RTEMS_INCORRECT_STATE The interrupt support was not initialized. 0688 * 0689 * @retval ::RTEMS_CALLED_FROM_ISR The function was called from within 0690 * interrupt context. 0691 * 0692 * @retval ::RTEMS_INVALID_ADDRESS The ``routine`` parameter was NULL. 0693 * 0694 * @retval ::RTEMS_INVALID_ID There was no interrupt vector associated with the 0695 * number specified by ``vector``. 0696 */ 0697 rtems_status_code bsp_interrupt_check_and_lock( 0698 rtems_vector_number vector, 0699 rtems_interrupt_handler handler 0700 ); 0701 0702 /* For internal use only */ 0703 rtems_interrupt_entry *bsp_interrupt_entry_find( 0704 rtems_vector_number vector, 0705 rtems_interrupt_handler routine, 0706 void *arg, 0707 rtems_interrupt_entry ***previous_next 0708 ); 0709 0710 /* For internal use only */ 0711 void bsp_interrupt_entry_remove( 0712 rtems_vector_number vector, 0713 rtems_interrupt_entry *entry, 0714 rtems_interrupt_entry **previous_next 0715 ); 0716 0717 /** 0718 * @brief This table contains a bit map which indicates if an entry is unique 0719 * or shared. 0720 * 0721 * If the bit associated with a vector is set, then the entry is unique, 0722 * otherwise it may be shared. If the bit with index 0723 * #BSP_INTERRUPT_DISPATCH_TABLE_SIZE is set, then the interrupt support is 0724 * initialized, otherwise it is not initialized. 0725 */ 0726 extern uint8_t bsp_interrupt_handler_unique_table[]; 0727 0728 /** 0729 * @brief Checks if the handler entry associated with the hander index is 0730 * unique. 0731 * 0732 * @param index is the handler index to check. 0733 * 0734 * @return Returns true, if handler entry associated with the hander index is 0735 * unique, otherwise false. 0736 */ 0737 static inline bool bsp_interrupt_is_handler_unique( rtems_vector_number index ) 0738 { 0739 rtems_vector_number table_index; 0740 uint8_t bit; 0741 0742 table_index = index / 8; 0743 bit = (uint8_t) ( 1U << ( index % 8 ) ); 0744 0745 return ( bsp_interrupt_handler_unique_table[ table_index ] & bit ) != 0; 0746 } 0747 0748 /** 0749 * @brief Sets the unique status of the handler entry. 0750 * 0751 * @param index is the handler index. 0752 * 0753 * @param unique is the unique status to set. 0754 */ 0755 static inline void bsp_interrupt_set_handler_unique( 0756 rtems_vector_number index, 0757 bool unique 0758 ) 0759 { 0760 rtems_vector_number table_index; 0761 uint8_t bit; 0762 0763 table_index = index / 8; 0764 bit = (uint8_t) ( 1U << ( index % 8 ) ); 0765 0766 if (unique) { 0767 bsp_interrupt_handler_unique_table[ table_index ] |= bit; 0768 } else { 0769 bsp_interrupt_handler_unique_table[ table_index ] &= ~bit; 0770 } 0771 } 0772 0773 /** 0774 * @brief Checks if the interrupt support is initialized. 0775 * 0776 * @return Returns true, if the interrupt support is initialized, otherwise 0777 * false. 0778 */ 0779 static inline bool bsp_interrupt_is_initialized( void ) 0780 { 0781 return bsp_interrupt_is_handler_unique( BSP_INTERRUPT_DISPATCH_TABLE_SIZE ); 0782 } 0783 0784 /** 0785 * @brief Gets a reference to the interrupt handler table slot associated with 0786 * the index. 0787 * 0788 * @return Returns a reference to the interrupt handler table slot associated 0789 * with the index. 0790 */ 0791 rtems_interrupt_entry **bsp_interrupt_get_dispatch_table_slot( 0792 rtems_vector_number index 0793 ); 0794 0795 #ifdef __cplusplus 0796 } 0797 #endif /* __cplusplus */ 0798 0799 #endif /* LIBBSP_SHARED_IRQ_GENERIC_H */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |