source: rtems/c/src/lib/libbsp/powerpc/mvme5500/irq/BSP_irq.c @ 2e9d27c0

4.104.115
Last change on this file since 2e9d27c0 was 2e9d27c0, checked in by Ralf Corsepius <ralf.corsepius@…>, on 10/23/09 at 06:28:17

2009-10-23 Ralf Corsépius <ralf.corsepius@…>

  • irq/BSP_irq.c, network/if_100MHz/GT64260eth.c, network/if_1GHz/if_wm.c, network/if_1GHz/pci_map.c, startup/bspstart.c: Add missing prototypes. Adjust bogus types. Remove unused vars.
  • Property mode set to 100644
File size: 14.9 KB
Line 
1/*  BSP_irq.c
2 *
3 *  This file contains the implementation of the function described in irq.h
4 *
5 *  Copyright (C) 1998, 1999 valette@crf.canon.fr
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.OARcorp.com/rtems/license.html.
10 *
11 *  Acknowledgement May 2004, to Till Straumann <strauman@slac.stanford.edu>
12 *  for some inputs.
13 *
14 *  Copyright 2003, 2004, 2005, 2007  Shuchen Kate Feng <feng1@bnl.gov>,
15 *            NSLS, Brookhaven National Laboratory. All rights reserved.
16 *
17 *  1) Used GT_GPP_Value register instead of the GT_GPP_Interrupt_Cause
18 *     register to monitor the cause of the level sensitive interrupts.
19 *     (Copyright : NDA item)
20 *  2) The implementation of picPrioTable[] is an original work by the
21 *     author to optimize the software IRQ priority scheduling because
22 *     Discovery controller does not provide H/W IRQ priority schedule.
23 *     It ensures the fastest/faster interrupt service to the
24 *     highest/higher priority IRQ, if pendig.
25 *  3) _CPU_MSR_SET() needs RTEMS_COMPILER_MEMORY_BARRIER()
26 *
27 */
28
29#include <stdio.h> 
30#include <rtems/system.h>
31#include <bsp.h>
32#include <bsp/irq.h>
33#include <rtems/score/thread.h>
34#include <rtems/score/apiext.h>
35#include <libcpu/raw_exception.h>
36#include <rtems/rtems/intr.h>
37#include <libcpu/io.h>
38#include <libcpu/byteorder.h>
39#include <bsp/vectors.h>
40
41#include <rtems/bspIo.h> /* for printk */
42#include "bsp/gtreg.h"
43
44#define HI_INT_CAUSE 0x40000000
45
46#define MAX_IRQ_LOOP 20
47
48/* #define DEBUG_IRQ*/
49
50/*
51 * pointer to the mask representing the additionnal irq vectors
52 * that must be disabled when a particular entry is activated.
53 * They will be dynamically computed from the table given
54 * in BSP_rtems_irq_mngt_set();
55 * CAUTION : this table is accessed directly by interrupt routine
56 *           prologue.
57 */
58static unsigned int BSP_irq_prio_mask_tbl[3][BSP_PIC_IRQ_NUMBER];
59
60/*
61 * location used to store initial tables used for interrupt
62 * management.BSP copy of the configuration
63 */
64static rtems_irq_global_settings        BSP_config;
65static rtems_irq_connect_data*          rtems_hdl_tbl;
66
67/*
68 * default handler connected on each irq after bsp initialization
69 * (locally cached copy)
70 */
71void (*default_rtems_hdl)(rtems_irq_hdl_param) = (void(*)(rtems_irq_hdl_param)) -1;
72
73
74static volatile unsigned  *BSP_irqMask_reg[3];
75static volatile unsigned  *BSP_irqCause_reg[3];
76static volatile unsigned  BSP_irqMask_cache[3]={0,0,0};
77
78static int picPrioTblPtr=0;
79static unsigned int GPPIrqInTbl=0;
80static unsigned long long MainIrqInTbl=0;
81
82/*
83 * The software developers are forbidden to setup picPrioTable[],
84 * as it is a powerful engine for the BSP to find the pending
85 * highest priority IRQ at run time.  It ensures the fastest/faster
86 * interrupt service to the highest/higher priority IRQ, if pendig.
87 *
88 * The picPrioTable[96] is updated dynamically at run time
89 * based on the priority levels set at BSPirqPrioTable[96],
90 * while the BSP_enable_irq_at_pic(), and BSP_disable_irq_at_pic()
91 * commands are invoked.
92 *
93 * The picPrioTable[96] lists the enabled CPU main and GPP external interrupt
94 * numbers [0 (lowest)- 95 (highest)] starting from the highest priority
95 * one to the lowest priority one. The highest priority interrupt is
96 * located at picPrioTable[0], and the lowest priority interrupt is located
97 * at picPrioTable[picPrioTblPtr-1].
98 *
99 *
100 */
101#define DynamicIsrTable
102#ifdef DynamicIsrTable
103/* BitNums for Main Interrupt Lo/High Cause, -1 means invalid bit */
104static unsigned int picPrioTable[BSP_PIC_IRQ_NUMBER]={
105     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
106     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
107     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
108     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
109     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
110     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
111     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
112     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
113     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
114     -1, -1, -1, -1, -1, -1 };
115#else
116static unsigned int picPrioTable[BSP_PIC_IRQ_NUMBER]={
117     80, 84, 76, 77, 32, -1, -1, -1, -1, -1,
118     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
119     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
120     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
121     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
122     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
123     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
124     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
125     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
126     -1, -1, -1, -1, -1, -1 };
127#endif
128
129/*
130 * Check if IRQ is a MAIN CPU internal IRQ or GPP external IRQ
131 */
132static inline int is_pic_irq(const rtems_irq_number irqLine)
133{
134  return (((int) irqLine <= BSP_GPP_IRQ_MAX_OFFSET) &
135          ((int) irqLine >= BSP_MICL_IRQ_LOWEST_OFFSET)
136         );
137}
138
139/*
140 * Check if IRQ is a Porcessor IRQ
141 */
142static inline int is_processor_irq(const rtems_irq_number irqLine)
143{
144  return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) &
145          ((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)
146         );
147}
148
149/*
150 * ------------------------ RTEMS Irq helper functions ----------------
151 */
152 
153/*
154 * Caution : this function assumes the variable "BSP_config"
155 * is already set and that the tables it contains are still valid
156 * and accessible.
157 */
158static void compute_pic_masks_from_prio(void)
159{
160  int i,j, k, isGppMain;
161  unsigned long long irq_prio_mask=0;
162
163  /*
164   * Always mask at least current interrupt to prevent re-entrance
165   */
166  for (i=0; i <BSP_PIC_IRQ_NUMBER; i++) {
167    switch(i) {
168      case BSP_MAIN_GPP7_0_IRQ:
169      case BSP_MAIN_GPP15_8_IRQ:
170      case BSP_MAIN_GPP23_16_IRQ:
171      case BSP_MAIN_GPP31_24_IRQ:
172        for (k=0; k< 3; k++)
173            BSP_irq_prio_mask_tbl[k][i]=0;
174
175        irq_prio_mask =0;
176        isGppMain =1;
177        break;
178      default :
179        isGppMain =0;
180        irq_prio_mask = (unsigned long long) (1LLU << i);
181        break;
182    }
183    if ( isGppMain) continue;
184    for (j = 0; j <BSP_MAIN_IRQ_NUMBER; j++) {
185        /*
186         * Mask interrupts at PIC level that have a lower priority
187         * or <Till Straumann> a equal priority.
188         */
189        if (BSP_config.irqPrioTbl [i] >= BSP_config.irqPrioTbl [j])
190           irq_prio_mask |= (unsigned long long)(1LLU << j);
191    }
192   
193
194    BSP_irq_prio_mask_tbl[0][i] = irq_prio_mask & 0xffffffff;
195    BSP_irq_prio_mask_tbl[1][i] = (irq_prio_mask>>32) & 0xffffffff;
196#if 0
197    printk("irq_mask_prio_tbl[%d]:0x%8x%8x\n",i,BSP_irq_prio_mask_tbl[1][i],
198           BSP_irq_prio_mask_tbl[0][i]);
199#endif
200
201    BSP_irq_prio_mask_tbl[2][i] = 1<<i;
202    /* Compute for the GPP priority interrupt mask */
203    for (j=BSP_GPP_IRQ_LOWEST_OFFSET; j <BSP_PROCESSOR_IRQ_LOWEST_OFFSET; j++) {     
204      if (BSP_config.irqPrioTbl [i] >= BSP_config.irqPrioTbl [j])
205           BSP_irq_prio_mask_tbl[2][i] |= 1 << (j-BSP_GPP_IRQ_LOWEST_OFFSET);
206    }
207#if 0
208    printk("GPPirq_mask_prio_tbl[%d]:0x%8x\n",i,BSP_irq_prio_mask_tbl[2][i]);
209#endif
210  }
211}
212
213static void UpdateMainIrqTbl(int irqNum)
214{
215  int i=0, j, shifted=0;
216
217  switch (irqNum) {
218    case BSP_MAIN_GPP7_0_IRQ:
219    case BSP_MAIN_GPP15_8_IRQ:
220    case BSP_MAIN_GPP23_16_IRQ:
221    case BSP_MAIN_GPP31_24_IRQ: 
222      return;  /* Do nothing, let GPP take care of it */
223      break;
224  }
225#ifdef SHOW_MORE_INIT_SETTINGS
226  unsigned long val2, val1;
227#endif
228
229  /* If entry not in table*/
230  if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
231        (!((unsigned long long)(1LLU << irqNum) & MainIrqInTbl))) ||
232       ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
233        (!(( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl))))
234  {
235      while ( picPrioTable[i]!=-1) {
236        if (BSP_config.irqPrioTbl[irqNum]>BSP_config.irqPrioTbl[picPrioTable[i]]) {
237          /* all other lower priority entries shifted right */
238          for (j=picPrioTblPtr;j>i; j--) {
239              picPrioTable[j]=picPrioTable[j-1];
240          }
241          picPrioTable[i]=irqNum;
242          shifted=1;
243          break;
244       }
245       i++;
246     }
247     if (!shifted) picPrioTable[picPrioTblPtr] =irqNum;
248
249     if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
250        GPPIrqInTbl |= (1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
251     else     
252        MainIrqInTbl |= (unsigned long long)(1LLU << irqNum);
253     picPrioTblPtr++;
254  }
255#ifdef SHOW_MORE_INIT_SETTINGS
256  val2 = (MainIrqInTbl>>32) & 0xffffffff;
257  val1 = MainIrqInTbl&0xffffffff;
258  printk("irqNum %d, MainIrqInTbl 0x%x%x\n", irqNum, val2, val1);
259  BSP_printPicIsrTbl();
260#endif
261
262}
263
264
265static void CleanMainIrqTbl(int irqNum)
266{
267  int i, j;
268
269  switch (irqNum) {
270    case BSP_MAIN_GPP7_0_IRQ:
271    case BSP_MAIN_GPP15_8_IRQ:
272    case BSP_MAIN_GPP23_16_IRQ:
273    case BSP_MAIN_GPP31_24_IRQ:
274      return;  /* Do nothing, let GPP take care of it */
275      break; 
276  }
277  if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
278        ((unsigned long long)(1LLU << irqNum) & MainIrqInTbl)) ||
279       ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
280        (( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl)))
281  { /* If entry in table*/
282     for (i=0; i<64; i++) {
283       if (picPrioTable[i]==irqNum) {/*remove it from the entry */
284          /* all other lower priority entries shifted left */
285          for (j=i;j<picPrioTblPtr; j++) {
286              picPrioTable[j]=picPrioTable[j+1];
287          }
288          if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
289            GPPIrqInTbl &= ~(1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
290          else     
291            MainIrqInTbl &= ~(1LLU << irqNum);
292          picPrioTblPtr--;
293          break;
294       }
295     }
296  }
297}
298
299void BSP_enable_irq_at_pic(const rtems_irq_number irqNum)
300{
301  unsigned bitNum, regNum;
302  unsigned int level;
303
304  if ( !is_pic_irq(irqNum) )
305        return;
306
307  bitNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)%32;
308  regNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)>>5;
309
310  rtems_interrupt_disable(level);
311
312#ifdef DynamicIsrTable
313  UpdateMainIrqTbl((int) irqNum);
314#endif
315  BSP_irqMask_cache[regNum] |= (1 << bitNum);
316
317  out_le32(BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
318  while (in_le32(BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
319
320  rtems_interrupt_enable(level);
321}
322
323void BSP_enable_pic_irq(const rtems_irq_number irqNum)
324{
325        BSP_enable_irq_at_pic(irqNum);
326}
327
328int BSP_disable_irq_at_pic(const rtems_irq_number irqNum)
329{
330  int      rval;
331  unsigned bitNum, regNum;
332  unsigned int level;
333
334  if ( ! is_pic_irq(irqNum) )
335        return -1;
336
337  bitNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)%32;
338  regNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)>>5;
339
340  rtems_interrupt_disable(level);
341
342#ifdef DynamicIsrTable
343  CleanMainIrqTbl((int) irqNum);
344#endif
345
346  rval = BSP_irqMask_cache[regNum] & (1<<bitNum);
347
348  BSP_irqMask_cache[regNum] &=  ~(1 << bitNum);
349
350  out_le32(BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
351  while (in_le32(BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
352
353  rtems_interrupt_enable(level);
354
355  return rval ? 1 : 0;
356}
357
358void BSP_disable_pic_irq(const rtems_irq_number irqNum)
359{
360        (void)BSP_disable_irq_at_pic(irqNum);
361}
362
363/* Use shared/irq : 2008 */
364int BSP_setup_the_pic(rtems_irq_global_settings* config) 
365{
366    int i;
367
368    BSP_config = *config;
369    default_rtems_hdl = config->defaultEntry.hdl;
370    rtems_hdl_tbl     = config->irqHdlTbl;
371
372    /* Get ready for discovery BSP */
373    BSP_irqMask_reg[0]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_CPU_INT_MASK_LO);
374    BSP_irqMask_reg[1]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_CPU_INT_MASK_HI);
375    BSP_irqCause_reg[0]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_MAIN_INT_CAUSE_LO);
376    BSP_irqCause_reg[1]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_MAIN_INT_CAUSE_HI);
377    BSP_irqMask_reg[2]= (volatile unsigned int *) (GT64x60_REG_BASE + GT_GPP_Interrupt_Mask);
378    BSP_irqCause_reg[2]= (volatile unsigned int *) (GT64x60_REG_BASE + GT_GPP_Value);
379
380    /* Page 401, Table 598:
381     * Comm Unit Arbiter Control register :
382     * bit 10:GPP interrupts as level sensitive(1) or edge sensitive(0).
383     * MOTload default is set as level sensitive(1). Set it agin to make sure.
384     */
385    out_le32(GT_CommUnitArb_Ctrl, (in_le32(GT_CommUnitArb_Ctrl)| (1<<10)));
386
387#if 0
388    printk("BSP_irqMask_reg[0] = 0x%x, BSP_irqCause_reg[0] 0x%x\n",
389           in_le32(BSP_irqMask_reg[0]),
390           in_le32(BSP_irqCause_reg[0]));
391    printk("BSP_irqMask_reg[1] = 0x%x, BSP_irqCause_reg[1] 0x%x\n",
392           in_le32(BSP_irqMask_reg[1]),
393           in_le32(BSP_irqCause_reg[1]));
394    printk("BSP_irqMask_reg[2] = 0x%x, BSP_irqCause_reg[2] 0x%x\n",
395           in_le32(BSP_irqMask_reg[2]),
396           in_le32(BSP_irqCause_reg[2]));
397#endif
398
399    /* Initialize the interrupt related  registers */
400    for (i=0; i<3; i++) {
401      out_le32(BSP_irqCause_reg[i], 0);
402      out_le32(BSP_irqMask_reg[i], 0);
403    }         
404    in_le32(BSP_irqMask_reg[2]);
405    compute_pic_masks_from_prio();
406
407#if 0
408    printk("BSP_irqMask_reg[0] = 0x%x, BSP_irqCause_reg[0] 0x%x\n",
409           in_le32(BSP_irqMask_reg[0]),
410           in_le32(BSP_irqCause_reg[0]));
411    printk("BSP_irqMask_reg[1] = 0x%x, BSP_irqCause_reg[1] 0x%x\n",
412           in_le32(BSP_irqMask_reg[1]),
413           in_le32(BSP_irqCause_reg[1]));
414    printk("BSP_irqMask_reg[2] = 0x%x, BSP_irqCause_reg[2] 0x%x\n",
415           in_le32(BSP_irqMask_reg[2]),
416           in_le32(BSP_irqCause_reg[2]));
417#endif
418
419    /*
420     *
421     */
422    for (i=BSP_MICL_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET ; i++) {
423      if ( BSP_config.irqHdlTbl[i].hdl != BSP_config.defaultEntry.hdl) {
424        BSP_enable_irq_at_pic(i);
425        BSP_config.irqHdlTbl[i].on(&BSP_config.irqHdlTbl[i]);
426      }
427      else {
428        BSP_config.irqHdlTbl[i].off(&BSP_config.irqHdlTbl[i]);
429        BSP_disable_irq_at_pic(i);
430      }
431    }
432    for (i= BSP_MAIN_GPP7_0_IRQ; i < BSP_MAIN_GPP31_24_IRQ; i++)
433      BSP_enable_irq_at_pic(i);
434   
435    return(1);
436}
437
438/*
439 * High level IRQ handler called from shared_raw_irq_code_entry
440 */
441int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
442{
443  unsigned long irqCause[3]={0, 0,0};
444  unsigned oldMask[3]={0,0,0};
445  int loop=0, i=0, j;
446  int irq=0, group=0;
447
448  if (excNum == ASM_DEC_VECTOR) {
449      bsp_irq_dispatch_list( rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_hdl);
450      return 0;   
451  }
452
453  for (j=0; j<3; j++ ) oldMask[j] = BSP_irqMask_cache[j];
454  for (j=0; j<3; j++) irqCause[j] = in_le32(BSP_irqCause_reg[j]) & in_le32(BSP_irqMask_reg[j]);
455
456  while (((irq = picPrioTable[i++])!=-1)&& (loop++ < MAX_IRQ_LOOP))
457  {   
458    if (irqCause[group= irq/32] & ( 1<<(irq % 32))) {
459      for (j=0; j<3; j++)
460        BSP_irqMask_cache[j] &= (~ BSP_irq_prio_mask_tbl[j][irq]);
461
462      out_le32(BSP_irqMask_reg[0], BSP_irqMask_cache[0]);
463      out_le32(BSP_irqMask_reg[1], BSP_irqMask_cache[1]);
464      out_le32(BSP_irqMask_reg[2], BSP_irqMask_cache[2]);
465      in_le32(BSP_irqMask_reg[2]);
466
467      bsp_irq_dispatch_list( rtems_hdl_tbl, irq, default_rtems_hdl);
468
469      for (j=0; j<3; j++ ) BSP_irqMask_cache[j] = oldMask[j];
470 
471      out_le32(BSP_irqMask_reg[0], oldMask[0]);
472      out_le32(BSP_irqMask_reg[1], oldMask[1]);
473      out_le32(BSP_irqMask_reg[2], oldMask[2]);
474      in_le32(BSP_irqMask_reg[2]);
475    }
476  }
477
478  return 0;
479}
480
481/* Only print part of the entries for now */
482void BSP_printPicIsrTbl(void)
483{
484  int i;
485
486  printf("picPrioTable[12]={ {irq# : ");
487  for (i=0; i<12; i++)
488    printf("%d,", picPrioTable[i]);
489  printf("}\n");
490
491  printf("GPPIrqInTbl: 0x%x :\n", GPPIrqInTbl);
492}
Note: See TracBrowser for help on using the repository browser.