Changes in kernel/genarch/src/drivers/i8259/i8259.c [3daba42e:c48de91] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/drivers/i8259/i8259.c
r3daba42e rc48de91 32 32 /** 33 33 * @file 34 * @brief PICdriver.34 * @brief i8259 driver. 35 35 * 36 36 * Programmable Interrupt Controller for UP systems based on i8259 chip. … … 42 42 #include <log.h> 43 43 #include <interrupt.h> 44 45 /* ICW1 bits */ 46 #define I8259_ICW1 (1 << 4) 47 #define I8259_ICW1_NEEDICW4 (1 << 0) 48 49 /* OCW3 bits */ 50 #define I8259_OCW3 (1 << 3) 51 #define I8259_OCW3_READ_ISR (3 << 0) 52 53 /* OCW4 bits */ 54 #define I8259_OCW4 (0 << 3) 55 #define I8259_OCW4_NSEOI (1 << 5) 56 57 #define I8259_IRQ_COUNT 8 58 59 #define I8259_IRQ_SLAVE 2 60 61 static const char *i8259_get_name(void); 62 63 pic_ops_t i8259_pic_ops = { 64 .get_name = i8259_get_name, 65 .enable_irqs = i8259_enable_irqs, 66 .disable_irqs = i8259_disable_irqs, 67 .eoi = i8259_eoi, 68 .is_spurious = i8259_is_spurious, 69 .handle_spurious = i8259_handle_spurious 70 }; 44 71 45 72 // XXX: need to change pic_* API to get rid of these … … 53 80 54 81 /* ICW1: this is ICW1, ICW4 to follow */ 55 pio_write_8(&pic0->port1, PIC_ICW1 | PIC_ICW1_NEEDICW4);82 pio_write_8(&pic0->port1, I8259_ICW1 | I8259_ICW1_NEEDICW4); 56 83 57 84 /* ICW2: IRQ 0 maps to interrupt vector address irq0_vec */ 58 85 pio_write_8(&pic0->port2, irq0_vec); 59 86 60 /* ICW3: pic1 using IRQ PIC0_IRQ_PIC1*/61 pio_write_8(&pic0->port2, 1 << PIC0_IRQ_PIC1);87 /* ICW3: pic1 using IRQ I8259_IRQ_SLAVE */ 88 pio_write_8(&pic0->port2, 1 << I8259_IRQ_SLAVE); 62 89 63 90 /* ICW4: i8086 mode */ … … 65 92 66 93 /* ICW1: ICW1, ICW4 to follow */ 67 pio_write_8(&pic1->port1, PIC_ICW1 | PIC_ICW1_NEEDICW4);94 pio_write_8(&pic1->port1, I8259_ICW1 | I8259_ICW1_NEEDICW4); 68 95 69 96 /* ICW2: IRQ 8 maps to interrupt vector address irq0_vec + 8 */ 70 pio_write_8(&pic1->port2, irq0_vec + PIC0_IRQ_COUNT);97 pio_write_8(&pic1->port2, irq0_vec + I8259_IRQ_COUNT); 71 98 72 /* ICW3: pic1 is known as PIC0_IRQ_PIC1*/73 pio_write_8(&pic1->port2, PIC0_IRQ_PIC1);99 /* ICW3: pic1 is known as I8259_IRQ_SLAVE */ 100 pio_write_8(&pic1->port2, I8259_IRQ_SLAVE); 74 101 75 102 /* ICW4: i8086 mode */ 76 103 pio_write_8(&pic1->port2, 1); 77 104 78 pic_disable_irqs(0xffff); /* disable all irq's */ 79 pic_enable_irqs(1 << PIC0_IRQ_PIC1); /* but enable PIC0_IRQ_PIC1 */ 105 /* disable all irq's */ 106 i8259_disable_irqs(0xffff); 107 /* but enable I8259_IRQ_SLAVE */ 108 i8259_enable_irqs(1 << I8259_IRQ_SLAVE); 80 109 } 81 110 82 void pic_enable_irqs(uint16_t irqmask) 111 const char *i8259_get_name(void) 112 { 113 return "i8259"; 114 } 115 116 void i8259_enable_irqs(uint16_t irqmask) 83 117 { 84 118 uint8_t x; … … 89 123 (uint8_t) (x & (~(irqmask & 0xff)))); 90 124 } 91 if (irqmask >> PIC0_IRQ_COUNT) {125 if (irqmask >> I8259_IRQ_COUNT) { 92 126 x = pio_read_8(&saved_pic1->port2); 93 127 pio_write_8(&saved_pic1->port2, 94 (uint8_t) (x & (~(irqmask >> PIC0_IRQ_COUNT))));128 (uint8_t) (x & (~(irqmask >> I8259_IRQ_COUNT)))); 95 129 } 96 130 } 97 131 98 void pic_disable_irqs(uint16_t irqmask)132 void i8259_disable_irqs(uint16_t irqmask) 99 133 { 100 134 uint8_t x; … … 105 139 (uint8_t) (x | (irqmask & 0xff))); 106 140 } 107 if (irqmask >> PIC0_IRQ_COUNT) {141 if (irqmask >> I8259_IRQ_COUNT) { 108 142 x = pio_read_8(&saved_pic1->port2); 109 143 pio_write_8(&saved_pic1->port2, 110 (uint8_t) (x | (irqmask >> PIC0_IRQ_COUNT)));144 (uint8_t) (x | (irqmask >> I8259_IRQ_COUNT))); 111 145 } 112 146 } 113 147 114 void pic_eoi(unsigned int irq)148 void i8259_eoi(unsigned int irq) 115 149 { 116 if (irq >= PIC0_IRQ_COUNT)117 pio_write_8(&saved_pic1->port1, PIC_OCW4 | PIC_OCW4_NSEOI);118 pio_write_8(&saved_pic0->port1, PIC_OCW4 | PIC_OCW4_NSEOI);150 if (irq >= I8259_IRQ_COUNT) 151 pio_write_8(&saved_pic1->port1, I8259_OCW4 | I8259_OCW4_NSEOI); 152 pio_write_8(&saved_pic0->port1, I8259_OCW4 | I8259_OCW4_NSEOI); 119 153 } 120 154 121 bool pic_is_spurious(unsigned int irq)155 bool i8259_is_spurious(unsigned int irq) 122 156 { 123 pio_write_8(&saved_pic0->port1, PIC_OCW3 | PIC_OCW3_READ_ISR);124 pio_write_8(&saved_pic1->port1, PIC_OCW3 | PIC_OCW3_READ_ISR);157 pio_write_8(&saved_pic0->port1, I8259_OCW3 | I8259_OCW3_READ_ISR); 158 pio_write_8(&saved_pic1->port1, I8259_OCW3 | I8259_OCW3_READ_ISR); 125 159 uint8_t isr_lo = pio_read_8(&saved_pic0->port1); 126 160 uint8_t isr_hi = pio_read_8(&saved_pic1->port1); 127 return !(((isr_hi << PIC0_IRQ_COUNT) | isr_lo) & (1 << irq));161 return !(((isr_hi << I8259_IRQ_COUNT) | isr_lo) & (1 << irq)); 128 162 } 129 163 130 void pic_handle_spurious(unsigned int irq)164 void i8259_handle_spurious(unsigned int irq) 131 165 { 132 166 /* For spurious IRQs from pic1, we need to isssue an EOI to pic0 */ 133 if (irq >= PIC0_IRQ_COUNT)134 pio_write_8(&saved_pic0->port1, PIC_OCW4 | PIC_OCW4_NSEOI);167 if (irq >= I8259_IRQ_COUNT) 168 pio_write_8(&saved_pic0->port1, I8259_OCW4 | I8259_OCW4_NSEOI); 135 169 } 136 170
Note:
See TracChangeset
for help on using the changeset viewer.