mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01: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:
committed by
Christian Helmuth
parent
00c9ac363f
commit
fa124dd340
@@ -65,11 +65,14 @@ class Lx_kit::Device : List<Device>::Element
|
|||||||
Index idx;
|
Index idx;
|
||||||
unsigned number;
|
unsigned number;
|
||||||
Io_signal_handler<Irq> handler;
|
Io_signal_handler<Irq> handler;
|
||||||
|
bool masked { true };
|
||||||
|
bool occured { false };
|
||||||
|
|
||||||
Constructible<Platform::Device::Irq> session {};
|
Constructible<Platform::Device::Irq> session {};
|
||||||
|
|
||||||
Irq(Entrypoint & ep, unsigned idx, unsigned number);
|
Irq(Entrypoint & ep, unsigned idx, unsigned number);
|
||||||
|
|
||||||
|
void _handle();
|
||||||
void handle();
|
void handle();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ int lx_emul_irq_task_function(void * data)
|
|||||||
lx_emul_irq_last());
|
lx_emul_irq_last());
|
||||||
} else {
|
} else {
|
||||||
generic_handle_irq(irq);
|
generic_handle_irq(irq);
|
||||||
|
lx_emul_irq_eoi(irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
irq_exit();
|
irq_exit();
|
||||||
|
|||||||
@@ -42,11 +42,22 @@ bool Device::Io_port::match(uint16_t addr)
|
|||||||
** Device::Irq**
|
** Device::Irq**
|
||||||
****************/
|
****************/
|
||||||
|
|
||||||
|
void Device::Irq::_handle()
|
||||||
|
{
|
||||||
|
handle();
|
||||||
|
env().scheduler.schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Device::Irq::handle()
|
void Device::Irq::handle()
|
||||||
{
|
{
|
||||||
|
occured = true;
|
||||||
|
|
||||||
|
if (masked)
|
||||||
|
return;
|
||||||
|
|
||||||
env().last_irq = number;
|
env().last_irq = number;
|
||||||
env().scheduler.unblock_irq_handler();
|
env().scheduler.unblock_irq_handler();
|
||||||
env().scheduler.schedule();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -54,7 +65,7 @@ Device::Irq::Irq(Entrypoint & ep, unsigned idx, unsigned number)
|
|||||||
:
|
:
|
||||||
idx{idx},
|
idx{idx},
|
||||||
number(number),
|
number(number),
|
||||||
handler(ep, *this, &Irq::handle) { }
|
handler(ep, *this, &Irq::_handle) { }
|
||||||
|
|
||||||
|
|
||||||
/************
|
/************
|
||||||
@@ -139,12 +150,14 @@ bool Device::irq_unmask(unsigned number)
|
|||||||
ret = true;
|
ret = true;
|
||||||
enable();
|
enable();
|
||||||
|
|
||||||
if (irq.session.constructed())
|
if (!irq.session.constructed()) {
|
||||||
return;
|
irq.session.construct(*_pdev, irq.idx);
|
||||||
|
irq.session->sigh_omit_initial_signal(irq.handler);
|
||||||
|
irq.session->ack();
|
||||||
|
}
|
||||||
|
|
||||||
irq.session.construct(*_pdev, irq.idx);
|
irq.masked = false;
|
||||||
irq.session->sigh_omit_initial_signal(irq.handler);
|
if (irq.occured) irq.handle();
|
||||||
irq.session->ack();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -157,10 +170,7 @@ void Device::irq_mask(unsigned number)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for_each_irq([&] (Irq & irq) {
|
for_each_irq([&] (Irq & irq) {
|
||||||
if (irq.number != number)
|
if (irq.number == number) irq.masked = true; });
|
||||||
return;
|
|
||||||
irq.session.destruct();
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,8 +181,9 @@ void Device::irq_ack(unsigned number)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for_each_irq([&] (Irq & irq) {
|
for_each_irq([&] (Irq & irq) {
|
||||||
if (irq.number != number || !irq.session.constructed())
|
if (irq.number != number || !irq.occured || !irq.session.constructed())
|
||||||
return;
|
return;
|
||||||
|
irq.occured = false;
|
||||||
irq.session->ack();
|
irq.session->ack();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user