File indexing completed on 2025-05-11 08:23:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <rtems.h>
0025 #include <rtems/libio.h>
0026
0027 #include <bsp.h>
0028 #include <libcpu/cecRegs.h>
0029 #include <libcpu/sicRegs.h>
0030 #include <string.h>
0031 #include <bsp/interrupt.h>
0032
0033 #define SIC_IAR_COUNT_SET0 4
0034 #define SIC_IAR_BASE_ADDRESS_0 0xFFC00150
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 #if INTERRUPT_USE_TABLE
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 static uint32_t sic_isr0_mask = 0;
0087
0088
0089
0090
0091
0092
0093
0094 static uint32_t sic_isr1_mask = 0;
0095
0096
0097
0098
0099
0100
0101 static struct {
0102 uint32_t mask0;
0103 uint32_t mask1;
0104 } vectors[CEC_INTERRUPT_COUNT];
0105
0106
0107
0108
0109
0110
0111 static bfin_isr_t ivt[IRQ_MAX];
0112
0113
0114
0115
0116 static const char clz_table[32] =
0117 {
0118 0, 31, 9, 30, 3, 8, 18, 29, 2, 5, 7, 14, 12, 17,
0119 22, 28, 1, 10, 4, 19, 6, 15, 13, 23, 11, 20, 16,
0120 24, 21, 25, 26, 27
0121 };
0122
0123
0124
0125
0126
0127
0128
0129 static unsigned long clz(unsigned long n)
0130 {
0131 unsigned long c = 0x7dcd629;
0132
0133 n |= (n >> 1);
0134 n |= (n >> 2);
0135 n |= (n >> 4);
0136 n |= (n >> 8);
0137 n |= (n >> 16);
0138 if (n == 0) return 32;
0139 n = c + (c * n);
0140 return 31 - clz_table[n >> 27];
0141 }
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 static rtems_isr interruptHandler(rtems_vector_number vector) {
0164 uint32_t mask = 0;
0165 int id = 0;
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177 vector -= CEC_INTERRUPT_BASE_VECTOR;
0178
0179
0180
0181
0182 if (vector >= 0 && vector < CEC_INTERRUPT_COUNT) {
0183
0184
0185
0186
0187 mask = *(uint32_t volatile *) SIC_ISR &
0188 *(uint32_t volatile *) SIC_IMASK & vectors[vector].mask0;
0189 id = clz(mask);
0190 if ( SIC_ISR0_MAX > id ) {
0191
0192 if( NULL != ivt[id].pFunc) {
0193
0194 ivt[id].pFunc( ivt[id].pArg );
0195 } else {
0196
0197
0198
0199
0200
0201 }
0202 } else {
0203
0204
0205
0206 }
0207
0208
0209
0210
0211
0212 mask = *(uint32_t volatile *) (SIC_ISR + SIC_ISR_PITCH) &
0213 *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH) &
0214 vectors[vector].mask1;
0215 id = clz(mask)+SIC_ISR0_MAX;
0216 if ( IRQ_MAX > id ) {
0217
0218 if( NULL != ivt[id].pFunc ) {
0219
0220 ivt[id].pFunc( ivt[id].pArg );
0221 } else {
0222
0223
0224
0225
0226
0227
0228 }
0229 } else {
0230
0231
0232
0233 }
0234
0235 }
0236 }
0237
0238
0239
0240
0241
0242
0243
0244
0245 rtems_status_code bfin_interrupt_register(bfin_isr_t *isr) {
0246 rtems_interrupt_level isrLevel;
0247 int id = 0;
0248 int position = 0;
0249
0250
0251
0252
0253 if ( NULL == isr ){
0254 return RTEMS_UNSATISFIED;
0255 }
0256
0257
0258
0259
0260 if ( NULL == isr->pFunc ) {
0261 return RTEMS_UNSATISFIED;
0262 }
0263
0264 id = isr->source;
0265
0266
0267
0268
0269
0270 if ( NULL != ivt[id].pFunc ) {
0271 return RTEMS_UNSATISFIED;
0272 }
0273
0274 rtems_interrupt_disable(isrLevel);
0275
0276
0277
0278 ivt[id].pFunc = isr->pFunc;
0279 ivt[id].pArg = isr->pArg;
0280
0281
0282
0283 if ( SIC_ISR0_MAX > id ) {
0284 sic_isr0_mask |= 0x1<<id;
0285 *(uint32_t volatile *) SIC_IMASK |= 0x1<<id;
0286 } else {
0287 position = id - SIC_ISR0_MAX;
0288 sic_isr1_mask |= 0x1<<position;
0289 *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH) |= 0x1<<position;
0290 }
0291
0292 rtems_interrupt_enable(isrLevel);
0293
0294 return RTEMS_SUCCESSFUL;
0295 }
0296
0297
0298
0299
0300
0301
0302 rtems_status_code bfin_interrupt_unregister(bfin_isr_t *isr) {
0303 rtems_interrupt_level isrLevel;
0304 int id = 0;
0305 int position = 0;
0306
0307
0308
0309
0310 if ( NULL == isr ){
0311 return RTEMS_UNSATISFIED;
0312 }
0313
0314 id = isr->source;
0315
0316 rtems_interrupt_disable(isrLevel);
0317
0318
0319
0320 ivt[id].pFunc = NULL;
0321 ivt[id].pArg = NULL;
0322
0323
0324
0325 if ( SIC_ISR0_MAX > id ) {
0326 sic_isr0_mask &= ~(0x1<<id);
0327 *(uint32_t volatile *) SIC_IMASK &= ~(0x1<<id);
0328 } else {
0329 position = id - SIC_ISR0_MAX;
0330 sic_isr1_mask &= ~(0x1<<position);
0331 *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH) &= ~(0x1<<position);
0332 }
0333
0334 rtems_interrupt_enable(isrLevel);
0335
0336 return RTEMS_SUCCESSFUL;
0337 }
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347 void bfin_interrupt_init(void) {
0348 int source;
0349 int vector;
0350 uint32_t r;
0351 int i;
0352 int j;
0353
0354 *(uint32_t volatile *) SIC_IMASK = 0;
0355 *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH) = 0;
0356
0357 memset(vectors, 0, sizeof(vectors));
0358
0359 source = 0;
0360
0361
0362
0363
0364
0365 for (i = 0; i < SIC_IAR_COUNT; i++) {
0366 if ( SIC_IAR_COUNT_SET0 > i ) {
0367 r = *(uint32_t volatile *) (SIC_IAR_BASE_ADDRESS + i * SIC_IAR_PITCH);
0368 } else {
0369 r = *(uint32_t volatile *) (SIC_IAR_BASE_ADDRESS_0 +
0370 ((i-SIC_IAR_COUNT_SET0) * SIC_IAR_PITCH));
0371 }
0372
0373 for (j = 0; j < 8; j++) {
0374 vector = r & 0x0f;
0375 if (vector >= 0 && vector < CEC_INTERRUPT_COUNT) {
0376
0377 if (vectors[vector].mask0 == 0 && vectors[vector].mask1 == 0){
0378 set_vector(interruptHandler, vector + CEC_INTERRUPT_BASE_VECTOR, 1);
0379 }
0380 if ( SIC_ISR0_MAX > source ) {
0381 vectors[vector].mask0 |= (1 << source);
0382 } else {
0383 vectors[vector].mask1 |= (1 << (source - SIC_ISR0_MAX));
0384 }
0385 }
0386 r >>= 4;
0387 source++;
0388 }
0389 }
0390 }
0391
0392
0393
0394
0395
0396 #else
0397
0398 static struct {
0399 uint32_t mask0;
0400 uint32_t mask1;
0401 bfin_isr_t *head;
0402 } vectors[CEC_INTERRUPT_COUNT];
0403
0404 static uint32_t globalMask0;
0405 static uint32_t globalMask1;
0406
0407 static rtems_isr interruptHandler(rtems_vector_number vector) {
0408 bfin_isr_t *isr = NULL;
0409 uint32_t sourceMask0 = 0;
0410 uint32_t sourceMask1 = 0;
0411 rtems_interrupt_level isrLevel;
0412
0413 rtems_interrupt_disable(isrLevel);
0414 vector -= CEC_INTERRUPT_BASE_VECTOR;
0415 if (vector >= 0 && vector < CEC_INTERRUPT_COUNT) {
0416 isr = vectors[vector].head;
0417 sourceMask0 = *(uint32_t volatile *) SIC_ISR &
0418 *(uint32_t volatile *) SIC_IMASK;
0419 sourceMask1 = *(uint32_t volatile *) (SIC_ISR + SIC_ISR_PITCH) &
0420 *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH);
0421 while (isr) {
0422 if ((sourceMask0 & isr->mask0) || (sourceMask1 & isr->mask1)) {
0423 isr->isr(isr->_arg);
0424 sourceMask0 = *(uint32_t volatile *) SIC_ISR &
0425 *(uint32_t volatile *) SIC_IMASK;
0426 sourceMask1 = *(uint32_t volatile *) (SIC_ISR + SIC_ISR_PITCH) &
0427 *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH);
0428 }
0429 isr = isr->next;
0430 }
0431 }
0432 rtems_interrupt_enable(isrLevel);
0433 }
0434
0435
0436
0437
0438 void bfin_interrupt_init(void) {
0439 int source;
0440 int vector;
0441 uint32_t r;
0442 int i;
0443 int j;
0444
0445 globalMask0 = ~(uint32_t) 0;
0446 globalMask1 = ~(uint32_t) 0;
0447 *(uint32_t volatile *) SIC_IMASK = 0;
0448 *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH) = 0;
0449
0450 memset(vectors, 0, sizeof(vectors));
0451
0452 source = 0;
0453
0454
0455
0456
0457
0458 for (i = 0; i < SIC_IAR_COUNT; i++) {
0459 if ( SIC_IAR_COUNT_SET0 > i ) {
0460 r = *(uint32_t volatile *) (SIC_IAR_BASE_ADDRESS + i * SIC_IAR_PITCH);
0461 } else {
0462 r = *(uint32_t volatile *) (SIC_IAR_BASE_ADDRESS_0 +
0463 ((i-SIC_IAR_COUNT_SET0) * SIC_IAR_PITCH));
0464 }
0465 for (j = 0; j < 8; j++) {
0466 vector = r & 0x0f;
0467 if (vector >= 0 && vector < CEC_INTERRUPT_COUNT) {
0468
0469 if (vectors[vector].mask0 == 0 && vectors[vector].mask1 == 0){
0470 set_vector(interruptHandler, vector + CEC_INTERRUPT_BASE_VECTOR, 1);
0471 }
0472 if ( SIC_ISR0_MAX > source ) {
0473 vectors[vector].mask0 |= (1 << source);
0474 } else {
0475 vectors[vector].mask1 |= (1 << (source - SIC_ISR0_MAX));
0476 }
0477 }
0478 r >>= 4;
0479 source++;
0480 }
0481 }
0482 }
0483
0484
0485 static void setMask(uint32_t vector) {
0486 bfin_isr_t *isr = NULL;
0487 uint32_t mask = 0;
0488 uint32_t r = 0;
0489
0490 mask = 0;
0491 isr = vectors[vector].head;
0492 while (isr) {
0493 mask |= isr->mask0;
0494 isr = isr->next;
0495 }
0496 r = *(uint32_t volatile *) SIC_IMASK;
0497 r &= ~vectors[vector].mask0;
0498 r |= mask;
0499 r &= globalMask0;
0500 *(uint32_t volatile *) SIC_IMASK = r;
0501
0502
0503 mask = 0;
0504 isr = vectors[vector].head;
0505 while (isr) {
0506 mask |= isr->mask1;
0507 isr = isr->next;
0508 }
0509 r = *(uint32_t volatile *) (SIC_IMASK+ SIC_IMASK_PITCH);
0510 r &= ~vectors[vector].mask1;
0511 r |= mask;
0512 r &= globalMask1;
0513 *(uint32_t volatile *) (SIC_IMASK+ SIC_IMASK_PITCH) = r;
0514 }
0515
0516
0517 rtems_status_code bfin_interrupt_register(bfin_isr_t *isr) {
0518 bfin_isr_t *walk;
0519 rtems_interrupt_level isrLevel;
0520
0521
0522 for (isr->vector = 0; isr->vector < CEC_INTERRUPT_COUNT; isr->vector++)
0523 if ( (vectors[isr->vector].mask0 & (1 << isr->source) ) || \
0524 (vectors[isr->vector].mask1 & (1 << (isr->source - SIC_ISR0_MAX)) ))
0525 break;
0526 if (isr->vector < CEC_INTERRUPT_COUNT) {
0527 isr->next = NULL;
0528 isr->mask0 = 0;
0529 isr->mask1 = 0;
0530 rtems_interrupt_disable(isrLevel);
0531
0532 walk = vectors[isr->vector].head;
0533 while (walk && walk->next)
0534 walk = walk->next;
0535
0536 if (walk)
0537 walk->next = isr;
0538 else
0539 vectors[isr->vector].head = isr;
0540 rtems_interrupt_enable(isrLevel);
0541 } else
0542
0543
0544 isr->vector = 0;
0545 return RTEMS_SUCCESSFUL;
0546 }
0547
0548 rtems_status_code bfin_interrupt_unregister(bfin_isr_t *isr) {
0549 bfin_isr_t *walk, *prev;
0550 rtems_interrupt_level isrLevel;
0551
0552 rtems_interrupt_disable(isrLevel);
0553 walk = vectors[isr->vector].head;
0554 prev = NULL;
0555
0556 while (walk && walk != isr) {
0557 prev = walk;
0558 walk = walk->next;
0559 }
0560 if (walk) {
0561
0562 if (prev)
0563 prev->next = walk->next;
0564 else
0565 vectors[isr->vector].head = walk->next;
0566
0567 setMask(isr->vector);
0568 }
0569 rtems_interrupt_enable(isrLevel);
0570 return RTEMS_SUCCESSFUL;
0571 }
0572
0573 void bfin_interrupt_enable(bfin_isr_t *isr, bool enable) {
0574 rtems_interrupt_level isrLevel;
0575
0576 rtems_interrupt_disable(isrLevel);
0577 if ( SIC_ISR0_MAX > isr->source ) {
0578 isr->mask0 = enable ? (1 << isr->source) : 0;
0579 *(uint32_t volatile *) SIC_IMASK |= isr->mask0;
0580 } else {
0581 isr->mask1 = enable ? (1 << (isr->source - SIC_ISR0_MAX)) : 0;
0582 *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH) |= isr->mask1;
0583 }
0584
0585
0586 rtems_interrupt_enable(isrLevel);
0587 }
0588
0589 void bfin_interrupt_enable_all(int source, bool enable) {
0590 rtems_interrupt_level isrLevel;
0591 int vector;
0592 bfin_isr_t *walk;
0593
0594 for (vector = 0; vector < CEC_INTERRUPT_COUNT; vector++)
0595 if ( (vectors[vector].mask0 & (1 << source) ) || \
0596 (vectors[vector].mask1 & (1 << (source - SIC_ISR0_MAX)) ))
0597 break;
0598 if (vector < CEC_INTERRUPT_COUNT) {
0599 rtems_interrupt_disable(isrLevel);
0600 walk = vectors[vector].head;
0601 while (walk) {
0602 walk->mask0 = enable ? (1 << source) : 0;
0603 walk = walk->next;
0604 }
0605
0606 walk = vectors[vector].head;
0607 while (walk) {
0608 walk->mask1 = enable ? (1 << (source - SIC_ISR0_MAX)) : 0;
0609 walk = walk->next;
0610 }
0611 setMask(vector);
0612 rtems_interrupt_enable(isrLevel);
0613 }
0614 }
0615
0616 void bfin_interrupt_enable_global(int source, bool enable) {
0617 int vector;
0618 rtems_interrupt_level isrLevel;
0619
0620 for (vector = 0; vector < CEC_INTERRUPT_COUNT; vector++)
0621 if ( (vectors[vector].mask0 & (1 << source) ) || \
0622 (vectors[vector].mask1 & (1 << (source - SIC_ISR0_MAX)) ))
0623 break;
0624 if (vector < CEC_INTERRUPT_COUNT) {
0625 rtems_interrupt_disable(isrLevel);
0626 if ( SIC_ISR0_MAX > source ) {
0627 if (enable)
0628 globalMask0 |= 1 << source;
0629 else
0630 globalMask0 &= ~(1 << source);
0631 }else {
0632 if (enable)
0633 globalMask1 |= 1 << (source - SIC_ISR0_MAX);
0634 else
0635 globalMask1 &= ~(1 << (source - SIC_ISR0_MAX));
0636 }
0637 setMask(vector);
0638 rtems_interrupt_enable(isrLevel);
0639 }
0640 }
0641
0642 #endif