Establish mappings during reply, #248

Caller thread sends echo thread mapping information. Echo thread
establish during reply the mappings.

Fixes #248
This commit is contained in:
Alexander Boettcher 2012-06-20 16:33:43 +02:00 committed by Norman Feske
parent 9ebbf9c9f2
commit 0bf642ff9a
3 changed files with 44 additions and 11 deletions

View File

@ -217,9 +217,11 @@ namespace Nova {
return sel_hotspot << 12;
}
mword_t addr() const { return base() << BASE_SHIFT; }
mword_t base() const { return _query<BASE_MASK, BASE_SHIFT>(); }
mword_t order() const { return _query<ORDER_MASK, ORDER_SHIFT>(); }
bool is_null() const { return (_value & TYPE_MASK) == NULL_CRD_TYPE; }
uint8_t type() const { return _query<TYPE_MASK, TYPE_SHIFT>(); }
} __attribute__((packed));

View File

@ -34,7 +34,26 @@ inline void *echo_stack_top()
/**
* IDC handler for the echo portal, executed by the echo EC
*/ static void echo_reply(){ Nova::reply(echo_stack_top()); }
*/
static void echo_reply()
{
/* collect map information from calling thread, sent as 3 words */
Nova::Crd snd_rcv(echo()->utcb()->msg[0]);
Nova::mword_t offset = echo()->utcb()->msg[1];
bool kern_pd = echo()->utcb()->msg[2];
/* reset message transfer descriptor */
echo()->utcb()->set_msg_word(0);
/* append capability-range as message-transfer item */
bool res = echo()->utcb()->append_item(snd_rcv, offset, kern_pd);
/* set return code, 0 means failure */
echo()->utcb()->msg[0] = res;
echo()->utcb()->items += 1;
/* during reply the mapping will be established */
Nova::reply(echo_stack_top());
}
Echo::Echo(Genode::addr_t utcb_addr)
@ -56,6 +75,9 @@ Echo::Echo(Genode::addr_t utcb_addr)
/* set up echo portal to ourself */
res = create_pt(_pt_sel, pd_sel, _ec_sel, Mtd(0), (mword_t)echo_reply);
if (res) { ((void (*)())(res*0x10001UL))(); }
/* echo thread doesn't receive anything, it transfers items during reply */
utcb()->crd_rcv = utcb()->crd_xlt = 0;
}

View File

@ -45,19 +45,28 @@ enum { verbose_local_map = false };
static int map_local(Nova::Utcb *utcb, Nova::Crd src_crd, Nova::Crd dst_crd,
bool kern_pd = false)
{
/* open receive window at the echo EC */
echo()->utcb()->crd_rcv = dst_crd;
/* open receive window at current EC */
utcb->crd_rcv = dst_crd;
/* reset message transfer descriptor */
utcb->set_msg_word(0);
/* tell echo thread what to map */
utcb->msg[0] = src_crd.value();
utcb->msg[1] = 0;
utcb->msg[2] = kern_pd;
utcb->set_msg_word(3);
/* append capability-range as message-transfer item */
utcb->append_item(src_crd, 0, kern_pd);
/* establish the mapping via a portal traversal during reply phase */
Nova::uint8_t res = Nova::call(echo()->pt_sel());
if (res != 0 || utcb->msg_words() != 1 || !utcb->msg[0]) {
PERR("Failure - map_local 0x%lx:%lu:%u->0x%lx:%lu:%u - call result=%x utcb=%x:%lx !!!",
src_crd.addr(), src_crd.order(), src_crd.type(),
dst_crd.addr(), dst_crd.order(), dst_crd.type(),
res, utcb->msg_words(), utcb->msg[0]);
return res > 0 ? res : -1;
}
/* clear receive window */
utcb->crd_rcv = 0;
/* establish the mapping via a portal traversal */
if (echo()->pt_sel() == 0)
PWRN("call to pt 0");
return Nova::call(echo()->pt_sel());
return 0;
}