From cb676f12111f52bbb3fb9b784a8b88a998729353 Mon Sep 17 00:00:00 2001 From: Liav A Date: Fri, 20 Mar 2020 16:52:14 +0200 Subject: Interrupts: Do a specific EOI when using the PIC Before this change, we did a non-specific EOI, which could lead to problems with other IRQs that are handled in the PIC. Since the original 8259A datasheet permits such functionality and we are not losing any functionality, this change is acceptable even though we don't experience problems with the EOI currently. --- Kernel/Interrupts/PIC.cpp | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'Kernel') diff --git a/Kernel/Interrupts/PIC.cpp b/Kernel/Interrupts/PIC.cpp index e5f1ca20fe..a471f4a699 100644 --- a/Kernel/Interrupts/PIC.cpp +++ b/Kernel/Interrupts/PIC.cpp @@ -66,9 +66,9 @@ void PIC::disable(const GenericInterruptHandler& handler) ASSERT(handler.interrupt_number() >= gsi_base() && handler.interrupt_number() < interrupt_vectors_count()); u8 irq = handler.interrupt_number(); u8 imr; - if (irq >= 8) { + if (irq & 8) { imr = IO::in8(PIC1_CMD); - imr |= 1 << (irq - 8); + imr |= 1 << (irq & 7); IO::out8(PIC1_CMD, imr); } else { imr = IO::in8(PIC0_CMD); @@ -88,16 +88,20 @@ PIC::PIC() void PIC::spurious_eoi(const GenericInterruptHandler& handler) const { ASSERT(handler.type() == HandlerType::SpuriousInterruptHandler); - if (handler.interrupt_number() == 15) - eoi_interrupt(7); + if (handler.interrupt_number() == 7) + return; + if (handler.interrupt_number() == 15) { + IO::in8(PIC1_CMD); /* dummy read */ + IO::out8(PIC0_CTL, 0x60 | (2)); + } } bool PIC::is_vector_enabled(u8 irq) const { u8 imr; - if (irq >= 8) { + if (irq & 8) { imr = IO::in8(PIC1_CMD); - imr &= 1 << (irq - 8); + imr &= 1 << (irq & 7); } else { imr = IO::in8(PIC0_CMD); imr &= 1 << irq; @@ -118,9 +122,9 @@ void PIC::enable_vector(u8 irq) InterruptDisabler disabler; ASSERT(!is_hard_disabled()); u8 imr; - if (irq >= 8) { + if (irq & 8) { imr = IO::in8(PIC1_CMD); - imr &= ~(1 << (irq - 8)); + imr &= ~(1 << (irq & 7)); IO::out8(PIC1_CMD, imr); } else { imr = IO::in8(PIC0_CMD); @@ -140,9 +144,14 @@ void PIC::eoi(const GenericInterruptHandler& handler) const void PIC::eoi_interrupt(u8 irq) const { - if (irq >= 8) - IO::out8(PIC1_CTL, 0x20); - IO::out8(PIC0_CTL, 0x20); + if (irq & 8) { + IO::in8(PIC1_CMD); /* dummy read */ + IO::out8(PIC1_CTL, 0x60 | (irq & 7)); + IO::out8(PIC0_CTL, 0x60 | (2)); + return; + } + IO::in8(PIC0_CMD); /* dummy read */ + IO::out8(PIC0_CTL, 0x60 | irq); } void PIC::complete_eoi() const @@ -175,8 +184,8 @@ void PIC::remap(u8 offset) IO::out8(PIC1_CMD, SLAVE_INDEX); /* ICW4 (set x86 mode) */ - IO::out8(PIC0_CMD, 0x01); - IO::out8(PIC1_CMD, 0x01); + IO::out8(PIC0_CMD, ICW4_8086); + IO::out8(PIC1_CMD, ICW4_8086); // Mask -- start out with all IRQs disabled. IO::out8(PIC0_CMD, 0xff); @@ -201,8 +210,8 @@ void PIC::initialize() IO::out8(PIC1_CMD, SLAVE_INDEX); /* ICW4 (set x86 mode) */ - IO::out8(PIC0_CMD, 0x01); - IO::out8(PIC1_CMD, 0x01); + IO::out8(PIC0_CMD, ICW4_8086); + IO::out8(PIC1_CMD, ICW4_8086); // Mask -- start out with all IRQs disabled. IO::out8(PIC0_CMD, 0xff); -- cgit v1.2.3