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
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <libcpu/spr.h>
0035 #include <bsp/irq.h>
0036 #include <bsp.h>
0037 #include <rtems/bspIo.h>
0038 #include <rtems/powerpc/powerpc.h>
0039 #include <bsp/vectors.h>
0040
0041 static rtems_irq_connect_data rtemsIrqTbl[BSP_IRQ_NUMBER];
0042 rtems_irq_connect_data *BSP_rtems_irq_tbl;
0043 rtems_irq_global_settings* BSP_rtems_irq_config;
0044
0045
0046
0047
0048
0049
0050 static void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
0051 {
0052
0053
0054
0055 }
0056
0057 static void BSP_irq_nop_hdl(void *hdl)
0058 {
0059
0060
0061
0062 }
0063
0064 static int BSP_irq_isOn_func(const rtems_irq_connect_data *unused)
0065 {
0066
0067
0068
0069 return 0;
0070 }
0071
0072
0073
0074
0075
0076
0077
0078
0079 void BSP_irqexc_on_fnc(const rtems_irq_connect_data *conn_data)
0080 {
0081 uint32_t msr_value;
0082
0083
0084
0085 _CPU_MSR_GET(msr_value);
0086
0087 msr_value |= PPC_MSR_EE;
0088 _CPU_MSR_SET(msr_value);
0089 }
0090
0091 void BSP_irqexc_off_fnc(const rtems_irq_connect_data *unused)
0092 {
0093 uint32_t msr_value;
0094
0095
0096
0097 _CPU_MSR_GET(msr_value);
0098
0099 msr_value &= ~PPC_MSR_EE;
0100 _CPU_MSR_SET(msr_value);
0101 }
0102
0103
0104
0105
0106 static int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
0107 {
0108
0109
0110
0111 switch(excNum) {
0112 case ASM_EXT_VECTOR:
0113 BSP_rtems_irq_tbl[BSP_EXT].hdl(BSP_rtems_irq_tbl[BSP_EXT].handle);
0114 break;
0115 case ASM_BOOKE_DEC_VECTOR:
0116 BSP_rtems_irq_tbl[BSP_PIT].hdl(BSP_rtems_irq_tbl[BSP_PIT].handle);
0117 break;
0118 #if 0
0119 case ASM_BOOKE_CRIT_VECTOR:
0120 BSP_rtems_irq_tbl[BSP_CRIT].hdl(BSP_rtems_irq_tbl[BSP_CRIT].handle);
0121 break;
0122 #endif
0123 }
0124
0125 return 0;
0126 }
0127
0128
0129
0130
0131 int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
0132 {
0133 rtems_interrupt_level level;
0134
0135
0136
0137
0138
0139 if (!BSP_IS_VALID_IRQ(irq->name)) {
0140 printk("Invalid interrupt vector %d\n",irq->name);
0141 return 0;
0142 }
0143
0144
0145
0146
0147 rtems_interrupt_disable(level);
0148
0149
0150
0151
0152 if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
0153 rtems_interrupt_enable(level);
0154 printk("IRQ vector %d already connected\n",irq->name);
0155 return 0;
0156 }
0157
0158
0159
0160
0161 rtemsIrqTbl[irq->name] = *irq;
0162
0163
0164
0165
0166 irq->on(irq);
0167
0168
0169
0170
0171 rtems_interrupt_enable(level);
0172
0173 return 1;
0174 }
0175
0176 int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
0177 {
0178 rtems_interrupt_level level;
0179
0180
0181
0182
0183 if (!BSP_IS_VALID_IRQ(irq->name)) {
0184 return 0;
0185 }
0186 rtems_interrupt_disable(level);
0187
0188
0189
0190
0191 *irq = rtemsIrqTbl[irq->name];
0192 rtems_interrupt_enable(level);
0193 return 1;
0194 }
0195
0196 int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
0197 {
0198 rtems_interrupt_level level;
0199
0200
0201
0202
0203 if (!BSP_IS_VALID_IRQ(irq->name)) {
0204 return 0;
0205 }
0206 rtems_interrupt_disable(level);
0207
0208
0209
0210
0211 if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
0212 rtems_interrupt_enable(level);
0213 return 0;
0214 }
0215
0216
0217
0218
0219 irq->off(irq);
0220
0221
0222
0223
0224 rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
0225
0226
0227
0228
0229 rtems_interrupt_enable(level);
0230
0231 return 1;
0232 }
0233
0234
0235
0236
0237
0238
0239
0240 int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
0241 {
0242 *ret_ptr = BSP_rtems_irq_config;
0243 return 0;
0244 }
0245
0246
0247
0248
0249
0250 int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
0251 {
0252 int i;
0253 rtems_interrupt_level level;
0254
0255 rtems_interrupt_disable(level);
0256
0257
0258
0259
0260 BSP_rtems_irq_config = config;
0261 BSP_rtems_irq_tbl = BSP_rtems_irq_config->irqHdlTbl;
0262
0263
0264
0265
0266 for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
0267 i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
0268 i++) {
0269 if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
0270 if (BSP_rtems_irq_tbl[i].on != NULL) {
0271 BSP_rtems_irq_tbl[i].on
0272 (&(BSP_rtems_irq_tbl[i]));
0273 }
0274 }
0275 else {
0276 if (BSP_rtems_irq_tbl[i].off != NULL) {
0277 BSP_rtems_irq_tbl[i].off
0278 (&(BSP_rtems_irq_tbl[i]));
0279 }
0280 }
0281 }
0282 rtems_interrupt_enable(level);
0283 return 1;
0284 }
0285
0286
0287
0288
0289 static rtems_irq_connect_data emptyIrq = {
0290 0,
0291 BSP_irq_nop_hdl,
0292 NULL,
0293 BSP_irq_nop_func,
0294 BSP_irq_nop_func,
0295 BSP_irq_isOn_func
0296 };
0297
0298 static rtems_irq_global_settings initialConfig = {
0299 BSP_IRQ_NUMBER,
0300 { 0,
0301 BSP_irq_nop_hdl,
0302 NULL,
0303 BSP_irq_nop_func,
0304 BSP_irq_nop_func,
0305 BSP_irq_isOn_func
0306 },
0307 rtemsIrqTbl,
0308 0,
0309 NULL
0310 };
0311
0312 void BSP_rtems_irq_mngt_init(unsigned cpuId)
0313 {
0314 int i;
0315
0316
0317
0318
0319 ppc_exc_set_handler(ASM_EXT_VECTOR, C_dispatch_irq_handler);
0320 ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_irq_handler);
0321
0322
0323
0324
0325 for (i = 0;
0326 i < BSP_IRQ_NUMBER;
0327 i++) {
0328 rtemsIrqTbl[i] = emptyIrq;
0329 rtemsIrqTbl[i].name = i;
0330 }
0331
0332
0333
0334
0335 if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
0336 rtems_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
0337 }
0338 }