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:
Alexander Boettcher 2013-09-23 10:44:50 +02:00 committed by Norman Feske
parent c426bac8bb
commit d3bcafc4c6
3 changed files with 18 additions and 18 deletions

View File

@ -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;

View File

@ -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());
}

View File

@ -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 *>(utcb());