summaryrefslogtreecommitdiff
path: root/Kernel/Interrupts/PIC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel/Interrupts/PIC.cpp')
-rw-r--r--Kernel/Interrupts/PIC.cpp39
1 files changed, 24 insertions, 15 deletions
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);