nova: support requesting multiple event portals
Enables us to request the exception handler portals at once instead each separately. Issue #478
This commit is contained in:
parent
c426bac8bb
commit
d3bcafc4c6
|
@ -30,7 +30,8 @@ inline void nova_die(const char * text = 0)
|
||||||
|
|
||||||
|
|
||||||
inline void request_event_portal(Genode::Native_capability cap,
|
inline void request_event_portal(Genode::Native_capability cap,
|
||||||
Genode::addr_t exc_base, Genode::addr_t event)
|
Genode::addr_t exc_base, Genode::addr_t event,
|
||||||
|
unsigned short log2_count = 0)
|
||||||
{
|
{
|
||||||
using namespace Nova;
|
using namespace Nova;
|
||||||
Utcb *utcb = (Utcb *)Genode::Thread_base::myself()->utcb();
|
Utcb *utcb = (Utcb *)Genode::Thread_base::myself()->utcb();
|
||||||
|
@ -39,14 +40,14 @@ inline void request_event_portal(Genode::Native_capability cap,
|
||||||
Crd orig_crd = utcb->crd_rcv;
|
Crd orig_crd = utcb->crd_rcv;
|
||||||
|
|
||||||
/* request event-handler portal */
|
/* request event-handler portal */
|
||||||
utcb->crd_rcv = Obj_crd(exc_base + event, 0);
|
utcb->crd_rcv = Obj_crd(exc_base + event, log2_count);
|
||||||
utcb->msg[0] = event;
|
utcb->msg[0] = event;
|
||||||
utcb->set_msg_word(1);
|
utcb->msg[1] = log2_count;
|
||||||
|
utcb->set_msg_word(2);
|
||||||
|
|
||||||
uint8_t res = call(cap.local_name());
|
uint8_t res = call(cap.local_name());
|
||||||
if (res)
|
if (res)
|
||||||
PERR("request of event (%lu) capability selector failed",
|
PERR("request of event (%lu) capability selector failed", event);
|
||||||
event);
|
|
||||||
|
|
||||||
/* restore original receive window */
|
/* restore original receive window */
|
||||||
utcb->crd_rcv = orig_crd;
|
utcb->crd_rcv = orig_crd;
|
||||||
|
|
|
@ -190,17 +190,21 @@ void Pager_object::_invoke_handler()
|
||||||
Utcb *utcb = _check_handler(myself, obj);
|
Utcb *utcb = _check_handler(myself, obj);
|
||||||
|
|
||||||
/* send single portal as reply */
|
/* send single portal as reply */
|
||||||
addr_t event = utcb->msg_words() != 1 ? 0 : utcb->msg[0];
|
addr_t const event = utcb->msg[0];
|
||||||
|
addr_t const logcount = utcb->msg[1];
|
||||||
utcb->mtd = 0;
|
utcb->mtd = 0;
|
||||||
utcb->set_msg_word(0);
|
utcb->set_msg_word(0);
|
||||||
|
|
||||||
if (event < PT_SEL_PARENT || event == PT_SEL_STARTUP ||
|
if (logcount > NUM_INITIAL_PT_LOG2 || event > 1UL << NUM_INITIAL_PT_LOG2 ||
|
||||||
event == SM_SEL_EC || event == PT_SEL_RECALL) {
|
event + (1UL << logcount) > (1UL << NUM_INITIAL_PT_LOG2))
|
||||||
|
reply(myself->stack_top());
|
||||||
|
|
||||||
bool res = utcb->append_item(Obj_crd(obj->exc_pt_sel_client() + event, 0), 0);
|
utcb->mtd = 0;
|
||||||
/* one item ever fits on the UTCB */
|
utcb->set_msg_word(0);
|
||||||
(void)res;
|
|
||||||
}
|
bool res = utcb->append_item(Obj_crd(obj->exc_pt_sel_client() + event, logcount), 0);
|
||||||
|
/* one item ever fits on the UTCB */
|
||||||
|
(void)res;
|
||||||
|
|
||||||
reply(myself->stack_top());
|
reply(myself->stack_top());
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,12 +176,7 @@ void Thread_base::start()
|
||||||
|
|
||||||
/* request exception portals for normal threads */
|
/* request exception portals for normal threads */
|
||||||
if (!_tid.is_vcpu) {
|
if (!_tid.is_vcpu) {
|
||||||
for (unsigned i = 0; i < PT_SEL_PARENT; i++)
|
request_event_portal(_pager_cap, _tid.exc_pt_sel, 0, NUM_INITIAL_PT_LOG2);
|
||||||
request_event_portal(_pager_cap, _tid.exc_pt_sel, i);
|
|
||||||
|
|
||||||
request_event_portal(_pager_cap, _tid.exc_pt_sel, PT_SEL_STARTUP);
|
|
||||||
request_event_portal(_pager_cap, _tid.exc_pt_sel, SM_SEL_EC);
|
|
||||||
request_event_portal(_pager_cap, _tid.exc_pt_sel, PT_SEL_RECALL);
|
|
||||||
|
|
||||||
/* default: we don't accept any mappings or translations */
|
/* default: we don't accept any mappings or translations */
|
||||||
Utcb * utcb_obj = reinterpret_cast<Utcb *>(utcb());
|
Utcb * utcb_obj = reinterpret_cast<Utcb *>(utcb());
|
||||||
|
|
Loading…
Reference in New Issue