File indexing completed on 2025-05-11 08:23:57
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 #include <inttypes.h>
0031 #include <stdio.h>
0032 #include <bsp.h>
0033 #include <bsp/irq.h>
0034 #include <rtems/score/thread.h>
0035 #include <rtems/rtems/intr.h>
0036 #include <libcpu/io.h>
0037 #include <libcpu/byteorder.h>
0038 #include <bsp/vectors.h>
0039
0040 #include <rtems/bspIo.h> /* for printk */
0041 #include "bsp/gtreg.h"
0042
0043 #define HI_INT_CAUSE 0x40000000
0044
0045 #define MAX_IRQ_LOOP 20
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 static unsigned int BSP_irq_prio_mask_tbl[3][BSP_PIC_IRQ_NUMBER];
0058
0059
0060
0061
0062
0063 static rtems_irq_global_settings BSP_config;
0064 static rtems_irq_connect_data* rtems_hdl_tbl;
0065
0066
0067
0068
0069
0070 void (*default_rtems_hdl)(rtems_irq_hdl_param) = (void(*)(rtems_irq_hdl_param)) -1;
0071
0072
0073 static volatile unsigned *BSP_irqMask_reg[3];
0074 static volatile unsigned *BSP_irqCause_reg[3];
0075 static volatile unsigned BSP_irqMask_cache[3]={0,0,0};
0076
0077 static int picPrioTblPtr=0;
0078 static unsigned int GPPIrqInTbl=0;
0079 static unsigned long long MainIrqInTbl=0;
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 #define DynamicIsrTable
0101 #ifdef DynamicIsrTable
0102
0103 static unsigned int picPrioTable[BSP_PIC_IRQ_NUMBER]={
0104 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0105 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0106 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0107 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0108 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0109 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0110 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0111 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0112 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0113 -1, -1, -1, -1, -1, -1 };
0114 #else
0115 static unsigned int picPrioTable[BSP_PIC_IRQ_NUMBER]={
0116 80, 84, 76, 77, 32, -1, -1, -1, -1, -1,
0117 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0118 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0119 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0120 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0121 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0122 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0123 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0124 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0125 -1, -1, -1, -1, -1, -1 };
0126 #endif
0127
0128
0129
0130
0131 static inline int is_pic_irq(const rtems_irq_number irqLine)
0132 {
0133 return (((int) irqLine <= BSP_GPP_IRQ_MAX_OFFSET) &
0134 ((int) irqLine >= BSP_MICL_IRQ_LOWEST_OFFSET)
0135 );
0136 }
0137
0138
0139
0140
0141 static inline int is_processor_irq(const rtems_irq_number irqLine)
0142 {
0143 return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) &
0144 ((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)
0145 );
0146 }
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 static void compute_pic_masks_from_prio(void)
0158 {
0159 int i,j, k, isGppMain;
0160 unsigned long long irq_prio_mask=0;
0161
0162
0163
0164
0165 for (i=0; i <BSP_PIC_IRQ_NUMBER; i++) {
0166 switch(i) {
0167 case BSP_MAIN_GPP7_0_IRQ:
0168 case BSP_MAIN_GPP15_8_IRQ:
0169 case BSP_MAIN_GPP23_16_IRQ:
0170 case BSP_MAIN_GPP31_24_IRQ:
0171 for (k=0; k< 3; k++)
0172 BSP_irq_prio_mask_tbl[k][i]=0;
0173
0174 irq_prio_mask =0;
0175 isGppMain =1;
0176 break;
0177 default :
0178 isGppMain =0;
0179 irq_prio_mask = (unsigned long long) (1LLU << i);
0180 break;
0181 }
0182 if ( isGppMain) continue;
0183 for (j = 0; j <BSP_MAIN_IRQ_NUMBER; j++) {
0184
0185
0186
0187
0188 if (BSP_config.irqPrioTbl [i] >= BSP_config.irqPrioTbl [j])
0189 irq_prio_mask |= (unsigned long long)(1LLU << j);
0190 }
0191
0192
0193 BSP_irq_prio_mask_tbl[0][i] = irq_prio_mask & 0xffffffff;
0194 BSP_irq_prio_mask_tbl[1][i] = (irq_prio_mask>>32) & 0xffffffff;
0195 #if 0
0196 printk("irq_mask_prio_tbl[%d]:0x%8x%8x\n",i,BSP_irq_prio_mask_tbl[1][i],
0197 BSP_irq_prio_mask_tbl[0][i]);
0198 #endif
0199
0200 BSP_irq_prio_mask_tbl[2][i] = 1<<i;
0201
0202 for (j=BSP_GPP_IRQ_LOWEST_OFFSET; j <BSP_PROCESSOR_IRQ_LOWEST_OFFSET; j++) {
0203 if (BSP_config.irqPrioTbl [i] >= BSP_config.irqPrioTbl [j])
0204 BSP_irq_prio_mask_tbl[2][i] |= 1 << (j-BSP_GPP_IRQ_LOWEST_OFFSET);
0205 }
0206 #if 0
0207 printk("GPPirq_mask_prio_tbl[%d]:0x%8x\n",i,BSP_irq_prio_mask_tbl[2][i]);
0208 #endif
0209 }
0210 }
0211
0212 static void UpdateMainIrqTbl(int irqNum)
0213 {
0214 int i=0, j, shifted=0;
0215
0216 switch (irqNum) {
0217 case BSP_MAIN_GPP7_0_IRQ:
0218 case BSP_MAIN_GPP15_8_IRQ:
0219 case BSP_MAIN_GPP23_16_IRQ:
0220 case BSP_MAIN_GPP31_24_IRQ:
0221 return;
0222 break;
0223 }
0224 #ifdef SHOW_MORE_INIT_SETTINGS
0225 unsigned long val2, val1;
0226 #endif
0227
0228
0229 if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
0230 (!((unsigned long long)(1LLU << irqNum) & MainIrqInTbl))) ||
0231 ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
0232 (!(( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl))))
0233 {
0234 while ( picPrioTable[i]!=-1) {
0235 if (BSP_config.irqPrioTbl[irqNum]>BSP_config.irqPrioTbl[picPrioTable[i]]) {
0236
0237 for (j=picPrioTblPtr;j>i; j--) {
0238 picPrioTable[j]=picPrioTable[j-1];
0239 }
0240 picPrioTable[i]=irqNum;
0241 shifted=1;
0242 break;
0243 }
0244 i++;
0245 }
0246 if (!shifted) picPrioTable[picPrioTblPtr] =irqNum;
0247
0248 if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
0249 GPPIrqInTbl |= (1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
0250 else
0251 MainIrqInTbl |= (unsigned long long)(1LLU << irqNum);
0252 picPrioTblPtr++;
0253 }
0254 #ifdef SHOW_MORE_INIT_SETTINGS
0255 val2 = (MainIrqInTbl>>32) & 0xffffffff;
0256 val1 = MainIrqInTbl&0xffffffff;
0257 printk("irqNum %d, MainIrqInTbl 0x%x%x\n", irqNum, val2, val1);
0258 BSP_printPicIsrTbl();
0259 #endif
0260
0261 }
0262
0263
0264 static void CleanMainIrqTbl(int irqNum)
0265 {
0266 int i, j;
0267
0268 switch (irqNum) {
0269 case BSP_MAIN_GPP7_0_IRQ:
0270 case BSP_MAIN_GPP15_8_IRQ:
0271 case BSP_MAIN_GPP23_16_IRQ:
0272 case BSP_MAIN_GPP31_24_IRQ:
0273 return;
0274 break;
0275 }
0276 if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
0277 ((unsigned long long)(1LLU << irqNum) & MainIrqInTbl)) ||
0278 ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
0279 (( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl)))
0280 {
0281 for (i=0; i<64; i++) {
0282 if (picPrioTable[i]==irqNum) {
0283
0284 for (j=i;j<picPrioTblPtr; j++) {
0285 picPrioTable[j]=picPrioTable[j+1];
0286 }
0287 if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
0288 GPPIrqInTbl &= ~(1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
0289 else
0290 MainIrqInTbl &= ~(1LLU << irqNum);
0291 picPrioTblPtr--;
0292 break;
0293 }
0294 }
0295 }
0296 }
0297
0298 void BSP_enable_irq_at_pic(const rtems_irq_number irqNum)
0299 {
0300 unsigned bitNum, regNum;
0301 unsigned int level;
0302
0303 if ( !is_pic_irq(irqNum) )
0304 return;
0305
0306 bitNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)%32;
0307 regNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)>>5;
0308
0309 rtems_interrupt_disable(level);
0310
0311 #ifdef DynamicIsrTable
0312 UpdateMainIrqTbl((int) irqNum);
0313 #endif
0314 BSP_irqMask_cache[regNum] |= (1 << bitNum);
0315
0316 out_le32((volatile uint32_t *)BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
0317 while (in_le32((volatile uint32_t *)BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
0318
0319 rtems_interrupt_enable(level);
0320 }
0321
0322 int BSP_disable_irq_at_pic(const rtems_irq_number irqNum)
0323 {
0324 int rval;
0325 unsigned bitNum, regNum;
0326 unsigned int level;
0327
0328 if ( ! is_pic_irq(irqNum) )
0329 return -1;
0330
0331 bitNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)%32;
0332 regNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)>>5;
0333
0334 rtems_interrupt_disable(level);
0335
0336 #ifdef DynamicIsrTable
0337 CleanMainIrqTbl((int) irqNum);
0338 #endif
0339
0340 rval = BSP_irqMask_cache[regNum] & (1<<bitNum);
0341
0342 BSP_irqMask_cache[regNum] &= ~(1 << bitNum);
0343
0344 out_le32((volatile uint32_t *)BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
0345 while (in_le32((volatile uint32_t *)BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
0346
0347 rtems_interrupt_enable(level);
0348
0349 return rval ? 1 : 0;
0350 }
0351
0352
0353 int BSP_setup_the_pic(rtems_irq_global_settings* config)
0354 {
0355 int i;
0356
0357 BSP_config = *config;
0358 default_rtems_hdl = config->defaultEntry.hdl;
0359 rtems_hdl_tbl = config->irqHdlTbl;
0360
0361
0362 BSP_irqMask_reg[0]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_CPU_INT_MASK_LO);
0363 BSP_irqMask_reg[1]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_CPU_INT_MASK_HI);
0364 BSP_irqCause_reg[0]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_MAIN_INT_CAUSE_LO);
0365 BSP_irqCause_reg[1]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_MAIN_INT_CAUSE_HI);
0366 BSP_irqMask_reg[2]= (volatile unsigned int *) (GT64x60_REG_BASE + GT_GPP_Interrupt_Mask);
0367 BSP_irqCause_reg[2]= (volatile unsigned int *) (GT64x60_REG_BASE + GT_GPP_Value);
0368
0369
0370
0371
0372
0373
0374 out_le32((volatile uint32_t *)GT_CommUnitArb_Ctrl,
0375 (in_le32((volatile uint32_t *)GT_CommUnitArb_Ctrl)| (1<<10)));
0376
0377 #if 0
0378 printk("BSP_irqMask_reg[0] = 0x%" PRIx32 ", BSP_irqCause_reg[0] 0x%" PRIx32 "\n",
0379 in_le32((volatile uint32_t *)BSP_irqMask_reg[0]),
0380 in_le32((volatile uint32_t *)BSP_irqCause_reg[0]));
0381 printk("BSP_irqMask_reg[1] = 0x%" PRIx32 ", BSP_irqCause_reg[1] 0x%" PRIx32 "\n",
0382 in_le32((volatile uint32_t *)BSP_irqMask_reg[1]),
0383 in_le32((volatile uint32_t *)BSP_irqCause_reg[1]));
0384 printk("BSP_irqMask_reg[2] = 0x%" PRIx32 ", BSP_irqCause_reg[2] 0x%" PRIx32 "\n",
0385 in_le32((volatile uint32_t *)BSP_irqMask_reg[2]),
0386 in_le32((volatile uint32_t *)BSP_irqCause_reg[2]));
0387 #endif
0388
0389
0390 for (i=0; i<3; i++) {
0391 out_le32((volatile uint32_t *)BSP_irqCause_reg[i], 0);
0392 out_le32((volatile uint32_t *)BSP_irqMask_reg[i], 0);
0393 }
0394 in_le32((volatile uint32_t *)BSP_irqMask_reg[2]);
0395 compute_pic_masks_from_prio();
0396
0397 #if 0
0398 printk("BSP_irqMask_reg[0] = 0x%" PRIx32 ", BSP_irqCause_reg[0] 0x%" PRIx32 "\n",
0399 in_le32((volatile uint32_t *)BSP_irqMask_reg[0]),
0400 in_le32((volatile uint32_t *)BSP_irqCause_reg[0]));
0401 printk("BSP_irqMask_reg[1] = 0x%" PRIx32 ", BSP_irqCause_reg[1] 0x%" PRIx32 "\n",
0402 in_le32((volatile uint32_t *)BSP_irqMask_reg[1]),
0403 in_le32((volatile uint32_t *)BSP_irqCause_reg[1]));
0404 printk("BSP_irqMask_reg[2] = 0x%" PRIx32 ", BSP_irqCause_reg[2] 0x%" PRIx32 "\n",
0405 in_le32((volatile uint32_t *)BSP_irqMask_reg[2]),
0406 in_le32((volatile uint32_t *)BSP_irqCause_reg[2]));
0407 #endif
0408
0409
0410
0411
0412 for (i=BSP_MICL_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET ; i++) {
0413 if ( BSP_config.irqHdlTbl[i].hdl != BSP_config.defaultEntry.hdl) {
0414 BSP_enable_irq_at_pic(i);
0415 BSP_config.irqHdlTbl[i].on(&BSP_config.irqHdlTbl[i]);
0416 }
0417 else {
0418 BSP_config.irqHdlTbl[i].off(&BSP_config.irqHdlTbl[i]);
0419 BSP_disable_irq_at_pic(i);
0420 }
0421 }
0422 for (i= BSP_MAIN_GPP7_0_IRQ; i < BSP_MAIN_GPP31_24_IRQ; i++)
0423 BSP_enable_irq_at_pic(i);
0424
0425 return(1);
0426 }
0427
0428
0429
0430
0431 int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
0432 {
0433 unsigned long irqCause[3]={0, 0,0};
0434 unsigned oldMask[3]={0,0,0};
0435 int loop=0, i=0, j;
0436 int irq=0, group=0;
0437
0438 if (excNum == ASM_DEC_VECTOR) {
0439 bsp_irq_dispatch_list( rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_hdl);
0440 return 0;
0441 }
0442
0443 for (j=0; j<3; j++ ) oldMask[j] = BSP_irqMask_cache[j];
0444 for (j=0; j<3; j++) irqCause[j] = in_le32((volatile uint32_t *)BSP_irqCause_reg[j]) & in_le32((volatile uint32_t *)BSP_irqMask_reg[j]);
0445
0446 while (((irq = picPrioTable[i++])!=-1)&& (loop++ < MAX_IRQ_LOOP))
0447 {
0448 if (irqCause[group= irq/32] & ( 1<<(irq % 32))) {
0449 for (j=0; j<3; j++)
0450 BSP_irqMask_cache[j] &= (~ BSP_irq_prio_mask_tbl[j][irq]);
0451
0452 out_le32((volatile uint32_t *)BSP_irqMask_reg[0], BSP_irqMask_cache[0]);
0453 out_le32((volatile uint32_t *)BSP_irqMask_reg[1], BSP_irqMask_cache[1]);
0454 out_le32((volatile uint32_t *)BSP_irqMask_reg[2], BSP_irqMask_cache[2]);
0455 in_le32((volatile uint32_t *)BSP_irqMask_reg[2]);
0456
0457 bsp_irq_dispatch_list( rtems_hdl_tbl, irq, default_rtems_hdl);
0458
0459 for (j=0; j<3; j++ ) BSP_irqMask_cache[j] = oldMask[j];
0460
0461 out_le32((volatile uint32_t *)BSP_irqMask_reg[0], oldMask[0]);
0462 out_le32((volatile uint32_t *)BSP_irqMask_reg[1], oldMask[1]);
0463 out_le32((volatile uint32_t *)BSP_irqMask_reg[2], oldMask[2]);
0464 in_le32((volatile uint32_t *)BSP_irqMask_reg[2]);
0465 }
0466 }
0467
0468 return 0;
0469 }
0470
0471
0472 void BSP_printPicIsrTbl(void)
0473 {
0474 int i;
0475
0476 printf("picPrioTable[12]={ {irq# : ");
0477 for (i=0; i<12; i++)
0478 printf("%d,", picPrioTable[i]);
0479 printf("}\n");
0480
0481 printf("GPPIrqInTbl: 0x%x :\n", GPPIrqInTbl);
0482 }