From d3bcafc4c68f8bfc737aa12158af654909c1b788 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Mon, 23 Sep 2013 10:44:50 +0200 Subject: [PATCH] nova: support requesting multiple event portals Enables us to request the exception handler portals at once instead each separately. Issue #478 --- base-nova/include/nova/util.h | 11 ++++++----- base-nova/src/base/pager/pager.cc | 18 +++++++++++------- base-nova/src/base/thread/thread_nova.cc | 7 +------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/base-nova/include/nova/util.h b/base-nova/include/nova/util.h index e884d0713..889b18032 100644 --- a/base-nova/include/nova/util.h +++ b/base-nova/include/nova/util.h @@ -30,7 +30,8 @@ inline void nova_die(const char * text = 0) 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; 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; /* 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->set_msg_word(1); + utcb->msg[1] = log2_count; + utcb->set_msg_word(2); uint8_t res = call(cap.local_name()); if (res) - PERR("request of event (%lu) capability selector failed", - event); + PERR("request of event (%lu) capability selector failed", event); /* restore original receive window */ utcb->crd_rcv = orig_crd; diff --git a/base-nova/src/base/pager/pager.cc b/base-nova/src/base/pager/pager.cc index 0b24d56ed..659fbb042 100644 --- a/base-nova/src/base/pager/pager.cc +++ b/base-nova/src/base/pager/pager.cc @@ -190,17 +190,21 @@ void Pager_object::_invoke_handler() Utcb *utcb = _check_handler(myself, obj); /* 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->set_msg_word(0); - if (event < PT_SEL_PARENT || event == PT_SEL_STARTUP || - event == SM_SEL_EC || event == PT_SEL_RECALL) { + if (logcount > NUM_INITIAL_PT_LOG2 || event > 1UL << NUM_INITIAL_PT_LOG2 || + 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); - /* one item ever fits on the UTCB */ - (void)res; - } + utcb->mtd = 0; + utcb->set_msg_word(0); + + 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()); } diff --git a/base-nova/src/base/thread/thread_nova.cc b/base-nova/src/base/thread/thread_nova.cc index 0f16a9c83..6547218ad 100644 --- a/base-nova/src/base/thread/thread_nova.cc +++ b/base-nova/src/base/thread/thread_nova.cc @@ -176,12 +176,7 @@ void Thread_base::start() /* request exception portals for normal threads */ if (!_tid.is_vcpu) { - for (unsigned i = 0; i < PT_SEL_PARENT; i++) - 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); + request_event_portal(_pager_cap, _tid.exc_pt_sel, 0, NUM_INITIAL_PT_LOG2); /* default: we don't accept any mappings or translations */ Utcb * utcb_obj = reinterpret_cast(utcb());