Changeset 8634637 in rtems


Ignore:
Timestamp:
Sep 8, 2009, 1:35:07 PM (10 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, master
Children:
ad41373
Parents:
17310b9d
Message:

2009-09-08 Sebastian Huber <sebastian.huber@…>

  • include/irq-config.h, include/irq-generic.h, include/irq-info.h, src/irq-generic.c, src/irq-info.c, src/irq-legacy.c, src/irq-shell.c: Format, cleanup and documentation.
  • src/irq-server.c: New file.
  • include/bootcard.h, include/stackalloc.h, src/stackalloc.c, bsplibc.c: Update for heap API changes. Documentation.
Location:
c/src/lib/libbsp/shared
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/shared/ChangeLog

    r17310b9d r8634637  
     12009-09-08      Sebastian Huber <sebastian.huber@embedded-brains.de>
     2
     3        * include/irq-config.h, include/irq-generic.h, include/irq-info.h,
     4        src/irq-generic.c, src/irq-info.c, src/irq-legacy.c, src/irq-shell.c:
     5        Format, cleanup and documentation.
     6        * src/irq-server.c: New file.
     7        * include/bootcard.h, include/stackalloc.h, src/stackalloc.c,
     8        bsplibc.c: Update for heap API changes. Documentation.
     9
    1102009-08-28      Joel Sherrill <joel.sherrill@OARcorp.com>
    211
  • c/src/lib/libbsp/shared/bsplibc.c

    r17310b9d r8634637  
    1313
    1414void bsp_libc_init(
    15   void   *heap_start,
    16   size_t heap_size,
    17   size_t  sbrk_amount
     15  void *heap_begin,
     16  uintptr_t heap_size,
     17  size_t sbrk_amount
    1818)
    1919{
    20     RTEMS_Malloc_Initialize( heap_start, heap_size, sbrk_amount );
     20    RTEMS_Malloc_Initialize( heap_begin, heap_size, sbrk_amount );
    2121
    2222    /*
  • c/src/lib/libbsp/shared/include/bootcard.h

    r17310b9d r8634637  
    22 * @file
    33 *
    4  * @ingroup bsp_shared
     4 * @ingroup bsp_bootcard
    55 *
    6  * @brief Header file for basic BSP startup functions.
     6 * @brief Standard system startup.
    77 */
    88
     
    2222
    2323/**
    24  * @defgroup bsp_shared Shared BSP Code
     24 * @defgroup bsp_kit Board Support Package
     25 *
     26 * @brief Board support package dependent code.
     27 */
     28
     29/**
     30 * @defgroup bsp_bootcard Bootcard
     31 *
     32 * @ingroup bsp_kit
     33 *
     34 * @brief Standard system startup.
     35 *
     36 * @{
    2537 */
    2638
     
    3850#endif /* __cplusplus */
    3951
     52/**
     53 * @brief Global pointer to the command line of boot_card().
     54 */
     55extern const char *bsp_boot_cmdline;
     56
    4057void bsp_start(void);
    4158
     
    5067void bsp_reset(void);
    5168
     69/**
     70 * @brief Should be used as the heap begin address in bsp_get_work_area() if
     71 * the heap area is contained in the work area.
     72 */
    5273#define BSP_BOOTCARD_HEAP_USES_WORK_AREA NULL
    5374
     75/**
     76 * @brief Should be used to request the default heap size in bsp_get_work_area().
     77 *
     78 * In case that the heap area is contained in the work area this heap size
     79 * value indicates that the area outside the work space should be used as heap
     80 * space.
     81 */
    5482#define BSP_BOOTCARD_HEAP_SIZE_DEFAULT 0
    5583
    5684void bsp_get_work_area(
    57   void      **work_area_start,
     85  void      **work_area_begin,
    5886  uintptr_t  *work_area_size,
    59   void      **heap_start,
     87  void      **heap_begin,
    6088  uintptr_t  *heap_size
    6189);
    6290
    63 int boot_card( const char *cmdline );
     91/**
     92 * @brief Standard system initialization procedure.
     93 *
     94 * You may pass a command line in @a cmdline.  It is later available via the
     95 * global @ref bsp_boot_cmdline variable.
     96 *
     97 * This is the C entry point for ALL RTEMS BSPs.  It is invoked from the
     98 * assembly language initialization file usually called @c start.S which does
     99 * the basic CPU setup (stack, C runtime environment, zero BSS, load other
     100 * sections) and calls afterwards boot_card().  The boot card function provides
     101 * the framework for the BSP initialization sequence.  The basic flow of
     102 * initialization is:
     103 *
     104 * - disable interrupts, interrupts will be enabled during the first context switch
     105 * - bsp_start() - more advanced initialization
     106 * - obtain information on BSP memory via bsp_get_work_area() and allocate RTEMS Workspace
     107 * - rtems_initialize_data_structures()
     108 * - allocate memory for C Program Heap
     109 * - initialize C Library and C Program Heap
     110 * - bsp_pretasking_hook()
     111 * - if defined( RTEMS_DEBUG )
     112 *   - rtems_debug_enable( RTEMS_DEBUG_ALL_MASK )
     113 * - rtems_initialize_before_drivers()
     114 * - bsp_predriver_hook()
     115 * - rtems_initialize_device_drivers()
     116 *   - initialization of all device drivers
     117 * - bsp_postdriver_hook()
     118 * - rtems_initialize_start_multitasking()
     119 *   - 1st task executes C++ global constructors
     120 *   - .... appplication runs ...
     121 *   - exit
     122 * - back to here eventually
     123 * - bsp_cleanup()
     124 *
     125 * If something goes wrong bsp_cleanup() will be called out of order.
     126 *
     127 * This style of initialization ensures that the C++ global constructors are
     128 * executed after RTEMS is initialized.
     129 */
     130int boot_card(const char *cmdline);
    64131
    65 void bsp_libc_init( void *heap_start, size_t heap_size, size_t sbrk_amount);
     132/** @} */
     133
     134void bsp_libc_init(void *heap_begin, uintptr_t heap_size, size_t sbrk_amount);
    66135
    67136#ifdef __cplusplus
  • c/src/lib/libbsp/shared/include/irq-config.h

    r17310b9d r8634637  
    1010 * Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
    1111 *
    12  * Copyright (c) 2008
    13  * Embedded Brains GmbH
     12 * Copyright (c) 2008, 2009
     13 * embedded brains GmbH
    1414 * Obere Lagerstr. 30
    1515 * D-82178 Puchheim
    1616 * Germany
    17  * rtems@embedded-brains.de
     17 * <rtems@embedded-brains.de>
    1818 *
    19  * The license and distribution terms for this file may be found in the file
    20  * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
     19 * The license and distribution terms for this file may be
     20 * found in the file LICENSE in this distribution or at
     21 * http://www.rtems.com/license/LICENSE.
    2122 */
    2223
     
    6162
    6263#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
     64  /**
     65   * @brief Size of the handler table.
     66   */
     67  #define BSP_INTERRUPT_HANDLER_TABLE_SIZE 0
    6368
    64 /**
    65  * @brief Size of the handler table.
    66  */
    67 #define BSP_INTERRUPT_HANDLER_TABLE_SIZE 0
    68 
    69 /**
    70  * @brief Integer type capable to index the complete handler table.
    71  */
    72 typedef uint8_t bsp_interrupt_handler_index_type;
    73 
    74 #endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
     69  /**
     70   * @brief Integer type capable to index the complete handler table.
     71   */
     72  typedef uint8_t bsp_interrupt_handler_index_type;
     73#endif
    7574
    7675/** @} */
  • c/src/lib/libbsp/shared/include/irq-generic.h

    r17310b9d r8634637  
    44 * @ingroup bsp_interrupt
    55 *
    6  * @brief Header file for generic BSP interrupt support.
     6 * @brief Generic BSP interrupt support API.
    77 */
    88
     
    1010 * Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
    1111 *
    12  * Copyright (c) 2008
    13  * Embedded Brains GmbH
     12 * Copyright (c) 2008, 2009
     13 * embedded brains GmbH
    1414 * Obere Lagerstr. 30
    1515 * D-82178 Puchheim
    1616 * Germany
    17  * rtems@embedded-brains.de
    18  *
    19  * The license and distribution terms for this file may be found in the file
    20  * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
     17 * <rtems@embedded-brains.de>
     18 *
     19 * The license and distribution terms for this file may be
     20 * found in the file LICENSE in this distribution or at
     21 * http://www.rtems.com/license/LICENSE.
    2122 */
    2223
     
    3435#endif /* __cplusplus */
    3536
    36 #if !defined( BSP_INTERRUPT_VECTOR_MIN) || !defined( BSP_INTERRUPT_VECTOR_MAX) || (BSP_INTERRUPT_VECTOR_MAX + 1) < BSP_INTERRUPT_VECTOR_MIN
    37 #error Invalid BSP_INTERRUPT_VECTOR_MIN or BSP_INTERRUPT_VECTOR_MAX.
    38 #endif /* !defined( BSP_INTERRUPT_VECTOR_MIN) ... */
    39 
    40 #if defined( BSP_INTERRUPT_USE_INDEX_TABLE) && !defined( BSP_INTERRUPT_HANDLER_TABLE_SIZE)
    41 #error If you define BSP_INTERRUPT_USE_INDEX_TABLE, you have to define BSP_INTERRUPT_HANDLER_TABLE_SIZE etc. as well.
    42 #endif /* defined( BSP_INTERRUPT_USE_INDEX_TABLE) ... */
    43 
    44 #if defined( BSP_INTERRUPT_NO_HEAP_USAGE) && !defined( BSP_INTERRUPT_USE_INDEX_TABLE)
    45 #error If you define BSP_INTERRUPT_NO_HEAP_USAGE, you have to define BSP_INTERRUPT_USE_INDEX_TABLE etc. as well.
    46 #endif /* defined( BSP_INTERRUPT_NO_HEAP_USAGE) ... */
    47 
    48 #define BSP_INTERRUPT_VECTOR_NUMBER (BSP_INTERRUPT_VECTOR_MAX - BSP_INTERRUPT_VECTOR_MIN + 1)
     37#if !defined(BSP_INTERRUPT_VECTOR_MIN) || !defined(BSP_INTERRUPT_VECTOR_MAX) || (BSP_INTERRUPT_VECTOR_MAX + 1) < BSP_INTERRUPT_VECTOR_MIN
     38  #error "invalid BSP_INTERRUPT_VECTOR_MIN or BSP_INTERRUPT_VECTOR_MAX"
     39#endif
     40
     41#if defined(BSP_INTERRUPT_USE_INDEX_TABLE) && !defined(BSP_INTERRUPT_HANDLER_TABLE_SIZE)
     42  #error "if you define BSP_INTERRUPT_USE_INDEX_TABLE, you have to define BSP_INTERRUPT_HANDLER_TABLE_SIZE etc. as well"
     43#endif
     44
     45#if defined(BSP_INTERRUPT_NO_HEAP_USAGE) && !defined(BSP_INTERRUPT_USE_INDEX_TABLE)
     46  #error "if you define BSP_INTERRUPT_NO_HEAP_USAGE, you have to define BSP_INTERRUPT_USE_INDEX_TABLE etc. as well"
     47#endif
     48
     49#define BSP_INTERRUPT_VECTOR_NUMBER \
     50  (BSP_INTERRUPT_VECTOR_MAX - BSP_INTERRUPT_VECTOR_MIN + 1)
    4951
    5052#ifndef BSP_INTERRUPT_HANDLER_TABLE_SIZE
    51 #define BSP_INTERRUPT_HANDLER_TABLE_SIZE BSP_INTERRUPT_VECTOR_NUMBER
    52 #endif /* BSP_INTERRUPT_HANDLER_TABLE_SIZE */
     53  #define BSP_INTERRUPT_HANDLER_TABLE_SIZE BSP_INTERRUPT_VECTOR_NUMBER
     54#endif
    5355
    5456struct bsp_interrupt_handler_entry {
    55         rtems_interrupt_handler handler;
    56         void *arg;
    57         const char *info;
    58         struct bsp_interrupt_handler_entry *next;
     57  rtems_interrupt_handler handler;
     58  void *arg;
     59  const char *info;
     60  struct bsp_interrupt_handler_entry *next;
    5961};
    6062
     
    6466
    6567#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
    66 extern bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table [];
    67 #endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
    68 
    69 static inline rtems_vector_number bsp_interrupt_handler_index( rtems_vector_number vector)
     68  extern bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table [];
     69#endif
     70
     71static inline rtems_vector_number bsp_interrupt_handler_index(
     72  rtems_vector_number vector
     73)
    7074{
    71 #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
    72         return bsp_interrupt_handler_index_table [vector - BSP_INTERRUPT_VECTOR_MIN];
    73 #else /* BSP_INTERRUPT_USE_INDEX_TABLE */
    74         return vector - BSP_INTERRUPT_VECTOR_MIN;
    75 #endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
     75  #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
     76    return bsp_interrupt_handler_index_table [vector - BSP_INTERRUPT_VECTOR_MIN];
     77  #else
     78    return vector - BSP_INTERRUPT_VECTOR_MIN;
     79  #endif
    7680}
    7781
     
    130134 * @brief Returns true if the interrupt vector with number @a vector is valid.
    131135 */
    132 static inline bool bsp_interrupt_is_valid_vector( rtems_vector_number vector)
     136static inline bool bsp_interrupt_is_valid_vector(rtems_vector_number vector)
    133137{
    134         return (rtems_vector_number) BSP_INTERRUPT_VECTOR_MIN <= vector
    135                 && vector <= (rtems_vector_number) BSP_INTERRUPT_VECTOR_MAX;
     138  return (rtems_vector_number) BSP_INTERRUPT_VECTOR_MIN <= vector
     139    && vector <= (rtems_vector_number) BSP_INTERRUPT_VECTOR_MAX;
    136140}
    137141
     
    145149 * @note This function must cope with arbitrary vector numbers @a vector.
    146150 */
    147 void bsp_interrupt_handler_default( rtems_vector_number vector);
     151void bsp_interrupt_handler_default(rtems_vector_number vector);
    148152
    149153/**
     
    155159 * is complete if everything was successful.
    156160 */
    157 rtems_status_code bsp_interrupt_initialize( void);
     161rtems_status_code bsp_interrupt_initialize(void);
    158162
    159163/**
     
    172176 * @return On success RTEMS_SUCCESSFUL shall be returned.
    173177 */
    174 rtems_status_code bsp_interrupt_facility_initialize( void);
     178rtems_status_code bsp_interrupt_facility_initialize(void);
    175179
    176180/**
     
    188192 * @return On success RTEMS_SUCCESSFUL shall be returned.
    189193 */
    190 rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number vector);
     194rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector);
    191195
    192196/**
     
    204208 * @return On success RTEMS_SUCCESSFUL shall be returned.
    205209 */
    206 rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector);
     210rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector);
    207211
    208212/**
     
    216220 * rtems_interrupt_disable().
    217221 */
    218 static inline void bsp_interrupt_handler_dispatch( rtems_vector_number vector)
     222static inline void bsp_interrupt_handler_dispatch(rtems_vector_number vector)
    219223{
    220         if (bsp_interrupt_is_valid_vector( vector)) {
    221                 bsp_interrupt_handler_entry *e = &bsp_interrupt_handler_table [bsp_interrupt_handler_index( vector)];
    222 
    223                 do {
    224                         e->handler( vector, e->arg);
    225                         e = e->next;
    226                 } while (e != NULL);
    227         } else {
    228                 bsp_interrupt_handler_default( vector);
    229         }
     224  if (bsp_interrupt_is_valid_vector(vector)) {
     225    bsp_interrupt_handler_entry *e =
     226      &bsp_interrupt_handler_table [bsp_interrupt_handler_index(vector)];
     227
     228    do {
     229      (*e->handler)(vector, e->arg);
     230      e = e->next;
     231    } while (e != NULL);
     232  } else {
     233    bsp_interrupt_handler_default(vector);
     234  }
    230235}
    231236
  • c/src/lib/libbsp/shared/include/irq-info.h

    r17310b9d r8634637  
    44 * @ingroup bsp_interrupt
    55 *
    6  * @brief Header file for generic BSP interrupt information.
     6 * @brief Generic BSP interrupt information API.
    77 */
    88
    99/*
    10  * Copyright (c) 2008
    11  * Embedded Brains GmbH
     10 * Copyright (c) 2008, 2009
     11 * embedded brains GmbH
    1212 * Obere Lagerstr. 30
    1313 * D-82178 Puchheim
    1414 * Germany
    15  * rtems@embedded-brains.de
     15 * <rtems@embedded-brains.de>
    1616 *
    17  * The license and distribution terms for this file may be found in the file
    18  * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
     17 * The license and distribution terms for this file may be
     18 * found in the file LICENSE in this distribution or at
     19 * http://www.rtems.com/license/LICENSE.
    1920 */
    2021
     
    3738 */
    3839
    39 void bsp_interrupt_report_with_plugin( void *context, rtems_printk_plugin_t print);
     40/**
     41 * @brief Prints interrupt information via the printk plugin @a print with the
     42 * context @a context.
     43 */
     44void bsp_interrupt_report_with_plugin(
     45  void *context,
     46  rtems_printk_plugin_t print
     47);
    4048
    41 void bsp_interrupt_report( void);
     49/**
     50 * @brief Prints interrupt information via the default printk plugin.
     51 */
     52void bsp_interrupt_report(void);
    4253
     54/**
     55 * @brief Shell command entry for interrupt information.
     56 */
    4357extern struct rtems_shell_cmd_tt bsp_interrupt_shell_command;
    4458
  • c/src/lib/libbsp/shared/include/stackalloc.h

    r17310b9d r8634637  
    22 * @file
    33 *
    4  * @ingroup bsp_shared
     4 * @ingroup bsp_stack
    55 *
    6  * @brief Stack initialization, allocation and free functions.
     6 * @brief Task stack initialization, allocation and free functions.
    77 */
    88
     
    2323#define LIBBSP_SHARED_STACK_ALLOC_H
    2424
     25#include <stddef.h>
    2526#include <stdint.h>
    2627
     
    2930#endif /* __cplusplus */
    3031
    31 void bsp_stack_initialize(void *start, intptr_t size);
     32/**
     33 * @defgroup bsp_stack Task Stack Allocator
     34 *
     35 * @ingroup bsp_kit
     36 *
     37 * @brief Task stack initialization, allocation and free functions.
     38 *
     39 * Initialize the task stack allocator with bsp_stack_initialize().  To enable
     40 * the task stack allocator use the following in the system configuration:
     41 *
     42 * @code
     43 * #include <bsp/stackalloc.h>
     44 *
     45 * #define CONFIGURE_INIT
     46 *
     47 * #include <confdefs.h>
     48 * @endcode
     49 *
     50 * @{
     51 */
    3252
    33 void *bsp_stack_allocate(uint32_t size);
     53/**
     54 * @brief Task stack management initialization.
     55 *
     56 * This function should be called in bsp_start() with the designated task stack
     57 * area begin address @a begin and task stack area size @a size in bytes.  The
     58 * area boundaries have to be aligned properly.
     59 */
     60void bsp_stack_initialize(void *begin, uintptr_t size);
    3461
     62/**
     63 * @brief Task stack allocator for @ref CONFIGURE_TASK_STACK_ALLOCATOR.
     64 *
     65 * In case the designated task stack space from bsp_stack_initialize() is
     66 * completely in use the work space will be used to allocate the stack.
     67 */
     68void *bsp_stack_allocate(size_t size);
     69
     70/**
     71 * @brief Task stack free function for @ref CONFIGURE_TASK_STACK_DEALLOCATOR.
     72 */
    3573void bsp_stack_free(void *stack);
    3674
     75/**
     76 * @brief Task stack allocator configuration option.
     77 */
    3778#define CONFIGURE_TASK_STACK_ALLOCATOR bsp_stack_allocate
    3879
     80/**
     81 * @brief Task stack deallocator configuration option.
     82 */
    3983#define CONFIGURE_TASK_STACK_DEALLOCATOR bsp_stack_free
     84
     85/** @} */
    4086
    4187#ifdef __cplusplus
  • c/src/lib/libbsp/shared/src/irq-generic.c

    r17310b9d r8634637  
    44 * @ingroup bsp_interrupt
    55 *
    6  * @brief Source file for generic BSP interrupt support.
     6 * @brief Generic BSP interrupt support implementation.
    77 */
    88
     
    1010 * Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
    1111 *
    12  * Copyright (c) 2008
    13  * Embedded Brains GmbH
     12 * Copyright (c) 2008, 2009
     13 * embedded brains GmbH
    1414 * Obere Lagerstr. 30
    1515 * D-82178 Puchheim
    1616 * Germany
    17  * rtems@embedded-brains.de
    18  *
    19  * The license and distribution terms for this file may be found in the file
    20  * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
     17 * <rtems@embedded-brains.de>
     18 *
     19 * The license and distribution terms for this file may be
     20 * found in the file LICENSE in this distribution or at
     21 * http://www.rtems.com/license/LICENSE.
    2122 */
    2223
    23 #include <stdlib.h> /* malloc, free */
     24#include <stdlib.h>
    2425
    2526#include <bsp/irq-generic.h>
    2627
    2728#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
    28 bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table [BSP_INTERRUPT_VECTOR_NUMBER];
    29 #endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
    30 
    31 static void bsp_interrupt_handler_empty( rtems_vector_number vector, void *arg)
    32 {
    33         bsp_interrupt_handler_default( vector);
    34 }
    35 
    36 bsp_interrupt_handler_entry bsp_interrupt_handler_table [BSP_INTERRUPT_HANDLER_TABLE_SIZE] = {
    37         [0 ... BSP_INTERRUPT_HANDLER_TABLE_SIZE - 1] = {
    38                 .handler = bsp_interrupt_handler_empty,
    39                 .arg = NULL,
    40                 .info = NULL,
    41                 .next = NULL
    42         }
    43 };
     29  bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table
     30    [BSP_INTERRUPT_VECTOR_NUMBER];
     31#endif
     32
     33bsp_interrupt_handler_entry bsp_interrupt_handler_table
     34  [BSP_INTERRUPT_HANDLER_TABLE_SIZE];
    4435
    4536/* The last entry indicates if everything is initialized */
    46 static uint8_t bsp_interrupt_handler_unique_table [(BSP_INTERRUPT_HANDLER_TABLE_SIZE + 7 + 1) / 8];
     37static uint8_t bsp_interrupt_handler_unique_table
     38  [(BSP_INTERRUPT_HANDLER_TABLE_SIZE + 7 + 1) / 8];
    4739
    4840static rtems_id bsp_interrupt_mutex = RTEMS_ID_NONE;
    4941
    50 static inline bool bsp_interrupt_is_handler_unique( rtems_vector_number index)
    51 {
    52         rtems_vector_number i = index / 8;
    53         rtems_vector_number s = index % 8;
    54         return (bsp_interrupt_handler_unique_table [i] >> s) & 0x1;
    55 }
    56 
    57 static inline void bsp_interrupt_set_handler_unique( rtems_vector_number index, bool unique)
    58 {
    59         rtems_vector_number i = index / 8;
    60         rtems_vector_number s = index % 8;
    61         if (unique) {
    62                 bsp_interrupt_handler_unique_table [i] |= (uint8_t) (0x1U << s);
    63         } else {
    64                 bsp_interrupt_handler_unique_table [i] &= (uint8_t) ~(0x1U << s);
    65         }
     42static void bsp_interrupt_handler_empty(rtems_vector_number vector, void *arg)
     43{
     44  bsp_interrupt_handler_default(vector);
     45}
     46
     47static inline bool bsp_interrupt_is_handler_unique(rtems_vector_number index)
     48{
     49  rtems_vector_number i = index / 8;
     50  rtems_vector_number s = index % 8;
     51  return (bsp_interrupt_handler_unique_table [i] >> s) & 0x1;
     52}
     53
     54static inline void bsp_interrupt_set_handler_unique(
     55  rtems_vector_number index,
     56  bool unique
     57)
     58{
     59  rtems_vector_number i = index / 8;
     60  rtems_vector_number s = index % 8;
     61  if (unique) {
     62    bsp_interrupt_handler_unique_table [i] |= (uint8_t) (0x1U << s);
     63  } else {
     64    bsp_interrupt_handler_unique_table [i] &= (uint8_t) ~(0x1U << s);
     65  }
    6666}
    6767
    6868static inline bool bsp_interrupt_is_initialized(void)
    6969{
    70         return bsp_interrupt_is_handler_unique( BSP_INTERRUPT_HANDLER_TABLE_SIZE);
     70  return bsp_interrupt_is_handler_unique(BSP_INTERRUPT_HANDLER_TABLE_SIZE);
    7171}
    7272
    7373static inline void bsp_interrupt_set_initialized(void)
    7474{
    75         bsp_interrupt_set_handler_unique( BSP_INTERRUPT_HANDLER_TABLE_SIZE, true);
    76 }
    77 
    78 static inline bool bsp_interrupt_is_empty_handler_entry( bsp_interrupt_handler_entry *e)
    79 {
    80         return e->handler == bsp_interrupt_handler_empty;
    81 }
    82 
    83 static inline void bsp_interrupt_clear_handler_entry( bsp_interrupt_handler_entry *e)
    84 {
    85         e->handler = bsp_interrupt_handler_empty;
    86         e->arg = NULL;
    87         e->info = NULL;
    88         e->next = NULL;
    89 }
    90 
    91 static inline bool bsp_interrupt_allocate_handler_index( rtems_vector_number vector, rtems_vector_number *index)
    92 {
    93 #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
    94         rtems_vector_number i = 0;
    95 
    96         /* The first entry will remain empty */
    97         for (i = 1; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i) {
    98                 if (bsp_interrupt_is_empty_handler_entry( &bsp_interrupt_handler_table [i])) {
    99                         *index = i;
    100                         return 1;
    101                 }
    102         }
    103 
    104         return 0;
    105 #else /* BSP_INTERRUPT_USE_INDEX_TABLE */
    106         *index = vector;
    107         return 1;
    108 #endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
    109 }
    110 
    111 static bsp_interrupt_handler_entry *bsp_interrupt_allocate_handler_entry( void)
    112 {
    113 #ifdef BSP_INTERRUPT_NO_HEAP_USAGE
    114         rtems_vector_number index = 0;
    115         if (bsp_interrupt_allocate_handler_index( 0, &index)) {
    116                 return &bsp_interrupt_handler_table [index];
    117         } else {
    118                 return NULL;
    119         }
    120 #else /* BSP_INTERRUPT_NO_HEAP_USAGE */
    121         return malloc( sizeof( bsp_interrupt_handler_entry));
    122 #endif /* BSP_INTERRUPT_NO_HEAP_USAGE */
    123 }
    124 
    125 static void bsp_interrupt_free_handler_entry( bsp_interrupt_handler_entry *e)
    126 {
    127 #ifdef BSP_INTERRUPT_NO_HEAP_USAGE
    128         bsp_interrupt_clear_handler_entry( e);
    129 #else /* BSP_INTERRUPT_NO_HEAP_USAGE */
    130         free( e);
    131 #endif /* BSP_INTERRUPT_NO_HEAP_USAGE */
    132 }
    133 
    134 static rtems_status_code bsp_interrupt_lock( void)
    135 {
    136         rtems_status_code sc = RTEMS_SUCCESSFUL;
    137         if (_System_state_Is_up( _System_state_Get())) {
    138                 if (bsp_interrupt_mutex == RTEMS_ID_NONE) {
    139                         rtems_id mutex = RTEMS_ID_NONE;
    140                         rtems_interrupt_level level;
    141 
    142                         /* Create a mutex */
    143                         sc = rtems_semaphore_create (
    144                                 rtems_build_name( 'I', 'N', 'T', 'R'),
    145                                 1,
    146                                 RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY,
    147                                 RTEMS_NO_PRIORITY,
    148                                 &mutex
    149                         );
    150                         if (sc != RTEMS_SUCCESSFUL) {
    151                                 return sc;
    152                         }
    153 
    154                         /* Assign the mutex */
    155                         rtems_interrupt_disable( level);
    156                         if (bsp_interrupt_mutex == RTEMS_ID_NONE) {
    157                                 /* Nobody else assigned the mutex in the meantime */
    158 
    159                                 bsp_interrupt_mutex = mutex;
    160                                 rtems_interrupt_enable( level);
    161                         } else {
    162                                 /* Somebody else won */
    163 
    164                                 rtems_interrupt_enable( level);
    165                                 sc = rtems_semaphore_delete( mutex);
    166                                 if (sc != RTEMS_SUCCESSFUL) {
    167                                         return sc;
    168                                 }
    169                         }
    170                 }
    171                 return rtems_semaphore_obtain( bsp_interrupt_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    172         } else {
    173                 return RTEMS_SUCCESSFUL;
    174         }
    175 }
    176 
    177 static rtems_status_code bsp_interrupt_unlock( void)
    178 {
    179         if (bsp_interrupt_mutex != RTEMS_ID_NONE) {
    180                 return rtems_semaphore_release( bsp_interrupt_mutex);
    181         } else {
    182                 return RTEMS_SUCCESSFUL;
    183         }
    184 }
    185 
    186 rtems_status_code bsp_interrupt_initialize( void)
    187 {
    188         rtems_status_code sc = RTEMS_SUCCESSFUL;
    189 
    190         /* Lock */
    191         sc = bsp_interrupt_lock();
    192         if (sc != RTEMS_SUCCESSFUL) {
    193                 return sc;
    194         }
    195 
    196         /* Check if already initialized */
    197         if (bsp_interrupt_is_initialized()) {
    198                 bsp_interrupt_unlock();
    199                 return RTEMS_INTERNAL_ERROR;
    200         }
    201 
    202         /* BSP specific initialization */
    203         sc = bsp_interrupt_facility_initialize();
    204         if (sc != RTEMS_SUCCESSFUL) {
    205                 bsp_interrupt_unlock();
    206                 return sc;
    207         }
    208 
    209         /* Now we are initialized */
    210         bsp_interrupt_set_initialized();
    211 
    212         /* Unlock */
    213         sc = bsp_interrupt_unlock();
    214         if (sc != RTEMS_SUCCESSFUL) {
    215                 return sc;
    216         }
    217 
    218         return RTEMS_SUCCESSFUL;
     75  bsp_interrupt_set_handler_unique(BSP_INTERRUPT_HANDLER_TABLE_SIZE, true);
     76}
     77
     78static inline bool bsp_interrupt_is_empty_handler_entry(
     79  bsp_interrupt_handler_entry *e
     80)
     81{
     82  return e->handler == bsp_interrupt_handler_empty;
     83}
     84
     85static inline void bsp_interrupt_clear_handler_entry(
     86  bsp_interrupt_handler_entry *e
     87)
     88{
     89  e->handler = bsp_interrupt_handler_empty;
     90  e->arg = NULL;
     91  e->info = NULL;
     92  e->next = NULL;
     93}
     94
     95static inline bool bsp_interrupt_allocate_handler_index(
     96  rtems_vector_number vector,
     97  rtems_vector_number *index
     98)
     99{
     100  #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
     101    rtems_vector_number i = 0;
     102
     103    /* The first entry will remain empty */
     104    for (i = 1; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i) {
     105      const bsp_interrupt_handler_entry *e = &bsp_interrupt_handler_table [i];
     106      if (bsp_interrupt_is_empty_handler_entry(e)) {
     107        *index = i;
     108        return true;
     109      }
     110    }
     111
     112    return false;
     113  #else
     114    *index = vector;
     115    return true;
     116  #endif
     117}
     118
     119static bsp_interrupt_handler_entry *bsp_interrupt_allocate_handler_entry(void)
     120{
     121  #ifdef BSP_INTERRUPT_NO_HEAP_USAGE
     122    rtems_vector_number index = 0;
     123    if (bsp_interrupt_allocate_handler_index(0, &index)) {
     124      return &bsp_interrupt_handler_table [index];
     125    } else {
     126      return NULL;
     127    }
     128  #else
     129    return malloc(sizeof(bsp_interrupt_handler_entry));
     130  #endif
     131}
     132
     133static void bsp_interrupt_free_handler_entry(bsp_interrupt_handler_entry *e)
     134{
     135  #ifdef BSP_INTERRUPT_NO_HEAP_USAGE
     136    bsp_interrupt_clear_handler_entry(e);
     137  #else
     138    free(e);
     139  #endif
     140}
     141
     142static rtems_status_code bsp_interrupt_lock(void)
     143{
     144  rtems_status_code sc = RTEMS_SUCCESSFUL;
     145  if (_System_state_Is_up(_System_state_Get())) {
     146    if (bsp_interrupt_mutex == RTEMS_ID_NONE) {
     147      rtems_id mutex = RTEMS_ID_NONE;
     148      rtems_interrupt_level level;
     149
     150      /* Create a mutex */
     151      sc = rtems_semaphore_create (
     152        rtems_build_name('I', 'N', 'T', 'R'),
     153        1,
     154        RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
     155        0,
     156        &mutex
     157      );
     158      if (sc != RTEMS_SUCCESSFUL) {
     159        return sc;
     160      }
     161
     162      /* Assign the mutex */
     163      rtems_interrupt_disable(level);
     164      if (bsp_interrupt_mutex == RTEMS_ID_NONE) {
     165        /* Nobody else assigned the mutex in the meantime */
     166
     167        bsp_interrupt_mutex = mutex;
     168        rtems_interrupt_enable(level);
     169      } else {
     170        /* Somebody else won */
     171
     172        rtems_interrupt_enable(level);
     173        sc = rtems_semaphore_delete(mutex);
     174        if (sc != RTEMS_SUCCESSFUL) {
     175          return sc;
     176        }
     177      }
     178    }
     179    return rtems_semaphore_obtain(
     180      bsp_interrupt_mutex,
     181      RTEMS_WAIT,
     182      RTEMS_NO_TIMEOUT
     183    );
     184  } else {
     185    return RTEMS_SUCCESSFUL;
     186  }
     187}
     188
     189static rtems_status_code bsp_interrupt_unlock(void)
     190{
     191  if (bsp_interrupt_mutex != RTEMS_ID_NONE) {
     192    return rtems_semaphore_release(bsp_interrupt_mutex);
     193  } else {
     194    return RTEMS_SUCCESSFUL;
     195  }
     196}
     197
     198rtems_status_code bsp_interrupt_initialize(void)
     199{
     200  rtems_status_code sc = RTEMS_SUCCESSFUL;
     201  size_t i = 0;
     202
     203  sc = bsp_interrupt_lock();
     204  if (sc != RTEMS_SUCCESSFUL) {
     205    return sc;
     206  }
     207
     208  /* We need one semaphore */
     209  if (_System_state_Is_before_initialization(_System_state_Get())) {
     210    Configuration.work_space_size += sizeof(Semaphore_Control);
     211    ++Configuration_RTEMS_API.maximum_semaphores;
     212  }
     213
     214  if (bsp_interrupt_is_initialized()) {
     215    bsp_interrupt_unlock();
     216    return RTEMS_INTERNAL_ERROR;
     217  }
     218
     219  /* Initialize handler table */
     220  for (i = 0; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i) {
     221    bsp_interrupt_handler_table [i].handler = bsp_interrupt_handler_empty;
     222  }
     223
     224  sc = bsp_interrupt_facility_initialize();
     225  if (sc != RTEMS_SUCCESSFUL) {
     226    bsp_interrupt_unlock();
     227    return sc;
     228  }
     229
     230  bsp_interrupt_set_initialized();
     231
     232  sc = bsp_interrupt_unlock();
     233  if (sc != RTEMS_SUCCESSFUL) {
     234    return sc;
     235  }
     236
     237  return RTEMS_SUCCESSFUL;
    219238}
    220239
     
    232251 * @see rtems_interrupt_handler_install()
    233252 */
    234 static rtems_status_code bsp_interrupt_handler_install( rtems_vector_number vector, const char *info, rtems_option options, rtems_interrupt_handler handler, void *arg)
    235 {
    236         rtems_status_code sc = RTEMS_SUCCESSFUL;
    237         rtems_interrupt_level level;
    238         rtems_vector_number index = 0;
    239         bsp_interrupt_handler_entry *head = NULL;
    240         bsp_interrupt_handler_entry *tail = NULL;
    241         bsp_interrupt_handler_entry *current = NULL;
    242         bsp_interrupt_handler_entry *match = NULL;
    243         bool enable_vector = false;
    244 
    245         /* Check parameters and system state */
    246         if (!bsp_interrupt_is_initialized()) {
    247                 return RTEMS_INTERNAL_ERROR;
    248         } else if (!bsp_interrupt_is_valid_vector( vector)) {
    249                 return RTEMS_INVALID_NUMBER;
    250         } else if (handler == NULL) {
    251                 return RTEMS_INVALID_ADDRESS;
    252         } else if (rtems_interrupt_is_in_progress()) {
    253                 return RTEMS_CALLED_FROM_ISR;
    254         }
    255 
    256         /* Lock */
    257         sc = bsp_interrupt_lock();
    258         if (sc != RTEMS_SUCCESSFUL) {
    259                 return sc;
    260         }
    261 
    262         /* Get handler table index */
    263         index = bsp_interrupt_handler_index( vector);
    264 
    265         /* Get head entry of the handler list for current vector */
    266         head = &bsp_interrupt_handler_table [index];
    267 
    268         if (bsp_interrupt_is_empty_handler_entry( head)) {
    269                 /*
    270                  * No real handler installed yet.  So allocate a new index in
    271                  * the handler table and fill the entry with life.
    272                  */
    273                 if (bsp_interrupt_allocate_handler_index( vector, &index)) {
    274                         rtems_interrupt_disable( level);
    275                         bsp_interrupt_handler_table [index].handler = handler;
    276                         bsp_interrupt_handler_table [index].arg = arg;
    277 #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
    278                         bsp_interrupt_handler_index_table [vector] = index;
    279 #endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
    280                         rtems_interrupt_enable( level);
    281                         bsp_interrupt_handler_table [index].info = info;
    282                 } else {
    283                         /* Handler table is full */
    284                         bsp_interrupt_unlock();
    285                         return RTEMS_NO_MEMORY;
    286                 }
    287 
    288                 /* This is the first handler so enable the vector later */
    289                 enable_vector = true;
    290         } else {
    291                 /* Ensure that a unique handler remains unique */
    292                 if (RTEMS_INTERRUPT_IS_UNIQUE( options) || bsp_interrupt_is_handler_unique( index)) {
    293                         /*
    294                          * Tried to install a unique handler on a not empty
    295                          * list or there is already a unique handler installed.
    296                          */
    297                         bsp_interrupt_unlock();
    298                         return RTEMS_RESOURCE_IN_USE;
    299                 }
    300 
    301                 /*
    302                  * Search for the list tail and check if the handler is already
    303                  * installed.
    304                  */
    305                 current = head;
    306                 do {
    307                         if (current->handler == handler && current->arg == arg) {
    308                                 match = current;
    309                         }
    310                         tail = current;
    311                         current = current->next;
    312                 } while (current != NULL);
    313 
    314                 /* Ensure the handler is not already installed */
    315                 if (match != NULL) {
    316                         /* The handler is already installed */
    317                         bsp_interrupt_unlock();
    318                         return RTEMS_TOO_MANY;
    319                 }
    320 
    321                 /* Allocate a new entry */
    322                 current = bsp_interrupt_allocate_handler_entry();
    323                 if (current == NULL) {
    324                         /* Not enough memory */
    325                         bsp_interrupt_unlock();
    326                         return RTEMS_NO_MEMORY;
    327                 }
    328 
    329                 /* Set entry */
    330                 current->handler = handler;
    331                 current->arg = arg;
    332                 current->info = info;
    333                 current->next = NULL;
    334 
    335                 /* Link to list tail */
    336                 rtems_interrupt_disable( level);
    337                 tail->next = current;
    338                 rtems_interrupt_enable( level);
    339         }
    340 
    341         /* Make the handler unique if necessary */
    342         bsp_interrupt_set_handler_unique( index, RTEMS_INTERRUPT_IS_UNIQUE( options));
    343 
    344         /* Enable the vector if necessary */
    345         if (enable_vector) {
    346                 sc = bsp_interrupt_vector_enable( vector);
    347                 if (sc != RTEMS_SUCCESSFUL) {
    348                         bsp_interrupt_unlock();
    349                         return sc;
    350                 }
    351         }
    352 
    353         /* Unlock */
    354         sc = bsp_interrupt_unlock();
    355         if (sc != RTEMS_SUCCESSFUL) {
    356                 return sc;
    357         }
    358 
    359         return RTEMS_SUCCESSFUL;
     253static rtems_status_code bsp_interrupt_handler_install(
     254  rtems_vector_number vector,
     255  const char *info,
     256  rtems_option options,
     257  rtems_interrupt_handler handler,
     258  void *arg
     259)
     260{
     261  rtems_status_code sc = RTEMS_SUCCESSFUL;
     262  rtems_interrupt_level level;
     263  rtems_vector_number index = 0;
     264  bsp_interrupt_handler_entry *head = NULL;
     265  bsp_interrupt_handler_entry *tail = NULL;
     266  bsp_interrupt_handler_entry *current = NULL;
     267  bsp_interrupt_handler_entry *match = NULL;
     268  bool enable_vector = false;
     269
     270  /* Check parameters and system state */
     271  if (!bsp_interrupt_is_initialized()) {
     272    return RTEMS_INTERNAL_ERROR;
     273  } else if (!bsp_interrupt_is_valid_vector(vector)) {
     274    return RTEMS_INVALID_ID;
     275  } else if (handler == NULL) {
     276    return RTEMS_INVALID_ADDRESS;
     277  } else if (rtems_interrupt_is_in_progress()) {
     278    return RTEMS_CALLED_FROM_ISR;
     279  }
     280
     281  /* Lock */
     282  sc = bsp_interrupt_lock();
     283  if (sc != RTEMS_SUCCESSFUL) {
     284    return sc;
     285  }
     286
     287  /* Get handler table index */
     288  index = bsp_interrupt_handler_index(vector);
     289
     290  /* Get head entry of the handler list for current vector */
     291  head = &bsp_interrupt_handler_table [index];
     292
     293  if (bsp_interrupt_is_empty_handler_entry(head)) {
     294    /*
     295     * No real handler installed yet.  So allocate a new index in
     296     * the handler table and fill the entry with life.
     297     */
     298    if (bsp_interrupt_allocate_handler_index(vector, &index)) {
     299      rtems_interrupt_disable(level);
     300      bsp_interrupt_handler_table [index].handler = handler;
     301      bsp_interrupt_handler_table [index].arg = arg;
     302      #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
     303        bsp_interrupt_handler_index_table [vector] = index;
     304      #endif
     305      rtems_interrupt_enable(level);
     306      bsp_interrupt_handler_table [index].info = info;
     307    } else {
     308      /* Handler table is full */
     309      bsp_interrupt_unlock();
     310      return RTEMS_NO_MEMORY;
     311    }
     312
     313    /* This is the first handler so enable the vector later */
     314    enable_vector = true;
     315  } else {
     316    /* Ensure that a unique handler remains unique */
     317    if (
     318      RTEMS_INTERRUPT_IS_UNIQUE(options)
     319        || bsp_interrupt_is_handler_unique(index)
     320    ) {
     321      /*
     322       * Tried to install a unique handler on a not empty
     323       * list or there is already a unique handler installed.
     324       */
     325      bsp_interrupt_unlock();
     326      return RTEMS_RESOURCE_IN_USE;
     327    }
     328
     329    /*
     330     * Search for the list tail and check if the handler is already
     331     * installed.
     332     */
     333    current = head;
     334    do {
     335      if (current->handler == handler && current->arg == arg) {
     336        match = current;
     337      }
     338      tail = current;
     339      current = current->next;
     340    } while (current != NULL);
     341
     342    /* Ensure the handler is not already installed */
     343    if (match != NULL) {
     344      /* The handler is already installed */
     345      bsp_interrupt_unlock();
     346      return RTEMS_TOO_MANY;
     347    }
     348
     349    /* Allocate a new entry */
     350    current = bsp_interrupt_allocate_handler_entry();
     351    if (current == NULL) {
     352      /* Not enough memory */
     353      bsp_interrupt_unlock();
     354      return RTEMS_NO_MEMORY;
     355    }
     356
     357    /* Set entry */
     358    current->handler = handler;
     359    current->arg = arg;
     360    current->info = info;
     361    current->next = NULL;
     362
     363    /* Link to list tail */
     364    rtems_interrupt_disable(level);
     365    tail->next = current;
     366    rtems_interrupt_enable(level);
     367  }
     368
     369  /* Make the handler unique if necessary */
     370  bsp_interrupt_set_handler_unique(index, RTEMS_INTERRUPT_IS_UNIQUE(options));
     371
     372  /* Enable the vector if necessary */
     373  if (enable_vector) {
     374    sc = bsp_interrupt_vector_enable(vector);
     375    if (sc != RTEMS_SUCCESSFUL) {
     376      bsp_interrupt_unlock();
     377      return sc;
     378    }
     379  }
     380
     381  /* Unlock */
     382  sc = bsp_interrupt_unlock();
     383  if (sc != RTEMS_SUCCESSFUL) {
     384    return sc;
     385  }
     386
     387  return RTEMS_SUCCESSFUL;
    360388}
    361389
     
    370398 * @see rtems_interrupt_handler_remove().
    371399 */
    372 static rtems_status_code bsp_interrupt_handler_remove( rtems_vector_number vector, rtems_interrupt_handler handler, void *arg)
    373 {
    374         rtems_status_code sc = RTEMS_SUCCESSFUL;
    375         rtems_interrupt_level level;
    376         rtems_vector_number index = 0;
    377         bsp_interrupt_handler_entry *head = NULL;
    378         bsp_interrupt_handler_entry *current = NULL;
    379         bsp_interrupt_handler_entry *previous = NULL;
    380         bsp_interrupt_handler_entry *match = NULL;
    381 
    382         /* Check parameters and system state */
    383         if (!bsp_interrupt_is_initialized()) {
    384                 return RTEMS_INTERNAL_ERROR;
    385         } else if (!bsp_interrupt_is_valid_vector( vector)) {
    386                 return RTEMS_INVALID_NUMBER;
    387         } else if (handler == NULL) {
    388                 return RTEMS_INVALID_ADDRESS;
    389         } else if (rtems_interrupt_is_in_progress()) {
    390                 return RTEMS_CALLED_FROM_ISR;
    391         }
    392 
    393         /* Lock */
    394         sc = bsp_interrupt_lock();
    395         if (sc != RTEMS_SUCCESSFUL) {
    396                 return sc;
    397         }
    398 
    399         /* Get handler table index */
    400         index = bsp_interrupt_handler_index( vector);
    401 
    402         /* Get head entry of the handler list for current vector */
    403         head = &bsp_interrupt_handler_table [index];
    404 
    405         /* Search for a matching entry */
    406         current = head;
    407         do {
    408                 if (current->handler == handler && current->arg == arg) {
    409                         match = current;
    410                         break;
    411                 }
    412                 previous = current;
    413                 current = current->next;
    414         } while (current != NULL);
    415 
    416         /* Remove the matching entry */
    417         if (match != NULL) {
    418                 if (match->next != NULL) {
    419                         /*
    420                          * The match has a successor.  A successor is always
    421                          * allocated.  So replace the match with its successor
    422                          * and free the successor entry.
    423                          */
    424                         current = match->next;
    425 
    426                         rtems_interrupt_disable( level);
    427                         *match = *current;
    428                         rtems_interrupt_enable( level);
    429 
    430                         bsp_interrupt_free_handler_entry( current);
    431                 } else if (match == head) {
    432                         /*
    433                          * The match is the list head and has no successor.
    434                          * The list head is stored in a static table so clear
    435                          * this entry.  Since now the list is empty disable the
    436                          * vector.
    437                          */
    438 
    439                         /* Disable the vector */
    440                         sc = bsp_interrupt_vector_disable( vector);
    441 
    442                         /* Clear entry */
    443                         rtems_interrupt_disable( level);
    444                         bsp_interrupt_clear_handler_entry( head);
    445 #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
    446                         bsp_interrupt_handler_index_table [vector] = 0;
    447 #endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
    448                         rtems_interrupt_enable( level);
    449 
    450                         /* Allow shared handlers */
    451                         bsp_interrupt_set_handler_unique( index, false);
    452 
    453                         /* Check status code */
    454                         if (sc != RTEMS_SUCCESSFUL) {
    455                                 bsp_interrupt_unlock();
    456                                 return sc;
    457                         }
    458                 } else {
    459                         /*
    460                          * The match is the list tail and has a predecessor.
    461                          * So terminate the predecessor and free the match.
    462                          */
    463                         rtems_interrupt_disable( level);
    464                         previous->next = NULL;
    465                         rtems_interrupt_enable( level);
    466 
    467                         bsp_interrupt_free_handler_entry( match);
    468                 }
    469         } else {
    470                 /* No matching entry found */
    471                 bsp_interrupt_unlock();
    472                 return RTEMS_UNSATISFIED;
    473         }
    474 
    475         /* Unlock */
    476         sc = bsp_interrupt_unlock();
    477         if (sc != RTEMS_SUCCESSFUL) {
    478                 return sc;
    479         }
    480 
    481         return RTEMS_SUCCESSFUL;
     400static rtems_status_code bsp_interrupt_handler_remove(
     401  rtems_vector_number vector,
     402  rtems_interrupt_handler handler,
     403  void *arg
     404)
     405{
     406  rtems_status_code sc = RTEMS_SUCCESSFUL;
     407  rtems_interrupt_level level;
     408  rtems_vector_number index = 0;
     409  bsp_interrupt_handler_entry *head = NULL;
     410  bsp_interrupt_handler_entry *current = NULL;
     411  bsp_interrupt_handler_entry *previous = NULL;
     412  bsp_interrupt_handler_entry *match = NULL;
     413
     414  /* Check parameters and system state */
     415  if (!bsp_interrupt_is_initialized()) {
     416    return RTEMS_INTERNAL_ERROR;
     417  } else if (!bsp_interrupt_is_valid_vector(vector)) {
     418    return RTEMS_INVALID_ID;
     419  } else if (handler == NULL) {
     420    return RTEMS_INVALID_ADDRESS;
     421  } else if (rtems_interrupt_is_in_progress()) {
     422    return RTEMS_CALLED_FROM_ISR;
     423  }
     424
     425  /* Lock */
     426  sc = bsp_interrupt_lock();
     427  if (sc != RTEMS_SUCCESSFUL) {
     428    return sc;
     429  }
     430
     431  /* Get handler table index */
     432  index = bsp_interrupt_handler_index(vector);
     433
     434  /* Get head entry of the handler list for current vector */
     435  head = &bsp_interrupt_handler_table [index];
     436
     437  /* Search for a matching entry */
     438  current = head;
     439  do {
     440    if (current->handler == handler && current->arg == arg) {
     441      match = current;
     442      break;
     443    }
     444    previous = current;
     445    current = current->next;
     446  } while (current != NULL);
     447
     448  /* Remove the matching entry */
     449  if (match != NULL) {
     450    if (match->next != NULL) {
     451      /*
     452       * The match has a successor.  A successor is always
     453       * allocated.  So replace the match with its successor
     454       * and free the successor entry.
     455       */
     456      current = match->next;
     457
     458      rtems_interrupt_disable(level);
     459      *match = *current;
     460      rtems_interrupt_enable(level);
     461
     462      bsp_interrupt_free_handler_entry(current);
     463    } else if (match == head) {
     464      /*
     465       * The match is the list head and has no successor.
     466       * The list head is stored in a static table so clear
     467       * this entry.  Since now the list is empty disable the
     468       * vector.
     469       */
     470
     471      /* Disable the vector */
     472      sc = bsp_interrupt_vector_disable(vector);
     473
     474      /* Clear entry */
     475      rtems_interrupt_disable(level);
     476      bsp_interrupt_clear_handler_entry(head);
     477      #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
     478        bsp_interrupt_handler_index_table [vector] = 0;
     479      #endif
     480      rtems_interrupt_enable(level);
     481
     482      /* Allow shared handlers */
     483      bsp_interrupt_set_handler_unique(index, false);
     484
     485      /* Check status code */
     486      if (sc != RTEMS_SUCCESSFUL) {
     487        bsp_interrupt_unlock();
     488        return sc;
     489      }
     490    } else {
     491      /*
     492       * The match is the list tail and has a predecessor.
     493       * So terminate the predecessor and free the match.
     494       */
     495      rtems_interrupt_disable(level);
     496      previous->next = NULL;
     497      rtems_interrupt_enable(level);
     498
     499      bsp_interrupt_free_handler_entry(match);
     500    }
     501  } else {
     502    /* No matching entry found */
     503    bsp_interrupt_unlock();
     504    return RTEMS_UNSATISFIED;
     505  }
     506
     507  /* Unlock */
     508  sc = bsp_interrupt_unlock();
     509  if (sc != RTEMS_SUCCESSFUL) {
     510    return sc;
     511  }
     512
     513  return RTEMS_SUCCESSFUL;
    482514}
    483515
     
    492524 * @see rtems_interrupt_handler_iterate().
    493525 */
    494 static rtems_status_code bsp_interrupt_handler_iterate( rtems_vector_number vector, rtems_interrupt_per_handler_routine routine, void *arg)
    495 {
    496         rtems_status_code sc = RTEMS_SUCCESSFUL;
    497         bsp_interrupt_handler_entry *current = NULL;
    498         rtems_option options = 0;
    499         rtems_vector_number index = 0;
    500 
    501         /* Check parameters and system state */
    502         if (!bsp_interrupt_is_initialized()) {
    503                 return RTEMS_INTERNAL_ERROR;
    504         } else if (!bsp_interrupt_is_valid_vector( vector)) {
    505                 return RTEMS_INVALID_NUMBER;
    506         } else if (rtems_interrupt_is_in_progress()) {
    507                 return RTEMS_CALLED_FROM_ISR;
    508         }
    509 
    510         /* Lock */
    511         sc = bsp_interrupt_lock();
    512         if (sc != RTEMS_SUCCESSFUL) {
    513                 return sc;
    514         }
    515 
    516         /* Interate */
    517         index = bsp_interrupt_handler_index( vector);
    518         current = &bsp_interrupt_handler_table [index];
    519         if (!bsp_interrupt_is_empty_handler_entry( current)) {
    520                 do {
    521                         options = bsp_interrupt_is_handler_unique( index) ? RTEMS_INTERRUPT_UNIQUE : RTEMS_INTERRUPT_SHARED;
    522                         routine( arg, current->info, options, current->handler, current->arg);
    523                         current = current->next;
    524                 } while (current != NULL);
    525         }
    526 
    527         /* Unlock */
    528         sc = bsp_interrupt_unlock();
    529         if (sc != RTEMS_SUCCESSFUL) {
    530                 return sc;
    531         }
    532 
    533         return RTEMS_SUCCESSFUL;
    534 }
    535 
    536 rtems_status_code rtems_interrupt_handler_install( rtems_vector_number vector, const char *info, rtems_option options, rtems_interrupt_handler handler, void *arg)
    537 {
    538         return bsp_interrupt_handler_install( vector, info, options, handler, arg);
    539 }
    540 
    541 rtems_status_code rtems_interrupt_handler_remove( rtems_vector_number vector, rtems_interrupt_handler handler, void *arg)
    542 {
    543         return bsp_interrupt_handler_remove( vector, handler, arg);
    544 }
    545 
    546 rtems_status_code rtems_interrupt_handler_iterate( rtems_vector_number vector, rtems_interrupt_per_handler_routine routine, void *arg)
    547 {
    548         return bsp_interrupt_handler_iterate( vector, routine, arg);
    549 }
     526static rtems_status_code bsp_interrupt_handler_iterate(
     527  rtems_vector_number vector,
     528  rtems_interrupt_per_handler_routine routine,
     529  void *arg
     530)
     531{
     532  rtems_status_code sc = RTEMS_SUCCESSFUL;
     533  bsp_interrupt_handler_entry *current = NULL;
     534  rtems_option options = 0;
     535  rtems_vector_number index = 0;
     536
     537  /* Check parameters and system state */
     538  if (!bsp_interrupt_is_initialized()) {
     539    return RTEMS_INTERNAL_ERROR;
     540  } else if (!bsp_interrupt_is_valid_vector(vector)) {
     541    return RTEMS_INVALID_ID;
     542  } else if (rtems_interrupt_is_in_progress()) {
     543    return RTEMS_CALLED_FROM_ISR;
     544  }
     545
     546  /* Lock */
     547  sc = bsp_interrupt_lock();
     548  if (sc != RTEMS_SUCCESSFUL) {
     549    return sc;
     550  }
     551
     552  /* Interate */
     553  index = bsp_interrupt_handler_index(vector);
     554  current = &bsp_interrupt_handler_table [index];
     555  if (!bsp_interrupt_is_empty_handler_entry(current)) {
     556    do {
     557      options = bsp_interrupt_is_handler_unique(index) ?
     558        RTEMS_INTERRUPT_UNIQUE : RTEMS_INTERRUPT_SHARED;
     559      routine(arg, current->info, options, current->handler, current->arg);
     560      current = current->next;
     561    } while (current != NULL);
     562  }
     563
     564  /* Unlock */
     565  sc = bsp_interrupt_unlock();
     566  if (sc != RTEMS_SUCCESSFUL) {
     567    return sc;
     568  }
     569
     570  return RTEMS_SUCCESSFUL;
     571}
     572
     573rtems_status_code rtems_interrupt_handler_install(
     574  rtems_vector_number vector,
     575  const char *info,
     576  rtems_option options,
     577  rtems_interrupt_handler handler,
     578  void *arg
     579)
     580{
     581  return bsp_interrupt_handler_install(vector, info, options, handler, arg);
     582}
     583
     584rtems_status_code rtems_interrupt_handler_remove(
     585  rtems_vector_number vector,
     586  rtems_interrupt_handler handler,
     587  void *arg
     588)
     589{
     590  return bsp_interrupt_handler_remove(vector, handler, arg);
     591}
     592
     593rtems_status_code rtems_interrupt_handler_iterate(
     594  rtems_vector_number vector,
     595  rtems_interrupt_per_handler_routine routine,
     596  void *arg
     597)
     598{
     599  return bsp_interrupt_handler_iterate(vector, routine, arg);
     600}
  • c/src/lib/libbsp/shared/src/irq-info.c

    r17310b9d r8634637  
    44 * @ingroup bsp_interrupt
    55 *
    6  * @brief Source file for generic BSP interrupt information code.
     6 * @brief Generic BSP interrupt information implementation.
    77 */
    88
    99/*
    10  * Copyright (c) 2008
    11  * Embedded Brains GmbH
     10 * Copyright (c) 2008, 2009
     11 * embedded brains GmbH
    1212 * Obere Lagerstr. 30
    1313 * D-82178 Puchheim
    1414 * Germany
    15  * rtems@embedded-brains.de
     15 * <rtems@embedded-brains.de>
    1616 *
    17  * The license and distribution terms for this file may be found in the file
    18  * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
     17 * The license and distribution terms for this file may be
     18 * found in the file LICENSE in this distribution or at
     19 * http://www.rtems.com/license/LICENSE.
    1920 */
    2021
     
    2829
    2930typedef struct {
    30         void *context;
    31         rtems_printk_plugin_t print;
    32         rtems_vector_number vector;
     31  void *context;
     32  rtems_printk_plugin_t print;
     33  rtems_vector_number vector;
    3334} bsp_interrupt_report_entry;
    3435
    3536static void bsp_interrupt_report_per_handler_routine(
    36         void *arg,
    37         const char *info,
    38         rtems_option options,
    39         rtems_interrupt_handler handler,
    40         void *handler_arg
     37  void *arg,
     38  const char *info,
     39  rtems_option options,
     40  rtems_interrupt_handler handler,
     41  void *handler_arg
    4142)
    4243{
    43         bsp_interrupt_report_entry *e = (bsp_interrupt_report_entry *) arg;
    44         const char *opt = options == RTEMS_INTERRUPT_UNIQUE ? "UNIQUE" : "SHARED";
     44  bsp_interrupt_report_entry *e = (bsp_interrupt_report_entry *) arg;
     45  const char *opt = options == RTEMS_INTERRUPT_UNIQUE ? "UNIQUE" : "SHARED";
    4546
    46         e->print( e->context, "%7" PRIu32 " | %-32s | %7s | %010p | %010p\n", e->vector, info, opt, handler, handler_arg);
     47  e->print(
     48    e->context,
     49    "%7" PRIu32 " | %-32s | %7s | %010p | %010p\n",
     50    e->vector,
     51    info,
     52    opt,
     53    handler,
     54    handler_arg
     55  );
    4756}
    4857
    49 /**
    50  * @brief Prints interrupt information via the printk plugin @a print with the
    51  * context @a context.
    52  */
    53 void bsp_interrupt_report_with_plugin( void *context, rtems_printk_plugin_t print)
     58void bsp_interrupt_report_with_plugin(
     59  void *context,
     60  rtems_printk_plugin_t print
     61)
    5462{
    55         rtems_vector_number v = 0;
    56         bsp_interrupt_report_entry e = {
    57                 .context = context,
    58                 .print = print,
    59                 .vector = 0
    60         };
     63  rtems_vector_number v = 0;
     64  bsp_interrupt_report_entry e = {
     65    .context = context,
     66    .print = print,
     67    .vector = 0
     68  };
    6169
    62         print(
    63                 context,
    64                 "-------------------------------------------------------------------------------\n"
    65                 "                             INTERRUPT INFORMATION\n"
    66                 "--------+----------------------------------+---------+------------+------------\n"
    67                 " VECTOR | INFO                             | OPTIONS | HANDLER    | ARGUMENT   \n"
    68                 "--------+----------------------------------+---------+------------+------------\n"
    69         );
     70  print(
     71    context,
     72    "-------------------------------------------------------------------------------\n"
     73    "                             INTERRUPT INFORMATION\n"
     74    "--------+----------------------------------+---------+------------+------------\n"
     75    " VECTOR | INFO                             | OPTIONS | HANDLER    | ARGUMENT   \n"
     76    "--------+----------------------------------+---------+------------+------------\n"
     77  );
    7078
    71         for (v = BSP_INTERRUPT_VECTOR_MIN; v <= BSP_INTERRUPT_VECTOR_MAX; ++v) {
    72                 e.vector = v;
    73                 (void) rtems_interrupt_handler_iterate( v, bsp_interrupt_report_per_handler_routine, &e);
    74         }
     79  for (v = BSP_INTERRUPT_VECTOR_MIN; v <= BSP_INTERRUPT_VECTOR_MAX; ++v) {
     80    e.vector = v;
     81    rtems_interrupt_handler_iterate(
     82      v,
     83      bsp_interrupt_report_per_handler_routine,
     84      &e
     85    );
     86  }
    7587
    76         print(
    77                 context,
    78                 "--------+----------------------------------+---------+------------+------------\n"
    79         );
     88  print(
     89    context,
     90    "--------+----------------------------------+---------+------------+------------\n"
     91  );
    8092}
    8193
    82 /**
    83  * @brief Prints interrupt information via the default printk plugin.
    84  */
    85 void bsp_interrupt_report( void)
     94void bsp_interrupt_report(void)
    8695{
    87         bsp_interrupt_report_with_plugin( NULL, printk_plugin);
     96  bsp_interrupt_report_with_plugin(NULL, printk_plugin);
    8897}
  • c/src/lib/libbsp/shared/src/irq-legacy.c

    r17310b9d r8634637  
    44 * @ingroup bsp_interrupt
    55 *
    6  * @brief Source file for generic BSP interrupt support legacy code.
     6 * @brief Generic BSP interrupt support legacy implementation.
    77 */
    88
    99/*
    10  * Copyright (c) 2008
    11  * Embedded Brains GmbH
     10 * Copyright (c) 2008, 2009
     11 * embedded brains GmbH
    1212 * Obere Lagerstr. 30
    1313 * D-82178 Puchheim
    1414 * Germany
    15  * rtems@embedded-brains.de
     15 * <rtems@embedded-brains.de>
    1616 *
    17  *  The license and distribution terms for this file may be
    18  *  found in the file LICENSE in this distribution or at
    19  *  http://www.rtems.com/license/LICENSE.
    20  *
     17 * The license and distribution terms for this file may be
     18 * found in the file LICENSE in this distribution or at
     19 * http://www.rtems.com/license/LICENSE.
    2120 */
    2221
    2322#include <stdbool.h>
    2423#include <stdlib.h>
     24
     25#define BSP_SHARED_HANDLER_SUPPORT
    2526
    2627#include <rtems/irq.h>
     
    8586{
    8687  rtems_status_code sc = RTEMS_SUCCESSFUL;
    87   bsp_interrupt_legacy_entry *e = malloc(sizeof( bsp_interrupt_legacy_entry));
     88  bsp_interrupt_legacy_entry *e = malloc(sizeof(bsp_interrupt_legacy_entry));
    8889
    8990  if (e == NULL) {
     
    9697  sc = rtems_interrupt_handler_install(
    9798    cd->name,
    98     "Unique interrupt handler "
    99         "(installed with obsolete BSP_install_rtems_irq_handler())",
     99    "LEGACY INSTALLED",
    100100    RTEMS_INTERRUPT_UNIQUE,
    101101    bsp_interrupt_legacy_dispatch,
     
    120120{
    121121  rtems_status_code sc = RTEMS_SUCCESSFUL;
    122   bsp_interrupt_legacy_entry *e = malloc(sizeof( bsp_interrupt_legacy_entry));
     122  bsp_interrupt_legacy_entry *e = malloc(sizeof(bsp_interrupt_legacy_entry));
    123123
    124124  if (e == NULL) {
     
    131131  sc = rtems_interrupt_handler_install(
    132132    cd->name,
    133     "Shared interrupt handler "
    134         "(installed with obsolete BSP_install_rtems_shared_irq_handler())",
     133    "LEGACY INSTALLED",
    135134    RTEMS_INTERRUPT_SHARED,
    136135    bsp_interrupt_legacy_dispatch,
  • c/src/lib/libbsp/shared/src/irq-shell.c

    r17310b9d r8634637  
    44 * @ingroup bsp_interrupt
    55 *
    6  * @brief Source file for generic BSP interrupt shell code.
     6 * @brief Generic BSP interrupt shell implementation.
    77 */
    88
    99/*
    10  * Copyright (c) 2008
    11  * Embedded Brains GmbH
     10 * Copyright (c) 2009
     11 * embedded brains GmbH
    1212 * Obere Lagerstr. 30
    1313 * D-82178 Puchheim
    1414 * Germany
    15  * rtems@embedded-brains.de
     15 * <rtems@embedded-brains.de>
    1616 *
    17  *  The license and distribution terms for this file may be
    18  *  found in the file LICENSE in this distribution or at
    19  *  http://www.rtems.com/license/LICENSE.
     17 * The license and distribution terms for this file may be
     18 * found in the file LICENSE in this distribution or at
     19 * http://www.rtems.com/license/LICENSE.
    2020 */
    2121
     
    2626#include <bsp/irq-info.h>
    2727
    28 static int bsp_interrupt_shell_main( int argc, char **argv)
     28static int bsp_interrupt_shell_main(int argc, char **argv)
    2929{
    30   bsp_interrupt_report_with_plugin( stdout, (rtems_printk_plugin_t) fprintf);
     30  bsp_interrupt_report_with_plugin(stdout, (rtems_printk_plugin_t) fprintf);
    3131
    3232  return 0;
    3333}
    3434
    35 /**
    36  * @brief Shell command entry for interrupt information.
    37  */
    3835struct rtems_shell_cmd_tt bsp_interrupt_shell_command = {
    3936  .name     = "irq",
  • c/src/lib/libbsp/shared/src/stackalloc.c

    r17310b9d r8634637  
    3131};
    3232
    33 void bsp_stack_initialize(void *start, intptr_t size)
     33void bsp_stack_initialize(void *begin, uintptr_t size)
    3434{
    35   bsp_stack_heap.begin = start;
    36   bsp_stack_heap.end = (void *) size;
     35  bsp_stack_heap.area_begin = (uintptr_t) begin;
     36  bsp_stack_heap.area_end = size;
    3737}
    3838
    39 void *bsp_stack_allocate(uint32_t size)
     39void *bsp_stack_allocate(size_t size)
    4040{
    4141  void *stack = NULL;
    4242
    4343  if (bsp_stack_heap.page_size == BSP_STACK_MAGIC) {
    44     uint32_t rv = _Heap_Initialize(
     44    uintptr_t rv = _Heap_Initialize(
    4545      &bsp_stack_heap,
    46       bsp_stack_heap.begin,
    47       (intptr_t) bsp_stack_heap.end,
     46      (void *) bsp_stack_heap.area_begin,
     47      bsp_stack_heap.area_end,
    4848      CPU_STACK_ALIGNMENT
    4949    );
     
    5353  }
    5454
    55   stack = _Heap_Allocate(&bsp_stack_heap, (intptr_t) size);
     55  stack = _Heap_Allocate(&bsp_stack_heap, size);
    5656
    5757  if (stack == NULL) {
Note: See TracChangeset for help on using the changeset viewer.