[PATCH 27.0 1/3 v2] SPARC BSPs: implemented shared-irq using libbsp/shared layer

Joel Sherrill joel.sherrill at OARcorp.com
Fri Apr 6 13:21:20 UTC 2012


On 04/06/2012 05:05 AM, Daniel Hellstrom wrote:
> The implementation use IRQ number instead of vector number since
> some IRQs does not have a unique vector, for example the extended
> interrupts all enter the same trap vector entry.
>
> Added support for the LEON3 extended interrupt controller when using
> the shared IRQ layer.

Thanks for adding this code.

I have committed it.
>
> ERC32 patches untested.
What would use this code on the ERC32 and how would we
test it?

Joel says knowing that all I have is tsim so if you can't test it,
then I can't test it. :)

--joel
> Signed-off-by: Daniel Hellstrom<daniel at gaisler.com>
> ---
>   c/src/lib/libbsp/sparc/Makefile.am                 |    3 +
>   c/src/lib/libbsp/sparc/erc32/Makefile.am           |   16 ++++-
>   c/src/lib/libbsp/sparc/erc32/include/bsp.h         |   75 +++++++++++++++++-
>   c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h     |   20 +++++
>   c/src/lib/libbsp/sparc/erc32/include/erc32.h       |   17 ++++
>   c/src/lib/libbsp/sparc/erc32/preinstall.am         |   12 +++
>   .../lib/libbsp/sparc/erc32/startup/bsppredriver.c  |   25 ++++++
>   c/src/lib/libbsp/sparc/leon2/Makefile.am           |   15 ++++-
>   c/src/lib/libbsp/sparc/leon2/include/bsp.h         |   74 +++++++++++++++++
>   c/src/lib/libbsp/sparc/leon2/include/bsp/irq.h     |   20 +++++
>   c/src/lib/libbsp/sparc/leon2/include/leon.h        |   17 ++++
>   c/src/lib/libbsp/sparc/leon2/preinstall.am         |   12 +++
>   .../lib/libbsp/sparc/leon2/startup/bsppredriver.c  |   25 ++++++
>   c/src/lib/libbsp/sparc/leon3/Makefile.am           |   16 ++++-
>   c/src/lib/libbsp/sparc/leon3/amba/amba.c           |    6 ++
>   c/src/lib/libbsp/sparc/leon3/include/bsp.h         |   74 +++++++++++++++++
>   c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h     |   36 +++++++++
>   c/src/lib/libbsp/sparc/leon3/include/leon.h        |   28 +++++++
>   c/src/lib/libbsp/sparc/leon3/preinstall.am         |   12 +++
>   .../lib/libbsp/sparc/leon3/startup/bsppredriver.c  |   25 ++++++
>   c/src/lib/libbsp/sparc/leon3/startup/eirq.c        |   25 ++++++
>   c/src/lib/libbsp/sparc/shared/include/ambapp.h     |    2 +
>   c/src/lib/libbsp/sparc/shared/irq/irq-shared.c     |   83 ++++++++++++++++++++
>   23 files changed, 634 insertions(+), 4 deletions(-)
>   create mode 100644 c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h
>   create mode 100644 c/src/lib/libbsp/sparc/erc32/startup/bsppredriver.c
>   create mode 100644 c/src/lib/libbsp/sparc/leon2/include/bsp/irq.h
>   create mode 100644 c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c
>   create mode 100644 c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h
>   create mode 100644 c/src/lib/libbsp/sparc/leon3/startup/bsppredriver.c
>   create mode 100644 c/src/lib/libbsp/sparc/leon3/startup/eirq.c
>   create mode 100644 c/src/lib/libbsp/sparc/shared/irq/irq-shared.c
>
> diff --git a/c/src/lib/libbsp/sparc/Makefile.am b/c/src/lib/libbsp/sparc/Makefile.am
> index b1b6a22..4f445ba 100644
> --- a/c/src/lib/libbsp/sparc/Makefile.am
> +++ b/c/src/lib/libbsp/sparc/Makefile.am
> @@ -12,6 +12,9 @@ EXTRA_DIST =
>   EXTRA_DIST += shared/gnatcommon.c
>   EXTRA_DIST += shared/start.S
>
> +# Interrupt
> +EXTRA_DIST += shared/irq/irq-shared.c
> +
>   # AMBA Plug&Play bus
>   EXTRA_DIST += shared/include/ambapp.h
>   EXTRA_DIST += shared/amba/ambapp.c
> diff --git a/c/src/lib/libbsp/sparc/erc32/Makefile.am b/c/src/lib/libbsp/sparc/erc32/Makefile.am
> index e70310d..615a3e0 100644
> --- a/c/src/lib/libbsp/sparc/erc32/Makefile.am
> +++ b/c/src/lib/libbsp/sparc/erc32/Makefile.am
> @@ -33,7 +33,7 @@ libbsp_a_SOURCES =
>
>   # startup
>   libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
> -    ../../shared/bsppredriverhook.c ../../sparc/shared/bspgetworkarea.c \
> +    startup/bsppredriver.c ../../sparc/shared/bspgetworkarea.c \
>       ../../sparc/shared/bsppretaskinghook.c ../../shared/bsppost.c \
>       ../../shared/bspstart.c ../../shared/bootcard.c ../../shared/bspinit.c \
>       ../../shared/sbrk.c startup/setvec.c startup/spurious.c \
> @@ -55,6 +55,20 @@ libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
>   # timer
>   libbsp_a_SOURCES += timer/timer.c
>
> +# IRQ
> +include_bsp_HEADERS = \
> +    ../../shared/include/irq-generic.h \
> +    ../../shared/include/irq-info.h \
> +    include/bsp/irq.h
> +libbsp_a_SOURCES += \
> +    ../../sparc/shared/irq/irq-shared.c \
> +    ../../shared/src/irq-default-handler.c \
> +    ../../shared/src/irq-generic.c \
> +    ../../shared/src/irq-info.c \
> +    ../../shared/src/irq-legacy.c \
> +    ../../shared/src/irq-server.c \
> +    ../../shared/src/irq-shell.c
> +
>   if HAS_SMP
>   libbsp_a_SOURCES += ../../shared/smp/getcpuid.c ../../shared/smp/smp_stub.c \
>       ../../shared/smp/bspsmp_wait_for.c
> diff --git a/c/src/lib/libbsp/sparc/erc32/include/bsp.h b/c/src/lib/libbsp/sparc/erc32/include/bsp.h
> index 70f1ce3..429157d 100644
> --- a/c/src/lib/libbsp/sparc/erc32/include/bsp.h
> +++ b/c/src/lib/libbsp/sparc/erc32/include/bsp.h
> @@ -30,8 +30,8 @@ extern "C" {
>   #include<rtems/iosupp.h>
>   #include<erc32.h>
>   #include<rtems/clockdrv.h>
> -
>   #include<rtems/console.h>
> +#include<rtems/irq-extension.h>
>
>   /*
>    *  BSP provides its own Idle thread body
> @@ -90,6 +90,79 @@ void bsp_spurious_initialize( void );
>    */
>   void *bsp_early_malloc(int size);
>
> +/* Interrupt Service Routine (ISR) pointer */
> +typedef void (*bsp_shared_isr)(void *arg);
> +
> +/* Initializes the Shared System Interrupt service */
> +extern int BSP_shared_interrupt_init(void);
> +
> +/* Registers a shared IRQ handler, and enable it at IRQ controller. Multiple
> + * interrupt handlers may use the same IRQ number, all ISRs will be called
> + * when an interrupt on that line is fired.
> + *
> + * Arguments
> + *  irq       System IRQ number
> + *  info      Optional Name of IRQ source
> + *  isr       Function pointer to the ISR
> + *  arg       Second argument to function isr
> + */
> +static __inline__ int BSP_shared_interrupt_register
> +       (
> +       int irq,
> +       const char *info,
> +       bsp_shared_isr isr,
> +       void *arg
> +       )
> +{
> +       return rtems_interrupt_handler_install(irq, info,
> +                                       RTEMS_INTERRUPT_SHARED, isr, arg);
> +}
> +
> +/* Unregister previously registered shared IRQ handler.
> + *
> + * Arguments
> + *  irq       System IRQ number
> + *  isr       Function pointer to the ISR
> + *  arg       Second argument to function isr
> + */
> +static __inline__ int BSP_shared_interrupt_unregister
> +       (
> +       int irq,
> +       bsp_shared_isr isr,
> +       void *arg
> +       )
> +{
> +       return rtems_interrupt_handler_remove(irq, isr, arg);
> +}
> +
> +/* Clear interrupt pending on IRQ controller, this is typically done on a
> + * level triggered interrupt source such as PCI to avoid taking double IRQs.
> + * In such a case the interrupt source must be cleared first on LEON, before
> + * acknowledging the IRQ with this function.
> + *
> + * Arguments
> + *  irq       System IRQ number
> + */
> +extern void BSP_shared_interrupt_clear(int irq);
> +
> +/* Enable Interrupt. This function will unmask the IRQ at the interrupt
> + * controller. This is normally done by _register(). Note that this will
> + * affect all ISRs on this IRQ.
> + *
> + * Arguments
> + *  irq       System IRQ number
> + */
> +extern void BSP_shared_interrupt_unmask(int irq);
> +
> +/* Disable Interrupt. This function will mask one IRQ at the interrupt
> + * controller. This is normally done by _unregister().  Note that this will
> + * affect all ISRs on this IRQ.
> + *
> + * Arguments
> + *  irq         System IRQ number
> + */
> +extern void BSP_shared_interrupt_mask(int irq);
> +
>   #ifdef __cplusplus
>   }
>   #endif
> diff --git a/c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h b/c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h
> new file mode 100644
> index 0000000..c0e931b
> --- /dev/null
> +++ b/c/src/lib/libbsp/sparc/erc32/include/bsp/irq.h
> @@ -0,0 +1,20 @@
> +/* ERC32 generic shared IRQ setup
> + *
> + * Based on libbsp/shared/include/irq.h.
> + *
> + * 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_ERC32_IRQ_CONFIG_H
> +#define LIBBSP_ERC32_IRQ_CONFIG_H
> +
> +#define BSP_INTERRUPT_VECTOR_MAX_STD 15 /* Standard IRQ controller */
> +#define BSP_INTERRUPT_VECTOR_MIN 0
> +#define BSP_INTERRUPT_VECTOR_MAX BSP_INTERRUPT_VECTOR_MAX_STD
> +
> +/* No extra check is needed */
> +#undef BSP_INTERRUPT_CUSTOM_VALID_VECTOR
> +
> +#endif /* LIBBSP_ERC32_IRQ_CONFIG_H */
> diff --git a/c/src/lib/libbsp/sparc/erc32/include/erc32.h b/c/src/lib/libbsp/sparc/erc32/include/erc32.h
> index dcc6190..4f4b9b0 100644
> --- a/c/src/lib/libbsp/sparc/erc32/include/erc32.h
> +++ b/c/src/lib/libbsp/sparc/erc32/include/erc32.h
> @@ -324,6 +324,11 @@ typedef struct {
>
>   extern ERC32_Register_Map ERC32_MEC;
>
> +static __inline__ int bsp_irq_fixup(int irq)
> +{
> +       return irq;
> +}
> +
>   /*
>    *  Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask,
>    *  and the Interrupt Pending Registers.
> @@ -396,6 +401,18 @@ extern ERC32_Register_Map ERC32_MEC;
>       sparc_enable_interrupts( _level ); \
>     } while (0)
>
> +/* Make all SPARC BSPs have common macros for interrupt handling */
> +#define BSP_Clear_interrupt(_source) ERC32_Clear_interrupt(_source)
> +#define BSP_Force_interrupt(_source) ERC32_Force_interrupt(_source)
> +#define BSP_Is_interrupt_pending(_source) ERC32_Is_interrupt_pending(_source)
> +#define BSP_Is_interrupt_masked(_source) ERC32_Is_interrupt_masked(_source)
> +#define BSP_Unmask_interrupt(_source) ERC32_Unmask_interrupt(_source)
> +#define BSP_Mask_interrupt(_source) ERC32_Mask_interrupt(_source)
> +#define BSP_Disable_interrupt(_source, _previous) \
> +        ERC32_Disable_interrupt(_source, _prev)
> +#define BSP_Restore_interrupt(_source, _previous) \
> +        ERC32_Restore_interrupt(_source, _previous)
> +
>   /*
>    *  The following macros attempt to hide the fact that the General Purpose
>    *  Timer and Real Time Clock Timer share the Timer Control Register.  Because
> diff --git a/c/src/lib/libbsp/sparc/erc32/preinstall.am b/c/src/lib/libbsp/sparc/erc32/preinstall.am
> index 6c0b907..a235296 100644
> --- a/c/src/lib/libbsp/sparc/erc32/preinstall.am
> +++ b/c/src/lib/libbsp/sparc/erc32/preinstall.am
> @@ -73,3 +73,15 @@ $(PROJECT_LIB)/linkcmds.base: ../shared/startup/linkcmds.base $(PROJECT_LIB)/$(d
>          $(INSTALL_DATA) $<  $(PROJECT_LIB)/linkcmds.base
>   PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.base
>
> +$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
> +       $(INSTALL_DATA) $<  $(PROJECT_INCLUDE)/bsp/irq-generic.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
> +
> +$(PROJECT_INCLUDE)/bsp/irq-info.h: ../../shared/include/irq-info.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
> +       $(INSTALL_DATA) $<  $(PROJECT_INCLUDE)/bsp/irq-info.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h
> +
> +$(PROJECT_INCLUDE)/bsp/irq.h: include/bsp/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
> +       $(INSTALL_DATA) $<  $(PROJECT_INCLUDE)/bsp/irq.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
> +
> diff --git a/c/src/lib/libbsp/sparc/erc32/startup/bsppredriver.c b/c/src/lib/libbsp/sparc/erc32/startup/bsppredriver.c
> new file mode 100644
> index 0000000..4084b5c
> --- /dev/null
> +++ b/c/src/lib/libbsp/sparc/erc32/startup/bsppredriver.c
> @@ -0,0 +1,25 @@
> +/*  Installs the BSP pre-driver hook
> + *
> + *  COPYRIGHT (c) 2011
> + *  Aeroflex Gaisler
> + *
> + *  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<bsp.h>
> +
> +/*
> + *  bsp_predriver_hook
> + *
> + *  BSP predriver hook. Called just before drivers are initialized.
> + *  Is used to initialize shared interrupt handling.
> + */
> +void bsp_predriver_hook( void )
> +{
> +  /* Initialize shared interrupt handling, must be done after IRQ
> +   * controller has been found and initialized.
> +   */
> +  BSP_shared_interrupt_init();
> +}
> diff --git a/c/src/lib/libbsp/sparc/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am
> index 6e2697f..2acca78 100644
> --- a/c/src/lib/libbsp/sparc/leon2/Makefile.am
> +++ b/c/src/lib/libbsp/sparc/leon2/Makefile.am
> @@ -51,7 +51,7 @@ libbsp_a_SOURCES =
>
>   # startup
>   libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
> -    ../../shared/bsppost.c ../../shared/bsppredriverhook.c \
> +    ../../shared/bsppost.c startup/bsppredriver.c \
>       startup/bspstart.c ../../sparc/shared/bsppretaskinghook.c \
>       ../../sparc/shared/bspgetworkarea.c ../../shared/bootcard.c \
>       ../../shared/sbrk.c startup/setvec.c startup/spurious.c startup/bspidle.c \
> @@ -66,6 +66,19 @@ libbsp_a_SOURCES += console/console.c console/debugputs.c
>   # clock
>   libbsp_a_SOURCES += clock/ckinit.c
>   libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
> +# IRQ
> +include_bsp_HEADERS = \
> +    ../../shared/include/irq-generic.h \
> +    ../../shared/include/irq-info.h \
> +    include/bsp/irq.h
> +libbsp_a_SOURCES += \
> +    ../../sparc/shared/irq/irq-shared.c \
> +    ../../shared/src/irq-default-handler.c \
> +    ../../shared/src/irq-generic.c \
> +    ../../shared/src/irq-info.c \
> +    ../../shared/src/irq-legacy.c \
> +    ../../shared/src/irq-server.c \
> +    ../../shared/src/irq-shell.c
>   # AMBA PnP Scanning
>   libbsp_a_SOURCES += ../../sparc/shared/amba/ambapp.c
>   # PCI
> diff --git a/c/src/lib/libbsp/sparc/leon2/include/bsp.h b/c/src/lib/libbsp/sparc/leon2/include/bsp.h
> index a2f3360..b087e06 100644
> --- a/c/src/lib/libbsp/sparc/leon2/include/bsp.h
> +++ b/c/src/lib/libbsp/sparc/leon2/include/bsp.h
> @@ -30,6 +30,7 @@ extern "C" {
>   #include<leon.h>
>   #include<rtems/clockdrv.h>
>   #include<rtems/console.h>
> +#include<rtems/irq-extension.h>
>
>   /* SPARC CPU variant: LEON2 */
>   #define LEON2 1
> @@ -109,6 +110,79 @@ void bsp_spurious_initialize( void );
>    */
>   void *bsp_early_malloc(int size);
>
> +/* Interrupt Service Routine (ISR) pointer */
> +typedef void (*bsp_shared_isr)(void *arg);
> +
> +/* Initializes the Shared System Interrupt service */
> +extern int BSP_shared_interrupt_init(void);
> +
> +/* Registers a shared IRQ handler, and enable it at IRQ controller. Multiple
> + * interrupt handlers may use the same IRQ number, all ISRs will be called
> + * when an interrupt on that line is fired.
> + *
> + * Arguments
> + *  irq       System IRQ number
> + *  info      Optional Name of IRQ source
> + *  isr       Function pointer to the ISR
> + *  arg       Second argument to function isr
> + */
> +static __inline__ int BSP_shared_interrupt_register
> +       (
> +       int irq,
> +       const char *info,
> +       bsp_shared_isr isr,
> +       void *arg
> +       )
> +{
> +       return rtems_interrupt_handler_install(irq, info,
> +                                       RTEMS_INTERRUPT_SHARED, isr, arg);
> +}
> +
> +/* Unregister previously registered shared IRQ handler.
> + *
> + * Arguments
> + *  irq       System IRQ number
> + *  isr       Function pointer to the ISR
> + *  arg       Second argument to function isr
> + */
> +static __inline__ int BSP_shared_interrupt_unregister
> +       (
> +       int irq,
> +       bsp_shared_isr isr,
> +       void *arg
> +       )
> +{
> +       return rtems_interrupt_handler_remove(irq, isr, arg);
> +}
> +
> +/* Clear interrupt pending on IRQ controller, this is typically done on a
> + * level triggered interrupt source such as PCI to avoid taking double IRQs.
> + * In such a case the interrupt source must be cleared first on LEON, before
> + * acknowledging the IRQ with this function.
> + *
> + * Arguments
> + *  irq       System IRQ number
> + */
> +extern void BSP_shared_interrupt_clear(int irq);
> +
> +/* Enable Interrupt. This function will unmask the IRQ at the interrupt
> + * controller. This is normally done by _register(). Note that this will
> + * affect all ISRs on this IRQ.
> + *
> + * Arguments
> + *  irq       System IRQ number
> + */
> +extern void BSP_shared_interrupt_unmask(int irq);
> +
> +/* Disable Interrupt. This function will mask one IRQ at the interrupt
> + * controller. This is normally done by _unregister().  Note that this will
> + * affect all ISRs on this IRQ.
> + *
> + * Arguments
> + *  irq         System IRQ number
> + */
> +extern void BSP_shared_interrupt_mask(int irq);
> +
>   #ifdef __cplusplus
>   }
>   #endif
> diff --git a/c/src/lib/libbsp/sparc/leon2/include/bsp/irq.h b/c/src/lib/libbsp/sparc/leon2/include/bsp/irq.h
> new file mode 100644
> index 0000000..709b563
> --- /dev/null
> +++ b/c/src/lib/libbsp/sparc/leon2/include/bsp/irq.h
> @@ -0,0 +1,20 @@
> +/* LEON2 generic shared IRQ setup
> + *
> + * Based on libbsp/shared/include/irq.h.
> + *
> + * 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_LEON2_IRQ_CONFIG_H
> +#define LIBBSP_LEON2_IRQ_CONFIG_H
> +
> +#define BSP_INTERRUPT_VECTOR_MAX_STD 15 /* Standard IRQ controller */
> +#define BSP_INTERRUPT_VECTOR_MIN 0
> +#define BSP_INTERRUPT_VECTOR_MAX BSP_INTERRUPT_VECTOR_MAX_STD
> +
> +/* No extra check is needed */
> +#undef BSP_INTERRUPT_CUSTOM_VALID_VECTOR
> +
> +#endif /* LIBBSP_LEON2_IRQ_CONFIG_H */
> diff --git a/c/src/lib/libbsp/sparc/leon2/include/leon.h b/c/src/lib/libbsp/sparc/leon2/include/leon.h
> index c183c90..726a5a7 100644
> --- a/c/src/lib/libbsp/sparc/leon2/include/leon.h
> +++ b/c/src/lib/libbsp/sparc/leon2/include/leon.h
> @@ -271,6 +271,11 @@ typedef struct {
>
>   extern LEON_Register_Map LEON_REG;
>
> +static __inline__ int bsp_irq_fixup(int irq)
> +{
> +       return irq;
> +}
> +
>   /*
>    *  Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask,
>    *  and the Interrupt Pending Registers.
> @@ -338,6 +343,18 @@ extern LEON_Register_Map LEON_REG;
>       sparc_enable_interrupts( _level ); \
>     } while (0)
>
> +/* Make all SPARC BSPs have common macros for interrupt handling */
> +#define BSP_Clear_interrupt(_source) LEON_Clear_interrupt(_source)
> +#define BSP_Force_interrupt(_source) LEON_Force_interrupt(_source)
> +#define BSP_Is_interrupt_pending(_source) LEON_Is_interrupt_pending(_source)
> +#define BSP_Is_interrupt_masked(_source) LEON_Is_interrupt_masked(_source)
> +#define BSP_Unmask_interrupt(_source) LEON_Unmask_interrupt(_source)
> +#define BSP_Mask_interrupt(_source) LEON_Mask_interrupt(_source)
> +#define BSP_Disable_interrupt(_source, _previous) \
> +        LEON_Disable_interrupt(_source, _prev)
> +#define BSP_Restore_interrupt(_source, _previous) \
> +        LEON_Restore_interrupt(_source, _previous)
> +
>   /*
>    *  Each timer control register is organized as follows:
>    *
> diff --git a/c/src/lib/libbsp/sparc/leon2/preinstall.am b/c/src/lib/libbsp/sparc/leon2/preinstall.am
> index 4b7d4da..00ed05e 100644
> --- a/c/src/lib/libbsp/sparc/leon2/preinstall.am
> +++ b/c/src/lib/libbsp/sparc/leon2/preinstall.am
> @@ -145,6 +145,18 @@ $(PROJECT_LIB)/linkcmds.base: ../shared/startup/linkcmds.base $(PROJECT_LIB)/$(d
>          $(INSTALL_DATA) $<  $(PROJECT_LIB)/linkcmds.base
>   PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.base
>
> +$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
> +       $(INSTALL_DATA) $<  $(PROJECT_INCLUDE)/bsp/irq-generic.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
> +
> +$(PROJECT_INCLUDE)/bsp/irq-info.h: ../../shared/include/irq-info.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
> +       $(INSTALL_DATA) $<  $(PROJECT_INCLUDE)/bsp/irq-info.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h
> +
> +$(PROJECT_INCLUDE)/bsp/irq.h: include/bsp/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
> +       $(INSTALL_DATA) $<  $(PROJECT_INCLUDE)/bsp/irq.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
> +
>   $(PROJECT_INCLUDE)/i2cmst.h: ../../sparc/shared/include/i2cmst.h $(PROJECT_INCLUDE)/$(dirstamp)
>          $(INSTALL_DATA) $<  $(PROJECT_INCLUDE)/i2cmst.h
>   PREINSTALL_FILES += $(PROJECT_INCLUDE)/i2cmst.h
> diff --git a/c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c b/c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c
> new file mode 100644
> index 0000000..4084b5c
> --- /dev/null
> +++ b/c/src/lib/libbsp/sparc/leon2/startup/bsppredriver.c
> @@ -0,0 +1,25 @@
> +/*  Installs the BSP pre-driver hook
> + *
> + *  COPYRIGHT (c) 2011
> + *  Aeroflex Gaisler
> + *
> + *  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<bsp.h>
> +
> +/*
> + *  bsp_predriver_hook
> + *
> + *  BSP predriver hook. Called just before drivers are initialized.
> + *  Is used to initialize shared interrupt handling.
> + */
> +void bsp_predriver_hook( void )
> +{
> +  /* Initialize shared interrupt handling, must be done after IRQ
> +   * controller has been found and initialized.
> +   */
> +  BSP_shared_interrupt_init();
> +}
> diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am
> index dc24051..ebbeb46 100644
> --- a/c/src/lib/libbsp/sparc/leon3/Makefile.am
> +++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am
> @@ -35,7 +35,7 @@ libbsp_a_SOURCES =
>   # startup
>   libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
>       ../../shared/bsppost.c ../../shared/bootcard.c startup/bspstart.c \
> -    ../../sparc/shared/bsppretaskinghook.c ../../shared/bsppredriverhook.c \
> +    ../../sparc/shared/bsppretaskinghook.c startup/bsppredriver.c \
>       ../../sparc/shared/bspgetworkarea.c ../../shared/sbrk.c startup/setvec.c \
>       startup/spurious.c startup/bspidle.S startup/bspdelay.c \
>       ../../shared/bspinit.c ../../sparc/shared/startup/early_malloc.c
> @@ -55,6 +55,20 @@ libbsp_a_SOURCES += console/debugputs.c
>   # clock
>   libbsp_a_SOURCES += clock/ckinit.c
>   libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
> +# IRQ
> +include_bsp_HEADERS = \
> +    ../../shared/include/irq-generic.h \
> +    ../../shared/include/irq-info.h \
> +    include/bsp/irq.h
> +libbsp_a_SOURCES += \
> +    startup/eirq.c \
> +    ../../sparc/shared/irq/irq-shared.c \
> +    ../../shared/src/irq-default-handler.c \
> +    ../../shared/src/irq-generic.c \
> +    ../../shared/src/irq-info.c \
> +    ../../shared/src/irq-legacy.c \
> +    ../../shared/src/irq-server.c \
> +    ../../shared/src/irq-shell.c
>   # PCI
>   include_HEADERS += ../../sparc/shared/include/pci.h
>   libbsp_a_SOURCES += pci/pci.c ../../sparc/shared/pci/pcifinddevice.c
> diff --git a/c/src/lib/libbsp/sparc/leon3/amba/amba.c b/c/src/lib/libbsp/sparc/leon3/amba/amba.c
> index b0a43f9..03af226 100644
> --- a/c/src/lib/libbsp/sparc/leon3/amba/amba.c
> +++ b/c/src/lib/libbsp/sparc/leon3/amba/amba.c
> @@ -18,6 +18,9 @@
>   /* Structure containing address to devices found on the Amba Plug&Play bus */
>   amba_confarea_type amba_conf;
>
> +/* GRLIB extended IRQ controller register */
> +extern void leon3_ext_irq_init(void);
> +
>   /* Pointers to Interrupt Controller configuration registers */
>   volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs;
>
> @@ -48,6 +51,9 @@ void amba_initialize(void)
>       LEON3_IrqCtrl_Regs = (volatile LEON3_IrqCtrl_Regs_Map *) dev.start;
>     }
>
> +  /* Init Extended IRQ controller if available */
> +  leon3_ext_irq_init();
> +
>     /* find GP Timer */
>     i = amba_find_apbslv(&amba_conf,VENDOR_GAISLER,GAISLER_GPTIMER,&dev);
>     if ( i>  0 ){
> diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp.h b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
> index 04279d9..fc42773 100644
> --- a/c/src/lib/libbsp/sparc/leon3/include/bsp.h
> +++ b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
> @@ -30,6 +30,7 @@ extern "C" {
>   #include<leon.h>
>   #include<rtems/clockdrv.h>
>   #include<rtems/console.h>
> +#include<rtems/irq-extension.h>
>
>   /* SPARC CPU variant: LEON3 */
>   #define LEON3 1
> @@ -119,6 +120,79 @@ void bsp_spurious_initialize( void );
>    */
>   void *bsp_early_malloc(int size);
>
> +/* Interrupt Service Routine (ISR) pointer */
> +typedef void (*bsp_shared_isr)(void *arg);
> +
> +/* Initializes the Shared System Interrupt service */
> +extern int BSP_shared_interrupt_init(void);
> +
> +/* Registers a shared IRQ handler, and enable it at IRQ controller. Multiple
> + * interrupt handlers may use the same IRQ number, all ISRs will be called
> + * when an interrupt on that line is fired.
> + *
> + * Arguments
> + *  irq       System IRQ number
> + *  info      Optional Name of IRQ source
> + *  isr       Function pointer to the ISR
> + *  arg       Second argument to function isr
> + */
> +static __inline__ int BSP_shared_interrupt_register
> +       (
> +       int irq,
> +       const char *info,
> +       bsp_shared_isr isr,
> +       void *arg
> +       )
> +{
> +       return rtems_interrupt_handler_install(irq, info,
> +                                       RTEMS_INTERRUPT_SHARED, isr, arg);
> +}
> +
> +/* Unregister previously registered shared IRQ handler.
> + *
> + * Arguments
> + *  irq       System IRQ number
> + *  isr       Function pointer to the ISR
> + *  arg       Second argument to function isr
> + */
> +static __inline__ int BSP_shared_interrupt_unregister
> +       (
> +       int irq,
> +       bsp_shared_isr isr,
> +       void *arg
> +       )
> +{
> +       return rtems_interrupt_handler_remove(irq, isr, arg);
> +}
> +
> +/* Clear interrupt pending on IRQ controller, this is typically done on a
> + * level triggered interrupt source such as PCI to avoid taking double IRQs.
> + * In such a case the interrupt source must be cleared first on LEON, before
> + * acknowledging the IRQ with this function.
> + *
> + * Arguments
> + *  irq       System IRQ number
> + */
> +extern void BSP_shared_interrupt_clear(int irq);
> +
> +/* Enable Interrupt. This function will unmask the IRQ at the interrupt
> + * controller. This is normally done by _register(). Note that this will
> + * affect all ISRs on this IRQ.
> + *
> + * Arguments
> + *  irq       System IRQ number
> + */
> +extern void BSP_shared_interrupt_unmask(int irq);
> +
> +/* Disable Interrupt. This function will mask one IRQ at the interrupt
> + * controller. This is normally done by _unregister().  Note that this will
> + * affect all ISRs on this IRQ.
> + *
> + * Arguments
> + *  irq         System IRQ number
> + */
> +extern void BSP_shared_interrupt_mask(int irq);
> +
>   #ifdef __cplusplus
>   }
>   #endif
> diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h b/c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h
> new file mode 100644
> index 0000000..71c0df3
> --- /dev/null
> +++ b/c/src/lib/libbsp/sparc/leon3/include/bsp/irq.h
> @@ -0,0 +1,36 @@
> +/* LEON3 generic shared IRQ setup
> + *
> + * Based on libbsp/shared/include/irq.h.
> + *
> + * 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_LEON3_IRQ_CONFIG_H
> +#define LIBBSP_LEON3_IRQ_CONFIG_H
> +
> +#define BSP_INTERRUPT_VECTOR_MAX_STD 15 /* Standard IRQ controller */
> +#define BSP_INTERRUPT_VECTOR_MAX_EXT 31 /* Extended IRQ controller */
> +
> +#define BSP_INTERRUPT_VECTOR_MIN 0
> +#define BSP_INTERRUPT_VECTOR_MAX BSP_INTERRUPT_VECTOR_MAX_EXT
> +
> +/* The check is different depending on IRQ controller, runtime detected */
> +#define BSP_INTERRUPT_CUSTOM_VALID_VECTOR
> +
> +extern int LEON3_IrqCtrl_EIrq;
> +
> +/**
> + * @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)
> +{
> +  return (rtems_vector_number) BSP_INTERRUPT_VECTOR_MIN<= vector
> +&&  ((vector<= (rtems_vector_number) BSP_INTERRUPT_VECTOR_MAX_STD&&
> +        LEON3_IrqCtrl_EIrq == 0) ||
> +       (vector<= (rtems_vector_number) BSP_INTERRUPT_VECTOR_MAX_EXT&&
> +        LEON3_IrqCtrl_EIrq != 0));
> +}
> +
> +#endif /* LIBBSP_LEON3_IRQ_CONFIG_H */
> diff --git a/c/src/lib/libbsp/sparc/leon3/include/leon.h b/c/src/lib/libbsp/sparc/leon3/include/leon.h
> index fd208b0..40617b1 100644
> --- a/c/src/lib/libbsp/sparc/leon3/include/leon.h
> +++ b/c/src/lib/libbsp/sparc/leon3/include/leon.h
> @@ -152,6 +152,23 @@ extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
>   /* LEON3 CPU Index of boot CPU */
>   extern int LEON3_Cpu_Index;
>
> +/* The external IRQ number, -1 if not external interrupts */
> +extern int LEON3_IrqCtrl_EIrq;
> +
> +static __inline__ int bsp_irq_fixup(int irq)
> +{
> +       int eirq;
> +
> +       if (LEON3_IrqCtrl_EIrq != 0&&  irq == LEON3_IrqCtrl_EIrq) {
> +               /* Get interrupt number from IRQ controller */
> +               eirq = LEON3_IrqCtrl_Regs->intid[LEON3_Cpu_Index]&  0x1f;
> +               if (eirq&  0x10)
> +                       irq = eirq;
> +       }
> +
> +       return irq;
> +}
> +
>   /* Macros used for manipulating bits in LEON3 GP Timer Control Register */
>
>   #define LEON3_GPTIMER_EN 1
> @@ -232,6 +249,17 @@ extern int LEON3_Cpu_Index;
>       sparc_enable_interrupts( _level ); \
>     } while (0)
>
> +/* Make all SPARC BSPs have common macros for interrupt handling */
> +#define BSP_Clear_interrupt(_source) LEON_Clear_interrupt(_source)
> +#define BSP_Force_interrupt(_source) LEON_Force_interrupt(_source)
> +#define BSP_Is_interrupt_pending(_source) LEON_Is_interrupt_pending(_source)
> +#define BSP_Is_interrupt_masked(_source) LEON_Is_interrupt_masked(_source)
> +#define BSP_Unmask_interrupt(_source) LEON_Unmask_interrupt(_source)
> +#define BSP_Mask_interrupt(_source) LEON_Mask_interrupt(_source)
> +#define BSP_Disable_interrupt(_source, _previous) \
> +        LEON_Disable_interrupt(_source, _prev)
> +#define BSP_Restore_interrupt(_source, _previous) \
> +        LEON_Restore_interrupt(_source, _previous)
>
>   /*
>    *  Each timer control register is organized as follows:
> diff --git a/c/src/lib/libbsp/sparc/leon3/preinstall.am b/c/src/lib/libbsp/sparc/leon3/preinstall.am
> index b948529..8c27b81 100644
> --- a/c/src/lib/libbsp/sparc/leon3/preinstall.am
> +++ b/c/src/lib/libbsp/sparc/leon3/preinstall.am
> @@ -85,6 +85,18 @@ $(PROJECT_INCLUDE)/ambapp.h: ../../sparc/shared/include/ambapp.h $(PROJECT_INCLU
>          $(INSTALL_DATA) $<  $(PROJECT_INCLUDE)/ambapp.h
>   PREINSTALL_FILES += $(PROJECT_INCLUDE)/ambapp.h
>
> +$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
> +       $(INSTALL_DATA) $<  $(PROJECT_INCLUDE)/bsp/irq-generic.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
> +
> +$(PROJECT_INCLUDE)/bsp/irq-info.h: ../../shared/include/irq-info.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
> +       $(INSTALL_DATA) $<  $(PROJECT_INCLUDE)/bsp/irq-info.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h
> +
> +$(PROJECT_INCLUDE)/bsp/irq.h: include/bsp/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
> +       $(INSTALL_DATA) $<  $(PROJECT_INCLUDE)/bsp/irq.h
> +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h
> +
>   $(PROJECT_INCLUDE)/pci.h: ../../sparc/shared/include/pci.h $(PROJECT_INCLUDE)/$(dirstamp)
>          $(INSTALL_DATA) $<  $(PROJECT_INCLUDE)/pci.h
>   PREINSTALL_FILES += $(PROJECT_INCLUDE)/pci.h
> diff --git a/c/src/lib/libbsp/sparc/leon3/startup/bsppredriver.c b/c/src/lib/libbsp/sparc/leon3/startup/bsppredriver.c
> new file mode 100644
> index 0000000..4084b5c
> --- /dev/null
> +++ b/c/src/lib/libbsp/sparc/leon3/startup/bsppredriver.c
> @@ -0,0 +1,25 @@
> +/*  Installs the BSP pre-driver hook
> + *
> + *  COPYRIGHT (c) 2011
> + *  Aeroflex Gaisler
> + *
> + *  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<bsp.h>
> +
> +/*
> + *  bsp_predriver_hook
> + *
> + *  BSP predriver hook. Called just before drivers are initialized.
> + *  Is used to initialize shared interrupt handling.
> + */
> +void bsp_predriver_hook( void )
> +{
> +  /* Initialize shared interrupt handling, must be done after IRQ
> +   * controller has been found and initialized.
> +   */
> +  BSP_shared_interrupt_init();
> +}
> diff --git a/c/src/lib/libbsp/sparc/leon3/startup/eirq.c b/c/src/lib/libbsp/sparc/leon3/startup/eirq.c
> new file mode 100644
> index 0000000..d62035e
> --- /dev/null
> +++ b/c/src/lib/libbsp/sparc/leon3/startup/eirq.c
> @@ -0,0 +1,25 @@
> +/*
> + *  GRLIB/LEON3 extended interrupt controller
> + *
> + *  COPYRIGHT (c) 2011
> + *  Aeroflex Gaisler
> + *
> + *  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<bsp.h>
> +
> +/* GRLIB extended IRQ controller IRQ number */
> +int LEON3_IrqCtrl_EIrq = -1;
> +
> +/* Initialize Extended Interrupt controller */
> +void leon3_ext_irq_init(void)
> +{
> +  if ( (LEON3_IrqCtrl_Regs->mpstat>>  16)&  0xf ) {
> +    /* Extended IRQ controller available */
> +    LEON3_IrqCtrl_EIrq = (LEON3_IrqCtrl_Regs->mpstat>>  16)&  0xf;
> +  }
> +}
> diff --git a/c/src/lib/libbsp/sparc/shared/include/ambapp.h b/c/src/lib/libbsp/sparc/shared/include/ambapp.h
> index e2b557d..cc8e120 100644
> --- a/c/src/lib/libbsp/sparc/shared/include/ambapp.h
> +++ b/c/src/lib/libbsp/sparc/shared/include/ambapp.h
> @@ -272,6 +272,8 @@ typedef struct {
>     volatile unsigned int notused23;
>     volatile unsigned int mask[16];
>     volatile unsigned int force[16];
> +  /* Extended IRQ registers */
> +  volatile unsigned int intid[16];
>   } LEON3_IrqCtrl_Regs_Map;
>
>   /*****************************/
> diff --git a/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c b/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c
> new file mode 100644
> index 0000000..5f478ef
> --- /dev/null
> +++ b/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c
> @@ -0,0 +1,83 @@
> +#include<rtems.h>
> +#include<bsp.h>
> +#include<bsp/irq-generic.h>
> +
> +static inline void bsp_dispatch_irq(int irq)
> +{
> +       bsp_interrupt_handler_entry *e =
> +&bsp_interrupt_handler_table[bsp_interrupt_handler_index(irq)];
> +
> +       while (e != NULL) {
> +               (*e->handler)(e->arg);
> +               e = e->next;
> +       }
> +}
> +
> +/* Called directly from IRQ trap handler TRAP[0x10..0x1F] = IRQ[0..15] */
> +static void BSP_ISR_handler(rtems_vector_number vector)
> +{
> +       int irq = vector - 0x10;
> +
> +       /* Let BSP fixup and/or handle incomming IRQ */
> +       irq = bsp_irq_fixup(irq);
> +
> +       bsp_dispatch_irq(irq);
> +}
> +
> +/* Initialize interrupts */
> +int BSP_shared_interrupt_init(void)
> +{
> +       rtems_vector_number vector;
> +       rtems_isr_entry previous_isr;
> +       int sc, i;
> +
> +       for (i=0; i<= BSP_INTERRUPT_VECTOR_MAX_STD; i++) {
> +               vector = SPARC_ASYNCHRONOUS_TRAP(i) + 0x10;
> +               rtems_interrupt_catch(BSP_ISR_handler, vector,&previous_isr);
> +       }
> +
> +       /* Initalize interrupt support */
> +       sc = bsp_interrupt_initialize();
> +       if (sc != RTEMS_SUCCESSFUL)
> +               return -1;
> +
> +       return 0;
> +}
> +
> +/* Callback from bsp_interrupt_initialize() */
> +rtems_status_code bsp_interrupt_facility_initialize(void)
> +{
> +       return RTEMS_SUCCESSFUL;
> +}
> +
> +rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
> +{
> +       BSP_Unmask_interrupt((int)vector);
> +
> +       return RTEMS_SUCCESSFUL;
> +}
> +
> +rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
> +{
> +       BSP_Mask_interrupt((int)vector);
> +
> +       return RTEMS_SUCCESSFUL;
> +}
> +
> +void BSP_shared_interrupt_mask(int irq)
> +{
> +       BSP_Mask_interrupt(irq);
> +}
> +
> +void BSP_shared_interrupt_unmask(int irq)
> +{
> +       BSP_Unmask_interrupt(irq);
> +}
> +
> +void BSP_shared_interrupt_clear(int irq)
> +{
> +       /* We don't have to interrupt lock here, because the register is only
> +        * written and self clearing
> +        */
> +       BSP_Clear_interrupt(irq);
> +}
> --
> 1.7.0.4
>


-- 
Joel Sherrill, Ph.D.             Director of Research&   Development
joel.sherrill at OARcorp.com        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
     Support Available             (256) 722-9985





More information about the devel mailing list