File indexing completed on 2025-05-11 08:23:52
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 #include <rtems.h>
0058 #include <bsp.h>
0059 #include <bsp/irq.h>
0060 #include <bsp/gtreg.h>
0061 #include <bsp/gtintrreg.h>
0062 #include <rtems/bspIo.h>
0063 #include <bsp/vectors.h>
0064 #include <libcpu/byteorder.h>
0065 #include <libcpu/spr.h>
0066
0067
0068
0069
0070 #define MAIN_LO_IDX 0
0071 #define MAIN_HI_IDX 1
0072 #define GPP_IDX 2
0073 #define NUM_INTR_REGS 3
0074
0075
0076 #define SYNC() __asm__ volatile("sync")
0077
0078
0079
0080
0081
0082
0083 #define MAX_SPIN_LOOPS 100
0084
0085
0086
0087
0088 #define FASTER
0089
0090
0091 #define NumberOf(arr) (sizeof(arr)/sizeof((arr)[0]))
0092
0093
0094
0095
0096
0097
0098 #define MVME6100_IRQ_DEBUG 4
0099
0100 #define GPP_WIRED_OUT_BIT_6100 26
0101 #define GPP_WIRED_OUT_BIT_5500 24
0102 #define GPP_WIRED_IN_BIT 6
0103
0104
0105 #define IRQ_DEBUG_BASIC 1
0106
0107 #define IRQ_DEBUG_DISPATCHER 2
0108
0109 #define IRQ_DEBUG_MAXLAT 8
0110
0111 #define IRQ_DEBUG (0 |(MVME6100_IRQ_DEBUG)|(IRQ_DEBUG_MAXLAT))
0112
0113
0114
0115
0116
0117
0118 typedef volatile unsigned IrqMask[NUM_INTR_REGS];
0119
0120 #define REGP(x) ((volatile uint32_t *)(x))
0121
0122
0123 typedef struct _Mv64x60PicRec {
0124
0125 uintptr_t reg_base;
0126
0127
0128 volatile uint32_t *causes[NUM_INTR_REGS];
0129
0130
0131 volatile uint32_t *masks[NUM_INTR_REGS];
0132
0133
0134
0135
0136
0137
0138
0139 volatile IrqMask mcache[BSP_IRQ_MAX_PRIO+1];
0140
0141
0142
0143
0144
0145 volatile rtems_irq_prio current_priority;
0146 } Mv64x60PicRec, *Mv64x60Pic;
0147
0148
0149
0150
0151
0152
0153
0154 static rtems_irq_global_settings theConfig;
0155
0156 static Mv64x60PicRec thePic;
0157
0158 #if (IRQ_DEBUG) & MVME6100_IRQ_DEBUG
0159 static unsigned long gpp_out_bit = 0;
0160 #endif
0161
0162 #if (IRQ_DEBUG) & IRQ_DEBUG_MAXLAT
0163 unsigned long discovery_pic_max_dispatching_latency = 0;
0164 #ifdef __PPC__
0165 static inline unsigned long mftb(void)
0166 {
0167 unsigned long rval;
0168 asm volatile("mftb %0":"=r"(rval));
0169 return rval;
0170 }
0171 #else
0172 #define mftb() 0
0173 #endif
0174 #endif
0175
0176
0177
0178
0179
0180
0181 static void pregs(volatile uint32_t **p)
0182 {
0183 int i;
0184 for (i=NUM_INTR_REGS-1; i>=0; i--) {
0185 printk(" 0x%08x", ld_le32(p[i]));
0186 printk( i ? " --":"\n");
0187 }
0188 }
0189
0190 static void pmsks(volatile IrqMask p)
0191 {
0192 int i;
0193 for (i=NUM_INTR_REGS-1; i>=0; i--) {
0194 printk(" 0x%08x", p[i]);
0195 printk( i ? " --":"\n");
0196 }
0197 }
0198
0199 static void discovery_dump_picregs(void)
0200 {
0201 printk(" ..GPP_IRQ. -- ..MAIN_HI. -- ..MAIN_LO.\n");
0202 printk("Cause:"); pregs(thePic.causes);
0203 printk("Mask: "); pregs(thePic.masks);
0204 }
0205
0206
0207
0208
0209
0210
0211
0212 static inline int
0213 validIrqNo(rtems_irq_number irq)
0214 {
0215 return
0216 irq >= BSP_PCI_IRQ_LOWEST_OFFSET
0217 && irq <= BSP_PCI_IRQ_MAX_OFFSET
0218 && ! (IMH_GPP_SUM & (1<<(irq-32)));
0219 }
0220
0221
0222 static inline int
0223 validPri(rtems_irq_prio pri)
0224 {
0225
0226
0227
0228 return pri <=BSP_IRQ_MAX_PRIO;
0229 }
0230
0231
0232 static inline int
0233 __ilog2(unsigned x)
0234 {
0235 asm volatile("cntlzw %0, %0":"=&r"(x):"0"(x));
0236 return 31-x;
0237 }
0238
0239
0240
0241
0242
0243 static inline unsigned
0244 irqDiv32(unsigned irq)
0245 {
0246 return (irq-BSP_PCI_IRQ_LOWEST_OFFSET)>>5;
0247 }
0248
0249
0250
0251
0252
0253 static inline unsigned
0254 irqMod32(unsigned irq)
0255 {
0256 return (irq-BSP_PCI_IRQ_LOWEST_OFFSET)&31;
0257 }
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268 static inline void
0269 gt_bitmod(unsigned off, unsigned set, unsigned clr)
0270 {
0271 st_le32(REGP(thePic.reg_base + off),
0272 (ld_le32(REGP(thePic.reg_base+off)) & ~clr) | set);
0273 }
0274
0275 static inline unsigned
0276 gt_read(unsigned off)
0277 {
0278 return ld_le32(REGP(thePic.reg_base + off));
0279 }
0280
0281 static inline void
0282 gt_write(unsigned off, unsigned val)
0283 {
0284 st_le32(REGP(thePic.reg_base + off), val);
0285 }
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302 void
0303 BSP_enable_irq_at_pic(rtems_irq_number irq)
0304 {
0305 unsigned i,j;
0306 unsigned long flags;
0307 volatile uint32_t *p;
0308 uint32_t v,m;
0309
0310 if ( !validIrqNo(irq) ) {
0311
0312
0313
0314 return;
0315 }
0316
0317 #if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
0318 printk("IRQ: Enable #%i;",irq);
0319 #endif
0320
0321 if ( (i=irqDiv32(irq)) > NUM_INTR_REGS ) {
0322
0323 printk("BSP_enable_irq_at_pic: illegal argument\n");
0324 return;
0325 }
0326
0327 p = thePic.masks[i];
0328 m = 1<<irqMod32(irq);
0329
0330 rtems_interrupt_disable(flags);
0331 {
0332
0333 rtems_irq_prio pri = theConfig.irqPrioTbl[irq];
0334 for ( j=0; j<pri; j++ ) {
0335 thePic.mcache[j][i] |= m;
0336 }
0337 st_le32(p, (v=thePic.mcache[thePic.current_priority][i]));
0338
0339 (void)ld_le32(thePic.masks[GPP_IDX]);
0340 }
0341 SYNC();
0342 rtems_interrupt_enable(flags);
0343
0344 #if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
0345 printk(" Mask[%i]: 0x%08x -> 0x%08x\n",i,v,ld_le32(p));
0346
0347 #endif
0348 }
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364 int
0365 BSP_disable_irq_at_pic(rtems_irq_number irq)
0366 {
0367 unsigned i,j;
0368 unsigned long flags;
0369 volatile uint32_t *p;
0370 uint32_t v,m;
0371 int rval;
0372
0373 if ( !validIrqNo(irq) ) {
0374
0375
0376
0377 return -1;
0378 }
0379
0380 #if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
0381 printk("IRQ: Disable #%i;",irq);
0382 #endif
0383
0384 if ( (i=irqDiv32(irq)) > NUM_INTR_REGS ) {
0385
0386 printk("BSP_enable_irq_at_pic: illegal argument\n");
0387 return -1;
0388 }
0389
0390
0391 p = thePic.masks[i];
0392 m = (1<<irqMod32(irq));
0393
0394 rtems_interrupt_disable(flags);
0395 {
0396 rval = thePic.mcache[thePic.current_priority][i] & m;
0397 for (j=0; j<=BSP_IRQ_MAX_PRIO; j++)
0398 thePic.mcache[j][i] &= ~m;
0399 st_le32(p, (v=thePic.mcache[thePic.current_priority][i]));
0400
0401 (void)ld_le32(thePic.masks[GPP_IDX]);
0402 }
0403 SYNC();
0404 rtems_interrupt_enable(flags);
0405
0406 #if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
0407 printk(" Mask[%i]: 0x%08x -> 0x%08x\n",i,v,ld_le32(p));
0408 #endif
0409
0410 return rval ? 1 : 0;
0411 }
0412
0413 int
0414 BSP_irq_is_enabled_at_pic(rtems_irq_number irq)
0415 {
0416 unsigned i;
0417 if ( !validIrqNo(irq) ) {
0418 printk("BSP_irq_is_enabled_at_pic: Invalid argument (irq #%i)\n",irq);
0419 return -1;
0420 }
0421
0422 if ( (i=irqDiv32(irq)) > NUM_INTR_REGS ) {
0423 printk("BSP_enable_irq_at_pic: illegal argument\n");
0424 return -1;
0425 }
0426 return ld_le32(thePic.masks[i]) & (1<<irqMod32(irq)) ? 1 : 0;
0427 }
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440 int
0441 BSP_irq_set_priority(rtems_irq_number irq, rtems_irq_prio pri)
0442 {
0443 unsigned long flags;
0444 volatile uint32_t *p;
0445 uint32_t v,m;
0446 unsigned i,j;
0447
0448 if ( thePic.current_priority > 0 ) {
0449 printk("BSP_irq_set_priority: must not be called from ISR level\n");
0450 return -1;
0451 }
0452
0453 if ( !validPri(pri) ) {
0454 printk("BSP_irq_set_priority: invalid argument (pri #%i)\n",pri);
0455 return -1;
0456 }
0457
0458 if ( BSP_DECREMENTER != irq ) {
0459 if ( !validIrqNo(irq) ) {
0460 printk("BSP_irq_set_priority: invalid argument (irq #%i)\n",irq);
0461 return -1;
0462 }
0463
0464 if ( (i=irqDiv32(irq)) > NUM_INTR_REGS ) {
0465 printk("BSP_irq_set_priority: illegal argument (irq #%i not PCI?)\n", irq);
0466 return -1;
0467 }
0468 }
0469
0470 #if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
0471 printk("IRQ: Set Priority #%i -> %i;",irq,pri);
0472 #endif
0473
0474 if ( BSP_DECREMENTER == irq ) {
0475 theConfig.irqPrioTbl[irq] = pri;
0476 return 0;
0477 }
0478
0479
0480 p = thePic.masks[i];
0481 m = 1<<irqMod32(irq);
0482
0483 rtems_interrupt_disable(flags);
0484 {
0485 for (j=0; j<=BSP_IRQ_MAX_PRIO; j++) {
0486 if ( j<pri )
0487 thePic.mcache[j][i] |= m;
0488 else
0489 thePic.mcache[j][i] &= ~m;
0490 }
0491 theConfig.irqPrioTbl[irq] = pri;
0492 st_le32(p, (v=thePic.mcache[thePic.current_priority][i]));
0493
0494 (void)ld_le32(thePic.masks[GPP_IDX]);
0495 }
0496 SYNC();
0497 rtems_interrupt_enable(flags);
0498
0499 #if (IRQ_DEBUG) & IRQ_DEBUG_BASIC
0500 printk(" Mask[%i]: 0x%08x -> 0x%08x\n",i,v,ld_le32(p));
0501 #endif
0502
0503 return 0;
0504 }
0505
0506
0507
0508
0509
0510 int
0511 BSP_setup_the_pic(rtems_irq_global_settings* config)
0512 {
0513 int i;
0514
0515
0516
0517 theConfig = *config;
0518
0519
0520 if ( theConfig.irqNb <= BSP_PCI_IRQ_MAX_OFFSET ) {
0521 printk("BSP_setup_the_pic: FATAL ERROR: configured IRQ table too small???\n");
0522 return 0;
0523 }
0524
0525 for ( i=0; i<theConfig.irqNb; i++ ) {
0526 if ( !validPri(theConfig.irqPrioTbl[i]) ) {
0527 printk("BSP_setup_the_pic: invalid priority (%i) for irg #%i; setting to 1\n", theConfig.irqPrioTbl[i], i);
0528 theConfig.irqPrioTbl[i]=1;
0529 }
0530 }
0531
0532
0533 thePic.reg_base = BSP_MV64x60_BASE;
0534
0535 thePic.current_priority = 0;
0536
0537 #if (IRQ_DEBUG) & MVME6100_IRQ_DEBUG
0538 #endif
0539
0540 switch ( BSP_getDiscoveryVersion( 1) ) {
0541 case MV_64360:
0542 thePic.causes[MAIN_LO_IDX] = REGP(thePic.reg_base + ICR_360_MIC_LO);
0543 thePic.causes[MAIN_HI_IDX] = REGP(thePic.reg_base + ICR_360_MIC_HI);
0544 thePic.masks[MAIN_LO_IDX] = REGP(thePic.reg_base + ICR_360_C0IM_LO);
0545 thePic.masks[MAIN_HI_IDX] = REGP(thePic.reg_base + ICR_360_C0IM_HI);
0546 break;
0547
0548 case GT_64260_A:
0549 case GT_64260_B:
0550 thePic.causes[MAIN_LO_IDX] = REGP(thePic.reg_base + ICR_260_MIC_LO);
0551 thePic.causes[MAIN_HI_IDX] = REGP(thePic.reg_base + ICR_260_MIC_HI);
0552 thePic.masks[MAIN_LO_IDX] = REGP(thePic.reg_base + ICR_260_CIM_LO);
0553 thePic.masks[MAIN_HI_IDX] = REGP(thePic.reg_base + ICR_260_CIM_HI);
0554 break;
0555
0556 default:
0557 rtems_panic("Unable to initialize interrupt controller; unknown chip");
0558 break;
0559 }
0560
0561 thePic.causes[GPP_IDX] = REGP(thePic.reg_base + GT_GPP_Interrupt_Cause);
0562 thePic.masks[GPP_IDX] = REGP(thePic.reg_base + GT_GPP_Interrupt_Mask);
0563
0564
0565 for ( i=0; i<=BSP_IRQ_MAX_PRIO; i++ ) {
0566 thePic.mcache[i][MAIN_LO_IDX] = 0;
0567
0568
0569
0570 thePic.mcache[i][MAIN_HI_IDX] = IMH_GPP_SUM;
0571 thePic.mcache[i][GPP_IDX] = 0;
0572 }
0573
0574
0575 for ( i=0; i<NUM_INTR_REGS; i++ ) {
0576 st_le32(thePic.causes[i], 0);
0577 st_le32(thePic.masks[i], 0);
0578 }
0579
0580
0581 gt_bitmod(
0582 GT_CommUnitArb_Ctrl,
0583 GT_CommUnitArb_Ctrl_GPP_Ints_Level_Sensitive,
0584 0);
0585
0586
0587 st_le32(thePic.masks[MAIN_LO_IDX], thePic.mcache[thePic.current_priority][MAIN_LO_IDX]);
0588 st_le32(thePic.masks[MAIN_HI_IDX], thePic.mcache[thePic.current_priority][MAIN_HI_IDX]);
0589 st_le32(thePic.masks[GPP_IDX ], thePic.mcache[thePic.current_priority][GPP_IDX ]);
0590
0591
0592
0593
0594
0595
0596
0597
0598 for ( i=BSP_PCI_IRQ_LOWEST_OFFSET; i<=BSP_PCI_IRQ_MAX_OFFSET; i++ ) {
0599 if ( theConfig.irqHdlTbl[i].hdl != theConfig.defaultEntry.hdl ) {
0600 BSP_enable_irq_at_pic(i);
0601 }
0602 }
0603
0604 return 1;
0605 }
0606
0607 int discovery_pic_max_loops = 0;
0608
0609
0610
0611
0612
0613
0614
0615
0616 static inline rtems_irq_prio
0617 change_executing_prio_level(rtems_irq_prio pri)
0618 {
0619 register rtems_irq_prio rval = thePic.current_priority;
0620 thePic.current_priority = pri;
0621 st_le32(thePic.masks[MAIN_LO_IDX], thePic.mcache[pri][MAIN_LO_IDX]);
0622 st_le32(thePic.masks[MAIN_HI_IDX], thePic.mcache[pri][MAIN_HI_IDX]);
0623 st_le32(thePic.masks[GPP_IDX ], thePic.mcache[pri][GPP_IDX ]);
0624
0625 (void)ld_le32(thePic.masks[GPP_IDX]);
0626 return rval;
0627 }
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658 static unsigned mlc, mhc, gpc;
0659
0660 static int decrementerPending = 0;
0661 #if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0662 int decrementerIrqs = 0;
0663 #endif
0664
0665 static inline unsigned
0666 find_highest_priority_pending_irq(rtems_irq_prio *ppri)
0667 {
0668 register int rval = -1;
0669 register rtems_irq_prio *pt = theConfig.irqPrioTbl + BSP_PCI_IRQ_LOWEST_OFFSET;
0670 register rtems_irq_prio pmax = *ppri;
0671 register unsigned cse,ocse;
0672
0673 #if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0674 discovery_dump_picregs();
0675 #endif
0676
0677 if ( decrementerPending ) {
0678
0679
0680
0681
0682
0683 if ( theConfig.irqPrioTbl[BSP_DECREMENTER] > pmax ) {
0684 pmax = theConfig.irqPrioTbl[BSP_DECREMENTER];
0685 rval = BSP_DECREMENTER;
0686 }
0687 }
0688
0689 mlc = cse = ld_le32(thePic.causes[MAIN_LO_IDX]);
0690 #if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0691 printk("MAIN_LO; cse: 0x%08x, msk 0x%08x\n", cse ,thePic.mcache[pmax][MAIN_LO_IDX]);
0692 #endif
0693 while ( cse &= thePic.mcache[pmax][MAIN_LO_IDX] ) {
0694 rval = __ilog2(cse);
0695 pmax = pt[rval];
0696 #if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0697 printk("Max pri IRQ now %i\n",rval);
0698 #endif
0699 }
0700 mhc = cse = ocse = ld_le32(thePic.causes[MAIN_HI_IDX]);
0701 #if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0702 printk("MAIN_HI; cse: 0x%08x, msk 0x%08x\n", cse, thePic.mcache[pmax][MAIN_HI_IDX]);
0703 #endif
0704
0705 cse &= ~IMH_GPP_SUM;
0706 while ( cse &= thePic.mcache[pmax][MAIN_HI_IDX] ) {
0707 rval = __ilog2(cse) + 32;
0708 pmax = pt[rval];
0709 #if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0710 printk("Max pri IRQ now %i\n",rval);
0711 #endif
0712 }
0713 gpc = cse = ld_le32(thePic.causes[GPP_IDX ]);
0714
0715 if ( ocse & IMH_GPP_SUM ) {
0716 #if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0717 printk("GPP; cse: 0x%08x, msk 0x%08x\n", cse, thePic.mcache[pmax][GPP_IDX ]);
0718 #endif
0719 cse &= thePic.mcache[pmax][GPP_IDX ];
0720 ocse = cse;
0721 while ( cse ) {
0722 rval = __ilog2(cse) + 64;
0723 pmax = pt[rval];
0724 cse &= thePic.mcache[pmax][GPP_IDX ];
0725 #if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0726 printk("Max pri IRQ now %i\n",rval);
0727 #endif
0728 }
0729 #ifndef FASTER
0730
0731 out_le32(thePic.causes[GPP_IDX], ~ocse);
0732 #endif
0733 }
0734 #ifndef FASTER
0735
0736 (void)in_le32(thePic.causes[GPP_IDX]);
0737 #endif
0738
0739 *ppri = pmax;
0740
0741 if ( BSP_DECREMENTER == rval ) {
0742 #if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0743 decrementerIrqs++;
0744 #endif
0745 decrementerPending = 0;
0746 }
0747
0748 return rval;
0749 }
0750
0751 #if 0
0752 #define _IRQ_DEBUG IRQ_DEBUG_DISPATCHER
0753 static inline unsigned
0754 ffind_highest_priority_pending_irq(rtems_irq_prio *ppri)
0755 {
0756 register int rval = -1;
0757 register rtems_irq_prio *pt = theConfig.irqPrioTbl + BSP_PCI_IRQ_LOWEST_OFFSET;
0758 register rtems_irq_prio pmax = *ppri;
0759 register unsigned cse,ocse;
0760
0761 #if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0762 discovery_dump_picregs();
0763 #endif
0764
0765 cse = in_le32(thePic.causes[MAIN_LO_IDX]);
0766 #if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0767 printk("MAIN_LO; cse: 0x%08x, msk 0x%08x\n", cse ,thePic.mcache[pmax][MAIN_LO_IDX]);
0768 #endif
0769 while ( cse &= thePic.mcache[pmax][MAIN_LO_IDX] ) {
0770 rval = __ilog2(cse);
0771 pmax = pt[rval];
0772 #if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0773 printk("Max pri IRQ now %i\n",rval);
0774 #endif
0775 }
0776 cse = ocse = in_le32(thePic.causes[MAIN_HI_IDX]);
0777 #if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0778 printk("MAIN_HI; cse: 0x%08x, msk 0x%08x\n", cse, thePic.mcache[pmax][MAIN_HI_IDX]);
0779 #endif
0780
0781 cse &= ~IMH_GPP_SUM;
0782 while ( cse &= thePic.mcache[pmax][MAIN_HI_IDX] ) {
0783 rval = __ilog2(cse) + 32;
0784 pmax = pt[rval];
0785 #if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0786 printk("Max pri IRQ now %i\n",rval);
0787 #endif
0788 }
0789
0790 if ( ocse & IMH_GPP_SUM ) {
0791 cse = in_le32(thePic.causes[GPP_IDX ]);
0792 #if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0793 printk("GPP; cse: 0x%08x, msk 0x%08x\n", cse, thePic.mcache[pmax][GPP_IDX ]);
0794 #endif
0795 cse &= thePic.mcache[pmax][GPP_IDX ];
0796 ocse = cse;
0797 while ( cse ) {
0798 rval = __ilog2(cse) + 64;
0799 pmax = pt[rval];
0800 cse &= thePic.mcache[pmax][GPP_IDX ];
0801 #if (_IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0802 printk("Max pri IRQ now %i\n",rval);
0803 #endif
0804 }
0805
0806 out_le32(thePic.causes[GPP_IDX], ~ocse);
0807 }
0808
0809 (void)in_le32(thePic.causes[GPP_IDX]);
0810
0811 *ppri = pmax;
0812 return rval;
0813 }
0814 #endif
0815
0816
0817
0818
0819
0820 int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
0821 {
0822 register int irq;
0823 int loop, last_irq;
0824 rtems_irq_prio pri;
0825 #if (IRQ_DEBUG) & IRQ_DEBUG_MAXLAT
0826 unsigned long diff;
0827 #endif
0828
0829 #if (IRQ_DEBUG) & IRQ_DEBUG_MAXLAT
0830 diff = mftb();
0831 #endif
0832
0833 if (excNum == ASM_DEC_VECTOR) {
0834 decrementerPending = 1;
0835 }
0836
0837
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848 for ( loop=0, last_irq=-1, pri = thePic.current_priority;
0849 (irq=find_highest_priority_pending_irq(&pri)) >=0;
0850 loop++, last_irq = irq ) {
0851
0852
0853 pri = change_executing_prio_level(pri);
0854
0855 SYNC();
0856
0857 #if (IRQ_DEBUG) & IRQ_DEBUG_MAXLAT
0858 if ( 0 == loop ) {
0859 diff = mftb()-diff;
0860 if ( diff > discovery_pic_max_dispatching_latency )
0861 discovery_pic_max_dispatching_latency = diff;
0862 }
0863 #endif
0864
0865 #if (IRQ_DEBUG) & IRQ_DEBUG_DISPATCHER
0866 if ( BSP_DECREMENTER == irq ) {
0867 printk("IRQ: dispatching DECREMENTER\n");
0868 } else {
0869 int idx = irqDiv32(irq);
0870 printk("IRQ: dispatching #%i; causes[%i]=0x%08x\n", irq, idx, ld_le32(thePic.causes[idx]));
0871 }
0872 #endif
0873
0874 bsp_irq_dispatch_list( theConfig.irqHdlTbl, irq, theConfig.defaultEntry.hdl );
0875
0876
0877 (void)change_executing_prio_level(pri);
0878
0879 if ( (loop > MAX_SPIN_LOOPS) && (last_irq == irq) ) {
0880
0881
0882
0883
0884 printk("Runaway IRQ #%i; disabling\n", irq);
0885 BSP_disable_irq_at_pic(irq);
0886 loop = 0;
0887 }
0888 }
0889
0890 if (!loop) {
0891 if ( decrementerPending && pri >= theConfig.irqPrioTbl[BSP_DECREMENTER] ) {
0892
0893
0894
0895
0896
0897
0898
0899
0900 } else {
0901 printk("Discovery: Spurious interrupt; causes were gpp: 0x%x, mhc: 0x%x, mlc: 0x%x\n", gpc, mhc, mlc);
0902 printk("Current priority level %i, decrementerPending %i\n", pri, decrementerPending);
0903 {
0904 rtems_irq_prio p=pri;
0905 printk("PIC register dump:\n");
0906 discovery_dump_picregs();
0907 printk("Current Priority: %i, found %i\n",pri,find_highest_priority_pending_irq(&p));
0908 discovery_dump_picregs();
0909 for (p=0; p<=BSP_IRQ_MAX_PRIO; p++) {
0910 printk("M[%i] :",p);pmsks(thePic.mcache[p]);
0911 }
0912 }
0913 }
0914 }
0915 else if (loop>discovery_pic_max_loops)
0916 discovery_pic_max_loops = loop;
0917
0918 return 0;
0919 }
0920
0921
0922 #if (IRQ_DEBUG) & MVME6100_IRQ_DEBUG
0923 void
0924 discovery_pic_install_debug_irq(void)
0925 {
0926 switch ( BSP_getBoardType() ) {
0927 case MVME6100: gpp_out_bit = GPP_WIRED_OUT_BIT_6100; break;
0928 case MVME5500: gpp_out_bit = GPP_WIRED_OUT_BIT_5500; break;
0929 default:
0930 gpp_out_bit = 0; break;
0931 break;
0932 }
0933 if ( gpp_out_bit ) {
0934 unsigned mppoff;
0935 switch (gpp_out_bit / 8) {
0936 default:
0937 case 0: mppoff = GT_MPP_Control0; break;
0938 case 1: mppoff = GT_MPP_Control1; break;
0939 case 2: mppoff = GT_MPP_Control2; break;
0940 case 3: mppoff = GT_MPP_Control3; break;
0941 }
0942
0943
0944
0945
0946 gt_bitmod(mppoff, 0, (0xf<<(4*(gpp_out_bit % 8))));
0947
0948
0949 gt_bitmod(GT_GPP_IO_Control, (1<<gpp_out_bit), 0);
0950
0951
0952 gt_bitmod(GT_GPP_Level_Control, 0, (1<<GPP_WIRED_IN_BIT) | (1<<gpp_out_bit));
0953
0954
0955 gt_bitmod(GT_GPP_Value, 0, 1<<gpp_out_bit);
0956
0957 printk("GPP levelctl now 0x%08x\n", gt_read(GT_GPP_Level_Control));
0958 printk("GPP value now 0x%08x\n", gt_read(GT_GPP_Value));
0959 printk("MPP ctl 0 now 0x%08x\n", gt_read(GT_MPP_Control0));
0960 printk("MPP ctl 1 now 0x%08x\n", gt_read(GT_MPP_Control1));
0961 printk("MPP ctl 2 now 0x%08x\n", gt_read(GT_MPP_Control2));
0962 printk("MPP ctl 3 now 0x%08x\n", gt_read(GT_MPP_Control3));
0963
0964 }
0965 }
0966
0967
0968
0969
0970 void
0971 discovery_pic_set_debug_irq(int on)
0972 {
0973 unsigned long flags, clr;
0974 if ( !gpp_out_bit ) {
0975 printk("discovery_pic_set_debug_irq(): unknown wire output\n");
0976 return;
0977 }
0978 if (on) {
0979 on = 1<<gpp_out_bit;
0980 clr = 0;
0981 } else {
0982 clr = 1<<gpp_out_bit;
0983 on = 0;
0984 }
0985 rtems_interrupt_disable(flags);
0986 gt_bitmod(GT_GPP_Value, on, clr);
0987 rtems_interrupt_enable(flags);
0988 }
0989 #endif
0990
0991 #if 0
0992
0993 #endif