[862c2317] | 1 | /*===============================================================*\ |
---|
| 2 | | Project: RTEMS virtex BSP | |
---|
| 3 | +-----------------------------------------------------------------+ |
---|
| 4 | | Partially based on the code references which are named below. | |
---|
| 5 | | Adaptions, modifications, enhancements and any recent parts of | |
---|
| 6 | | the code are: | |
---|
| 7 | | Copyright (c) 2007 | |
---|
[e560ee85] | 8 | | embedded brains GmbH | |
---|
[862c2317] | 9 | | Obere Lagerstr. 30 | |
---|
[e560ee85] | 10 | | 82178 Puchheim | |
---|
[862c2317] | 11 | | Germany | |
---|
| 12 | | rtems@embedded-brains.de | |
---|
| 13 | +-----------------------------------------------------------------+ |
---|
| 14 | | The license and distribution terms for this file may be | |
---|
| 15 | | found in the file LICENSE in this distribution or at | |
---|
| 16 | | | |
---|
[c499856] | 17 | | http://www.rtems.org/license/LICENSE. | |
---|
[862c2317] | 18 | | | |
---|
| 19 | +-----------------------------------------------------------------+ |
---|
| 20 | | this file contains the irq controller handler | |
---|
| 21 | \*===============================================================*/ |
---|
[39c1534f] | 22 | |
---|
| 23 | /* Content moved from opbintctrl.c: |
---|
| 24 | * |
---|
| 25 | * This file contains definitions and declarations for the |
---|
| 26 | * Xilinx Off Processor Bus (OPB) Interrupt Controller |
---|
| 27 | * |
---|
| 28 | * Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca> |
---|
| 29 | * COPYRIGHT (c) 2005 Linn Products Ltd, Scotland. |
---|
| 30 | * |
---|
| 31 | * The license and distribution terms for this file may be |
---|
| 32 | * found in the file LICENSE in this distribution or at |
---|
[c499856] | 33 | * http://www.rtems.org/license/LICENSE. |
---|
[39c1534f] | 34 | */ |
---|
| 35 | |
---|
[862c2317] | 36 | #include <bsp.h> |
---|
[39c1534f] | 37 | #include <bsp/irq.h> |
---|
| 38 | #include <bsp/irq-generic.h> |
---|
[862c2317] | 39 | #include <bsp/vectors.h> |
---|
| 40 | |
---|
[d168079] | 41 | #include <libcpu/powerpc-utility.h> |
---|
| 42 | |
---|
[39c1534f] | 43 | /* |
---|
| 44 | * Acknowledge a mask of interrupts. |
---|
[862c2317] | 45 | */ |
---|
[39c1534f] | 46 | static void set_iar(uint32_t mask) |
---|
[862c2317] | 47 | { |
---|
[39c1534f] | 48 | *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IAR)) = mask; |
---|
[862c2317] | 49 | } |
---|
| 50 | |
---|
[39c1534f] | 51 | /* |
---|
| 52 | * Set IER state. Used to (dis)enable a mask of vectors. |
---|
| 53 | * If you only have to do one, use enable/disable_vector. |
---|
| 54 | */ |
---|
| 55 | static void set_ier(uint32_t mask) |
---|
[862c2317] | 56 | { |
---|
[39c1534f] | 57 | *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IER)) = mask; |
---|
[862c2317] | 58 | } |
---|
| 59 | |
---|
[39c1534f] | 60 | /* |
---|
| 61 | * Retrieve contents of Interrupt Pending Register |
---|
| 62 | */ |
---|
| 63 | static uint32_t get_ipr(void) |
---|
[862c2317] | 64 | { |
---|
[39c1534f] | 65 | uint32_t c = *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IPR)); |
---|
| 66 | return c; |
---|
[862c2317] | 67 | } |
---|
| 68 | |
---|
[39c1534f] | 69 | static void BSP_irq_enable_at_opbintc (rtems_irq_number irqnum) |
---|
[862c2317] | 70 | { |
---|
[39c1534f] | 71 | *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_SIE)) |
---|
| 72 | = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET); |
---|
[862c2317] | 73 | } |
---|
| 74 | |
---|
[39c1534f] | 75 | static void BSP_irq_disable_at_opbintc (rtems_irq_number irqnum) |
---|
[862c2317] | 76 | { |
---|
[39c1534f] | 77 | *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_CIE)) |
---|
| 78 | = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET); |
---|
[862c2317] | 79 | } |
---|
| 80 | |
---|
[39c1534f] | 81 | /* |
---|
| 82 | * IRQ Handler: this is called from the primary exception dispatcher |
---|
[862c2317] | 83 | */ |
---|
[39c1534f] | 84 | static void BSP_irq_handle_at_opbintc(void) |
---|
[862c2317] | 85 | { |
---|
[3916cec] | 86 | uint32_t ipr; |
---|
[296b60d7] | 87 | |
---|
| 88 | /* Get pending interrupts */ |
---|
[39c1534f] | 89 | ipr = get_ipr(); |
---|
[862c2317] | 90 | |
---|
[d168079] | 91 | if (ipr != 0) { |
---|
| 92 | /* Acknowledge all pending interrupts now and service them afterwards */ |
---|
| 93 | set_iar(ipr); |
---|
[862c2317] | 94 | |
---|
[d168079] | 95 | do { |
---|
| 96 | /* Get highest priority pending interrupt */ |
---|
| 97 | uint32_t i = 31 - ppc_count_leading_zeros(ipr); |
---|
[764b72e] | 98 | |
---|
[d168079] | 99 | ipr &= ~(1U << i); |
---|
[862c2317] | 100 | |
---|
[39c1534f] | 101 | bsp_interrupt_handler_dispatch(i+BSP_OPBINTC_IRQ_LOWEST_OFFSET); |
---|
[d168079] | 102 | } while (ipr != 0); |
---|
[862c2317] | 103 | } |
---|
| 104 | } |
---|
| 105 | |
---|
[39c1534f] | 106 | /* |
---|
| 107 | * activate the interrupt controller |
---|
| 108 | */ |
---|
| 109 | static void opb_intc_init(void) |
---|
[862c2317] | 110 | { |
---|
[39c1534f] | 111 | uint32_t i, mask = 0; |
---|
[ac7af4a] | 112 | |
---|
[39c1534f] | 113 | /* mask off all interrupts */ |
---|
| 114 | set_ier(0x0); |
---|
| 115 | |
---|
| 116 | for (i = 0; i < OPB_INTC_IRQ_MAX; i++) { |
---|
| 117 | mask |= (1 << i); |
---|
[862c2317] | 118 | } |
---|
| 119 | |
---|
[39c1534f] | 120 | /* make sure interupt status register is clear before we enable the interrupt controller */ |
---|
| 121 | *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_ISR)) = 0; |
---|
[ac7af4a] | 122 | |
---|
[39c1534f] | 123 | /* acknowledge all interrupt sources */ |
---|
| 124 | set_iar(mask); |
---|
[862c2317] | 125 | |
---|
[39c1534f] | 126 | /* Turn on normal hardware operation of interrupt controller */ |
---|
| 127 | *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) = |
---|
| 128 | (OPB_INTC_MER_HIE); |
---|
[862c2317] | 129 | |
---|
[39c1534f] | 130 | /* Enable master interrupt switch for the interrupt controller */ |
---|
| 131 | *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) = |
---|
| 132 | (OPB_INTC_MER_HIE | OPB_INTC_MER_ME); |
---|
[862c2317] | 133 | } |
---|
| 134 | |
---|
[eebecd0] | 135 | rtems_status_code bsp_interrupt_get_attributes( |
---|
| 136 | rtems_vector_number vector, |
---|
| 137 | rtems_interrupt_attributes *attributes |
---|
| 138 | ) |
---|
| 139 | { |
---|
| 140 | return RTEMS_SUCCESSFUL; |
---|
| 141 | } |
---|
| 142 | |
---|
[deb5afb] | 143 | rtems_status_code bsp_interrupt_is_pending( |
---|
| 144 | rtems_vector_number vector, |
---|
| 145 | bool *pending |
---|
| 146 | ) |
---|
| 147 | { |
---|
| 148 | bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); |
---|
| 149 | bsp_interrupt_assert(pending != NULL); |
---|
| 150 | *pending = false; |
---|
| 151 | return RTEMS_UNSATISFIED; |
---|
| 152 | } |
---|
| 153 | |
---|
[9832652c] | 154 | rtems_status_code bsp_interrupt_raise(rtems_vector_number vector) |
---|
| 155 | { |
---|
| 156 | bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); |
---|
| 157 | return RTEMS_UNSATISFIED; |
---|
| 158 | } |
---|
| 159 | |
---|
| 160 | rtems_status_code bsp_interrupt_clear(rtems_vector_number vector) |
---|
| 161 | { |
---|
| 162 | bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); |
---|
| 163 | return RTEMS_UNSATISFIED; |
---|
| 164 | } |
---|
| 165 | |
---|
[781213f9] | 166 | rtems_status_code bsp_interrupt_vector_is_enabled( |
---|
| 167 | rtems_vector_number vector, |
---|
| 168 | bool *enabled |
---|
| 169 | ) |
---|
| 170 | { |
---|
| 171 | bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); |
---|
| 172 | bsp_interrupt_assert(enabled != NULL); |
---|
| 173 | *enabled = false; |
---|
| 174 | return RTEMS_UNSATISFIED; |
---|
| 175 | } |
---|
| 176 | |
---|
[bc86a5fa] | 177 | rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector) |
---|
[862c2317] | 178 | { |
---|
[c6810c8] | 179 | bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); |
---|
[862c2317] | 180 | |
---|
[c6810c8] | 181 | if (BSP_IS_OPBINTC_IRQ(vector)) { |
---|
| 182 | BSP_irq_enable_at_opbintc(vector); |
---|
| 183 | } |
---|
[bc86a5fa] | 184 | |
---|
| 185 | return RTEMS_SUCCESSFUL; |
---|
[39c1534f] | 186 | } |
---|
[862c2317] | 187 | |
---|
[32f5a195] | 188 | rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) |
---|
[862c2317] | 189 | { |
---|
[c6810c8] | 190 | bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); |
---|
[39c1534f] | 191 | |
---|
[c6810c8] | 192 | if (BSP_IS_OPBINTC_IRQ(vector)) { |
---|
| 193 | BSP_irq_disable_at_opbintc(vector); |
---|
| 194 | } |
---|
[32f5a195] | 195 | |
---|
| 196 | return RTEMS_SUCCESSFUL; |
---|
[862c2317] | 197 | } |
---|
| 198 | |
---|
[39c1534f] | 199 | static int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned int excNum) |
---|
| 200 | { |
---|
| 201 | BSP_irq_handle_at_opbintc(); |
---|
[862c2317] | 202 | |
---|
[39c1534f] | 203 | return 0; |
---|
| 204 | } |
---|
[862c2317] | 205 | |
---|
[c7b4eca7] | 206 | void bsp_interrupt_facility_initialize(void) |
---|
[862c2317] | 207 | { |
---|
[c7b4eca7] | 208 | rtems_status_code sc; |
---|
[aee685a3] | 209 | |
---|
[c7b4eca7] | 210 | opb_intc_init(); |
---|
[aee685a3] | 211 | |
---|
[c7b4eca7] | 212 | sc = ppc_exc_set_handler(ASM_EXT_VECTOR, C_dispatch_irq_handler); |
---|
| 213 | _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL); |
---|
[862c2317] | 214 | } |
---|