mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-10 21:01:49 +00:00
lx_kit: do not close/re-open IRQ session
Instead of dynamically close/open IRQ session whenever an IRQ gots masked/unmasked, track the state internally and resp. deliver an interrupt delayed.
This commit is contained in:
parent
00c9ac363f
commit
fa124dd340
@ -65,11 +65,14 @@ class Lx_kit::Device : List<Device>::Element
|
||||
Index idx;
|
||||
unsigned number;
|
||||
Io_signal_handler<Irq> handler;
|
||||
bool masked { true };
|
||||
bool occured { false };
|
||||
|
||||
Constructible<Platform::Device::Irq> session {};
|
||||
|
||||
Irq(Entrypoint & ep, unsigned idx, unsigned number);
|
||||
|
||||
void _handle();
|
||||
void handle();
|
||||
};
|
||||
|
||||
|
@ -60,6 +60,7 @@ int lx_emul_irq_task_function(void * data)
|
||||
lx_emul_irq_last());
|
||||
} else {
|
||||
generic_handle_irq(irq);
|
||||
lx_emul_irq_eoi(irq);
|
||||
}
|
||||
|
||||
irq_exit();
|
||||
|
@ -42,11 +42,22 @@ bool Device::Io_port::match(uint16_t addr)
|
||||
** Device::Irq**
|
||||
****************/
|
||||
|
||||
void Device::Irq::_handle()
|
||||
{
|
||||
handle();
|
||||
env().scheduler.schedule();
|
||||
}
|
||||
|
||||
|
||||
void Device::Irq::handle()
|
||||
{
|
||||
occured = true;
|
||||
|
||||
if (masked)
|
||||
return;
|
||||
|
||||
env().last_irq = number;
|
||||
env().scheduler.unblock_irq_handler();
|
||||
env().scheduler.schedule();
|
||||
}
|
||||
|
||||
|
||||
@ -54,7 +65,7 @@ Device::Irq::Irq(Entrypoint & ep, unsigned idx, unsigned number)
|
||||
:
|
||||
idx{idx},
|
||||
number(number),
|
||||
handler(ep, *this, &Irq::handle) { }
|
||||
handler(ep, *this, &Irq::_handle) { }
|
||||
|
||||
|
||||
/************
|
||||
@ -139,12 +150,14 @@ bool Device::irq_unmask(unsigned number)
|
||||
ret = true;
|
||||
enable();
|
||||
|
||||
if (irq.session.constructed())
|
||||
return;
|
||||
if (!irq.session.constructed()) {
|
||||
irq.session.construct(*_pdev, irq.idx);
|
||||
irq.session->sigh_omit_initial_signal(irq.handler);
|
||||
irq.session->ack();
|
||||
}
|
||||
|
||||
irq.session.construct(*_pdev, irq.idx);
|
||||
irq.session->sigh_omit_initial_signal(irq.handler);
|
||||
irq.session->ack();
|
||||
irq.masked = false;
|
||||
if (irq.occured) irq.handle();
|
||||
});
|
||||
|
||||
return ret;
|
||||
@ -157,10 +170,7 @@ void Device::irq_mask(unsigned number)
|
||||
return;
|
||||
|
||||
for_each_irq([&] (Irq & irq) {
|
||||
if (irq.number != number)
|
||||
return;
|
||||
irq.session.destruct();
|
||||
});
|
||||
if (irq.number == number) irq.masked = true; });
|
||||
|
||||
}
|
||||
|
||||
@ -171,8 +181,9 @@ void Device::irq_ack(unsigned number)
|
||||
return;
|
||||
|
||||
for_each_irq([&] (Irq & irq) {
|
||||
if (irq.number != number || !irq.session.constructed())
|
||||
if (irq.number != number || !irq.occured || !irq.session.constructed())
|
||||
return;
|
||||
irq.occured = false;
|
||||
irq.session->ack();
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user