[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