SPARC BSPs: implemented shared-irq using libbsp/shared layer

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.

ERC32 patches untested.

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>

Regenerate
This commit is contained in:
Daniel Hellstrom
2012-04-06 05:05:07 -05:00
committed by Joel Sherrill
parent e60e862c64
commit 95518e59bd
23 changed files with 634 additions and 4 deletions

View File

@@ -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

View File

@@ -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 ){

View File

@@ -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
@@ -115,6 +116,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

View File

@@ -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 */

View File

@@ -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:

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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;
}
}