mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-09 04:15:52 +00:00
nova: request native ec cap via pager
Prerequisite to get rid of the base-nova special native_cap method in cpu_session. Vancouver/Seoul bootstrap code gets also much simpler. Issue #478
This commit is contained in:
parent
d3bcafc4c6
commit
dd2e006309
@ -29,8 +29,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,
|
||||
inline void request_event_portal(Genode::Native_capability const &cap,
|
||||
Genode::addr_t sel, Genode::addr_t event,
|
||||
unsigned short log2_count = 0)
|
||||
{
|
||||
using namespace Nova;
|
||||
@ -40,7 +40,7 @@ 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, log2_count);
|
||||
utcb->crd_rcv = Obj_crd(sel, log2_count);
|
||||
utcb->msg[0] = event;
|
||||
utcb->msg[1] = log2_count;
|
||||
utcb->set_msg_word(2);
|
||||
@ -53,4 +53,9 @@ inline void request_event_portal(Genode::Native_capability cap,
|
||||
utcb->crd_rcv = orig_crd;
|
||||
}
|
||||
|
||||
|
||||
inline void request_native_ec_cap(Genode::Native_capability const &cap,
|
||||
Genode::addr_t sel) {
|
||||
request_event_portal(cap, sel , ~0U, 0); }
|
||||
|
||||
#endif /* _NOVA__INCLUDE__UTIL_H_ */
|
||||
|
@ -192,18 +192,37 @@ void Pager_object::_invoke_handler()
|
||||
/* send single portal as reply */
|
||||
addr_t const event = utcb->msg[0];
|
||||
addr_t const logcount = utcb->msg[1];
|
||||
|
||||
utcb->mtd = 0;
|
||||
utcb->set_msg_word(0);
|
||||
|
||||
if (event == ~0UL) {
|
||||
/**
|
||||
* Return native EC cap with specific rights mask set.
|
||||
* If the cap is mapped the kernel will demote the
|
||||
* rights of the EC as specified by the rights mask.
|
||||
*
|
||||
* The cap is supposed to be returned to clients,
|
||||
* which they have to use as argument to identify
|
||||
* the thread to which they want attach portals.
|
||||
*
|
||||
* The demotion by the kernel during the map operation
|
||||
* takes care that the EC cap itself contains
|
||||
* no usable rights for the clients.
|
||||
*/
|
||||
bool res = utcb->append_item(Obj_crd(obj->_state.sel_client_ec, 0,
|
||||
Obj_crd::RIGHT_EC_RECALL), 0);
|
||||
(void)res;
|
||||
reply(myself->stack_top());
|
||||
}
|
||||
|
||||
/* sanity check - if event is not valid return nothing */
|
||||
if (logcount > NUM_INITIAL_PT_LOG2 || event > 1UL << NUM_INITIAL_PT_LOG2 ||
|
||||
event + (1UL << logcount) > (1UL << NUM_INITIAL_PT_LOG2))
|
||||
reply(myself->stack_top());
|
||||
|
||||
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 */
|
||||
bool res = utcb->append_item(Obj_crd(obj->exc_pt_sel_client() + event,
|
||||
logcount), 0);
|
||||
(void)res;
|
||||
|
||||
reply(myself->stack_top());
|
||||
|
@ -166,11 +166,11 @@ void Thread_base::start()
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
/* request native EC thread cap */
|
||||
Genode::Cpu_session_client cpu(env()->cpu_session_cap());
|
||||
Native_capability ec_cap = cpu.native_cap(_thread_cap);
|
||||
if (!ec_cap.valid())
|
||||
_tid.ec_sel = cap_selector_allocator()->alloc();
|
||||
if (_tid.ec_sel == Native_thread::INVALID_INDEX)
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
_tid.ec_sel = ec_cap.local_name();
|
||||
|
||||
request_native_ec_cap(_pager_cap, _tid.ec_sel);
|
||||
|
||||
using namespace Nova;
|
||||
|
||||
|
@ -49,7 +49,6 @@
|
||||
#include <os/alarm.h>
|
||||
#include <os/synced_interface.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <nova_cpu_session/connection.h>
|
||||
#include <rtc_session/connection.h>
|
||||
|
||||
/* NOVA includes that come with Genode */
|
||||
@ -317,15 +316,7 @@ class Vcpu_thread : Genode::Thread<STACK_SIZE>
|
||||
* Request native EC thread cap and put it next to the
|
||||
* SM cap - see Vcpu_dispatcher->sel_sm_ec description
|
||||
*/
|
||||
|
||||
Nova_cpu_connection cpu;
|
||||
/* Use selector next to SM cap to retrieve EC cap */
|
||||
cpu.rcv_window(sel_ec);
|
||||
|
||||
Native_capability ec_cap = cpu.native_cap(_thread_cap);
|
||||
|
||||
if (!ec_cap.valid() || sel_ec != ec_cap.local_name())
|
||||
Logging::panic("Could not collocate EC cap");
|
||||
request_native_ec_cap(_pager_cap, sel_ec);
|
||||
}
|
||||
|
||||
void entry() { }
|
||||
@ -815,47 +806,9 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/* create new pager object and assign it to the new thread */
|
||||
Pager_capability const pager_cap =
|
||||
env()->rm_session()->add_client(_thread_cap);
|
||||
|
||||
if (!pager_cap.valid())
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
if (env()->cpu_session()->set_pager(_thread_cap, pager_cap))
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
env()->cpu_session()->state(_thread_cap,
|
||||
Thread_state(false, _tid.exc_pt_sel));
|
||||
|
||||
addr_t const thread_sp = (addr_t)&_context->stack[-4];
|
||||
|
||||
if (env()->cpu_session()->start(_thread_cap, 0, thread_sp))
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
/* Request exception portals for vCPU dispatcher */
|
||||
for (unsigned i = 0; i < Nova::PT_SEL_PARENT; i++)
|
||||
request_event_portal(pager_cap, _tid.exc_pt_sel, i);
|
||||
|
||||
request_event_portal(pager_cap, _tid.exc_pt_sel,
|
||||
Nova::SM_SEL_EC);
|
||||
request_event_portal(pager_cap, _tid.exc_pt_sel,
|
||||
Nova::PT_SEL_RECALL);
|
||||
|
||||
/**
|
||||
* Request native thread cap, _thread_cap only a token.
|
||||
* The native thread cap is required to attach new rpc objects
|
||||
* (to create portals bound to the ec)
|
||||
*/
|
||||
Genode::Nova_cpu_connection cpu;
|
||||
Native_capability ec_cap = cpu.native_cap(_thread_cap);
|
||||
_tid.ec_sel = ec_cap.local_name();
|
||||
|
||||
/* init utcb of dispatcher thread */
|
||||
Nova::Utcb * utcb = reinterpret_cast<Nova::Utcb *>(&_context->utcb);
|
||||
utcb->set_msg_word(0);
|
||||
utcb->crd_xlt = Nova::Crd(0);
|
||||
utcb->crd_rcv = Nova::Crd(0);
|
||||
/* request creation of a 'local' EC */
|
||||
_tid.ec_sel = Native_thread::INVALID_INDEX - 1;
|
||||
Thread_base::start();
|
||||
|
||||
using namespace Nova;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user