mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 15:32:25 +00:00
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:
parent
9ebbf9c9f2
commit
0bf642ff9a
@ -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));
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user