summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2009-09-08 13:35:07 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2009-09-08 13:35:07 +0000
commit8634637d1dbb4f736d7bf050c32814165c9a6d3f (patch)
tree7ff0a95d7d847501174213edf9603be09bf879b3 /c
parentFix GDB_VERS. (diff)
downloadrtems-8634637d1dbb4f736d7bf050c32814165c9a6d3f.tar.bz2
2009-09-08 Sebastian Huber <sebastian.huber@embedded-brains.de>
* 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.
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libbsp/shared/ChangeLog9
-rw-r--r--c/src/lib/libbsp/shared/bsplibc.c8
-rw-r--r--c/src/lib/libbsp/shared/include/bootcard.h83
-rw-r--r--c/src/lib/libbsp/shared/include/irq-config.h31
-rw-r--r--c/src/lib/libbsp/shared/include/irq-generic.h103
-rw-r--r--c/src/lib/libbsp/shared/include/irq-info.h30
-rw-r--r--c/src/lib/libbsp/shared/include/stackalloc.h54
-rw-r--r--c/src/lib/libbsp/shared/src/irq-generic.c921
-rw-r--r--c/src/lib/libbsp/shared/src/irq-info.c107
-rw-r--r--c/src/lib/libbsp/shared/src/irq-legacy.c27
-rw-r--r--c/src/lib/libbsp/shared/src/irq-server.c275
-rw-r--r--c/src/lib/libbsp/shared/src/irq-shell.c21
-rw-r--r--c/src/lib/libbsp/shared/src/stackalloc.c16
13 files changed, 1079 insertions, 606 deletions
diff --git a/c/src/lib/libbsp/shared/ChangeLog b/c/src/lib/libbsp/shared/ChangeLog
index 4cecea7cab..fed8fab637 100644
--- a/c/src/lib/libbsp/shared/ChangeLog
+++ b/c/src/lib/libbsp/shared/ChangeLog
@@ -1,3 +1,12 @@
+2009-09-08 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * 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.
+
2009-08-28 Joel Sherrill <joel.sherrill@OARcorp.com>
* bootcard.c, bsplibc.c, clockdrv_shell.h, console-polled.c: Fix
diff --git a/c/src/lib/libbsp/shared/bsplibc.c b/c/src/lib/libbsp/shared/bsplibc.c
index ce0090077d..05fdaa7ca8 100644
--- a/c/src/lib/libbsp/shared/bsplibc.c
+++ b/c/src/lib/libbsp/shared/bsplibc.c
@@ -12,12 +12,12 @@
#include <bsp/bootcard.h>
void bsp_libc_init(
- void *heap_start,
- size_t heap_size,
- size_t sbrk_amount
+ void *heap_begin,
+ uintptr_t heap_size,
+ size_t sbrk_amount
)
{
- RTEMS_Malloc_Initialize( heap_start, heap_size, sbrk_amount );
+ RTEMS_Malloc_Initialize( heap_begin, heap_size, sbrk_amount );
/*
* Init the RTEMS libio facility to provide UNIX-like system
diff --git a/c/src/lib/libbsp/shared/include/bootcard.h b/c/src/lib/libbsp/shared/include/bootcard.h
index 9a6dcfdb93..ed0c5598bb 100644
--- a/c/src/lib/libbsp/shared/include/bootcard.h
+++ b/c/src/lib/libbsp/shared/include/bootcard.h
@@ -1,9 +1,9 @@
/**
* @file
*
- * @ingroup bsp_shared
+ * @ingroup bsp_bootcard
*
- * @brief Header file for basic BSP startup functions.
+ * @brief Standard system startup.
*/
/*
@@ -21,7 +21,19 @@
*/
/**
- * @defgroup bsp_shared Shared BSP Code
+ * @defgroup bsp_kit Board Support Package
+ *
+ * @brief Board support package dependent code.
+ */
+
+/**
+ * @defgroup bsp_bootcard Bootcard
+ *
+ * @ingroup bsp_kit
+ *
+ * @brief Standard system startup.
+ *
+ * @{
*/
#ifndef LIBBSP_SHARED_BOOTCARD_H
@@ -37,6 +49,11 @@
extern "C" {
#endif /* __cplusplus */
+/**
+ * @brief Global pointer to the command line of boot_card().
+ */
+extern const char *bsp_boot_cmdline;
+
void bsp_start(void);
void bsp_pretasking_hook(void);
@@ -49,20 +66,72 @@ void bsp_cleanup(void);
void bsp_reset(void);
+/**
+ * @brief Should be used as the heap begin address in bsp_get_work_area() if
+ * the heap area is contained in the work area.
+ */
#define BSP_BOOTCARD_HEAP_USES_WORK_AREA NULL
+/**
+ * @brief Should be used to request the default heap size in bsp_get_work_area().
+ *
+ * In case that the heap area is contained in the work area this heap size
+ * value indicates that the area outside the work space should be used as heap
+ * space.
+ */
#define BSP_BOOTCARD_HEAP_SIZE_DEFAULT 0
void bsp_get_work_area(
- void **work_area_start,
+ void **work_area_begin,
uintptr_t *work_area_size,
- void **heap_start,
+ void **heap_begin,
uintptr_t *heap_size
);
-int boot_card( const char *cmdline );
+/**
+ * @brief Standard system initialization procedure.
+ *
+ * You may pass a command line in @a cmdline. It is later available via the
+ * global @ref bsp_boot_cmdline variable.
+ *
+ * This is the C entry point for ALL RTEMS BSPs. It is invoked from the
+ * assembly language initialization file usually called @c start.S which does
+ * the basic CPU setup (stack, C runtime environment, zero BSS, load other
+ * sections) and calls afterwards boot_card(). The boot card function provides
+ * the framework for the BSP initialization sequence. The basic flow of
+ * initialization is:
+ *
+ * - disable interrupts, interrupts will be enabled during the first context switch
+ * - bsp_start() - more advanced initialization
+ * - obtain information on BSP memory via bsp_get_work_area() and allocate RTEMS Workspace
+ * - rtems_initialize_data_structures()
+ * - allocate memory for C Program Heap
+ * - initialize C Library and C Program Heap
+ * - bsp_pretasking_hook()
+ * - if defined( RTEMS_DEBUG )
+ * - rtems_debug_enable( RTEMS_DEBUG_ALL_MASK )
+ * - rtems_initialize_before_drivers()
+ * - bsp_predriver_hook()
+ * - rtems_initialize_device_drivers()
+ * - initialization of all device drivers
+ * - bsp_postdriver_hook()
+ * - rtems_initialize_start_multitasking()
+ * - 1st task executes C++ global constructors
+ * - .... appplication runs ...
+ * - exit
+ * - back to here eventually
+ * - bsp_cleanup()
+ *
+ * If something goes wrong bsp_cleanup() will be called out of order.
+ *
+ * This style of initialization ensures that the C++ global constructors are
+ * executed after RTEMS is initialized.
+ */
+int boot_card(const char *cmdline);
+
+/** @} */
-void bsp_libc_init( void *heap_start, size_t heap_size, size_t sbrk_amount);
+void bsp_libc_init(void *heap_begin, uintptr_t heap_size, size_t sbrk_amount);
#ifdef __cplusplus
}
diff --git a/c/src/lib/libbsp/shared/include/irq-config.h b/c/src/lib/libbsp/shared/include/irq-config.h
index 3fffc779a1..9596f98b5c 100644
--- a/c/src/lib/libbsp/shared/include/irq-config.h
+++ b/c/src/lib/libbsp/shared/include/irq-config.h
@@ -9,15 +9,16 @@
/*
* Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
*
- * Copyright (c) 2008
- * Embedded Brains GmbH
+ * Copyright (c) 2008, 2009
+ * embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
* Germany
- * rtems@embedded-brains.de
+ * <rtems@embedded-brains.de>
*
- * The license and distribution terms for this file may be found in the file
- * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
*/
#ifndef LIBBSP_SHARED_IRQ_CONFIG_H
@@ -60,18 +61,16 @@
#undef BSP_INTERRUPT_NO_HEAP_USAGE
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
+ /**
+ * @brief Size of the handler table.
+ */
+ #define BSP_INTERRUPT_HANDLER_TABLE_SIZE 0
-/**
- * @brief Size of the handler table.
- */
-#define BSP_INTERRUPT_HANDLER_TABLE_SIZE 0
-
-/**
- * @brief Integer type capable to index the complete handler table.
- */
-typedef uint8_t bsp_interrupt_handler_index_type;
-
-#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
+ /**
+ * @brief Integer type capable to index the complete handler table.
+ */
+ typedef uint8_t bsp_interrupt_handler_index_type;
+#endif
/** @} */
diff --git a/c/src/lib/libbsp/shared/include/irq-generic.h b/c/src/lib/libbsp/shared/include/irq-generic.h
index f396e18d17..2386587ccb 100644
--- a/c/src/lib/libbsp/shared/include/irq-generic.h
+++ b/c/src/lib/libbsp/shared/include/irq-generic.h
@@ -3,21 +3,22 @@
*
* @ingroup bsp_interrupt
*
- * @brief Header file for generic BSP interrupt support.
+ * @brief Generic BSP interrupt support API.
*/
/*
* Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
*
- * Copyright (c) 2008
- * Embedded Brains GmbH
+ * Copyright (c) 2008, 2009
+ * embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
* Germany
- * rtems@embedded-brains.de
+ * <rtems@embedded-brains.de>
*
- * The license and distribution terms for this file may be found in the file
- * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
*/
#ifndef LIBBSP_SHARED_IRQ_GENERIC_H
@@ -33,29 +34,30 @@
extern "C" {
#endif /* __cplusplus */
-#if !defined( BSP_INTERRUPT_VECTOR_MIN) || !defined( BSP_INTERRUPT_VECTOR_MAX) || (BSP_INTERRUPT_VECTOR_MAX + 1) < BSP_INTERRUPT_VECTOR_MIN
-#error Invalid BSP_INTERRUPT_VECTOR_MIN or BSP_INTERRUPT_VECTOR_MAX.
-#endif /* !defined( BSP_INTERRUPT_VECTOR_MIN) ... */
+#if !defined(BSP_INTERRUPT_VECTOR_MIN) || !defined(BSP_INTERRUPT_VECTOR_MAX) || (BSP_INTERRUPT_VECTOR_MAX + 1) < BSP_INTERRUPT_VECTOR_MIN
+ #error "invalid BSP_INTERRUPT_VECTOR_MIN or BSP_INTERRUPT_VECTOR_MAX"
+#endif
-#if defined( BSP_INTERRUPT_USE_INDEX_TABLE) && !defined( BSP_INTERRUPT_HANDLER_TABLE_SIZE)
-#error If you define BSP_INTERRUPT_USE_INDEX_TABLE, you have to define BSP_INTERRUPT_HANDLER_TABLE_SIZE etc. as well.
-#endif /* defined( BSP_INTERRUPT_USE_INDEX_TABLE) ... */
+#if defined(BSP_INTERRUPT_USE_INDEX_TABLE) && !defined(BSP_INTERRUPT_HANDLER_TABLE_SIZE)
+ #error "if you define BSP_INTERRUPT_USE_INDEX_TABLE, you have to define BSP_INTERRUPT_HANDLER_TABLE_SIZE etc. as well"
+#endif
-#if defined( BSP_INTERRUPT_NO_HEAP_USAGE) && !defined( BSP_INTERRUPT_USE_INDEX_TABLE)
-#error If you define BSP_INTERRUPT_NO_HEAP_USAGE, you have to define BSP_INTERRUPT_USE_INDEX_TABLE etc. as well.
-#endif /* defined( BSP_INTERRUPT_NO_HEAP_USAGE) ... */
+#if defined(BSP_INTERRUPT_NO_HEAP_USAGE) && !defined(BSP_INTERRUPT_USE_INDEX_TABLE)
+ #error "if you define BSP_INTERRUPT_NO_HEAP_USAGE, you have to define BSP_INTERRUPT_USE_INDEX_TABLE etc. as well"
+#endif
-#define BSP_INTERRUPT_VECTOR_NUMBER (BSP_INTERRUPT_VECTOR_MAX - BSP_INTERRUPT_VECTOR_MIN + 1)
+#define BSP_INTERRUPT_VECTOR_NUMBER \
+ (BSP_INTERRUPT_VECTOR_MAX - BSP_INTERRUPT_VECTOR_MIN + 1)
#ifndef BSP_INTERRUPT_HANDLER_TABLE_SIZE
-#define BSP_INTERRUPT_HANDLER_TABLE_SIZE BSP_INTERRUPT_VECTOR_NUMBER
-#endif /* BSP_INTERRUPT_HANDLER_TABLE_SIZE */
+ #define BSP_INTERRUPT_HANDLER_TABLE_SIZE BSP_INTERRUPT_VECTOR_NUMBER
+#endif
struct bsp_interrupt_handler_entry {
- rtems_interrupt_handler handler;
- void *arg;
- const char *info;
- struct bsp_interrupt_handler_entry *next;
+ rtems_interrupt_handler handler;
+ void *arg;
+ const char *info;
+ struct bsp_interrupt_handler_entry *next;
};
typedef struct bsp_interrupt_handler_entry bsp_interrupt_handler_entry;
@@ -63,16 +65,18 @@ typedef struct bsp_interrupt_handler_entry bsp_interrupt_handler_entry;
extern bsp_interrupt_handler_entry bsp_interrupt_handler_table [];
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
-extern bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table [];
-#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
+ extern bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table [];
+#endif
-static inline rtems_vector_number bsp_interrupt_handler_index( rtems_vector_number vector)
+static inline rtems_vector_number bsp_interrupt_handler_index(
+ rtems_vector_number vector
+)
{
-#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
- return bsp_interrupt_handler_index_table [vector - BSP_INTERRUPT_VECTOR_MIN];
-#else /* BSP_INTERRUPT_USE_INDEX_TABLE */
- return vector - BSP_INTERRUPT_VECTOR_MIN;
-#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
+ #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
+ return bsp_interrupt_handler_index_table [vector - BSP_INTERRUPT_VECTOR_MIN];
+ #else
+ return vector - BSP_INTERRUPT_VECTOR_MIN;
+ #endif
}
/**
@@ -129,10 +133,10 @@ static inline rtems_vector_number bsp_interrupt_handler_index( rtems_vector_numb
/**
* @brief Returns true if the interrupt vector with number @a vector is valid.
*/
-static inline bool bsp_interrupt_is_valid_vector( rtems_vector_number vector)
+static inline bool bsp_interrupt_is_valid_vector(rtems_vector_number vector)
{
- return (rtems_vector_number) BSP_INTERRUPT_VECTOR_MIN <= vector
- && vector <= (rtems_vector_number) BSP_INTERRUPT_VECTOR_MAX;
+ return (rtems_vector_number) BSP_INTERRUPT_VECTOR_MIN <= vector
+ && vector <= (rtems_vector_number) BSP_INTERRUPT_VECTOR_MAX;
}
/**
@@ -144,7 +148,7 @@ static inline bool bsp_interrupt_is_valid_vector( rtems_vector_number vector)
*
* @note This function must cope with arbitrary vector numbers @a vector.
*/
-void bsp_interrupt_handler_default( rtems_vector_number vector);
+void bsp_interrupt_handler_default(rtems_vector_number vector);
/**
* @brief Initialize BSP interrupt support.
@@ -154,7 +158,7 @@ void bsp_interrupt_handler_default( rtems_vector_number vector);
* function will be called after all internals are initialized. Initialization
* is complete if everything was successful.
*/
-rtems_status_code bsp_interrupt_initialize( void);
+rtems_status_code bsp_interrupt_initialize(void);
/**
* @brief BSP specific initialization.
@@ -171,7 +175,7 @@ rtems_status_code bsp_interrupt_initialize( void);
*
* @return On success RTEMS_SUCCESSFUL shall be returned.
*/
-rtems_status_code bsp_interrupt_facility_initialize( void);
+rtems_status_code bsp_interrupt_facility_initialize(void);
/**
* @brief Enables the interrupt vector with number @a vector.
@@ -187,7 +191,7 @@ rtems_status_code bsp_interrupt_facility_initialize( void);
*
* @return On success RTEMS_SUCCESSFUL shall be returned.
*/
-rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number vector);
+rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector);
/**
* @brief Disables the interrupt vector with number @a vector.
@@ -203,7 +207,7 @@ rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number vector);
*
* @return On success RTEMS_SUCCESSFUL shall be returned.
*/
-rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector);
+rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector);
/**
* @brief Sequencially calls all interrupt handlers for the vector number @a
@@ -215,18 +219,19 @@ rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number vector);
* You can call this function within every context which can be disabled via
* rtems_interrupt_disable().
*/
-static inline void bsp_interrupt_handler_dispatch( rtems_vector_number vector)
+static inline void bsp_interrupt_handler_dispatch(rtems_vector_number vector)
{
- if (bsp_interrupt_is_valid_vector( vector)) {
- bsp_interrupt_handler_entry *e = &bsp_interrupt_handler_table [bsp_interrupt_handler_index( vector)];
-
- do {
- e->handler( vector, e->arg);
- e = e->next;
- } while (e != NULL);
- } else {
- bsp_interrupt_handler_default( vector);
- }
+ if (bsp_interrupt_is_valid_vector(vector)) {
+ bsp_interrupt_handler_entry *e =
+ &bsp_interrupt_handler_table [bsp_interrupt_handler_index(vector)];
+
+ do {
+ (*e->handler)(vector, e->arg);
+ e = e->next;
+ } while (e != NULL);
+ } else {
+ bsp_interrupt_handler_default(vector);
+ }
}
/** @} */
diff --git a/c/src/lib/libbsp/shared/include/irq-info.h b/c/src/lib/libbsp/shared/include/irq-info.h
index f2dee7ed35..02efc955c0 100644
--- a/c/src/lib/libbsp/shared/include/irq-info.h
+++ b/c/src/lib/libbsp/shared/include/irq-info.h
@@ -3,19 +3,20 @@
*
* @ingroup bsp_interrupt
*
- * @brief Header file for generic BSP interrupt information.
+ * @brief Generic BSP interrupt information API.
*/
/*
- * Copyright (c) 2008
- * Embedded Brains GmbH
+ * Copyright (c) 2008, 2009
+ * embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
* Germany
- * rtems@embedded-brains.de
+ * <rtems@embedded-brains.de>
*
- * The license and distribution terms for this file may be found in the file
- * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
*/
#ifndef LIBBSP_SHARED_IRQ_INFO_H
@@ -36,10 +37,23 @@ extern "C" {
* @{
*/
-void bsp_interrupt_report_with_plugin( void *context, rtems_printk_plugin_t print);
+/**
+ * @brief Prints interrupt information via the printk plugin @a print with the
+ * context @a context.
+ */
+void bsp_interrupt_report_with_plugin(
+ void *context,
+ rtems_printk_plugin_t print
+);
-void bsp_interrupt_report( void);
+/**
+ * @brief Prints interrupt information via the default printk plugin.
+ */
+void bsp_interrupt_report(void);
+/**
+ * @brief Shell command entry for interrupt information.
+ */
extern struct rtems_shell_cmd_tt bsp_interrupt_shell_command;
/** @} */
diff --git a/c/src/lib/libbsp/shared/include/stackalloc.h b/c/src/lib/libbsp/shared/include/stackalloc.h
index e95f43591a..56132da317 100644
--- a/c/src/lib/libbsp/shared/include/stackalloc.h
+++ b/c/src/lib/libbsp/shared/include/stackalloc.h
@@ -1,9 +1,9 @@
/**
* @file
*
- * @ingroup bsp_shared
+ * @ingroup bsp_stack
*
- * @brief Stack initialization, allocation and free functions.
+ * @brief Task stack initialization, allocation and free functions.
*/
/*
@@ -22,22 +22,68 @@
#ifndef LIBBSP_SHARED_STACK_ALLOC_H
#define LIBBSP_SHARED_STACK_ALLOC_H
+#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-void bsp_stack_initialize(void *start, intptr_t size);
+/**
+ * @defgroup bsp_stack Task Stack Allocator
+ *
+ * @ingroup bsp_kit
+ *
+ * @brief Task stack initialization, allocation and free functions.
+ *
+ * Initialize the task stack allocator with bsp_stack_initialize(). To enable
+ * the task stack allocator use the following in the system configuration:
+ *
+ * @code
+ * #include <bsp/stackalloc.h>
+ *
+ * #define CONFIGURE_INIT
+ *
+ * #include <confdefs.h>
+ * @endcode
+ *
+ * @{
+ */
+
+/**
+ * @brief Task stack management initialization.
+ *
+ * This function should be called in bsp_start() with the designated task stack
+ * area begin address @a begin and task stack area size @a size in bytes. The
+ * area boundaries have to be aligned properly.
+ */
+void bsp_stack_initialize(void *begin, uintptr_t size);
-void *bsp_stack_allocate(uint32_t size);
+/**
+ * @brief Task stack allocator for @ref CONFIGURE_TASK_STACK_ALLOCATOR.
+ *
+ * In case the designated task stack space from bsp_stack_initialize() is
+ * completely in use the work space will be used to allocate the stack.
+ */
+void *bsp_stack_allocate(size_t size);
+/**
+ * @brief Task stack free function for @ref CONFIGURE_TASK_STACK_DEALLOCATOR.
+ */
void bsp_stack_free(void *stack);
+/**
+ * @brief Task stack allocator configuration option.
+ */
#define CONFIGURE_TASK_STACK_ALLOCATOR bsp_stack_allocate
+/**
+ * @brief Task stack deallocator configuration option.
+ */
#define CONFIGURE_TASK_STACK_DEALLOCATOR bsp_stack_free
+/** @} */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/c/src/lib/libbsp/shared/src/irq-generic.c b/c/src/lib/libbsp/shared/src/irq-generic.c
index 71ab216ded..8356728f41 100644
--- a/c/src/lib/libbsp/shared/src/irq-generic.c
+++ b/c/src/lib/libbsp/shared/src/irq-generic.c
@@ -3,219 +3,238 @@
*
* @ingroup bsp_interrupt
*
- * @brief Source file for generic BSP interrupt support.
+ * @brief Generic BSP interrupt support implementation.
*/
/*
* Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
*
- * Copyright (c) 2008
- * Embedded Brains GmbH
+ * Copyright (c) 2008, 2009
+ * embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
* Germany
- * rtems@embedded-brains.de
+ * <rtems@embedded-brains.de>
*
- * The license and distribution terms for this file may be found in the file
- * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
*/
-#include <stdlib.h> /* malloc, free */
+#include <stdlib.h>
#include <bsp/irq-generic.h>
#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
-bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table [BSP_INTERRUPT_VECTOR_NUMBER];
-#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
+ bsp_interrupt_handler_index_type bsp_interrupt_handler_index_table
+ [BSP_INTERRUPT_VECTOR_NUMBER];
+#endif
-static void bsp_interrupt_handler_empty( rtems_vector_number vector, void *arg)
-{
- bsp_interrupt_handler_default( vector);
-}
-
-bsp_interrupt_handler_entry bsp_interrupt_handler_table [BSP_INTERRUPT_HANDLER_TABLE_SIZE] = {
- [0 ... BSP_INTERRUPT_HANDLER_TABLE_SIZE - 1] = {
- .handler = bsp_interrupt_handler_empty,
- .arg = NULL,
- .info = NULL,
- .next = NULL
- }
-};
+bsp_interrupt_handler_entry bsp_interrupt_handler_table
+ [BSP_INTERRUPT_HANDLER_TABLE_SIZE];
/* The last entry indicates if everything is initialized */
-static uint8_t bsp_interrupt_handler_unique_table [(BSP_INTERRUPT_HANDLER_TABLE_SIZE + 7 + 1) / 8];
+static uint8_t bsp_interrupt_handler_unique_table
+ [(BSP_INTERRUPT_HANDLER_TABLE_SIZE + 7 + 1) / 8];
static rtems_id bsp_interrupt_mutex = RTEMS_ID_NONE;
-static inline bool bsp_interrupt_is_handler_unique( rtems_vector_number index)
+static void bsp_interrupt_handler_empty(rtems_vector_number vector, void *arg)
{
- rtems_vector_number i = index / 8;
- rtems_vector_number s = index % 8;
- return (bsp_interrupt_handler_unique_table [i] >> s) & 0x1;
+ bsp_interrupt_handler_default(vector);
}
-static inline void bsp_interrupt_set_handler_unique( rtems_vector_number index, bool unique)
+static inline bool bsp_interrupt_is_handler_unique(rtems_vector_number index)
{
- rtems_vector_number i = index / 8;
- rtems_vector_number s = index % 8;
- if (unique) {
- bsp_interrupt_handler_unique_table [i] |= (uint8_t) (0x1U << s);
- } else {
- bsp_interrupt_handler_unique_table [i] &= (uint8_t) ~(0x1U << s);
- }
+ rtems_vector_number i = index / 8;
+ rtems_vector_number s = index % 8;
+ return (bsp_interrupt_handler_unique_table [i] >> s) & 0x1;
+}
+
+static inline void bsp_interrupt_set_handler_unique(
+ rtems_vector_number index,
+ bool unique
+)
+{
+ rtems_vector_number i = index / 8;
+ rtems_vector_number s = index % 8;
+ if (unique) {
+ bsp_interrupt_handler_unique_table [i] |= (uint8_t) (0x1U << s);
+ } else {
+ bsp_interrupt_handler_unique_table [i] &= (uint8_t) ~(0x1U << s);
+ }
}
static inline bool bsp_interrupt_is_initialized(void)
{
- return bsp_interrupt_is_handler_unique( BSP_INTERRUPT_HANDLER_TABLE_SIZE);
+ return bsp_interrupt_is_handler_unique(BSP_INTERRUPT_HANDLER_TABLE_SIZE);
}
static inline void bsp_interrupt_set_initialized(void)
{
- bsp_interrupt_set_handler_unique( BSP_INTERRUPT_HANDLER_TABLE_SIZE, true);
+ bsp_interrupt_set_handler_unique(BSP_INTERRUPT_HANDLER_TABLE_SIZE, true);
}
-static inline bool bsp_interrupt_is_empty_handler_entry( bsp_interrupt_handler_entry *e)
+static inline bool bsp_interrupt_is_empty_handler_entry(
+ bsp_interrupt_handler_entry *e
+)
{
- return e->handler == bsp_interrupt_handler_empty;
+ return e->handler == bsp_interrupt_handler_empty;
}
-static inline void bsp_interrupt_clear_handler_entry( bsp_interrupt_handler_entry *e)
+static inline void bsp_interrupt_clear_handler_entry(
+ bsp_interrupt_handler_entry *e
+)
{
- e->handler = bsp_interrupt_handler_empty;
- e->arg = NULL;
- e->info = NULL;
- e->next = NULL;
+ e->handler = bsp_interrupt_handler_empty;
+ e->arg = NULL;
+ e->info = NULL;
+ e->next = NULL;
}
-static inline bool bsp_interrupt_allocate_handler_index( rtems_vector_number vector, rtems_vector_number *index)
+static inline bool bsp_interrupt_allocate_handler_index(
+ rtems_vector_number vector,
+ rtems_vector_number *index
+)
{
-#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
- rtems_vector_number i = 0;
-
- /* The first entry will remain empty */
- for (i = 1; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i) {
- if (bsp_interrupt_is_empty_handler_entry( &bsp_interrupt_handler_table [i])) {
- *index = i;
- return 1;
- }
- }
-
- return 0;
-#else /* BSP_INTERRUPT_USE_INDEX_TABLE */
- *index = vector;
- return 1;
-#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
+ #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
+ rtems_vector_number i = 0;
+
+ /* The first entry will remain empty */
+ for (i = 1; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i) {
+ const bsp_interrupt_handler_entry *e = &bsp_interrupt_handler_table [i];
+ if (bsp_interrupt_is_empty_handler_entry(e)) {
+ *index = i;
+ return true;
+ }
+ }
+
+ return false;
+ #else
+ *index = vector;
+ return true;
+ #endif
}
-static bsp_interrupt_handler_entry *bsp_interrupt_allocate_handler_entry( void)
+static bsp_interrupt_handler_entry *bsp_interrupt_allocate_handler_entry(void)
{
-#ifdef BSP_INTERRUPT_NO_HEAP_USAGE
- rtems_vector_number index = 0;
- if (bsp_interrupt_allocate_handler_index( 0, &index)) {
- return &bsp_interrupt_handler_table [index];
- } else {
- return NULL;
- }
-#else /* BSP_INTERRUPT_NO_HEAP_USAGE */
- return malloc( sizeof( bsp_interrupt_handler_entry));
-#endif /* BSP_INTERRUPT_NO_HEAP_USAGE */
+ #ifdef BSP_INTERRUPT_NO_HEAP_USAGE
+ rtems_vector_number index = 0;
+ if (bsp_interrupt_allocate_handler_index(0, &index)) {
+ return &bsp_interrupt_handler_table [index];
+ } else {
+ return NULL;
+ }
+ #else
+ return malloc(sizeof(bsp_interrupt_handler_entry));
+ #endif
}
-static void bsp_interrupt_free_handler_entry( bsp_interrupt_handler_entry *e)
+static void bsp_interrupt_free_handler_entry(bsp_interrupt_handler_entry *e)
{
-#ifdef BSP_INTERRUPT_NO_HEAP_USAGE
- bsp_interrupt_clear_handler_entry( e);
-#else /* BSP_INTERRUPT_NO_HEAP_USAGE */
- free( e);
-#endif /* BSP_INTERRUPT_NO_HEAP_USAGE */
+ #ifdef BSP_INTERRUPT_NO_HEAP_USAGE
+ bsp_interrupt_clear_handler_entry(e);
+ #else
+ free(e);
+ #endif
}
-static rtems_status_code bsp_interrupt_lock( void)
+static rtems_status_code bsp_interrupt_lock(void)
{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- if (_System_state_Is_up( _System_state_Get())) {
- if (bsp_interrupt_mutex == RTEMS_ID_NONE) {
- rtems_id mutex = RTEMS_ID_NONE;
- rtems_interrupt_level level;
-
- /* Create a mutex */
- sc = rtems_semaphore_create (
- rtems_build_name( 'I', 'N', 'T', 'R'),
- 1,
- RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY,
- RTEMS_NO_PRIORITY,
- &mutex
- );
- if (sc != RTEMS_SUCCESSFUL) {
- return sc;
- }
-
- /* Assign the mutex */
- rtems_interrupt_disable( level);
- if (bsp_interrupt_mutex == RTEMS_ID_NONE) {
- /* Nobody else assigned the mutex in the meantime */
-
- bsp_interrupt_mutex = mutex;
- rtems_interrupt_enable( level);
- } else {
- /* Somebody else won */
-
- rtems_interrupt_enable( level);
- sc = rtems_semaphore_delete( mutex);
- if (sc != RTEMS_SUCCESSFUL) {
- return sc;
- }
- }
- }
- return rtems_semaphore_obtain( bsp_interrupt_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
- } else {
- return RTEMS_SUCCESSFUL;
- }
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ if (_System_state_Is_up(_System_state_Get())) {
+ if (bsp_interrupt_mutex == RTEMS_ID_NONE) {
+ rtems_id mutex = RTEMS_ID_NONE;
+ rtems_interrupt_level level;
+
+ /* Create a mutex */
+ sc = rtems_semaphore_create (
+ rtems_build_name('I', 'N', 'T', 'R'),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
+ 0,
+ &mutex
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+
+ /* Assign the mutex */
+ rtems_interrupt_disable(level);
+ if (bsp_interrupt_mutex == RTEMS_ID_NONE) {
+ /* Nobody else assigned the mutex in the meantime */
+
+ bsp_interrupt_mutex = mutex;
+ rtems_interrupt_enable(level);
+ } else {
+ /* Somebody else won */
+
+ rtems_interrupt_enable(level);
+ sc = rtems_semaphore_delete(mutex);
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+ }
+ }
+ return rtems_semaphore_obtain(
+ bsp_interrupt_mutex,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+ } else {
+ return RTEMS_SUCCESSFUL;
+ }
}
-static rtems_status_code bsp_interrupt_unlock( void)
+static rtems_status_code bsp_interrupt_unlock(void)
{
- if (bsp_interrupt_mutex != RTEMS_ID_NONE) {
- return rtems_semaphore_release( bsp_interrupt_mutex);
- } else {
- return RTEMS_SUCCESSFUL;
- }
+ if (bsp_interrupt_mutex != RTEMS_ID_NONE) {
+ return rtems_semaphore_release(bsp_interrupt_mutex);
+ } else {
+ return RTEMS_SUCCESSFUL;
+ }
}
-rtems_status_code bsp_interrupt_initialize( void)
+rtems_status_code bsp_interrupt_initialize(void)
{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
-
- /* Lock */
- sc = bsp_interrupt_lock();
- if (sc != RTEMS_SUCCESSFUL) {
- return sc;
- }
-
- /* Check if already initialized */
- if (bsp_interrupt_is_initialized()) {
- bsp_interrupt_unlock();
- return RTEMS_INTERNAL_ERROR;
- }
-
- /* BSP specific initialization */
- sc = bsp_interrupt_facility_initialize();
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_interrupt_unlock();
- return sc;
- }
-
- /* Now we are initialized */
- bsp_interrupt_set_initialized();
-
- /* Unlock */
- sc = bsp_interrupt_unlock();
- if (sc != RTEMS_SUCCESSFUL) {
- return sc;
- }
-
- return RTEMS_SUCCESSFUL;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ size_t i = 0;
+
+ sc = bsp_interrupt_lock();
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+
+ /* We need one semaphore */
+ if (_System_state_Is_before_initialization(_System_state_Get())) {
+ Configuration.work_space_size += sizeof(Semaphore_Control);
+ ++Configuration_RTEMS_API.maximum_semaphores;
+ }
+
+ if (bsp_interrupt_is_initialized()) {
+ bsp_interrupt_unlock();
+ return RTEMS_INTERNAL_ERROR;
+ }
+
+ /* Initialize handler table */
+ for (i = 0; i < BSP_INTERRUPT_HANDLER_TABLE_SIZE; ++i) {
+ bsp_interrupt_handler_table [i].handler = bsp_interrupt_handler_empty;
+ }
+
+ sc = bsp_interrupt_facility_initialize();
+ if (sc != RTEMS_SUCCESSFUL) {
+ bsp_interrupt_unlock();
+ return sc;
+ }
+
+ bsp_interrupt_set_initialized();
+
+ sc = bsp_interrupt_unlock();
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+
+ return RTEMS_SUCCESSFUL;
}
/**
@@ -231,132 +250,141 @@ rtems_status_code bsp_interrupt_initialize( void)
*
* @see rtems_interrupt_handler_install()
*/
-static rtems_status_code bsp_interrupt_handler_install( rtems_vector_number vector, const char *info, rtems_option options, rtems_interrupt_handler handler, void *arg)
+static rtems_status_code bsp_interrupt_handler_install(
+ rtems_vector_number vector,
+ const char *info,
+ rtems_option options,
+ rtems_interrupt_handler handler,
+ void *arg
+)
{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- rtems_interrupt_level level;
- rtems_vector_number index = 0;
- bsp_interrupt_handler_entry *head = NULL;
- bsp_interrupt_handler_entry *tail = NULL;
- bsp_interrupt_handler_entry *current = NULL;
- bsp_interrupt_handler_entry *match = NULL;
- bool enable_vector = false;
-
- /* Check parameters and system state */
- if (!bsp_interrupt_is_initialized()) {
- return RTEMS_INTERNAL_ERROR;
- } else if (!bsp_interrupt_is_valid_vector( vector)) {
- return RTEMS_INVALID_NUMBER;
- } else if (handler == NULL) {
- return RTEMS_INVALID_ADDRESS;
- } else if (rtems_interrupt_is_in_progress()) {
- return RTEMS_CALLED_FROM_ISR;
- }
-
- /* Lock */
- sc = bsp_interrupt_lock();
- if (sc != RTEMS_SUCCESSFUL) {
- return sc;
- }
-
- /* Get handler table index */
- index = bsp_interrupt_handler_index( vector);
-
- /* Get head entry of the handler list for current vector */
- head = &bsp_interrupt_handler_table [index];
-
- if (bsp_interrupt_is_empty_handler_entry( head)) {
- /*
- * No real handler installed yet. So allocate a new index in
- * the handler table and fill the entry with life.
- */
- if (bsp_interrupt_allocate_handler_index( vector, &index)) {
- rtems_interrupt_disable( level);
- bsp_interrupt_handler_table [index].handler = handler;
- bsp_interrupt_handler_table [index].arg = arg;
-#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
- bsp_interrupt_handler_index_table [vector] = index;
-#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
- rtems_interrupt_enable( level);
- bsp_interrupt_handler_table [index].info = info;
- } else {
- /* Handler table is full */
- bsp_interrupt_unlock();
- return RTEMS_NO_MEMORY;
- }
-
- /* This is the first handler so enable the vector later */
- enable_vector = true;
- } else {
- /* Ensure that a unique handler remains unique */
- if (RTEMS_INTERRUPT_IS_UNIQUE( options) || bsp_interrupt_is_handler_unique( index)) {
- /*
- * Tried to install a unique handler on a not empty
- * list or there is already a unique handler installed.
- */
- bsp_interrupt_unlock();
- return RTEMS_RESOURCE_IN_USE;
- }
-
- /*
- * Search for the list tail and check if the handler is already
- * installed.
- */
- current = head;
- do {
- if (current->handler == handler && current->arg == arg) {
- match = current;
- }
- tail = current;
- current = current->next;
- } while (current != NULL);
-
- /* Ensure the handler is not already installed */
- if (match != NULL) {
- /* The handler is already installed */
- bsp_interrupt_unlock();
- return RTEMS_TOO_MANY;
- }
-
- /* Allocate a new entry */
- current = bsp_interrupt_allocate_handler_entry();
- if (current == NULL) {
- /* Not enough memory */
- bsp_interrupt_unlock();
- return RTEMS_NO_MEMORY;
- }
-
- /* Set entry */
- current->handler = handler;
- current->arg = arg;
- current->info = info;
- current->next = NULL;
-
- /* Link to list tail */
- rtems_interrupt_disable( level);
- tail->next = current;
- rtems_interrupt_enable( level);
- }
-
- /* Make the handler unique if necessary */
- bsp_interrupt_set_handler_unique( index, RTEMS_INTERRUPT_IS_UNIQUE( options));
-
- /* Enable the vector if necessary */
- if (enable_vector) {
- sc = bsp_interrupt_vector_enable( vector);
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_interrupt_unlock();
- return sc;
- }
- }
-
- /* Unlock */
- sc = bsp_interrupt_unlock();
- if (sc != RTEMS_SUCCESSFUL) {
- return sc;
- }
-
- return RTEMS_SUCCESSFUL;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ rtems_interrupt_level level;
+ rtems_vector_number index = 0;
+ bsp_interrupt_handler_entry *head = NULL;
+ bsp_interrupt_handler_entry *tail = NULL;
+ bsp_interrupt_handler_entry *current = NULL;
+ bsp_interrupt_handler_entry *match = NULL;
+ bool enable_vector = false;
+
+ /* Check parameters and system state */
+ if (!bsp_interrupt_is_initialized()) {
+ return RTEMS_INTERNAL_ERROR;
+ } else if (!bsp_interrupt_is_valid_vector(vector)) {
+ return RTEMS_INVALID_ID;
+ } else if (handler == NULL) {
+ return RTEMS_INVALID_ADDRESS;
+ } else if (rtems_interrupt_is_in_progress()) {
+ return RTEMS_CALLED_FROM_ISR;
+ }
+
+ /* Lock */
+ sc = bsp_interrupt_lock();
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+
+ /* Get handler table index */
+ index = bsp_interrupt_handler_index(vector);
+
+ /* Get head entry of the handler list for current vector */
+ head = &bsp_interrupt_handler_table [index];
+
+ if (bsp_interrupt_is_empty_handler_entry(head)) {
+ /*
+ * No real handler installed yet. So allocate a new index in
+ * the handler table and fill the entry with life.
+ */
+ if (bsp_interrupt_allocate_handler_index(vector, &index)) {
+ rtems_interrupt_disable(level);
+ bsp_interrupt_handler_table [index].handler = handler;
+ bsp_interrupt_handler_table [index].arg = arg;
+ #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
+ bsp_interrupt_handler_index_table [vector] = index;
+ #endif
+ rtems_interrupt_enable(level);
+ bsp_interrupt_handler_table [index].info = info;
+ } else {
+ /* Handler table is full */
+ bsp_interrupt_unlock();
+ return RTEMS_NO_MEMORY;
+ }
+
+ /* This is the first handler so enable the vector later */
+ enable_vector = true;
+ } else {
+ /* Ensure that a unique handler remains unique */
+ if (
+ RTEMS_INTERRUPT_IS_UNIQUE(options)
+ || bsp_interrupt_is_handler_unique(index)
+ ) {
+ /*
+ * Tried to install a unique handler on a not empty
+ * list or there is already a unique handler installed.
+ */
+ bsp_interrupt_unlock();
+ return RTEMS_RESOURCE_IN_USE;
+ }
+
+ /*
+ * Search for the list tail and check if the handler is already
+ * installed.
+ */
+ current = head;
+ do {
+ if (current->handler == handler && current->arg == arg) {
+ match = current;
+ }
+ tail = current;
+ current = current->next;
+ } while (current != NULL);
+
+ /* Ensure the handler is not already installed */
+ if (match != NULL) {
+ /* The handler is already installed */
+ bsp_interrupt_unlock();
+ return RTEMS_TOO_MANY;
+ }
+
+ /* Allocate a new entry */
+ current = bsp_interrupt_allocate_handler_entry();
+ if (current == NULL) {
+ /* Not enough memory */
+ bsp_interrupt_unlock();
+ return RTEMS_NO_MEMORY;
+ }
+
+ /* Set entry */
+ current->handler = handler;
+ current->arg = arg;
+ current->info = info;
+ current->next = NULL;
+
+ /* Link to list tail */
+ rtems_interrupt_disable(level);
+ tail->next = current;
+ rtems_interrupt_enable(level);
+ }
+
+ /* Make the handler unique if necessary */
+ bsp_interrupt_set_handler_unique(index, RTEMS_INTERRUPT_IS_UNIQUE(options));
+
+ /* Enable the vector if necessary */
+ if (enable_vector) {
+ sc = bsp_interrupt_vector_enable(vector);
+ if (sc != RTEMS_SUCCESSFUL) {
+ bsp_interrupt_unlock();
+ return sc;
+ }
+ }
+
+ /* Unlock */
+ sc = bsp_interrupt_unlock();
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+
+ return RTEMS_SUCCESSFUL;
}
/**
@@ -369,116 +397,120 @@ static rtems_status_code bsp_interrupt_handler_install( rtems_vector_number vect
*
* @see rtems_interrupt_handler_remove().
*/
-static rtems_status_code bsp_interrupt_handler_remove( rtems_vector_number vector, rtems_interrupt_handler handler, void *arg)
+static rtems_status_code bsp_interrupt_handler_remove(
+ rtems_vector_number vector,
+ rtems_interrupt_handler handler,
+ void *arg
+)
{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- rtems_interrupt_level level;
- rtems_vector_number index = 0;
- bsp_interrupt_handler_entry *head = NULL;
- bsp_interrupt_handler_entry *current = NULL;
- bsp_interrupt_handler_entry *previous = NULL;
- bsp_interrupt_handler_entry *match = NULL;
-
- /* Check parameters and system state */
- if (!bsp_interrupt_is_initialized()) {
- return RTEMS_INTERNAL_ERROR;
- } else if (!bsp_interrupt_is_valid_vector( vector)) {
- return RTEMS_INVALID_NUMBER;
- } else if (handler == NULL) {
- return RTEMS_INVALID_ADDRESS;
- } else if (rtems_interrupt_is_in_progress()) {
- return RTEMS_CALLED_FROM_ISR;
- }
-
- /* Lock */
- sc = bsp_interrupt_lock();
- if (sc != RTEMS_SUCCESSFUL) {
- return sc;
- }
-
- /* Get handler table index */
- index = bsp_interrupt_handler_index( vector);
-
- /* Get head entry of the handler list for current vector */
- head = &bsp_interrupt_handler_table [index];
-
- /* Search for a matching entry */
- current = head;
- do {
- if (current->handler == handler && current->arg == arg) {
- match = current;
- break;
- }
- previous = current;
- current = current->next;
- } while (current != NULL);
-
- /* Remove the matching entry */
- if (match != NULL) {
- if (match->next != NULL) {
- /*
- * The match has a successor. A successor is always
- * allocated. So replace the match with its successor
- * and free the successor entry.
- */
- current = match->next;
-
- rtems_interrupt_disable( level);
- *match = *current;
- rtems_interrupt_enable( level);
-
- bsp_interrupt_free_handler_entry( current);
- } else if (match == head) {
- /*
- * The match is the list head and has no successor.
- * The list head is stored in a static table so clear
- * this entry. Since now the list is empty disable the
- * vector.
- */
-
- /* Disable the vector */
- sc = bsp_interrupt_vector_disable( vector);
-
- /* Clear entry */
- rtems_interrupt_disable( level);
- bsp_interrupt_clear_handler_entry( head);
-#ifdef BSP_INTERRUPT_USE_INDEX_TABLE
- bsp_interrupt_handler_index_table [vector] = 0;
-#endif /* BSP_INTERRUPT_USE_INDEX_TABLE */
- rtems_interrupt_enable( level);
-
- /* Allow shared handlers */
- bsp_interrupt_set_handler_unique( index, false);
-
- /* Check status code */
- if (sc != RTEMS_SUCCESSFUL) {
- bsp_interrupt_unlock();
- return sc;
- }
- } else {
- /*
- * The match is the list tail and has a predecessor.
- * So terminate the predecessor and free the match.
- */
- rtems_interrupt_disable( level);
- previous->next = NULL;
- rtems_interrupt_enable( level);
-
- bsp_interrupt_free_handler_entry( match);
- }
- } else {
- /* No matching entry found */
- bsp_interrupt_unlock();
- return RTEMS_UNSATISFIED;
- }
-
- /* Unlock */
- sc = bsp_interrupt_unlock();
- if (sc != RTEMS_SUCCESSFUL) {
- return sc;
- }
-
- return RTEMS_SUCCESSFUL;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ rtems_interrupt_level level;
+ rtems_vector_number index = 0;
+ bsp_interrupt_handler_entry *head = NULL;
+ bsp_interrupt_handler_entry *current = NULL;
+ bsp_interrupt_handler_entry *previous = NULL;
+ bsp_interrupt_handler_entry *match = NULL;
+
+ /* Check parameters and system state */
+ if (!bsp_interrupt_is_initialized()) {
+ return RTEMS_INTERNAL_ERROR;
+ } else if (!bsp_interrupt_is_valid_vector(vector)) {
+ return RTEMS_INVALID_ID;
+ } else if (handler == NULL) {
+ return RTEMS_INVALID_ADDRESS;
+ } else if (rtems_interrupt_is_in_progress()) {
+ return RTEMS_CALLED_FROM_ISR;
+ }
+
+ /* Lock */
+ sc = bsp_interrupt_lock();
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+
+ /* Get handler table index */
+ index = bsp_interrupt_handler_index(vector);
+
+ /* Get head entry of the handler list for current vector */
+ head = &bsp_interrupt_handler_table [index];
+
+ /* Search for a matching entry */
+ current = head;
+ do {
+ if (current->handler == handler && current->arg == arg) {
+ match = current;
+ break;
+ }
+ previous = current;
+ current = current->next;
+ } while (current != NULL);
+
+ /* Remove the matching entry */
+ if (match != NULL) {
+ if (match->next != NULL) {
+ /*
+ * The match has a successor. A successor is always
+ * allocated. So replace the match with its successor
+ * and free the successor entry.
+ */
+ current = match->next;
+
+ rtems_interrupt_disable(level);
+ *match = *current;
+ rtems_interrupt_enable(level);
+
+ bsp_interrupt_free_handler_entry(current);
+ } else if (match == head) {
+ /*
+ * The match is the list head and has no successor.
+ * The list head is stored in a static table so clear
+ * this entry. Since now the list is empty disable the
+ * vector.
+ */
+
+ /* Disable the vector */
+ sc = bsp_interrupt_vector_disable(vector);
+
+ /* Clear entry */
+ rtems_interrupt_disable(level);
+ bsp_interrupt_clear_handler_entry(head);
+ #ifdef BSP_INTERRUPT_USE_INDEX_TABLE
+ bsp_interrupt_handler_index_table [vector] = 0;
+ #endif
+ rtems_interrupt_enable(level);
+
+ /* Allow shared handlers */
+ bsp_interrupt_set_handler_unique(index, false);
+
+ /* Check status code */
+ if (sc != RTEMS_SUCCESSFUL) {
+ bsp_interrupt_unlock();
+ return sc;
+ }
+ } else {
+ /*
+ * The match is the list tail and has a predecessor.
+ * So terminate the predecessor and free the match.
+ */
+ rtems_interrupt_disable(level);
+ previous->next = NULL;
+ rtems_interrupt_enable(level);
+
+ bsp_interrupt_free_handler_entry(match);
+ }
+ } else {
+ /* No matching entry found */
+ bsp_interrupt_unlock();
+ return RTEMS_UNSATISFIED;
+ }
+
+ /* Unlock */
+ sc = bsp_interrupt_unlock();
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+
+ return RTEMS_SUCCESSFUL;
}
/**
@@ -491,59 +523,78 @@ static rtems_status_code bsp_interrupt_handler_remove( rtems_vector_number vecto
*
* @see rtems_interrupt_handler_iterate().
*/
-static rtems_status_code bsp_interrupt_handler_iterate( rtems_vector_number vector, rtems_interrupt_per_handler_routine routine, void *arg)
+static rtems_status_code bsp_interrupt_handler_iterate(
+ rtems_vector_number vector,
+ rtems_interrupt_per_handler_routine routine,
+ void *arg
+)
{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- bsp_interrupt_handler_entry *current = NULL;
- rtems_option options = 0;
- rtems_vector_number index = 0;
-
- /* Check parameters and system state */
- if (!bsp_interrupt_is_initialized()) {
- return RTEMS_INTERNAL_ERROR;
- } else if (!bsp_interrupt_is_valid_vector( vector)) {
- return RTEMS_INVALID_NUMBER;
- } else if (rtems_interrupt_is_in_progress()) {
- return RTEMS_CALLED_FROM_ISR;
- }
-
- /* Lock */
- sc = bsp_interrupt_lock();
- if (sc != RTEMS_SUCCESSFUL) {
- return sc;
- }
-
- /* Interate */
- index = bsp_interrupt_handler_index( vector);
- current = &bsp_interrupt_handler_table [index];
- if (!bsp_interrupt_is_empty_handler_entry( current)) {
- do {
- options = bsp_interrupt_is_handler_unique( index) ? RTEMS_INTERRUPT_UNIQUE : RTEMS_INTERRUPT_SHARED;
- routine( arg, current->info, options, current->handler, current->arg);
- current = current->next;
- } while (current != NULL);
- }
-
- /* Unlock */
- sc = bsp_interrupt_unlock();
- if (sc != RTEMS_SUCCESSFUL) {
- return sc;
- }
-
- return RTEMS_SUCCESSFUL;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ bsp_interrupt_handler_entry *current = NULL;
+ rtems_option options = 0;
+ rtems_vector_number index = 0;
+
+ /* Check parameters and system state */
+ if (!bsp_interrupt_is_initialized()) {
+ return RTEMS_INTERNAL_ERROR;
+ } else if (!bsp_interrupt_is_valid_vector(vector)) {
+ return RTEMS_INVALID_ID;
+ } else if (rtems_interrupt_is_in_progress()) {
+ return RTEMS_CALLED_FROM_ISR;
+ }
+
+ /* Lock */
+ sc = bsp_interrupt_lock();
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+
+ /* Interate */
+ index = bsp_interrupt_handler_index(vector);
+ current = &bsp_interrupt_handler_table [index];
+ if (!bsp_interrupt_is_empty_handler_entry(current)) {
+ do {
+ options = bsp_interrupt_is_handler_unique(index) ?
+ RTEMS_INTERRUPT_UNIQUE : RTEMS_INTERRUPT_SHARED;
+ routine(arg, current->info, options, current->handler, current->arg);
+ current = current->next;
+ } while (current != NULL);
+ }
+
+ /* Unlock */
+ sc = bsp_interrupt_unlock();
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+
+ return RTEMS_SUCCESSFUL;
}
-rtems_status_code rtems_interrupt_handler_install( rtems_vector_number vector, const char *info, rtems_option options, rtems_interrupt_handler handler, void *arg)
+rtems_status_code rtems_interrupt_handler_install(
+ rtems_vector_number vector,
+ const char *info,
+ rtems_option options,
+ rtems_interrupt_handler handler,
+ void *arg
+)
{
- return bsp_interrupt_handler_install( vector, info, options, handler, arg);
+ return bsp_interrupt_handler_install(vector, info, options, handler, arg);
}
-rtems_status_code rtems_interrupt_handler_remove( rtems_vector_number vector, rtems_interrupt_handler handler, void *arg)
+rtems_status_code rtems_interrupt_handler_remove(
+ rtems_vector_number vector,
+ rtems_interrupt_handler handler,
+ void *arg
+)
{
- return bsp_interrupt_handler_remove( vector, handler, arg);
+ return bsp_interrupt_handler_remove(vector, handler, arg);
}
-rtems_status_code rtems_interrupt_handler_iterate( rtems_vector_number vector, rtems_interrupt_per_handler_routine routine, void *arg)
+rtems_status_code rtems_interrupt_handler_iterate(
+ rtems_vector_number vector,
+ rtems_interrupt_per_handler_routine routine,
+ void *arg
+)
{
- return bsp_interrupt_handler_iterate( vector, routine, arg);
+ return bsp_interrupt_handler_iterate(vector, routine, arg);
}
diff --git a/c/src/lib/libbsp/shared/src/irq-info.c b/c/src/lib/libbsp/shared/src/irq-info.c
index 6736d508b7..474784752d 100644
--- a/c/src/lib/libbsp/shared/src/irq-info.c
+++ b/c/src/lib/libbsp/shared/src/irq-info.c
@@ -3,19 +3,20 @@
*
* @ingroup bsp_interrupt
*
- * @brief Source file for generic BSP interrupt information code.
+ * @brief Generic BSP interrupt information implementation.
*/
/*
- * Copyright (c) 2008
- * Embedded Brains GmbH
+ * Copyright (c) 2008, 2009
+ * embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
* Germany
- * rtems@embedded-brains.de
+ * <rtems@embedded-brains.de>
*
- * The license and distribution terms for this file may be found in the file
- * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
*/
#include <inttypes.h>
@@ -27,62 +28,70 @@
#include <bsp/irq-config.h>
typedef struct {
- void *context;
- rtems_printk_plugin_t print;
- rtems_vector_number vector;
+ void *context;
+ rtems_printk_plugin_t print;
+ rtems_vector_number vector;
} bsp_interrupt_report_entry;
static void bsp_interrupt_report_per_handler_routine(
- void *arg,
- const char *info,
- rtems_option options,
- rtems_interrupt_handler handler,
- void *handler_arg
+ void *arg,
+ const char *info,
+ rtems_option options,
+ rtems_interrupt_handler handler,
+ void *handler_arg
)
{
- bsp_interrupt_report_entry *e = (bsp_interrupt_report_entry *) arg;
- const char *opt = options == RTEMS_INTERRUPT_UNIQUE ? "UNIQUE" : "SHARED";
+ bsp_interrupt_report_entry *e = (bsp_interrupt_report_entry *) arg;
+ const char *opt = options == RTEMS_INTERRUPT_UNIQUE ? "UNIQUE" : "SHARED";
- e->print( e->context, "%7" PRIu32 " | %-32s | %7s | %010p | %010p\n", e->vector, info, opt, handler, handler_arg);
+ e->print(
+ e->context,
+ "%7" PRIu32 " | %-32s | %7s | %010p | %010p\n",
+ e->vector,
+ info,
+ opt,
+ handler,
+ handler_arg
+ );
}
-/**
- * @brief Prints interrupt information via the printk plugin @a print with the
- * context @a context.
- */
-void bsp_interrupt_report_with_plugin( void *context, rtems_printk_plugin_t print)
+void bsp_interrupt_report_with_plugin(
+ void *context,
+ rtems_printk_plugin_t print
+)
{
- rtems_vector_number v = 0;
- bsp_interrupt_report_entry e = {
- .context = context,
- .print = print,
- .vector = 0
- };
+ rtems_vector_number v = 0;
+ bsp_interrupt_report_entry e = {
+ .context = context,
+ .print = print,
+ .vector = 0
+ };
- print(
- context,
- "-------------------------------------------------------------------------------\n"
- " INTERRUPT INFORMATION\n"
- "--------+----------------------------------+---------+------------+------------\n"
- " VECTOR | INFO | OPTIONS | HANDLER | ARGUMENT \n"
- "--------+----------------------------------+---------+------------+------------\n"
- );
+ print(
+ context,
+ "-------------------------------------------------------------------------------\n"
+ " INTERRUPT INFORMATION\n"
+ "--------+----------------------------------+---------+------------+------------\n"
+ " VECTOR | INFO | OPTIONS | HANDLER | ARGUMENT \n"
+ "--------+----------------------------------+---------+------------+------------\n"
+ );
- for (v = BSP_INTERRUPT_VECTOR_MIN; v <= BSP_INTERRUPT_VECTOR_MAX; ++v) {
- e.vector = v;
- (void) rtems_interrupt_handler_iterate( v, bsp_interrupt_report_per_handler_routine, &e);
- }
+ for (v = BSP_INTERRUPT_VECTOR_MIN; v <= BSP_INTERRUPT_VECTOR_MAX; ++v) {
+ e.vector = v;
+ rtems_interrupt_handler_iterate(
+ v,
+ bsp_interrupt_report_per_handler_routine,
+ &e
+ );
+ }
- print(
- context,
- "--------+----------------------------------+---------+------------+------------\n"
- );
+ print(
+ context,
+ "--------+----------------------------------+---------+------------+------------\n"
+ );
}
-/**
- * @brief Prints interrupt information via the default printk plugin.
- */
-void bsp_interrupt_report( void)
+void bsp_interrupt_report(void)
{
- bsp_interrupt_report_with_plugin( NULL, printk_plugin);
+ bsp_interrupt_report_with_plugin(NULL, printk_plugin);
}
diff --git a/c/src/lib/libbsp/shared/src/irq-legacy.c b/c/src/lib/libbsp/shared/src/irq-legacy.c
index 9f916235d0..b864541b8b 100644
--- a/c/src/lib/libbsp/shared/src/irq-legacy.c
+++ b/c/src/lib/libbsp/shared/src/irq-legacy.c
@@ -3,26 +3,27 @@
*
* @ingroup bsp_interrupt
*
- * @brief Source file for generic BSP interrupt support legacy code.
+ * @brief Generic BSP interrupt support legacy implementation.
*/
/*
- * Copyright (c) 2008
- * Embedded Brains GmbH
+ * Copyright (c) 2008, 2009
+ * embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
* Germany
- * rtems@embedded-brains.de
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.com/license/LICENSE.
+ * <rtems@embedded-brains.de>
*
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
*/
#include <stdbool.h>
#include <stdlib.h>
+#define BSP_SHARED_HANDLER_SUPPORT
+
#include <rtems/irq.h>
#include <bsp/irq-generic.h>
@@ -84,7 +85,7 @@ int BSP_get_current_rtems_irq_handler(rtems_irq_connect_data *cd)
int BSP_install_rtems_irq_handler(const rtems_irq_connect_data *cd)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
- bsp_interrupt_legacy_entry *e = malloc(sizeof( bsp_interrupt_legacy_entry));
+ bsp_interrupt_legacy_entry *e = malloc(sizeof(bsp_interrupt_legacy_entry));
if (e == NULL) {
return 0;
@@ -95,8 +96,7 @@ int BSP_install_rtems_irq_handler(const rtems_irq_connect_data *cd)
sc = rtems_interrupt_handler_install(
cd->name,
- "Unique interrupt handler "
- "(installed with obsolete BSP_install_rtems_irq_handler())",
+ "LEGACY INSTALLED",
RTEMS_INTERRUPT_UNIQUE,
bsp_interrupt_legacy_dispatch,
e
@@ -119,7 +119,7 @@ int BSP_install_rtems_irq_handler(const rtems_irq_connect_data *cd)
int BSP_install_rtems_shared_irq_handler(const rtems_irq_connect_data *cd)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
- bsp_interrupt_legacy_entry *e = malloc(sizeof( bsp_interrupt_legacy_entry));
+ bsp_interrupt_legacy_entry *e = malloc(sizeof(bsp_interrupt_legacy_entry));
if (e == NULL) {
return 0;
@@ -130,8 +130,7 @@ int BSP_install_rtems_shared_irq_handler(const rtems_irq_connect_data *cd)
sc = rtems_interrupt_handler_install(
cd->name,
- "Shared interrupt handler "
- "(installed with obsolete BSP_install_rtems_shared_irq_handler())",
+ "LEGACY INSTALLED",
RTEMS_INTERRUPT_SHARED,
bsp_interrupt_legacy_dispatch,
e
diff --git a/c/src/lib/libbsp/shared/src/irq-server.c b/c/src/lib/libbsp/shared/src/irq-server.c
new file mode 100644
index 0000000000..ac923a9a8e
--- /dev/null
+++ b/c/src/lib/libbsp/shared/src/irq-server.c
@@ -0,0 +1,275 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_interrupt
+ *
+ * @brief Generic BSP interrupt server implementation.
+ */
+
+/*
+ * Copyright (c) 2009
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * D-82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#include <stdlib.h>
+
+#include <bsp/irq-generic.h>
+
+typedef struct bsp_interrupt_server_entry {
+ rtems_vector_number vector;
+ rtems_interrupt_handler handler;
+ void *arg;
+ struct bsp_interrupt_server_entry *volatile next;
+} bsp_interrupt_server_entry;
+
+static rtems_id bsp_interrupt_server_semaphore = RTEMS_ID_NONE;
+
+/* LIFO list head */
+static bsp_interrupt_server_entry *volatile
+bsp_interrupt_server_list_head = NULL;
+
+static rtems_status_code bsp_interrupt_server_is_initialized(void)
+{
+ if (bsp_interrupt_server_semaphore != RTEMS_ID_NONE) {
+ return RTEMS_SUCCESSFUL;
+ } else {
+ return RTEMS_INCORRECT_STATE;
+ }
+}
+
+static void bsp_interrupt_server_trigger(rtems_vector_number vector, void *arg)
+{
+ bsp_interrupt_server_entry *e = arg;
+ rtems_interrupt_level level;
+
+ bsp_interrupt_vector_disable(e->vector);
+
+ /* Add interrupt server entry to the list */
+ rtems_interrupt_disable(level);
+ e->next = bsp_interrupt_server_list_head;
+ bsp_interrupt_server_list_head = e;
+ rtems_interrupt_enable(level);
+
+ rtems_semaphore_release(bsp_interrupt_server_semaphore);
+}
+
+static void bsp_interrupt_server_task(rtems_task_argument arg)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ rtems_id sema = bsp_interrupt_server_semaphore;
+ rtems_interrupt_level level;
+ bsp_interrupt_server_entry *e = NULL;
+
+ while (true) {
+ sc = rtems_semaphore_obtain(sema, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ if (sc != RTEMS_SUCCESSFUL) {
+ break;
+ }
+
+ /* Fetch next interrupt server entry from the list */
+ rtems_interrupt_disable(level);
+ e = bsp_interrupt_server_list_head;
+ bsp_interrupt_server_list_head = e->next;
+ rtems_interrupt_enable(level);
+
+ (*e->handler)(e->vector, e->arg);
+
+ bsp_interrupt_vector_enable(e->vector);
+ }
+
+ rtems_task_delete(RTEMS_SELF);
+}
+
+typedef struct {
+ rtems_interrupt_handler handler;
+ void *arg;
+ bsp_interrupt_server_entry *entry;
+} bsp_interrupt_server_iterate_entry;
+
+static void bsp_interrupt_server_per_handler_routine(
+ void *iterate_arg,
+ const char *info,
+ rtems_option options,
+ rtems_interrupt_handler handler,
+ void *handler_arg
+)
+{
+ bsp_interrupt_server_iterate_entry *ie = iterate_arg;
+ bsp_interrupt_server_entry *e = handler_arg;
+
+ if (handler == bsp_interrupt_server_trigger) {
+ if (e->handler == ie->handler && e->arg == ie->arg) {
+ ie->entry = e;
+ }
+ }
+}
+
+rtems_status_code rtems_interrupt_server_handler_install(
+ rtems_id server,
+ rtems_vector_number vector,
+ const char *info,
+ rtems_option options,
+ rtems_interrupt_handler handler,
+ void *arg
+)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ bsp_interrupt_server_entry *e = NULL;
+
+ sc = bsp_interrupt_server_is_initialized();
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+
+ if (RTEMS_INTERRUPT_IS_SHARED(options)) {
+ return RTEMS_NOT_IMPLEMENTED;
+ }
+
+ e = malloc(sizeof(bsp_interrupt_server_entry));
+ if (e == NULL) {
+ return RTEMS_NO_MEMORY;
+ }
+
+ e->vector = vector;
+ e->handler = handler;
+ e->arg = arg;
+
+ sc = rtems_interrupt_handler_install(
+ vector,
+ info,
+ options,
+ bsp_interrupt_server_trigger,
+ e
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ free(e);
+
+ return sc;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code rtems_interrupt_server_handler_remove(
+ rtems_id server,
+ rtems_vector_number vector,
+ rtems_interrupt_handler handler,
+ void *arg
+)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ bsp_interrupt_server_iterate_entry ie = {
+ .handler = handler,
+ .arg = arg,
+ .entry = NULL
+ };
+
+ sc = bsp_interrupt_server_is_initialized();
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+
+ /* Query corresponding interrupt server entry */
+ sc = rtems_interrupt_handler_iterate(
+ vector,
+ bsp_interrupt_server_per_handler_routine,
+ &ie
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ } else if (ie.entry == NULL) {
+ return RTEMS_INVALID_ID;
+ }
+
+ sc = rtems_interrupt_handler_remove(
+ vector,
+ ie.entry->handler,
+ ie.entry->arg
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+
+ free(ie.entry);
+
+ return RTEMS_SUCCESSFUL;
+}
+
+rtems_status_code rtems_interrupt_server_initialize(
+ rtems_task_priority priority,
+ size_t stack_size,
+ rtems_mode modes,
+ rtems_attribute attributes,
+ rtems_id *server
+)
+{
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ rtems_id sema_id = RTEMS_ID_NONE;
+ rtems_id task_id = RTEMS_ID_NONE;
+ rtems_interrupt_level level;
+
+ sc = rtems_semaphore_create(
+ rtems_build_name('I', 'R', 'Q', 'S'),
+ 0,
+ RTEMS_LOCAL | RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE,
+ 0,
+ &sema_id
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ return sc;
+ }
+
+ sc = rtems_task_create(
+ rtems_build_name('I', 'R', 'Q', 'S'),
+ priority,
+ stack_size,
+ modes,
+ attributes,
+ &task_id
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ rtems_semaphore_delete(sema_id);
+
+ return sc;
+ }
+
+ /* Initialize global data (this must be done before the task starts) */
+ rtems_interrupt_disable(level);
+ if (bsp_interrupt_server_semaphore == RTEMS_ID_NONE) {
+ bsp_interrupt_server_semaphore = sema_id;
+ sc = RTEMS_SUCCESSFUL;
+ } else {
+ sc = RTEMS_INCORRECT_STATE;
+ }
+ rtems_interrupt_enable(level);
+ if (sc != RTEMS_SUCCESSFUL) {
+ rtems_semaphore_delete(sema_id);
+ rtems_task_delete(task_id);
+
+ return sc;
+ }
+
+ sc = rtems_task_start(
+ task_id,
+ bsp_interrupt_server_task,
+ 0
+ );
+ if (sc != RTEMS_SUCCESSFUL) {
+ /* In this case we could also panic */
+ bsp_interrupt_server_semaphore = RTEMS_ID_NONE;
+ rtems_semaphore_delete(sema_id);
+ rtems_task_delete(task_id);
+
+ return sc;
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
diff --git a/c/src/lib/libbsp/shared/src/irq-shell.c b/c/src/lib/libbsp/shared/src/irq-shell.c
index 341f30364a..2d8d508378 100644
--- a/c/src/lib/libbsp/shared/src/irq-shell.c
+++ b/c/src/lib/libbsp/shared/src/irq-shell.c
@@ -3,20 +3,20 @@
*
* @ingroup bsp_interrupt
*
- * @brief Source file for generic BSP interrupt shell code.
+ * @brief Generic BSP interrupt shell implementation.
*/
/*
- * Copyright (c) 2008
- * Embedded Brains GmbH
+ * Copyright (c) 2009
+ * embedded brains GmbH
* Obere Lagerstr. 30
* D-82178 Puchheim
* Germany
- * rtems@embedded-brains.de
+ * <rtems@embedded-brains.de>
*
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.com/license/LICENSE.
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
*/
#include <stdio.h>
@@ -25,16 +25,13 @@
#include <bsp/irq-info.h>
-static int bsp_interrupt_shell_main( int argc, char **argv)
+static int bsp_interrupt_shell_main(int argc, char **argv)
{
- bsp_interrupt_report_with_plugin( stdout, (rtems_printk_plugin_t) fprintf);
+ bsp_interrupt_report_with_plugin(stdout, (rtems_printk_plugin_t) fprintf);
return 0;
}
-/**
- * @brief Shell command entry for interrupt information.
- */
struct rtems_shell_cmd_tt bsp_interrupt_shell_command = {
.name = "irq",
.usage = "Prints interrupt information",
diff --git a/c/src/lib/libbsp/shared/src/stackalloc.c b/c/src/lib/libbsp/shared/src/stackalloc.c
index 31b7c14db3..e6145d5873 100644
--- a/c/src/lib/libbsp/shared/src/stackalloc.c
+++ b/c/src/lib/libbsp/shared/src/stackalloc.c
@@ -30,21 +30,21 @@ static Heap_Control bsp_stack_heap = {
.page_size = BSP_STACK_MAGIC
};
-void bsp_stack_initialize(void *start, intptr_t size)
+void bsp_stack_initialize(void *begin, uintptr_t size)
{
- bsp_stack_heap.begin = start;
- bsp_stack_heap.end = (void *) size;
+ bsp_stack_heap.area_begin = (uintptr_t) begin;
+ bsp_stack_heap.area_end = size;
}
-void *bsp_stack_allocate(uint32_t size)
+void *bsp_stack_allocate(size_t size)
{
void *stack = NULL;
if (bsp_stack_heap.page_size == BSP_STACK_MAGIC) {
- uint32_t rv = _Heap_Initialize(
+ uintptr_t rv = _Heap_Initialize(
&bsp_stack_heap,
- bsp_stack_heap.begin,
- (intptr_t) bsp_stack_heap.end,
+ (void *) bsp_stack_heap.area_begin,
+ bsp_stack_heap.area_end,
CPU_STACK_ALIGNMENT
);
if (rv == 0) {
@@ -52,7 +52,7 @@ void *bsp_stack_allocate(uint32_t size)
}
}
- stack = _Heap_Allocate(&bsp_stack_heap, (intptr_t) size);
+ stack = _Heap_Allocate(&bsp_stack_heap, size);
if (stack == NULL) {
stack = _Workspace_Allocate(size);