[PATCH 27.0 1/3] LEON: implemented shared-irq using libbsp/shared layer

Daniel Hellstrom daniel at gaisler.com
Fri Apr 6 07:24:02 UTC 2012


On 04/05/2012 05:38 PM, Joel Sherrill wrote:
>
>
> I am happy to see this BUT... it leaves ONE
> other BSPs in the same architecture without
> this feature.
>
> Could you please make the set complete and add
> this to the ERC32 as well? Looking at leon2 changes,
> it doesn't look like a lot to do.
>
> I hate to ask this but inconsistency sucks. I imposed
> this requirement on us for the MIPS and we got
> the privilege of fixing 6 BSPs plus the one we really
> needed it on.
>
> Take care of this and I think 27 is a no brainer to
> merge given no warnings. :)

Ok, I have never worked with ERC32 and have no chance to test it, but I will give it a try. I'm not even sure that ERC32 have shared interrupts, but a common shared-irq interface would be good anyway 
I guess.

Thanks,
Daniel

>
> --joel
>
> On 04/05/2012 10:23 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.
>>
>> Signed-off-by: Daniel Hellstrom<daniel at gaisler.com>
>> ---
>>   c/src/lib/libbsp/sparc/Makefile.am                 |    3 +
>>   c/src/lib/libbsp/sparc/leon2/Makefile.am           |   14 +++-
>>   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        |    5 +
>>   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           |   15 +++-
>>   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        |   17 +++
>>   c/src/lib/libbsp/sparc/leon3/preinstall.am         |   12 ++
>>   .../lib/libbsp/sparc/leon3/startup/bsppredriver.c  |   27 +++++
>>   c/src/lib/libbsp/sparc/leon3/startup/eirq.c        |   27 +++++
>>   c/src/lib/libbsp/sparc/shared/include/ambapp.h     |    2 +
>>   c/src/lib/libbsp/sparc/shared/irq/irq-shared.c     |  110 ++++++++++++++++++++
>>   17 files changed, 477 insertions(+), 2 deletions(-)
>>   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/leon2/Makefile.am b/c/src/lib/libbsp/sparc/leon2/Makefile.am
>> index 6e2697f..c0102db 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,18 @@ 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-generic.c \
>> +    ../../shared/src/irq-legacy.c \
>> +    ../../shared/src/irq-info.c \
>> +    ../../shared/src/irq-shell.c \
>> +    ../../shared/src/irq-server.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..8cfc761 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 leon_irq_fixup(int irq)
>> +{
>> +       return irq;
>> +}
>> +
>>   /*
>>    *  Macros to manipulate the Interrupt Clear, Interrupt Force, Interrupt Mask,
>>    *  and the Interrupt Pending Registers.
>> 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..f64cca6
>> --- /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.
>> + *
>> + *  $Id$
>> + */
>> +
>> +/*
>> + *  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..013be52 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,19 @@ 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-generic.c \
>> +    ../../shared/src/irq-legacy.c \
>> +    ../../shared/src/irq-info.c \
>> +    ../../shared/src/irq-shell.c \
>> +    ../../shared/src/irq-server.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..c7a302b 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 leon_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
>> 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..ff633fe
>> --- /dev/null
>> +++ b/c/src/lib/libbsp/sparc/leon3/startup/bsppredriver.c
>> @@ -0,0 +1,27 @@
>> +/*  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.
>> + *
>> + *  $Id$
>> + */
>> +
>> +#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..68089a3
>> --- /dev/null
>> +++ b/c/src/lib/libbsp/sparc/leon3/startup/eirq.c
>> @@ -0,0 +1,27 @@
>> +/*
>> + *  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>
>> +
>> +extern int LEON3_Cpu_Index;
>> +
>> +/* GRLIB extended IRQ controller IRQ number */
>> +int LEON3_IrqCtrl_EIrq = -1;
>> +
>> +/* Initialize Exteneded 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..99480e4
>> --- /dev/null
>> +++ b/c/src/lib/libbsp/sparc/shared/irq/irq-shared.c
>> @@ -0,0 +1,110 @@
>> +#include<rtems.h>
>> +#include<bsp.h>
>> +#include<bsp/irq-generic.h>
>> +#include<leon.h>
>> +
>> +static inline void leon_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] */
>> +void LEON_ISR_handler(rtems_vector_number vector)
>> +{
>> +       int irq = LEON_TRAP_SOURCE(vector);
>> +
>> +       /* Let BSP fixup and/or handle incomming IRQ */
>> +       irq = leon_irq_fixup(irq);
>> +
>> +       leon_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 = LEON_TRAP_TYPE(i);
>> +               rtems_interrupt_catch(LEON_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;
>> +}
>> +
>> +/* Spurious IRQ handler */
>> +void bsp_interrupt_handler_default(rtems_vector_number vector)
>> +{
>> +       printk("Spurious IRQ %d\n", (int)vector);
>> +}
>> +
>> +rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
>> +{
>> +       rtems_interrupt_level level;
>> +
>> +       rtems_interrupt_disable(level);
>> +       LEON_Unmask_interrupt((int)vector);
>> +       rtems_interrupt_enable(level);
>> +
>> +       return RTEMS_SUCCESSFUL;
>> +}
>> +
>> +rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
>> +{
>> +       rtems_interrupt_level level;
>> +
>> +       rtems_interrupt_disable(level);
>> +       LEON_Mask_interrupt((int)vector);
>> +       rtems_interrupt_enable(level);
>> +
>> +       return RTEMS_SUCCESSFUL;
>> +}
>> +
>> +void BSP_shared_interrupt_mask(int irq)
>> +{
>> +       rtems_interrupt_level level;
>> +
>> +       rtems_interrupt_disable(level);
>> +
>> +       LEON_Mask_interrupt(irq);
>> +
>> +       rtems_interrupt_enable(level);
>> +}
>> +
>> +void BSP_shared_interrupt_unmask(int irq)
>> +{
>> +       rtems_interrupt_level level;
>> +
>> +       rtems_interrupt_disable(level);
>> +
>> +       LEON_Unmask_interrupt(irq);
>> +
>> +       rtems_interrupt_enable(level);
>> +}
>> +
>> +void BSP_shared_interrupt_clear(int irq)
>> +{
>> +       /* We don't have to interrupt lock here, because the register is only
>> +        * written and self clearing
>> +        */
>> +       LEON_Clear_interrupt(irq);
>> +}
>> -- 
>> 1.7.0.4
>>
>> _______________________________________________
>> rtems-devel mailing list
>> rtems-devel at rtems.org
>> http://www.rtems.org/mailman/listinfo/rtems-devel
>
>




More information about the devel mailing list