diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-23 09:50:39 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-23 15:18:44 +0200 |
commit | 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708 (patch) | |
tree | 5dc76f7a4527b0a500fbf5ee91486b2780e47a1a /bsps/powerpc/virtex | |
parent | bsps: Move SPI drivers to bsps (diff) | |
download | rtems-8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708.tar.bz2 |
bsps: Move interrupt controller support to bsps
This patch is a part of the BSP source reorganization.
Update #3285.
Diffstat (limited to 'bsps/powerpc/virtex')
-rw-r--r-- | bsps/powerpc/virtex/irq/irq_init.c | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/bsps/powerpc/virtex/irq/irq_init.c b/bsps/powerpc/virtex/irq/irq_init.c new file mode 100644 index 0000000000..55194cb1e6 --- /dev/null +++ b/bsps/powerpc/virtex/irq/irq_init.c @@ -0,0 +1,167 @@ +/*===============================================================*\ +| Project: RTEMS virtex BSP | ++-----------------------------------------------------------------+ +| Partially based on the code references which are named below. | +| Adaptions, modifications, enhancements and any recent parts of | +| the code are: | +| Copyright (c) 2007 | +| Embedded Brains GmbH | +| Obere Lagerstr. 30 | +| D-82178 Puchheim | +| Germany | +| rtems@embedded-brains.de | ++-----------------------------------------------------------------+ +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| | +| http://www.rtems.org/license/LICENSE. | +| | ++-----------------------------------------------------------------+ +| this file contains the irq controller handler | +\*===============================================================*/ + +/* Content moved from opbintctrl.c: + * + * This file contains definitions and declarations for the + * Xilinx Off Processor Bus (OPB) Interrupt Controller + * + * Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca> + * COPYRIGHT (c) 2005 Linn Products Ltd, Scotland. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <bsp.h> +#include <bsp/irq.h> +#include <bsp/irq-generic.h> +#include <bsp/vectors.h> + +#include <libcpu/powerpc-utility.h> + +/* + * Acknowledge a mask of interrupts. + */ +static void set_iar(uint32_t mask) +{ + *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IAR)) = mask; +} + +/* + * Set IER state. Used to (dis)enable a mask of vectors. + * If you only have to do one, use enable/disable_vector. + */ +static void set_ier(uint32_t mask) +{ + *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IER)) = mask; +} + +/* + * Retrieve contents of Interrupt Pending Register + */ +static uint32_t get_ipr(void) +{ + uint32_t c = *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IPR)); + return c; +} + +static void BSP_irq_enable_at_opbintc (rtems_irq_number irqnum) +{ + *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_SIE)) + = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET); +} + +static void BSP_irq_disable_at_opbintc (rtems_irq_number irqnum) +{ + *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_CIE)) + = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET); +} + +/* + * IRQ Handler: this is called from the primary exception dispatcher + */ +static void BSP_irq_handle_at_opbintc(void) +{ + uint32_t ipr; + + /* Get pending interrupts */ + ipr = get_ipr(); + + if (ipr != 0) { + /* Acknowledge all pending interrupts now and service them afterwards */ + set_iar(ipr); + + do { + /* Get highest priority pending interrupt */ + uint32_t i = 31 - ppc_count_leading_zeros(ipr); + + ipr &= ~(1U << i); + + bsp_interrupt_handler_dispatch(i+BSP_OPBINTC_IRQ_LOWEST_OFFSET); + } while (ipr != 0); + } +} + +/* + * activate the interrupt controller + */ +static void opb_intc_init(void) +{ + uint32_t i, mask = 0; + + /* mask off all interrupts */ + set_ier(0x0); + + for (i = 0; i < OPB_INTC_IRQ_MAX; i++) { + mask |= (1 << i); + } + + /* make sure interupt status register is clear before we enable the interrupt controller */ + *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_ISR)) = 0; + + /* acknowledge all interrupt sources */ + set_iar(mask); + + /* Turn on normal hardware operation of interrupt controller */ + *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) = + (OPB_INTC_MER_HIE); + + /* Enable master interrupt switch for the interrupt controller */ + *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) = + (OPB_INTC_MER_HIE | OPB_INTC_MER_ME); +} + +void bsp_interrupt_vector_enable(rtems_vector_number vector) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + + if (BSP_IS_OPBINTC_IRQ(vector)) { + BSP_irq_enable_at_opbintc(vector); + } +} + +void bsp_interrupt_vector_disable(rtems_vector_number vector) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + + if (BSP_IS_OPBINTC_IRQ(vector)) { + BSP_irq_disable_at_opbintc(vector); + } +} + +static int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned int excNum) +{ + BSP_irq_handle_at_opbintc(); + + return 0; +} + +rtems_status_code bsp_interrupt_facility_initialize(void) +{ + opb_intc_init(); + + ppc_exc_set_handler(ASM_EXT_VECTOR, C_dispatch_irq_handler); + + return RTEMS_SUCCESSFUL; +} |