Changeset 39c1534f in rtems


Ignore:
Timestamp:
Jun 18, 2013, 3:20:28 PM (6 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
53dc697
Parents:
894e93f
git-author:
Sebastian Huber <sebastian.huber@…> (06/18/13 15:20:28)
git-committer:
Sebastian Huber <sebastian.huber@…> (06/24/13 08:54:00)
Message:

bsp/virtex: Use generic interrupt support

Location:
c/src/lib/libbsp/powerpc/virtex
Files:
1 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/powerpc/virtex/Makefile.am

    r894e93f r39c1534f  
    5454    ../../shared/console_select.c ../../shared/console_control.c \
    5555    ../../shared/console_read.c ../../shared/console_write.c
     56
     57# irq
     58include_bsp_HEADERS += ../../shared/include/irq-generic.h
     59include_bsp_HEADERS += ../../shared/include/irq-info.h
    5660include_bsp_HEADERS += include/opbintctrl.h
    57 # opbintctrl
    58 libbsp_a_SOURCES += opbintctrl/opbintctrl.c
    59 
    6061include_bsp_HEADERS += irq/irq.h
    61 # irq
     62libbsp_a_SOURCES += ../../shared/src/irq-default-handler.c
     63libbsp_a_SOURCES += ../../shared/src/irq-generic.c
     64libbsp_a_SOURCES += ../../shared/src/irq-info.c
     65libbsp_a_SOURCES += ../../shared/src/irq-legacy.c
     66libbsp_a_SOURCES += ../../shared/src/irq-server.c
     67libbsp_a_SOURCES += ../../shared/src/irq-shell.c
    6268libbsp_a_SOURCES += irq/irq_init.c
    6369
  • c/src/lib/libbsp/powerpc/virtex/include/bsp.h

    r894e93f r39c1534f  
    6262#include <bsp/default-initial-extension.h>
    6363
     64#define BSP_FEATURE_IRQ_EXTENSION
     65
    6466#define BSP_INTERRUPT_STACK_AT_WORK_AREA_BEGIN
    6567
  • c/src/lib/libbsp/powerpc/virtex/include/opbintctrl.h

    r894e93f r39c1534f  
    6969#define OPB_INTC_MER_ME         0x1
    7070
    71   /*
    72    * make this fast: is this a opbintc interrupt?
    73    */
    74   void BSP_irq_enable_at_opbintc (rtems_irq_number irqnum);
    75 
    76   void BSP_irq_disable_at_opbintc (rtems_irq_number irqnum);
    77   /*
    78    *  IRQ Handler: this is called from the primary exception dispatcher
    79    */
    80   void BSP_irq_handle_at_opbintc(void);
    81   /*
    82    * activate the interrupt controller
    83    */
    84   rtems_status_code opb_intc_init(void);
    85 
    8671#ifdef __cplusplus
    8772}
  • c/src/lib/libbsp/powerpc/virtex/irq/irq.h

    r894e93f r39c1534f  
    2121
    2222#include <rtems/irq.h>
     23#include <rtems/irq-extension.h>
    2324#include <bsp/opbintctrl.h>
    2425
     
    6162           || BSP_IS_OPBINTC_IRQ(irqnum))
    6263
     64#define BSP_INTERRUPT_VECTOR_MIN 0
     65#define BSP_INTERRUPT_VECTOR_MAX BSP_PROCESSOR_IRQ_MAX_OFFSET
     66
    6367#ifndef ASM
    6468#ifdef __cplusplus
     
    8387#define BSP_OPBINTC_XPAR(xname) (BSP_OPBINTC_IRQ_LOWEST_OFFSET+xname)
    8488
    85   extern rtems_irq_connect_data *BSP_rtems_irq_tbl;
    86   void BSP_rtems_irq_mng_init(unsigned cpuId);
    87 
    8889#ifdef __cplusplus
    8990}
  • c/src/lib/libbsp/powerpc/virtex/irq/irq_init.c

    r894e93f r39c1534f  
    2020| this file contains the irq controller handler                   |
    2121\*===============================================================*/
    22 #include <libcpu/spr.h>
     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
     33 *  http://www.rtems.com/license/LICENSE.
     34 */
     35
     36#include <bsp.h>
    2337#include <bsp/irq.h>
    24 #include <bsp.h>
    25 #include <rtems/bspIo.h>
    26 #include <rtems/powerpc/powerpc.h>
     38#include <bsp/irq-generic.h>
    2739#include <bsp/vectors.h>
    2840
    29 static rtems_irq_connect_data rtemsIrqTbl[BSP_IRQ_NUMBER];
    30 rtems_irq_connect_data *BSP_rtems_irq_tbl;
    31 rtems_irq_global_settings* BSP_rtems_irq_config;
    32 
    33 /***********************************************************
    34  * dummy functions for on/off/isOn calls
    35  * these functions just do nothing fulfill the semantic
    36  * requirements to enable/disable a certain interrupt or exception
     41/*
     42 * Acknowledge a mask of interrupts.
    3743 */
    38 void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
     44static void set_iar(uint32_t mask)
    3945{
    40   /*
    41    * nothing to do
    42    */
     46  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IAR)) = mask;
    4347}
    4448
    45 void BSP_irq_nop_hdl(void *hdl)
     49/*
     50 * Set IER state.  Used to (dis)enable a mask of vectors.
     51 * If you only have to do one, use enable/disable_vector.
     52 */
     53static void set_ier(uint32_t mask)
    4654{
    47   /*
    48    * nothing to do
    49    */
     55  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IER)) = mask;
    5056}
    5157
    52 int BSP_irq_true_func(const rtems_irq_connect_data *unused)
     58/*
     59 * Retrieve contents of Interrupt Pending Register
     60 */
     61static uint32_t get_ipr(void)
    5362{
    54   /*
    55    * nothing to do
    56    */
    57   return TRUE;
     63  uint32_t c = *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IPR));
     64  return c;
    5865}
    5966
    60 /***********************************************************
    61  * interrupt handler and its enable/disable functions
    62  ***********************************************************/
    63 
    64 /***********************************************************
    65  * functions to enable/disable/query external/critical interrupts
    66  */
    67 void BSP_irqexc_on_fnc(rtems_irq_connect_data *conn_data)
     67static void BSP_irq_enable_at_opbintc (rtems_irq_number irqnum)
    6868{
    69   uint32_t msr_value;
    70   /*
    71    * get current MSR value
    72    */
    73   _CPU_MSR_GET(msr_value);
    74 
    75 
    76    msr_value |= PPC_MSR_EE;
    77    _CPU_MSR_SET(msr_value);
     69  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_SIE))
     70    = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET);
    7871}
    7972
    80 void BSP_irqexc_off_fnc(rtems_irq_connect_data *unused)
     73static void BSP_irq_disable_at_opbintc (rtems_irq_number irqnum)
    8174{
    82   /*
    83    * nothing to do
    84    */
     75  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_CIE))
     76    = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET);
    8577}
    8678
    87 /***********************************************************
    88  * High level IRQ handler called from shared_raw_irq_code_entry
     79/*
     80 *  IRQ Handler: this is called from the primary exception dispatcher
    8981 */
    90 int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
     82static void BSP_irq_handle_at_opbintc(void)
    9183{
     84  uint32_t ipr, mask, i, c;
     85  ipr = get_ipr();
    9286
     87  c = 0;
     88  mask = 0;
    9389
    94   /*
    95    * Handle interrupt
    96    */
    97   switch(excNum) {
    98   case ASM_EXT_VECTOR:
    99     BSP_irq_handle_at_opbintc();
    100     break;
    101 #if 0 /* We now let the clock driver hook the exception directly */
    102   case ASM_BOOKE_DEC_VECTOR:
    103     BSP_rtems_irq_tbl[BSP_PIT].hdl
    104       (BSP_rtems_irq_tbl[BSP_PIT].handle);
    105     break;
    106 #endif
    107 #if 0 /* Critical interrupts not yet supported */
    108   case ASM_BOOKE_CRIT_VECTOR:
    109     break;
    110 #endif
     90  for (i = 0;
     91       (i < BSP_OPBINTC_PER_IRQ_NUMBER)
     92         && (ipr != 0);
     93       i++) {
     94    c = (1 << i);
     95
     96    if ((ipr & c) != 0) {
     97      /* interrupt is asserted */
     98      mask |= c;
     99      ipr &= ~c;
     100
     101      bsp_interrupt_handler_dispatch(i+BSP_OPBINTC_IRQ_LOWEST_OFFSET);
     102    }
    111103  }
     104
     105  if (mask) {
     106    /* ack all the interrupts we serviced */
     107    set_iar(mask);
     108  }
     109}
     110
     111/*
     112 * activate the interrupt controller
     113 */
     114static void opb_intc_init(void)
     115{
     116  uint32_t i, mask = 0;
     117
     118  /* mask off all interrupts */
     119  set_ier(0x0);
     120
     121  for (i = 0; i < OPB_INTC_IRQ_MAX; i++) {
     122    mask |= (1 << i);
     123  }
     124
     125  /* make sure interupt status register is clear before we enable the interrupt controller */
     126  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_ISR)) = 0;
     127
     128  /* acknowledge all interrupt sources */
     129  set_iar(mask);
     130
     131  /* Turn on normal hardware operation of interrupt controller */
     132  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
     133    (OPB_INTC_MER_HIE);
     134
     135  /* Enable master interrupt switch for the interrupt controller */
     136  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
     137    (OPB_INTC_MER_HIE | OPB_INTC_MER_ME);
     138}
     139
     140rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
     141{
     142  rtems_status_code sc = RTEMS_SUCCESSFUL;
     143
     144  if (bsp_interrupt_is_valid_vector(vector)) {
     145    if (BSP_IS_OPBINTC_IRQ(vector)) {
     146      BSP_irq_enable_at_opbintc(vector);
     147    }
     148  } else {
     149    sc = RTEMS_INVALID_ID;
     150  }
     151
     152  return sc;
     153}
     154
     155rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
     156{
     157  rtems_status_code sc = RTEMS_SUCCESSFUL;
     158
     159  if (bsp_interrupt_is_valid_vector(vector)) {
     160    if (BSP_IS_OPBINTC_IRQ(vector)) {
     161      BSP_irq_disable_at_opbintc(vector);
     162    }
     163  } else {
     164    sc = RTEMS_INVALID_ID;
     165  }
     166
     167  return sc;
     168}
     169
     170static int C_dispatch_irq_handler(BSP_Exception_frame *frame, unsigned int excNum)
     171{
     172  BSP_irq_handle_at_opbintc();
     173
    112174  return 0;
    113175}
    114176
    115 /***********************************************************
    116  * functions to set/get/remove interrupt handlers
    117  ***********************************************************/
    118 int BSP_install_rtems_irq_handler  (const rtems_irq_connect_data* irq)
     177rtems_status_code bsp_interrupt_facility_initialize(void)
    119178{
    120   rtems_interrupt_level level;
     179  opb_intc_init();
    121180
    122   /*
    123    * check for valid irq name
    124    * if invalid, print error and return 0
    125    */
    126   if (!BSP_IS_VALID_IRQ(irq->name)) {
    127     printk("Invalid interrupt vector %d\n",irq->name);
    128     return 0;
    129   }
     181  ppc_exc_set_handler(ASM_EXT_VECTOR, C_dispatch_irq_handler);
    130182
    131   /*
    132    * disable interrupts
    133    */
    134   rtems_interrupt_disable(level);
    135   /*
    136    * check, that default handler is installed now
    137    */
    138   if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
    139     rtems_interrupt_enable(level);
    140     printk("IRQ vector %d already connected\n",irq->name);
    141     return 0;
    142   }
    143   /*
    144    * store new handler data
    145    */
    146   rtemsIrqTbl[irq->name] = *irq;
    147 
    148   /*
    149    * enable irq at interrupt controller
    150    */
    151   if (BSP_IS_OPBINTC_IRQ(irq->name)) {
    152     BSP_irq_enable_at_opbintc(irq->name);
    153   }
    154   /*
    155    * call "on" function to enable interrupt at device
    156    */
    157   irq->on(irq);
    158   /*
    159    * reenable interrupts
    160    */
    161   rtems_interrupt_enable(level);
    162 
    163   return 1;
     183  return RTEMS_SUCCESSFUL;
    164184}
    165 
    166 int BSP_get_current_rtems_irq_handler   (rtems_irq_connect_data* irq)
    167 {
    168   rtems_interrupt_level level;
    169 
    170   /*
    171    * check for valid IRQ name
    172    */
    173   if (!BSP_IS_VALID_IRQ(irq->name)) {
    174     return 0;
    175   }
    176   rtems_interrupt_disable(level);
    177   /*
    178    * return current IRQ entry
    179    */
    180   *irq = rtemsIrqTbl[irq->name];
    181   rtems_interrupt_enable(level);
    182   return 1;
    183 }
    184 
    185 int BSP_remove_rtems_irq_handler  (const rtems_irq_connect_data* irq)
    186 {
    187   rtems_interrupt_level level;
    188 
    189   /*
    190    * check for valid IRQ name
    191    */
    192   if (!BSP_IS_VALID_IRQ(irq->name)) {
    193     return 0;
    194   }
    195   rtems_interrupt_disable(level);
    196   /*
    197    * check, that specified handler is really connected now
    198    */
    199   if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
    200     rtems_interrupt_enable(level);
    201     return 0;
    202   }
    203   /*
    204    * disable interrupt at interrupt controller
    205    */
    206   if (BSP_IS_OPBINTC_IRQ(irq->name)) {
    207     BSP_irq_disable_at_opbintc(irq->name);
    208   }
    209   /*
    210    * disable interrupt at source
    211    */
    212   irq->off(irq);
    213   /*
    214    * restore default interrupt handler
    215    */
    216   rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
    217 
    218   /*
    219    * reenable interrupts
    220    */
    221   rtems_interrupt_enable(level);
    222 
    223   return 1;
    224 }
    225 
    226 /***********************************************************
    227  * functions to set/get the basic interrupt management setup
    228  ***********************************************************/
    229 /*
    230  * (Re) get info on current RTEMS interrupt management.
    231  */
    232 int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
    233 {
    234   *ret_ptr = BSP_rtems_irq_config;
    235   return 0;
    236 }
    237 
    238 
    239 /*
    240  * set management stuff
    241  */
    242 int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
    243 {
    244   int                    i;
    245   rtems_interrupt_level  level;
    246 
    247   rtems_interrupt_disable(level);
    248   /*
    249    * store given configuration
    250    */
    251   BSP_rtems_irq_config = config;
    252   BSP_rtems_irq_tbl    = BSP_rtems_irq_config->irqHdlTbl;
    253   /*
    254    * enable any non-empty IRQ entries at OPBINTC
    255    */
    256   for (i =  BSP_OPBINTC_IRQ_LOWEST_OFFSET;
    257        i <= BSP_OPBINTC_IRQ_MAX_OFFSET;
    258        i++) {
    259     if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
    260       BSP_irq_enable_at_opbintc(i);
    261       BSP_rtems_irq_tbl[i].on((&BSP_rtems_irq_tbl[i]));
    262     }
    263     else {
    264       BSP_rtems_irq_tbl[i].off(&(BSP_rtems_irq_tbl[i]));
    265       BSP_irq_disable_at_opbintc(i);
    266     }
    267   }
    268   /*
    269    * store any irq-like processor exceptions
    270    */
    271   for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
    272        i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
    273        i++) {
    274     if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
    275       if (BSP_rtems_irq_tbl[i].on != NULL) {
    276         BSP_rtems_irq_tbl[i].on
    277           (&(BSP_rtems_irq_tbl[i]));
    278       }
    279     }
    280     else {
    281       if (BSP_rtems_irq_tbl[i].off != NULL) {
    282         BSP_rtems_irq_tbl[i].off
    283           (&(BSP_rtems_irq_tbl[i]));
    284       }
    285     }
    286   }
    287   rtems_interrupt_enable(level);
    288   return 1;
    289 }
    290 
    291 /*
    292  * dummy for an empty IRQ handler entry
    293  */
    294 static rtems_irq_connect_data emptyIrq = {
    295   0,                     /* Irq Name                 */
    296   BSP_irq_nop_hdl,       /* handler function         */
    297   NULL,                  /* handle passed to handler */
    298   BSP_irq_nop_func,      /* on function              */
    299   BSP_irq_nop_func,      /* off function             */
    300   BSP_irq_true_func      /* isOn function            */
    301 };
    302 
    303 static rtems_irq_global_settings initialConfig = {
    304   BSP_IRQ_NUMBER,    /* irqNb */
    305   {  0,                          /* Irq Name                 */
    306      BSP_irq_nop_hdl,       /* handler function         */
    307      NULL,                  /* handle passed to handler */
    308      BSP_irq_nop_func,      /* on function              */
    309      BSP_irq_nop_func,      /* off function             */
    310      BSP_irq_true_func      /* isOn function            */
    311   }, /* emptyIrq */
    312   rtemsIrqTbl, /* irqHdlTbl  */
    313   0,           /* irqBase    */
    314   NULL         /* irqPrioTbl */
    315 };
    316 
    317 void BSP_rtems_irq_mng_init(unsigned cpuId)
    318 {
    319   int i;
    320 
    321   /*
    322    * connect all exception vectors needed
    323    */
    324  ppc_exc_set_handler(ASM_EXT_VECTOR, C_dispatch_irq_handler);
    325  ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_irq_handler);
    326 
    327   /*
    328    * setup interrupt handlers table
    329    */
    330   for (i = 0;
    331        i < BSP_IRQ_NUMBER;
    332        i++) {
    333     rtemsIrqTbl[i]      = emptyIrq;
    334     rtemsIrqTbl[i].name = i;
    335   }
    336   /*
    337    * init interrupt controller
    338    */
    339   opb_intc_init();
    340   /*
    341    * initialize interrupt management
    342    */
    343   if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
    344     BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
    345   }
    346 }
    347 
  • c/src/lib/libbsp/powerpc/virtex/preinstall.am

    r894e93f r39c1534f  
    8787PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.base
    8888
     89$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     90        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-generic.h
     91PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h
     92
     93$(PROJECT_INCLUDE)/bsp/irq-info.h: ../../shared/include/irq-info.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
     94        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-info.h
     95PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h
     96
    8997$(PROJECT_INCLUDE)/bsp/opbintctrl.h: include/opbintctrl.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
    9098        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/opbintctrl.h
  • c/src/lib/libbsp/powerpc/virtex/startup/bspstart.c

    r894e93f r39c1534f  
    5757#include <bsp.h>
    5858#include <bsp/irq.h>
     59#include <bsp/irq-generic.h>
    5960#include <bsp/bootcard.h>
    6061#include <bsp/linker-symbols.h>
     
    105106  __asm__ volatile ("mtevpr %0" : : "r" (virtex_exc_vector_base));
    106107
    107   /*
    108    * Install our own set of exception vectors
    109    */
    110   BSP_rtems_irq_mng_init(0);
     108  bsp_interrupt_initialize();
    111109}
    112110
Note: See TracChangeset for help on using the changeset viewer.