File indexing completed on 2025-05-11 08:23:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <stdlib.h>
0014
0015 #include <bsp.h>
0016 #include <bsp/irq.h>
0017 #include <bsp/irq_supp.h>
0018 #include <bsp/irq-generic.h>
0019 #ifndef BSP_HAS_NO_VME
0020 #include <bsp/VMEConfig.h>
0021 #endif
0022 #if BSP_PCI_IRQ_NUMBER > 0
0023 #include <bsp/openpic.h>
0024 #endif
0025 #include <libcpu/io.h>
0026 #include <bsp/vectors.h>
0027 #include <stdlib.h>
0028
0029 #include <rtems/bspIo.h> /* for printk */
0030
0031 #ifndef qemu
0032 #define RAVEN_INTR_ACK_REG 0xfeff0030
0033 #else
0034 #define RAVEN_INTR_ACK_REG 0xbffffff0
0035 #endif
0036
0037 #if BSP_ISA_IRQ_NUMBER > 0
0038
0039
0040
0041
0042
0043
0044
0045
0046 rtems_i8259_masks irq_mask_or_tbl[BSP_IRQ_NUMBER];
0047 #endif
0048
0049
0050
0051
0052 static rtems_irq_connect_data default_rtems_entry;
0053
0054 static rtems_irq_connect_data* rtems_hdl_tbl;
0055
0056 #if BSP_ISA_IRQ_NUMBER > 0
0057
0058
0059
0060 static inline int is_isa_irq(const rtems_irq_number irqLine)
0061 {
0062 return (((int) irqLine <= BSP_ISA_IRQ_MAX_OFFSET) &&
0063 ((int) irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET)
0064 );
0065 }
0066 #endif
0067
0068 #if BSP_PCI_IRQ_NUMBER > 0
0069
0070
0071
0072 static inline int is_pci_irq(const rtems_irq_number irqLine)
0073 {
0074 return OpenPIC && (((int) irqLine <= BSP_PCI_IRQ_MAX_OFFSET) &&
0075 ((int) irqLine >= BSP_PCI_IRQ_LOWEST_OFFSET)
0076 );
0077 }
0078 #endif
0079
0080
0081
0082
0083
0084 #if BSP_ISA_IRQ_NUMBER > 0
0085
0086
0087
0088
0089
0090 static void compute_i8259_masks_from_prio (rtems_irq_global_settings* config)
0091 {
0092 int i;
0093 int j;
0094
0095
0096
0097 for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
0098 * ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i);
0099 for (j = BSP_ISA_IRQ_LOWEST_OFFSET; j < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; j++) {
0100
0101
0102
0103 if (config->irqPrioTbl [i] > config->irqPrioTbl [j]) {
0104 * ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j);
0105 }
0106 }
0107 }
0108 }
0109 #endif
0110
0111 void
0112 BSP_enable_irq_at_pic(const rtems_irq_number name)
0113 {
0114 #if BSP_ISA_IRQ_NUMBER > 0
0115 if (is_isa_irq(name)) {
0116
0117
0118
0119 BSP_irq_enable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET);
0120 }
0121 #endif
0122
0123 #if BSP_PCI_IRQ_NUMBER > 0
0124 if (is_pci_irq(name)) {
0125
0126
0127
0128 openpic_enable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET);
0129 }
0130 #endif
0131 }
0132
0133 int
0134 BSP_disable_irq_at_pic(const rtems_irq_number name)
0135 {
0136 #if BSP_ISA_IRQ_NUMBER > 0
0137 if (is_isa_irq(name)) {
0138
0139
0140
0141 return BSP_irq_disable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET);
0142 }
0143 #endif
0144 #if BSP_PCI_IRQ_NUMBER > 0
0145 if (is_pci_irq(name)) {
0146
0147
0148
0149 return openpic_disable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET);
0150 }
0151 #endif
0152 return -1;
0153 }
0154
0155
0156
0157
0158 int BSP_setup_the_pic(rtems_irq_global_settings* config)
0159 {
0160 int i;
0161
0162
0163
0164 default_rtems_entry = config->defaultEntry;
0165 rtems_hdl_tbl = config->irqHdlTbl;
0166
0167
0168
0169
0170
0171 #if BSP_ISA_IRQ_NUMBER > 0
0172
0173
0174
0175 compute_i8259_masks_from_prio (config);
0176
0177 for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
0178 if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
0179 BSP_irq_enable_at_i8259s (i);
0180 }
0181 else {
0182 BSP_irq_disable_at_i8259s (i);
0183 }
0184 }
0185
0186 if ( BSP_ISA_IRQ_NUMBER > 0 ) {
0187
0188
0189
0190 BSP_irq_enable_at_i8259s (2);
0191 }
0192 #endif
0193
0194 #if BSP_PCI_IRQ_NUMBER > 0
0195 if ( ! OpenPIC )
0196 return 1;
0197
0198
0199
0200 for (i=BSP_PCI_IRQ_LOWEST_OFFSET; i < BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER ; i++) {
0201
0202
0203
0204 openpic_set_source_priority(i - BSP_PCI_IRQ_LOWEST_OFFSET,
0205 config->irqPrioTbl[i]);
0206 if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
0207 openpic_enable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
0208 }
0209 else {
0210 openpic_disable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
0211 }
0212 }
0213
0214 #ifdef BSP_PCI_ISA_BRIDGE_IRQ
0215
0216
0217
0218 openpic_enable_irq (BSP_PCI_ISA_BRIDGE_IRQ - BSP_PCI_IRQ_LOWEST_OFFSET);
0219 #endif
0220 #endif
0221
0222 return 1;
0223 }
0224
0225 int _BSP_vme_bridge_irq = -1;
0226
0227 unsigned BSP_spuriousIntr = 0;
0228
0229
0230
0231
0232 int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
0233 {
0234 register unsigned int irq;
0235 #if BSP_ISA_IRQ_NUMBER > 0
0236 register unsigned isaIntr;
0237 register unsigned oldMask = 0;
0238 #endif
0239
0240 if (excNum == ASM_DEC_VECTOR) {
0241 #ifdef BSP_POWERPC_IRQ_GENERIC_SUPPORT
0242 bsp_interrupt_handler_dispatch(BSP_DECREMENTER);
0243 #else
0244 bsp_irq_dispatch_list(rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_entry.hdl);
0245 #endif
0246 return 0;
0247 }
0248
0249 #if BSP_PCI_IRQ_NUMBER > 0
0250 if ( OpenPIC ) {
0251 irq = openpic_irq(0);
0252 if (irq == OPENPIC_VEC_SPURIOUS) {
0253 ++BSP_spuriousIntr;
0254 return 0;
0255 }
0256
0257
0258 irq = irq - OPENPIC_VEC_SOURCE + BSP_PCI_IRQ_LOWEST_OFFSET;
0259 } else {
0260 #if BSP_ISA_IRQ_NUMBER > 0
0261 #ifdef BSP_PCI_ISA_BRIDGE_IRQ
0262 irq = BSP_PCI_ISA_BRIDGE_IRQ;
0263 #else
0264 #error "Configuration Error -- BSP with ISA + PCI IRQs MUST define BSP_PCI_ISA_BRIDGE_IRQ"
0265 #endif
0266 #else
0267 rtems_panic("MUST have an OpenPIC if BSP has PCI IRQs but no ISA IRQs");
0268
0269
0270
0271 return -1;
0272 #endif
0273 }
0274 #endif
0275
0276 #if BSP_ISA_IRQ_NUMBER > 0
0277 #ifdef BSP_PCI_ISA_BRIDGE_IRQ
0278 #if 0 == BSP_PCI_IRQ_NUMBER
0279 #error "Configuration Error -- BSP w/o PCI IRQs MUST NOT define BSP_PCI_ISA_BRIDGE_IRQ"
0280 #endif
0281 isaIntr = (irq == BSP_PCI_ISA_BRIDGE_IRQ);
0282 #else
0283 isaIntr = 1;
0284 #endif
0285 if (isaIntr) {
0286
0287
0288
0289 irq = (unsigned int) (*(unsigned char *) RAVEN_INTR_ACK_REG);
0290
0291
0292
0293 oldMask = BSP_irq_suspend_i8259s(irq_mask_or_tbl [irq]);
0294 BSP_irq_ack_at_i8259s (irq);
0295 #if BSP_PCI_IRQ_NUMBER > 0
0296 if ( OpenPIC )
0297 openpic_eoi(0);
0298 #endif
0299 }
0300 #endif
0301
0302
0303 #ifdef BSP_POWERPC_IRQ_GENERIC_SUPPORT
0304 bsp_interrupt_handler_dispatch(irq);
0305 #else
0306 bsp_irq_dispatch_list(rtems_hdl_tbl, irq, default_rtems_entry.hdl);
0307 #endif
0308
0309 #if BSP_ISA_IRQ_NUMBER > 0
0310 if (isaIntr) {
0311 BSP_irq_resume_i8259s(oldMask);
0312 }
0313 else
0314 #endif
0315 {
0316 #if BSP_PCI_IRQ_NUMBER > 0
0317 #ifdef BSP_PCI_VME_DRIVER_DOES_EOI
0318
0319
0320
0321
0322 if (_BSP_vme_bridge_irq != irq && OpenPIC)
0323 #endif
0324 openpic_eoi(0);
0325 #else
0326 do {} while (0);
0327 #endif
0328 }
0329 return 0;
0330 }