File indexing completed on 2025-05-11 08:23:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <rtems.h>
0013 #include <rtems/libio.h>
0014
0015 #include <bsp.h>
0016 #include <libcpu/cecRegs.h>
0017 #include <libcpu/sicRegs.h>
0018 #include <string.h>
0019 #include <libcpu/interrupt.h>
0020
0021
0022 static struct {
0023 uint32_t mask;
0024 bfin_isr_t *head;
0025 } vectors[CEC_INTERRUPT_COUNT];
0026
0027 static uint32_t globalMask;
0028
0029
0030 static rtems_isr interruptHandler(rtems_vector_number vector) {
0031 bfin_isr_t *isr;
0032 uint32_t sourceMask;
0033
0034 vector -= CEC_INTERRUPT_BASE_VECTOR;
0035 if (vector >= 0 && vector < CEC_INTERRUPT_COUNT) {
0036 isr = vectors[vector].head;
0037 sourceMask = *(uint32_t volatile *) SIC_ISR &
0038 *(uint32_t volatile *) SIC_IMASK;
0039 while (isr) {
0040 if (sourceMask & isr->mask) {
0041 isr->isr(isr->source);
0042 sourceMask = *(uint32_t volatile *) SIC_ISR &
0043 *(uint32_t volatile *) SIC_IMASK;
0044 }
0045 isr = isr->next;
0046 }
0047 }
0048 }
0049
0050 void bfin_interrupt_init(void) {
0051 int source;
0052 int vector;
0053 uint32_t r;
0054 int i;
0055 int j;
0056
0057 globalMask = ~(uint32_t) 0;
0058 *(uint32_t volatile *) SIC_IMASK = 0;
0059 memset(vectors, 0, sizeof(vectors));
0060
0061 source = 0;
0062 for (i = 0; i < SIC_IAR_COUNT; i++) {
0063 r = *(uint32_t volatile *) (SIC_IAR_BASE_ADDRESS + i * SIC_IAR_PITCH);
0064 for (j = 0; j < 8; j++) {
0065 vector = r & 0x0f;
0066 if (vector >= 0 && vector < CEC_INTERRUPT_COUNT) {
0067 if (vectors[vector].mask == 0)
0068
0069 set_vector(interruptHandler, vector + CEC_INTERRUPT_BASE_VECTOR, 1);
0070 vectors[vector].mask |= (1 << source);
0071 }
0072 r >>= 4;
0073 source++;
0074 }
0075 }
0076 }
0077
0078
0079 static void setMask(int vector) {
0080 bfin_isr_t *isr;
0081 uint32_t mask;
0082 uint32_t r;
0083
0084 mask = 0;
0085 isr = vectors[vector].head;
0086 while (isr) {
0087 mask |= isr->mask;
0088 isr = isr->next;
0089 }
0090 r = *(uint32_t volatile *) SIC_IMASK;
0091 r &= ~vectors[vector].mask;
0092 r |= mask;
0093 r &= globalMask;
0094 *(uint32_t volatile *) SIC_IMASK = r;
0095 }
0096
0097
0098 void bfin_interrupt_register(bfin_isr_t *isr) {
0099 bfin_isr_t *walk;
0100 rtems_interrupt_level isrLevel;
0101
0102
0103 for (isr->vector = 0; isr->vector < CEC_INTERRUPT_COUNT; isr->vector++)
0104 if (vectors[isr->vector].mask & (1 << isr->source))
0105 break;
0106 if (isr->vector < CEC_INTERRUPT_COUNT) {
0107 isr->next = NULL;
0108 isr->mask = 0;
0109 rtems_interrupt_disable(isrLevel);
0110
0111 walk = vectors[isr->vector].head;
0112 while (walk && walk->next)
0113 walk = walk->next;
0114
0115 if (walk)
0116 walk->next = isr;
0117 else
0118 vectors[isr->vector].head = isr;
0119 rtems_interrupt_enable(isrLevel);
0120 } else
0121
0122
0123 isr->vector = 0;
0124 }
0125
0126 void bfin_interrupt_unregister(bfin_isr_t *isr) {
0127 bfin_isr_t *walk, *prev;
0128 rtems_interrupt_level isrLevel;
0129
0130 rtems_interrupt_disable(isrLevel);
0131 walk = vectors[isr->vector].head;
0132 prev = NULL;
0133
0134 while (walk && walk != isr) {
0135 prev = walk;
0136 walk = walk->next;
0137 }
0138 if (walk) {
0139
0140 if (prev)
0141 prev->next = walk->next;
0142 else
0143 vectors[isr->vector].head = walk->next;
0144
0145 setMask(isr->vector);
0146 }
0147 rtems_interrupt_enable(isrLevel);
0148 }
0149
0150 void bfin_interrupt_enable(bfin_isr_t *isr, bool enable) {
0151 rtems_interrupt_level isrLevel;
0152
0153 rtems_interrupt_disable(isrLevel);
0154 isr->mask = enable ? (1 << isr->source) : 0;
0155 setMask(isr->vector);
0156 rtems_interrupt_enable(isrLevel);
0157 }
0158
0159 void bfin_interrupt_enable_all(int source, bool enable) {
0160 rtems_interrupt_level isrLevel;
0161 int vector;
0162 bfin_isr_t *walk;
0163
0164 for (vector = 0; vector < CEC_INTERRUPT_COUNT; vector++)
0165 if (vectors[vector].mask & (1 << source))
0166 break;
0167 if (vector < CEC_INTERRUPT_COUNT) {
0168 rtems_interrupt_disable(isrLevel);
0169 walk = vectors[vector].head;
0170 while (walk) {
0171 walk->mask = enable ? (1 << source) : 0;
0172 walk = walk->next;
0173 }
0174 setMask(vector);
0175 rtems_interrupt_enable(isrLevel);
0176 }
0177 }
0178
0179 void bfin_interrupt_enable_global(int source, bool enable) {
0180 int vector;
0181 rtems_interrupt_level isrLevel;
0182
0183 for (vector = 0; vector < CEC_INTERRUPT_COUNT; vector++)
0184 if (vectors[vector].mask & (1 << source))
0185 break;
0186 if (vector < CEC_INTERRUPT_COUNT) {
0187 rtems_interrupt_disable(isrLevel);
0188 if (enable)
0189 globalMask |= 1 << source;
0190 else
0191 globalMask &= ~(1 << source);
0192 setMask(vector);
0193 rtems_interrupt_enable(isrLevel);
0194 }
0195 }
0196