mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 05:47:35 +00:00
Interrupts: Simplify IRQ disabling & enabling in IRQController(s)
Instead of blindly setting masks, if we want to disable an IRQ and it's already masked, we just return. The same happens if we want to enable an IRQ and it's unmasked.
This commit is contained in:
parent
3f98a67d75
commit
0b7fc525e1
5 changed files with 31 additions and 19 deletions
|
@ -54,9 +54,14 @@ namespace Kernel {
|
|||
#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */
|
||||
#define ICW4_SFNM 0x10 /* Special fully nested (not) */
|
||||
|
||||
bool inline static is_all_masked(u8 reg)
|
||||
bool inline static is_all_masked(u16 reg)
|
||||
{
|
||||
return reg == 0xFF;
|
||||
return reg == 0xFFFF;
|
||||
}
|
||||
|
||||
bool PIC::is_enabled() const
|
||||
{
|
||||
return !is_all_masked(m_cached_irq_mask) && !is_hard_disabled();
|
||||
}
|
||||
|
||||
void PIC::disable(const GenericInterruptHandler& handler)
|
||||
|
@ -65,6 +70,8 @@ void PIC::disable(const GenericInterruptHandler& handler)
|
|||
ASSERT(!is_hard_disabled());
|
||||
ASSERT(handler.interrupt_number() >= gsi_base() && handler.interrupt_number() < interrupt_vectors_count());
|
||||
u8 irq = handler.interrupt_number();
|
||||
if (m_cached_irq_mask & (1 << irq))
|
||||
return;
|
||||
u8 imr;
|
||||
if (irq & 8) {
|
||||
imr = IO::in8(PIC1_CMD);
|
||||
|
@ -75,9 +82,7 @@ void PIC::disable(const GenericInterruptHandler& handler)
|
|||
imr |= 1 << irq;
|
||||
IO::out8(PIC0_CMD, imr);
|
||||
}
|
||||
|
||||
if (is_all_masked(imr))
|
||||
m_enabled = false;
|
||||
m_cached_irq_mask |= 1 << irq;
|
||||
}
|
||||
|
||||
PIC::PIC()
|
||||
|
@ -98,15 +103,7 @@ void PIC::spurious_eoi(const GenericInterruptHandler& handler) const
|
|||
|
||||
bool PIC::is_vector_enabled(u8 irq) const
|
||||
{
|
||||
u8 imr;
|
||||
if (irq & 8) {
|
||||
imr = IO::in8(PIC1_CMD);
|
||||
imr &= 1 << (irq & 7);
|
||||
} else {
|
||||
imr = IO::in8(PIC0_CMD);
|
||||
imr &= 1 << irq;
|
||||
}
|
||||
return imr != 0;
|
||||
return m_cached_irq_mask & (1 << irq);
|
||||
}
|
||||
|
||||
void PIC::enable(const GenericInterruptHandler& handler)
|
||||
|
@ -121,6 +118,8 @@ void PIC::enable_vector(u8 irq)
|
|||
{
|
||||
InterruptDisabler disabler;
|
||||
ASSERT(!is_hard_disabled());
|
||||
if (!(m_cached_irq_mask & (1 << irq)))
|
||||
return;
|
||||
u8 imr;
|
||||
if (irq & 8) {
|
||||
imr = IO::in8(PIC1_CMD);
|
||||
|
@ -131,7 +130,7 @@ void PIC::enable_vector(u8 irq)
|
|||
imr &= ~(1 << irq);
|
||||
IO::out8(PIC0_CMD, imr);
|
||||
}
|
||||
m_enabled = true;
|
||||
m_cached_irq_mask &= ~(1 << irq);
|
||||
}
|
||||
|
||||
void PIC::eoi(const GenericInterruptHandler& handler) const
|
||||
|
@ -166,6 +165,7 @@ void PIC::hard_disable()
|
|||
remap(0x20);
|
||||
IO::out8(PIC0_CMD, 0xff);
|
||||
IO::out8(PIC1_CMD, 0xff);
|
||||
m_cached_irq_mask = 0xffff;
|
||||
IRQController::hard_disable();
|
||||
}
|
||||
|
||||
|
@ -190,6 +190,7 @@ void PIC::remap(u8 offset)
|
|||
// Mask -- start out with all IRQs disabled.
|
||||
IO::out8(PIC0_CMD, 0xff);
|
||||
IO::out8(PIC1_CMD, 0xff);
|
||||
m_cached_irq_mask = 0xffff;
|
||||
|
||||
// ...except IRQ2, since that's needed for the master to let through slave interrupts.
|
||||
enable_vector(2);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue