Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:59

0001 /*
0002  * RTEMS virtex BSP
0003  *
0004  * This file contains the irq controller handler.
0005  *
0006  * Content moved from opbintctrl.c:
0007  *
0008  *  This file contains definitions and declarations for the
0009  *  Xilinx Off Processor Bus (OPB) Interrupt Controller
0010  */
0011 
0012 /*
0013  * Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
0014  * COPYRIGHT (c) 2005 Linn Products Ltd, Scotland.
0015  * Copyright (c) 2007 embedded brains GmbH & Co. KG
0016  *
0017  * The license and distribution terms for this file may be
0018  * found in the file LICENSE in this distribution or at
0019  * http://www.rtems.org/license/LICENSE.
0020  */
0021 
0022 #include <bsp.h>
0023 #include <bsp/irq.h>
0024 #include <bsp/irq-generic.h>
0025 #include <bsp/vectors.h>
0026 
0027 #include <libcpu/powerpc-utility.h>
0028 
0029 /*
0030  * Acknowledge a mask of interrupts.
0031  */
0032 static void set_iar(uint32_t mask)
0033 {
0034   *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IAR)) = mask;
0035 }
0036 
0037 /*
0038  * Set IER state.  Used to (dis)enable a mask of vectors.
0039  * If you only have to do one, use enable/disable_vector.
0040  */
0041 static void set_ier(uint32_t mask)
0042 {
0043   *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IER)) = mask;
0044 }
0045 
0046 /*
0047  * Retrieve contents of Interrupt Pending Register
0048  */
0049 static uint32_t get_ipr(void)
0050 {
0051   uint32_t c = *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IPR));
0052   return c;
0053 }
0054 
0055 static void BSP_irq_enable_at_opbintc (rtems_irq_number irqnum)
0056 {
0057   *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_SIE))
0058     = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET);
0059 }
0060 
0061 static void BSP_irq_disable_at_opbintc (rtems_irq_number irqnum)
0062 {
0063   *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_CIE))
0064     = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET);
0065 }
0066 
0067 /*
0068  *  IRQ Handler: this is called from the primary exception dispatcher
0069  */
0070 static void BSP_irq_handle_at_opbintc(void)
0071 {
0072   uint32_t ipr;
0073 
0074   /* Get pending interrupts */
0075   ipr = get_ipr();
0076 
0077   if (ipr != 0) {
0078     /* Acknowledge all pending interrupts now and service them afterwards */
0079     set_iar(ipr);
0080 
0081     do {
0082       /* Get highest priority pending interrupt */
0083       uint32_t i = 31 - ppc_count_leading_zeros(ipr);
0084 
0085       ipr &= ~(1U << i);
0086 
0087       bsp_interrupt_handler_dispatch(i+BSP_OPBINTC_IRQ_LOWEST_OFFSET);
0088     } while (ipr != 0);
0089   }
0090 }
0091 
0092 /*
0093  * activate the interrupt controller
0094  */
0095 static void opb_intc_init(void)
0096 {
0097   uint32_t i, mask = 0;
0098 
0099   /* mask off all interrupts */
0100   set_ier(0x0);
0101 
0102   for (i = 0; i < OPB_INTC_IRQ_MAX; i++) {
0103     mask |= (1 << i);
0104   }
0105 
0106   /* make sure interupt status register is clear before we enable the interrupt controller */
0107   *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_ISR)) = 0;
0108 
0109   /* acknowledge all interrupt sources */
0110   set_iar(mask);
0111 
0112   /* Turn on normal hardware operation of interrupt controller */
0113   *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
0114     (OPB_INTC_MER_HIE);
0115 
0116   /* Enable master interrupt switch for the interrupt controller */
0117   *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
0118     (OPB_INTC_MER_HIE | OPB_INTC_MER_ME);
0119 }
0120 
0121 rtems_status_code bsp_interrupt_get_attributes(
0122   rtems_vector_number         vector,
0123   rtems_interrupt_attributes *attributes
0124 )
0125 {
0126   return RTEMS_SUCCESSFUL;
0127 }
0128 
0129 rtems_status_code bsp_interrupt_is_pending(
0130   rtems_vector_number vector,
0131   bool               *pending
0132 )
0133 {
0134   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0135   bsp_interrupt_assert(pending != NULL);
0136   *pending = false;
0137   return RTEMS_UNSATISFIED;
0138 }
0139 
0140 rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
0141 {
0142   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0143   return RTEMS_UNSATISFIED;
0144 }
0145 
0146 rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
0147 {
0148   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0149   return RTEMS_UNSATISFIED;
0150 }
0151 
0152 rtems_status_code bsp_interrupt_vector_is_enabled(
0153   rtems_vector_number vector,
0154   bool               *enabled
0155 )
0156 {
0157   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0158   bsp_interrupt_assert(enabled != NULL);
0159   *enabled = false;
0160   return RTEMS_UNSATISFIED;
0161 }
0162 
0163 rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
0164 {
0165   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0166 
0167   if (BSP_IS_OPBINTC_IRQ(vector)) {
0168     BSP_irq_enable_at_opbintc(vector);
0169   }
0170 
0171   return RTEMS_SUCCESSFUL;
0172 }
0173 
0174 rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
0175 {
0176   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0177 
0178   if (BSP_IS_OPBINTC_IRQ(vector)) {
0179     BSP_irq_disable_at_opbintc(vector);
0180   }
0181 
0182   return RTEMS_SUCCESSFUL;
0183 }
0184 
0185 rtems_status_code bsp_interrupt_set_priority(
0186   rtems_vector_number vector,
0187   uint32_t priority
0188 )
0189 {
0190   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0191   return RTEMS_UNSATISFIED;
0192 }
0193 
0194 rtems_status_code bsp_interrupt_get_priority(
0195   rtems_vector_number vector,
0196   uint32_t *priority
0197 )
0198 {
0199   bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0200   bsp_interrupt_assert(priority != NULL);
0201   return RTEMS_UNSATISFIED;
0202 }
0203 
0204 static int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned int excNum)
0205 {
0206   BSP_irq_handle_at_opbintc();
0207 
0208   return 0;
0209 }
0210 
0211 void bsp_interrupt_facility_initialize(void)
0212 {
0213   rtems_status_code sc;
0214 
0215   opb_intc_init();
0216 
0217   sc = ppc_exc_set_handler(ASM_EXT_VECTOR, C_dispatch_irq_handler);
0218   _Assert_Unused_variable_equals(sc, RTEMS_SUCCESSFUL);
0219 }