File indexing completed on 2025-05-11 08:23:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <rtems.h>
0019 #include <mpc5xx.h>
0020 #include <libcpu/vectors.h>
0021 #include <libcpu/raw_exception.h>
0022 #include <libcpu/irq.h>
0023 #include <bsp/irq.h>
0024
0025
0026
0027
0028
0029 int CPU_irq_level_from_symbolic_name(const rtems_irq_number name)
0030 {
0031 if (CPU_USIU_EXT_IRQ_0 <= name && name <= CPU_USIU_INT_IRQ_7)
0032 return (name - CPU_USIU_EXT_IRQ_0) / 2;
0033
0034 if (CPU_UIMB_IRQ_8 <= name && name <= CPU_UIMB_IRQ_31)
0035 return 8 + (name - CPU_UIMB_IRQ_8);
0036
0037 return 31;
0038 }
0039
0040
0041
0042
0043 static rtems_irq_connect_data default_rtems_entry;
0044
0045
0046
0047
0048
0049 static rtems_irq_global_settings* internal_config;
0050 static rtems_irq_connect_data* rtems_hdl_tbl;
0051
0052
0053
0054
0055 static inline int is_usiu_irq(const rtems_irq_number irqLine)
0056 {
0057 return (((int) irqLine <= CPU_USIU_IRQ_MAX_OFFSET) &&
0058 ((int) irqLine >= CPU_USIU_IRQ_MIN_OFFSET)
0059 );
0060 }
0061
0062
0063
0064
0065 static inline int is_uimb_irq(const rtems_irq_number irqLine)
0066 {
0067 return (((int) irqLine <= CPU_UIMB_IRQ_MAX_OFFSET) &&
0068 ((int) irqLine >= CPU_UIMB_IRQ_MIN_OFFSET)
0069 );
0070 }
0071
0072
0073
0074
0075 static inline int is_proc_irq(const rtems_irq_number irqLine)
0076 {
0077 return (((int) irqLine <= CPU_PROC_IRQ_MAX_OFFSET) &&
0078 ((int) irqLine >= CPU_PROC_IRQ_MIN_OFFSET)
0079 );
0080 }
0081
0082
0083
0084
0085
0086
0087
0088
0089 const static unsigned int USIU_IvectMask[CPU_USIU_IRQ_COUNT] =
0090 {
0091 0,
0092 0xFFFFFFFF << 31,
0093 0xFFFFFFFF << 30,
0094 0xFFFFFFFF << 29,
0095 0xFFFFFFFF << 28,
0096 0xFFFFFFFF << 27,
0097 0xFFFFFFFF << 26,
0098 0xFFFFFFFF << 25,
0099 0xFFFFFFFF << 24,
0100 0xFFFFFFFF << 23,
0101 0xFFFFFFFF << 22,
0102 0xFFFFFFFF << 21,
0103 0xFFFFFFFF << 20,
0104 0xFFFFFFFF << 19,
0105 0xFFFFFFFF << 18,
0106 0xFFFFFFFF << 17
0107 };
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119 static void compute_USIU_IvectMask_from_prio (void)
0120 {
0121
0122
0123
0124
0125
0126 }
0127
0128
0129
0130
0131
0132 static int isValidInterrupt(int irq)
0133 {
0134 if ( (irq < CPU_MIN_OFFSET) || (irq > CPU_MAX_OFFSET)
0135 || (irq == CPU_UIMB_INTERRUPT) )
0136 return 0;
0137 return 1;
0138 }
0139
0140 static int CPU_irq_enable_at_uimb(const rtems_irq_number irqLine)
0141 {
0142 if (!is_uimb_irq(irqLine))
0143 return 1;
0144 return 0;
0145 }
0146
0147 static int CPU_irq_disable_at_uimb(const rtems_irq_number irqLine)
0148 {
0149 if (!is_uimb_irq(irqLine))
0150 return 1;
0151 return 0;
0152 }
0153
0154 static int CPU_irq_enable_at_usiu(const rtems_irq_number irqLine)
0155 {
0156 int usiu_irq_index;
0157
0158 if (!is_usiu_irq(irqLine))
0159 return 1;
0160
0161 usiu_irq_index = ((int) (irqLine) - CPU_USIU_IRQ_MIN_OFFSET);
0162 ppc_cached_irq_mask |= (1 << (31-usiu_irq_index));
0163 usiu.simask = ppc_cached_irq_mask;
0164
0165 return 0;
0166 }
0167
0168 static int CPU_irq_disable_at_usiu(const rtems_irq_number irqLine)
0169 {
0170 int usiu_irq_index;
0171
0172 if (!is_usiu_irq(irqLine))
0173 return 1;
0174
0175 usiu_irq_index = ((int) (irqLine) - CPU_USIU_IRQ_MIN_OFFSET);
0176 ppc_cached_irq_mask &= ~(1 << (31-usiu_irq_index));
0177 usiu.simask = ppc_cached_irq_mask;
0178
0179 return 0;
0180 }
0181
0182
0183
0184
0185
0186 int CPU_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
0187 {
0188 rtems_interrupt_level level;
0189
0190 if (!isValidInterrupt(irq->name)) {
0191 return 0;
0192 }
0193
0194
0195
0196
0197
0198
0199
0200 if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) {
0201 return 0;
0202 }
0203
0204 rtems_interrupt_disable(level);
0205
0206
0207
0208
0209 rtems_hdl_tbl[irq->name] = *irq;
0210
0211 if (is_uimb_irq(irq->name)) {
0212
0213
0214
0215 CPU_irq_enable_at_uimb (irq->name);
0216 }
0217
0218 if (is_usiu_irq(irq->name)) {
0219
0220
0221
0222 CPU_irq_enable_at_usiu (irq->name);
0223 }
0224
0225 if (is_proc_irq(irq->name)) {
0226
0227
0228
0229
0230 }
0231
0232
0233
0234 if (irq->on)
0235 irq->on(irq);
0236
0237 rtems_interrupt_enable(level);
0238
0239 return 1;
0240 }
0241
0242
0243 int CPU_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
0244 {
0245 if (!isValidInterrupt(irq->name)) {
0246 return 0;
0247 }
0248 *irq = rtems_hdl_tbl[irq->name];
0249 return 1;
0250 }
0251
0252 int CPU_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
0253 {
0254 rtems_interrupt_level level;
0255
0256 if (!isValidInterrupt(irq->name)) {
0257 return 0;
0258 }
0259
0260
0261
0262
0263
0264
0265
0266 if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
0267 return 0;
0268 }
0269 rtems_interrupt_disable(level);
0270
0271
0272
0273
0274 if (irq->off)
0275 irq->off(irq);
0276
0277 if (is_uimb_irq(irq->name)) {
0278
0279
0280
0281 CPU_irq_disable_at_uimb (irq->name);
0282 }
0283 if (is_usiu_irq(irq->name)) {
0284
0285
0286
0287 CPU_irq_disable_at_usiu (irq->name);
0288 }
0289 if (is_proc_irq(irq->name)) {
0290
0291
0292
0293 }
0294
0295
0296
0297
0298 rtems_hdl_tbl[irq->name] = default_rtems_entry;
0299
0300 rtems_interrupt_enable(level);
0301
0302 return 1;
0303 }
0304
0305
0306
0307
0308
0309 int CPU_rtems_irq_mngt_set (rtems_irq_global_settings* config)
0310 {
0311 int i;
0312 rtems_interrupt_level level;
0313
0314
0315
0316
0317 internal_config = config;
0318 default_rtems_entry = config->defaultEntry;
0319 rtems_hdl_tbl = config->irqHdlTbl;
0320
0321 rtems_interrupt_disable(level);
0322
0323
0324
0325
0326 for (i = CPU_UIMB_IRQ_MIN_OFFSET; i <= CPU_UIMB_IRQ_MAX_OFFSET ; i++) {
0327 if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
0328 CPU_irq_enable_at_uimb (i);
0329 if (rtems_hdl_tbl[i].on)
0330 rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
0331 }
0332 else {
0333 if (rtems_hdl_tbl[i].off)
0334 rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
0335 CPU_irq_disable_at_uimb (i);
0336 }
0337 }
0338
0339
0340
0341
0342
0343 compute_USIU_IvectMask_from_prio ();
0344
0345 for (i = CPU_USIU_IRQ_MIN_OFFSET; i <= CPU_USIU_IRQ_MAX_OFFSET ; i++) {
0346 if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
0347 CPU_irq_enable_at_usiu (i);
0348 if (rtems_hdl_tbl[i].on)
0349 rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
0350 }
0351 else {
0352 if (rtems_hdl_tbl[i].off)
0353 rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
0354 CPU_irq_disable_at_usiu (i);
0355 }
0356 }
0357
0358
0359
0360
0361 imb.uimb.umcr |= UIMB_UMCR_IRQMUX(3);
0362 CPU_irq_enable_at_usiu (CPU_UIMB_INTERRUPT);
0363
0364
0365
0366
0367 for (i = CPU_PROC_IRQ_MIN_OFFSET; i <= CPU_PROC_IRQ_MAX_OFFSET; i++) {
0368 if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
0369 if (rtems_hdl_tbl[i].on)
0370 rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
0371 }
0372 else {
0373 if (rtems_hdl_tbl[i].off)
0374 rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
0375 }
0376 }
0377 rtems_interrupt_enable(level);
0378 return 1;
0379 }
0380
0381 int CPU_rtems_irq_mngt_get(rtems_irq_global_settings** config)
0382 {
0383 *config = internal_config;
0384 return 0;
0385 }
0386
0387
0388
0389
0390
0391 void C_dispatch_irq_handler (MPC5XX_Interrupt_frame *frame, unsigned int excNum)
0392 {
0393 register unsigned int irq;
0394 register unsigned uimbIntr;
0395 register unsigned oldMask;
0396 register unsigned msr;
0397 register unsigned new_msr;
0398
0399
0400
0401
0402 if (excNum == ASM_DEC_VECTOR) {
0403 _CPU_MSR_GET(msr);
0404 new_msr = msr | MSR_EE;
0405 _CPU_MSR_SET(new_msr);
0406
0407 rtems_hdl_tbl[CPU_DECREMENTER].hdl(rtems_hdl_tbl[CPU_DECREMENTER].handle);
0408
0409 _CPU_MSR_SET(msr);
0410 return;
0411 }
0412
0413
0414
0415
0416 while ((ppc_cached_irq_mask & usiu.sipend) != 0) {
0417 irq = (usiu.sivec >> 26);
0418 uimbIntr = (irq == CPU_UIMB_INTERRUPT);
0419
0420
0421
0422 oldMask = ppc_cached_irq_mask;
0423 ppc_cached_irq_mask = oldMask & USIU_IvectMask[irq];
0424 usiu.simask = ppc_cached_irq_mask;
0425
0426
0427
0428
0429 usiu.sipend = (1 << (31 - irq));
0430
0431 if (uimbIntr) {
0432
0433
0434
0435
0436
0437
0438
0439
0440 int uipend = imb.uimb.uipend << 8;
0441
0442 if (uipend == 0) {
0443 irq = CPU_UIMB_IRQ_MAX_OFFSET;
0444 }
0445 else {
0446 irq = CPU_UIMB_IRQ_MIN_OFFSET;
0447 for ( ; (uipend & 0x8000000) == 0; uipend <<= 1) {
0448 irq++;
0449 }
0450 }
0451 }
0452 _CPU_MSR_GET(msr);
0453 new_msr = msr | MSR_EE;
0454 _CPU_MSR_SET(new_msr);
0455
0456 rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle);
0457
0458 _CPU_MSR_SET(msr);
0459
0460 ppc_cached_irq_mask = oldMask;
0461 usiu.simask = ppc_cached_irq_mask;
0462 }
0463 }