File indexing completed on 2025-05-11 08:23:39
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 #include <bsp.h>
0044 #include <bsp/irq-generic.h>
0045 #include <bsp/tms570.h>
0046 #include <bsp/irq.h>
0047 #include <rtems/score/armv4.h>
0048
0049 #define VIM_CHANCTRL_COUNT 24
0050 #define VIM_CHANMAP_MASK UINT32_C(0x7f)
0051 #define VIM_CHANMAP_SHIFT(i) (24 - (8 * (i)))
0052 #define VIM_REQ_REG(vector) ((vector) >> 5)
0053 #define VIM_REQ_BIT(vector) (UINT32_C(1) << ((vector) & 0x1f))
0054
0055 static void vim_set_channel_request(uint32_t channel, uint32_t request)
0056 {
0057 uint32_t chanctrl;
0058 int shift;
0059
0060 chanctrl = TMS570_VIM.CHANCTRL[channel / 4];
0061 shift = VIM_CHANMAP_SHIFT(channel % 4);
0062 chanctrl &= ~(VIM_CHANMAP_MASK << shift);
0063 chanctrl |= request << shift;
0064 TMS570_VIM.CHANCTRL[channel / 4] = chanctrl;
0065 }
0066
0067 rtems_status_code tms570_irq_set_priority(
0068 rtems_vector_number vector,
0069 uint32_t priority
0070 )
0071 {
0072 rtems_interrupt_level level;
0073 uint32_t current_channel;
0074 uint32_t chanctrl;
0075 size_t i;
0076 size_t j;
0077
0078 if (!bsp_interrupt_is_valid_vector(vector)) {
0079 return RTEMS_INVALID_ID;
0080 }
0081
0082 if (priority < 2) {
0083 return RTEMS_INVALID_PRIORITY;
0084 }
0085
0086 if (priority >= BSP_INTERRUPT_VECTOR_COUNT) {
0087 return RTEMS_INVALID_PRIORITY;
0088 }
0089
0090 rtems_interrupt_disable(level);
0091 current_channel = TMS570_VIM.CHANCTRL[priority / 4];
0092 current_channel >>= VIM_CHANMAP_SHIFT(priority % 4);
0093 current_channel &= VIM_CHANMAP_MASK;
0094
0095 for (i = 0; i < VIM_CHANCTRL_COUNT; ++i) {
0096 chanctrl = TMS570_VIM.CHANCTRL[i];
0097
0098 for (j = 0; j < 4; ++j) {
0099 uint32_t channel_vector;
0100
0101 channel_vector = (chanctrl >> VIM_CHANMAP_SHIFT(j)) & VIM_CHANMAP_MASK;
0102
0103 if (channel_vector == vector) {
0104 vim_set_channel_request(i * 4 + j, current_channel);
0105 goto set_my_request;
0106 }
0107 }
0108 }
0109
0110 set_my_request:
0111
0112 vim_set_channel_request(priority, vector);
0113 rtems_interrupt_enable(level);
0114 return RTEMS_SUCCESSFUL;
0115 }
0116
0117 rtems_status_code tms570_irq_get_priority(
0118 rtems_vector_number vector,
0119 unsigned *priority
0120 )
0121 {
0122 rtems_interrupt_level level;
0123 size_t i;
0124 size_t j;
0125
0126 if (priority == NULL) {
0127 return RTEMS_INVALID_ADDRESS;
0128 }
0129
0130 if (!bsp_interrupt_is_valid_vector(vector)) {
0131 return RTEMS_INVALID_ID;
0132 }
0133
0134 rtems_interrupt_disable(level);
0135
0136 for (i = 0; i < VIM_CHANCTRL_COUNT; ++i) {
0137 uint32_t chanctrl;
0138
0139 chanctrl = TMS570_VIM.CHANCTRL[i];
0140
0141 for (j = 0; j < 4; ++j) {
0142 uint32_t channel_vector;
0143
0144 channel_vector = (chanctrl >> VIM_CHANMAP_SHIFT(j)) & VIM_CHANMAP_MASK;
0145
0146 if (channel_vector == vector) {
0147 rtems_interrupt_enable(level);
0148 *priority = i * 4 + j;
0149 return RTEMS_SUCCESSFUL;
0150 }
0151 }
0152 }
0153
0154 rtems_interrupt_enable(level);
0155 *priority = UINT32_MAX;
0156 return RTEMS_NOT_DEFINED;
0157 }
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 void bsp_interrupt_dispatch(void)
0168 {
0169 while (true) {
0170 uint32_t irqindex;
0171
0172 irqindex = TMS570_VIM.IRQINDEX;
0173
0174 if (irqindex == 0) {
0175 return;
0176 }
0177
0178 bsp_interrupt_handler_dispatch(irqindex - 1);
0179 }
0180 }
0181
0182 static bool can_disable(rtems_vector_number vector)
0183 {
0184
0185 return vector >= 2;
0186 }
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197 rtems_status_code bsp_interrupt_get_attributes(
0198 rtems_vector_number vector,
0199 rtems_interrupt_attributes *attributes
0200 )
0201 {
0202 bool can_disable_vector;
0203
0204 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0205 bsp_interrupt_assert(attributes != NULL);
0206
0207 can_disable_vector = can_disable(vector);
0208 attributes->is_maskable = can_disable_vector;
0209 attributes->can_enable = true;
0210 attributes->maybe_enable = true;
0211 attributes->can_disable = can_disable_vector;
0212 attributes->maybe_disable = can_disable_vector;
0213 attributes->can_get_affinity = true;
0214 attributes->can_set_affinity = true;
0215
0216 return RTEMS_SUCCESSFUL;
0217 }
0218
0219 rtems_status_code bsp_interrupt_is_pending(
0220 rtems_vector_number vector,
0221 bool *pending
0222 )
0223 {
0224 uint32_t intreq;
0225
0226 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0227 bsp_interrupt_assert(pending != NULL);
0228
0229 intreq = TMS570_VIM.INTREQ[VIM_REQ_REG(vector)];
0230 *pending = (intreq & VIM_REQ_BIT(vector)) != 0;
0231 return RTEMS_SUCCESSFUL;
0232 }
0233
0234 rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
0235 {
0236 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0237 return RTEMS_UNSATISFIED;
0238 }
0239
0240 rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
0241 {
0242 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0243 return RTEMS_UNSATISFIED;
0244 }
0245
0246 rtems_status_code bsp_interrupt_vector_is_enabled(
0247 rtems_vector_number vector,
0248 bool *enabled
0249 )
0250 {
0251 uint32_t reqen;
0252
0253 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0254 bsp_interrupt_assert(enabled != NULL);
0255
0256 reqen = TMS570_VIM.REQENASET[VIM_REQ_REG(vector)];
0257 *enabled = (reqen & VIM_REQ_BIT(vector)) != 0;
0258 return RTEMS_SUCCESSFUL;
0259 }
0260
0261 rtems_status_code bsp_interrupt_vector_enable(
0262 rtems_vector_number vector
0263 )
0264 {
0265 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0266 TMS570_VIM.REQENASET[VIM_REQ_REG(vector)] = VIM_REQ_BIT(vector);
0267 return RTEMS_SUCCESSFUL;
0268 }
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279 rtems_status_code bsp_interrupt_vector_disable(
0280 rtems_vector_number vector
0281 )
0282 {
0283 if (!can_disable(vector)) {
0284 return RTEMS_UNSATISFIED;
0285 }
0286
0287 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0288 TMS570_VIM.REQENACLR[VIM_REQ_REG(vector)] = VIM_REQ_BIT(vector);
0289 return RTEMS_SUCCESSFUL;
0290 }
0291
0292 rtems_status_code bsp_interrupt_set_priority(
0293 rtems_vector_number vector,
0294 uint32_t priority
0295 )
0296 {
0297 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0298 return RTEMS_UNSATISFIED;
0299 }
0300
0301 rtems_status_code bsp_interrupt_get_priority(
0302 rtems_vector_number vector,
0303 uint32_t *priority
0304 )
0305 {
0306 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0307 bsp_interrupt_assert(priority != NULL);
0308 return RTEMS_UNSATISFIED;
0309 }
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320 void bsp_interrupt_facility_initialize(void)
0321 {
0322 void (**vim_vec)(void) = (void (**)(void)) 0xFFF82000;
0323 unsigned int value = 0x00010203;
0324 unsigned int i = 0;
0325 uint32_t sctlr;
0326
0327
0328 for ( i = 0; i < 3; i++ ) {
0329 TMS570_VIM.REQENACLR[i] = 0xffffffff;
0330 }
0331
0332 for ( i = 0; i < VIM_CHANCTRL_COUNT; i += 1, value += 0x04040404) {
0333 TMS570_VIM.CHANCTRL[i] = value;
0334 }
0335
0336 TMS570_VIM.FIRQPR[0] = 3;
0337 TMS570_VIM.FIRQPR[1] = 0;
0338 TMS570_VIM.FIRQPR[2] = 0;
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353 for ( i = 0; i <= 94; ++i ) {
0354 vim_vec[i] = _ARMV4_Exception_interrupt;
0355 }
0356
0357 asm volatile ("mrc p15, 0, %0, c1, c0, 0\n": "=r" (sctlr));
0358
0359
0360
0361
0362 sctlr &= ~(1 << 24);
0363 #if 0
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384 sctlr |= 1 << 24;
0385 #endif
0386 asm volatile ("mcr p15, 0, %0, c1, c0, 0\n": : "r" (sctlr));
0387 }