File indexing completed on 2025-05-11 08:23:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <bsp.h>
0013 #include <bsp/irq.h>
0014
0015 #define PIC_EOSI 0x60
0016 #define PIC_EOI 0x20
0017
0018
0019 #define PIC_OCW3_RIS 0x01
0020 #define PIC_OCW3_RR 0x02
0021 #define PIC_OCW3_P 0x04
0022
0023 #define PIC_OCW3_SEL 0x08
0024
0025 #define PIC_OCW3_SMM 0x20
0026 #define PIC_OCW3_ESMM 0x40
0027
0028
0029
0030
0031
0032
0033
0034
0035 static rtems_i8259_masks i8259s_imr_cache = 0xFFFB;
0036 static rtems_i8259_masks i8259s_in_progress = 0;
0037
0038 static inline
0039 void BSP_i8259s_irq_update_master_imr( void )
0040 {
0041 rtems_i8259_masks mask = i8259s_in_progress | i8259s_imr_cache;
0042 outport_byte( PIC_MASTER_IMR_IO_PORT, mask & 0xff );
0043 }
0044
0045 static inline
0046 void BSP_i8259s_irq_update_slave_imr( void )
0047 {
0048 rtems_i8259_masks mask = i8259s_in_progress | i8259s_imr_cache;
0049 outport_byte( PIC_SLAVE_IMR_IO_PORT, ( mask >> 8 ) & 0xff );
0050 }
0051
0052
0053
0054
0055 static inline bool BSP_i8259s_irq_valid(const rtems_irq_number irqLine)
0056 {
0057 return ((int)irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET) &&
0058 ((int)irqLine <= BSP_ISA_IRQ_MAX_OFFSET);
0059 }
0060
0061
0062
0063
0064 static inline uint8_t BSP_i8259s_irq_int_request_reg(uint32_t ioport)
0065 {
0066 uint8_t isr;
0067 inport_byte(ioport, isr);
0068 return isr;
0069 }
0070
0071
0072
0073
0074 static inline uint8_t BSP_i8259s_irq_in_service_reg(uint32_t ioport)
0075 {
0076 uint8_t isr;
0077 outport_byte(ioport, PIC_OCW3_SEL | PIC_OCW3_RR | PIC_OCW3_RIS);
0078 inport_byte(ioport, isr);
0079 outport_byte(ioport, PIC_OCW3_SEL | PIC_OCW3_RR);
0080 return isr;
0081 }
0082
0083
0084
0085
0086
0087
0088
0089
0090 int BSP_irq_disable_at_i8259s(const rtems_irq_number irqLine)
0091 {
0092 unsigned short mask;
0093 rtems_interrupt_level level;
0094
0095 if (!BSP_i8259s_irq_valid(irqLine))
0096 return -1;
0097
0098 rtems_interrupt_disable(level);
0099
0100 mask = 1 << irqLine;
0101 i8259s_imr_cache |= mask;
0102
0103 if (irqLine < 8)
0104 {
0105 BSP_i8259s_irq_update_master_imr();
0106 }
0107 else
0108 {
0109 BSP_i8259s_irq_update_slave_imr();
0110 }
0111
0112 rtems_interrupt_enable(level);
0113
0114 return 0;
0115 }
0116
0117
0118
0119
0120
0121
0122
0123
0124 int BSP_irq_enable_at_i8259s(const rtems_irq_number irqLine)
0125 {
0126 rtems_interrupt_level level;
0127 unsigned short mask;
0128
0129 if (!BSP_i8259s_irq_valid(irqLine))
0130 return 1;
0131
0132 rtems_interrupt_disable(level);
0133
0134 mask = 1 << irqLine;
0135 i8259s_imr_cache &= ~mask;
0136
0137 if (irqLine < 8)
0138 {
0139 BSP_i8259s_irq_update_master_imr();
0140 }
0141 else
0142 {
0143 BSP_i8259s_irq_update_slave_imr();
0144 }
0145
0146 rtems_interrupt_enable(level);
0147
0148 return 0;
0149 }
0150
0151 int BSP_irq_enabled_at_i8259s(const rtems_irq_number irqLine)
0152 {
0153 unsigned short mask;
0154
0155 if (!BSP_i8259s_irq_valid(irqLine))
0156 return 1;
0157
0158 mask = (1 << irqLine);
0159 return (~(i8259s_imr_cache & mask));
0160 }
0161
0162
0163
0164
0165
0166
0167
0168
0169 int BSP_irq_ack_at_i8259s(const rtems_irq_number irqLine)
0170 {
0171 uint8_t slave_isr = 0;
0172
0173 if (irqLine >= 8) {
0174 outport_byte(PIC_SLAVE_COMMAND_IO_PORT, PIC_EOI);
0175 slave_isr = BSP_i8259s_irq_in_service_reg(PIC_SLAVE_COMMAND_IO_PORT);
0176 }
0177
0178
0179
0180
0181
0182
0183 if (slave_isr == 0)
0184 outport_byte(PIC_MASTER_COMMAND_IO_PORT, PIC_EOI);
0185
0186 return 0;
0187
0188 }
0189
0190 unsigned short BSP_irq_suspend_i8259s(unsigned short mask)
0191 {
0192 unsigned short in_progress_save = i8259s_in_progress;
0193 i8259s_in_progress |= mask;
0194 BSP_i8259s_irq_update_master_imr();
0195 BSP_i8259s_irq_update_slave_imr();
0196 return in_progress_save;
0197 }
0198
0199 void BSP_irq_resume_i8259s(unsigned short in_progress_save)
0200 {
0201 i8259s_in_progress = in_progress_save;
0202 BSP_i8259s_irq_update_master_imr();
0203 BSP_i8259s_irq_update_slave_imr();
0204 }
0205
0206 void BSP_i8259s_init(void)
0207 {
0208
0209
0210
0211 outport_byte(PIC_MASTER_COMMAND_IO_PORT, 0x11);
0212 outport_byte(PIC_MASTER_IMR_IO_PORT, 0x00);
0213 outport_byte(PIC_MASTER_IMR_IO_PORT, 0x04);
0214 outport_byte(PIC_MASTER_IMR_IO_PORT, 0x01);
0215 outport_byte(PIC_MASTER_IMR_IO_PORT, 0xFB);
0216
0217
0218
0219 outport_byte(PIC_SLAVE_COMMAND_IO_PORT, 0x11);
0220 outport_byte(PIC_SLAVE_IMR_IO_PORT, 0x08);
0221 outport_byte(PIC_SLAVE_IMR_IO_PORT, 0x02);
0222 outport_byte(PIC_SLAVE_IMR_IO_PORT, 0x01);
0223 outport_byte(PIC_SLAVE_IMR_IO_PORT, 0xFF);
0224
0225 }