mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 11:27:29 +00:00
block: use new server framework in block drivers
As a side effect, the entrypoints in the USB driver are merged into one thread. Fixes #1027
This commit is contained in:
parent
2e99c19601
commit
6a076ff621
@ -4,9 +4,12 @@
|
||||
* \date 2013-02-20
|
||||
*/
|
||||
|
||||
int main()
|
||||
{
|
||||
extern void start_usb_driver();
|
||||
start_usb_driver();
|
||||
return 0;
|
||||
#include <os/server.h>
|
||||
|
||||
extern void start_usb_driver(Server::Entrypoint &e);
|
||||
|
||||
namespace Server {
|
||||
char const *name() { return "usb_drv_ep"; }
|
||||
size_t stack_size() { return 4*1024*sizeof(long); }
|
||||
void construct(Entrypoint &e) { start_usb_driver(e); }
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = usb_drv
|
||||
SRC_CC = main.cc
|
||||
LIBS = usb
|
||||
LIBS = usb server
|
||||
|
@ -246,12 +246,11 @@ namespace Nic {
|
||||
*/
|
||||
Session_component(Dataspace_capability tx_ds,
|
||||
Dataspace_capability rx_ds,
|
||||
Rpc_entrypoint &ep,
|
||||
Signal_receiver *sig_rec,
|
||||
Server::Entrypoint &ep,
|
||||
::Device *device)
|
||||
:
|
||||
Nic::Packet_allocator(Genode::env()->heap()),
|
||||
Packet_session_component(tx_ds, rx_ds, this, ep, sig_rec),
|
||||
Packet_session_component(tx_ds, rx_ds, this, ep),
|
||||
_device(static_cast<Device *>(device)),
|
||||
_tx_sink(Session_rpc_object::_tx.sink()),
|
||||
_tx_alloc(true)
|
||||
@ -296,10 +295,9 @@ namespace Nic {
|
||||
{
|
||||
public:
|
||||
|
||||
Root(Rpc_entrypoint *session_ep, Allocator *md_alloc,
|
||||
Signal_receiver *sig_rec, Device *device)
|
||||
:
|
||||
Packet_root(session_ep, md_alloc, sig_rec, device) { }
|
||||
Root(Server::Entrypoint &ep, Allocator *md_alloc,
|
||||
Device *device)
|
||||
: Packet_root(ep, md_alloc, device) { }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ class Routine : public Genode::List<Routine>::Element
|
||||
char *_stack; /* stack pointer */
|
||||
static Routine *_current; /* currently scheduled object */
|
||||
static Routine *_dead; /* object to remove */
|
||||
static Routine *_main; /* main routine */
|
||||
static bool _all; /* true when all objects must be scheduled */
|
||||
|
||||
|
||||
@ -129,12 +130,16 @@ class Routine : public Genode::List<Routine>::Element
|
||||
*
|
||||
* If all is true, each object will be scheduled once.
|
||||
*/
|
||||
static void schedule(bool all = false) __attribute__((noinline))
|
||||
static void schedule(bool all = false, bool main = false)
|
||||
__attribute__((noinline))
|
||||
{
|
||||
if (!_list()->first())
|
||||
if (!_list()->first() && !_main)
|
||||
return;
|
||||
|
||||
Routine *next = _next(all);
|
||||
if (_current == _main)
|
||||
all = true;
|
||||
|
||||
Routine *next = main ? _main : _next(all);
|
||||
|
||||
if (next == _current) {
|
||||
_check_dead();
|
||||
@ -184,6 +189,22 @@ class Routine : public Genode::List<Routine>::Element
|
||||
schedule();
|
||||
}
|
||||
|
||||
static void main()
|
||||
{
|
||||
if (!_current)
|
||||
return;
|
||||
|
||||
_list()->remove(_current);
|
||||
_main = _current;
|
||||
|
||||
if (_main && _setjmp(_main->_env))
|
||||
return;
|
||||
|
||||
schedule();
|
||||
}
|
||||
|
||||
static void schedule_main() { schedule(false, true); }
|
||||
|
||||
/**
|
||||
* True when 'schedule_all' has been called and is still in progress
|
||||
*/
|
||||
|
@ -17,19 +17,17 @@
|
||||
#include <base/env.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/signal.h>
|
||||
#include <os/server.h>
|
||||
|
||||
#include "routine.h"
|
||||
|
||||
/**
|
||||
* This singelton currently received all signals
|
||||
* This singleton currently received all signals
|
||||
*/
|
||||
class Service_handler
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
Genode::Signal_receiver *_receiver;
|
||||
|
||||
Service_handler() { }
|
||||
|
||||
public:
|
||||
@ -40,8 +38,6 @@ class Service_handler
|
||||
return &_s;
|
||||
}
|
||||
|
||||
void receiver(Genode::Signal_receiver *recv) { _receiver = recv; }
|
||||
|
||||
/**
|
||||
* Dispatch for wait for signal
|
||||
*/
|
||||
@ -52,68 +48,54 @@ class Service_handler
|
||||
return;
|
||||
}
|
||||
|
||||
check_signal();
|
||||
}
|
||||
|
||||
void check_signal(bool block = true)
|
||||
{
|
||||
while (_receiver->pending() || block) {
|
||||
|
||||
Genode::Signal s = _receiver->wait_for_signal();
|
||||
|
||||
/* handle signal IRQ, timer, or event signals */
|
||||
static_cast<Genode::Signal_dispatcher_base *>(s.context())->dispatch(s.num());
|
||||
block = false;
|
||||
}
|
||||
Routine::schedule_main();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper that holds sender and receiver
|
||||
* Helper that holds sender and entrypoint
|
||||
*/
|
||||
class Signal_helper
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Signal_receiver *_receiver;
|
||||
Genode::Signal_transmitter *_sender;
|
||||
|
||||
Server::Entrypoint &_ep;
|
||||
Genode::Signal_transmitter _sender;
|
||||
|
||||
public:
|
||||
|
||||
Signal_helper(Genode::Signal_receiver *recv)
|
||||
: _receiver(recv),
|
||||
_sender(new (Genode::env()->heap()) Genode::Signal_transmitter()) { }
|
||||
Signal_helper(Server::Entrypoint &ep) : _ep(ep) { }
|
||||
|
||||
Genode::Signal_receiver *receiver() const { return _receiver; }
|
||||
Genode::Signal_transmitter *sender() const { return _sender; }
|
||||
Server::Entrypoint &ep() { return _ep; }
|
||||
Genode::Signal_transmitter &sender() { return _sender; }
|
||||
};
|
||||
|
||||
|
||||
namespace Timer
|
||||
{
|
||||
void init(Genode::Signal_receiver *recv);
|
||||
void init(Server::Entrypoint &ep);
|
||||
}
|
||||
|
||||
namespace Irq
|
||||
{
|
||||
void init(Genode::Signal_receiver *recv);
|
||||
void init(Server::Entrypoint &ep);
|
||||
void check_irq();
|
||||
}
|
||||
|
||||
namespace Event
|
||||
{
|
||||
void init(Genode::Signal_receiver *recv);
|
||||
void init(Server::Entrypoint &ep);
|
||||
}
|
||||
|
||||
namespace Storage
|
||||
{
|
||||
void init(Genode::Signal_receiver *recv);
|
||||
void init(Server::Entrypoint &ep);
|
||||
}
|
||||
|
||||
namespace Nic
|
||||
{
|
||||
void init(Genode::Signal_receiver *recv);
|
||||
void init(Server::Entrypoint &ep);
|
||||
}
|
||||
|
||||
#endif /* _SIGNAL_H_ */
|
||||
|
@ -27,7 +27,7 @@ class Packet_session_component : public RPC
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Signal_dispatcher<Packet_session_component> _process_packet_dispatcher;
|
||||
Genode::Signal_rpc_member<Packet_session_component> _dispatcher;
|
||||
|
||||
protected:
|
||||
|
||||
@ -36,37 +36,31 @@ class Packet_session_component : public RPC
|
||||
public:
|
||||
|
||||
Packet_session_component(Genode::Dataspace_capability tx_ds,
|
||||
Genode::Rpc_entrypoint &ep,
|
||||
Genode::Signal_receiver *sig_rec)
|
||||
:
|
||||
RPC(tx_ds, ep),
|
||||
_process_packet_dispatcher(*sig_rec, *this,
|
||||
&Packet_session_component::_process_packets)
|
||||
{
|
||||
Server::Entrypoint &ep)
|
||||
: RPC(tx_ds, ep.rpc_ep()),
|
||||
_dispatcher(ep, *this, &Packet_session_component::_process_packets)
|
||||
{
|
||||
/*
|
||||
* Register '_process_packets' dispatch function as signal
|
||||
* handler for packet-avail and ready-to-ack signals.
|
||||
*/
|
||||
RPC::_tx.sigh_packet_avail(_process_packet_dispatcher);
|
||||
RPC::_tx.sigh_ready_to_ack(_process_packet_dispatcher);
|
||||
RPC::_tx.sigh_packet_avail(_dispatcher);
|
||||
RPC::_tx.sigh_ready_to_ack(_dispatcher);
|
||||
}
|
||||
|
||||
Packet_session_component(Genode::Dataspace_capability tx_ds,
|
||||
Genode::Dataspace_capability rx_ds,
|
||||
Genode::Range_allocator *rx_buffer_alloc,
|
||||
Genode::Rpc_entrypoint &ep,
|
||||
Genode::Signal_receiver *sig_rec)
|
||||
:
|
||||
RPC(tx_ds, rx_ds, rx_buffer_alloc, ep),
|
||||
_process_packet_dispatcher(*sig_rec, *this,
|
||||
&Packet_session_component::_process_packets)
|
||||
{
|
||||
Server::Entrypoint &ep)
|
||||
: RPC(tx_ds, rx_ds, rx_buffer_alloc, ep.rpc_ep()),
|
||||
_dispatcher(ep, *this, &Packet_session_component::_process_packets)
|
||||
{
|
||||
/*
|
||||
* Register '_process_packets' dispatch function as signal
|
||||
* handler for packet-avail and ready-to-ack signals.
|
||||
*/
|
||||
RPC::_tx.sigh_packet_avail(_process_packet_dispatcher);
|
||||
RPC::_tx.sigh_ready_to_ack(_process_packet_dispatcher);
|
||||
RPC::_tx.sigh_packet_avail(_dispatcher);
|
||||
RPC::_tx.sigh_ready_to_ack(_dispatcher);
|
||||
}
|
||||
};
|
||||
|
||||
@ -85,9 +79,8 @@ class Packet_session_component : public RPC
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Rpc_entrypoint &_ep;
|
||||
Genode::Signal_receiver *_sig_rec;
|
||||
Device *_device;
|
||||
Server::Entrypoint &_ep;
|
||||
Device *_device;
|
||||
|
||||
protected:
|
||||
|
||||
@ -125,17 +118,15 @@ class Packet_session_component : public RPC
|
||||
return new (ROOT_COMPONENT::md_alloc())
|
||||
SESSION_COMPONENT(Backend_memory::alloc(tx_buf_size, CACHED),
|
||||
Backend_memory::alloc(rx_buf_size, CACHED),
|
||||
_ep, _sig_rec, _device);
|
||||
_ep, _device);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Packet_root(Genode::Rpc_entrypoint *session_ep, Genode::Allocator *md_alloc,
|
||||
Genode::Signal_receiver *sig_rec, Device *device)
|
||||
:
|
||||
ROOT_COMPONENT(session_ep, md_alloc),
|
||||
_ep(*session_ep), _sig_rec(sig_rec), _device(device)
|
||||
{ }
|
||||
Packet_root(Server::Entrypoint &ep, Genode::Allocator *md_alloc,
|
||||
Device *device)
|
||||
: ROOT_COMPONENT(&ep.rpc_ep(), md_alloc),
|
||||
_ep(ep), _device(device) { }
|
||||
};
|
||||
|
||||
#endif /* _SIGNAL__DISPATCHER_H_ */
|
||||
|
@ -14,11 +14,9 @@
|
||||
|
||||
|
||||
/* Genode */
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <cap_session/connection.h>
|
||||
|
||||
#include <os/server.h>
|
||||
#include <nic_session/nic_session.h>
|
||||
|
||||
/* Local */
|
||||
@ -45,6 +43,7 @@ extern "C" void start_input_service(void *ep);
|
||||
|
||||
Routine *Routine::_current = 0;
|
||||
Routine *Routine::_dead = 0;
|
||||
Routine *Routine::_main = 0;
|
||||
bool Routine::_all = false;
|
||||
|
||||
void breakpoint() { PDBG("BREAK"); }
|
||||
@ -79,34 +78,22 @@ static void init(Services *services)
|
||||
}
|
||||
|
||||
|
||||
void start_usb_driver()
|
||||
void start_usb_driver(Server::Entrypoint &ep)
|
||||
{
|
||||
/*
|
||||
* Initialize server entry point
|
||||
*/
|
||||
enum { STACK_SIZE = 4096 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep_hid(&cap, STACK_SIZE, "usb_hid_ep");
|
||||
static Signal_receiver recv;
|
||||
|
||||
Services services;
|
||||
|
||||
if (services.hid)
|
||||
start_input_service(&ep_hid);
|
||||
start_input_service(&ep.rpc_ep());
|
||||
|
||||
Timer::init(&recv);
|
||||
Irq::init(&recv);
|
||||
Event::init(&recv);
|
||||
Service_handler::s()->receiver(&recv);
|
||||
Storage::init(&recv);
|
||||
Nic::init(&recv);
|
||||
Timer::init(ep);
|
||||
Irq::init(ep);
|
||||
Event::init(ep);
|
||||
Storage::init(ep);
|
||||
Nic::init(ep);
|
||||
|
||||
Routine::add(0, 0, "Main", true);
|
||||
Routine::current_use_first();
|
||||
init(&services);
|
||||
|
||||
Routine::remove();
|
||||
|
||||
/* will never be reached */
|
||||
sleep_forever();
|
||||
Routine::main();
|
||||
}
|
||||
|
@ -283,8 +283,8 @@ class Nic_device : public Nic::Device
|
||||
static Nic_device *_nic = 0;
|
||||
|
||||
|
||||
void Nic::init(Genode::Signal_receiver *recv) {
|
||||
_signal = new (Genode::env()->heap()) Signal_helper(recv); }
|
||||
void Nic::init(Server::Entrypoint &ep) {
|
||||
_signal = new (Genode::env()->heap()) Signal_helper(ep); }
|
||||
|
||||
|
||||
/***********************
|
||||
@ -301,9 +301,7 @@ int register_netdev(struct net_device *ndev)
|
||||
|
||||
/* XXX: move to 'main' */
|
||||
if (!announce) {
|
||||
static Cap_connection cap_nic;
|
||||
static Rpc_entrypoint ep_nic(&cap_nic, 4096, "usb_nic_ep");
|
||||
static Nic::Root root(&ep_nic, env()->heap(), _signal->receiver(), nic);
|
||||
static Nic::Root root(_signal->ep(), env()->heap(), nic);
|
||||
|
||||
announce = true;
|
||||
|
||||
@ -321,7 +319,7 @@ int register_netdev(struct net_device *ndev)
|
||||
ndev->netdev_ops->ndo_change_mtu(ndev, 4000);
|
||||
*/
|
||||
_nic = nic;
|
||||
env()->parent()->announce(ep_nic.manage(&root));
|
||||
env()->parent()->announce(_signal->ep().rpc_ep().manage(&root));
|
||||
}
|
||||
|
||||
return err;
|
||||
|
@ -23,14 +23,14 @@ class Event_context
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Signal_dispatcher<Event_context> _dispatcher;
|
||||
Genode::Signal_rpc_member<Event_context> _dispatcher;
|
||||
|
||||
void _handle(unsigned) {
|
||||
Routine::schedule_all(); }
|
||||
|
||||
Event_context()
|
||||
: _dispatcher(*_signal->receiver(), *this, &Event_context::_handle) {
|
||||
_signal->sender()->context(_dispatcher); }
|
||||
: _dispatcher(_signal->ep(), *this, &Event_context::_handle) {
|
||||
_signal->sender().context(_dispatcher); }
|
||||
|
||||
public:
|
||||
|
||||
@ -41,14 +41,14 @@ class Event_context
|
||||
}
|
||||
|
||||
void submit() {
|
||||
_signal->sender()->submit(); }
|
||||
_signal->sender().submit(); }
|
||||
|
||||
char const *debug() { return "Event_context"; }
|
||||
};
|
||||
|
||||
|
||||
void Event::init(Genode::Signal_receiver *recv) {
|
||||
_signal = new (Genode::env()->heap()) Signal_helper(recv); }
|
||||
void Event::init(Server::Entrypoint &ep) {
|
||||
_signal = new (Genode::env()->heap()) Signal_helper(ep); }
|
||||
|
||||
|
||||
/**
|
||||
|
@ -48,7 +48,7 @@ class Irq_context : public Genode::List<Irq_context>::Element
|
||||
|
||||
unsigned int _irq; /* IRQ number */
|
||||
Genode::List<Irq_handler> _handler_list; /* List of registered handlers */
|
||||
Genode::Signal_dispatcher<Irq_context> _dispatcher;
|
||||
Genode::Signal_rpc_member<Irq_context> _dispatcher;
|
||||
|
||||
static Genode::List<Irq_context> *_list()
|
||||
{
|
||||
@ -82,8 +82,8 @@ class Irq_context : public Genode::List<Irq_context>::Element
|
||||
Irq_context *ctx = static_cast<Irq_context *>(irq);
|
||||
|
||||
/* set context & submit signal */
|
||||
_signal->sender()->context(ctx->_dispatcher);
|
||||
_signal->sender()->submit();
|
||||
_signal->sender().context(ctx->_dispatcher);
|
||||
_signal->sender().submit();
|
||||
|
||||
/* wait for interrupt to get acked at device side */
|
||||
_irq_sync.lock();
|
||||
@ -122,7 +122,7 @@ class Irq_context : public Genode::List<Irq_context>::Element
|
||||
/* report IRQ to all clients */
|
||||
for (Irq_handler *h = _handler_list.first(); h; h = h->next()) {
|
||||
|
||||
if (_handle_one(h))
|
||||
if ((handled = _handle_one(h)))
|
||||
break;
|
||||
|
||||
dde_kit_log(DEBUG_IRQ, "IRQ: %u ret: %u h: %p dev: %p", _irq, handled, h->handler, h->dev);
|
||||
@ -143,7 +143,7 @@ class Irq_context : public Genode::List<Irq_context>::Element
|
||||
|
||||
Irq_context(unsigned int irq)
|
||||
: _irq(irq),
|
||||
_dispatcher(*_signal->receiver(), *this, &Irq_context::_handle)
|
||||
_dispatcher(_signal->ep(), *this, &Irq_context::_handle)
|
||||
{
|
||||
/* register at DDE (shared) */
|
||||
int ret = dde_kit_interrupt_attach(_irq, 0, 0, _dde_handler, this);
|
||||
@ -184,8 +184,8 @@ class Irq_context : public Genode::List<Irq_context>::Element
|
||||
};
|
||||
|
||||
|
||||
void Irq::init(Genode::Signal_receiver *recv) {
|
||||
_signal = new (Genode::env()->heap()) Signal_helper(recv); }
|
||||
void Irq::init(Server::Entrypoint &ep) {
|
||||
_signal = new (Genode::env()->heap()) Signal_helper(ep); }
|
||||
|
||||
|
||||
void Irq::check_irq()
|
||||
|
@ -33,7 +33,7 @@ class Timer_context
|
||||
|
||||
timer_list *_timer; /* Linux timer */
|
||||
dde_kit_timer *_dde_timer; /* DDE kit timer */
|
||||
Genode::Signal_dispatcher<Timer_context> _dispatcher;
|
||||
Genode::Signal_rpc_member<Timer_context> _dispatcher;
|
||||
|
||||
/* call timer function */
|
||||
void _handle(unsigned) { _timer->function(_timer->data); }
|
||||
@ -42,7 +42,7 @@ class Timer_context
|
||||
|
||||
Timer_context(timer_list *timer)
|
||||
: _timer(timer), _dde_timer(0),
|
||||
_dispatcher(*_signal->receiver(), *this, &Timer_context::_handle) {}
|
||||
_dispatcher(_signal->ep(), *this, &Timer_context::_handle) {}
|
||||
|
||||
/* schedule next timeout */
|
||||
void schedule(unsigned long expires)
|
||||
@ -93,13 +93,13 @@ static void handler(void *timer)
|
||||
Timer_context *t = static_cast<Timer_context *>(timer);
|
||||
|
||||
/* set context and submit */
|
||||
_signal->sender()->context(t->cap());
|
||||
_signal->sender()->submit();
|
||||
_signal->sender().context(t->cap());
|
||||
_signal->sender().submit();
|
||||
}
|
||||
|
||||
|
||||
void Timer::init(Genode::Signal_receiver *recv) {
|
||||
_signal = new (Genode::env()->heap()) Signal_helper(recv); }
|
||||
void Timer::init(Server::Entrypoint &ep) {
|
||||
_signal = new (Genode::env()->heap()) Signal_helper(ep); }
|
||||
|
||||
|
||||
/*******************
|
||||
|
@ -180,8 +180,8 @@ class Storage_device : public Genode::List<Storage_device>::Element,
|
||||
};
|
||||
|
||||
|
||||
void Storage::init(Genode::Signal_receiver *recv) {
|
||||
_signal = new (Genode::env()->heap()) Signal_helper(recv); }
|
||||
void Storage::init(Server::Entrypoint &ep) {
|
||||
_signal = new (Genode::env()->heap()) Signal_helper(ep); }
|
||||
|
||||
|
||||
struct Factory : Block::Driver_factory
|
||||
@ -206,11 +206,8 @@ void scsi_add_device(struct scsi_device *sdev)
|
||||
* XXX move to 'main'
|
||||
*/
|
||||
if (!announce) {
|
||||
enum { STACK_SIZE = 1024 * sizeof(addr_t) };
|
||||
static Cap_connection cap_stor;
|
||||
static Rpc_entrypoint ep_stor(&cap_stor, STACK_SIZE, "usb_stor_ep");
|
||||
static Block::Root root(&ep_stor, env()->heap(), factory, *_signal->receiver());
|
||||
env()->parent()->announce(ep_stor.manage(&root));
|
||||
static Block::Root root(_signal->ep(), env()->heap(), factory);
|
||||
env()->parent()->announce(_signal->ep().rpc_ep().manage(&root));
|
||||
announce = true;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ void tx_test() {
|
||||
while (1) {
|
||||
sk_buff *skb = alloc_skb(1066 + HEAD_ROOM, 0);
|
||||
if (!skb) {
|
||||
Service_handler::s()->check_signal(true);
|
||||
Service_handler::s()->check_signal();
|
||||
continue;
|
||||
}
|
||||
skb->len = 1066;
|
||||
|
@ -89,22 +89,24 @@ class Factory : public Block::Driver_factory
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
struct Main
|
||||
{
|
||||
enum { STACK_SIZE = 4*1024 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "http_block_ep");
|
||||
Server::Entrypoint &ep;
|
||||
struct Factory factory;
|
||||
Block::Root root;
|
||||
|
||||
static Signal_receiver receiver;
|
||||
static Factory driver_factory;
|
||||
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver);
|
||||
Main(Server::Entrypoint &ep)
|
||||
: ep(ep), root(ep, Genode::env()->heap(), factory) {
|
||||
Genode::env()->parent()->announce(ep.manage(root)); }
|
||||
};
|
||||
|
||||
env()->parent()->announce(ep.manage(&block_root));
|
||||
|
||||
while (true) {
|
||||
Signal s = receiver.wait_for_signal();
|
||||
static_cast<Signal_dispatcher_base *>(s.context())->dispatch(s.num());
|
||||
}
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
return 0;
|
||||
namespace Server {
|
||||
char const *name() { return "http_blk_ep"; }
|
||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
TARGET = http_blk
|
||||
SRC_CC = main.cc http.cc
|
||||
LIBS = libc libc_lwip_nic_dhcp
|
||||
LIBS = libc libc_lwip_nic_dhcp server
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
#define _INCLUDE__BLOCK__COMPONENT_H_
|
||||
|
||||
#include <root/component.h>
|
||||
#include <os/signal_rpc_dispatcher.h>
|
||||
#include <os/server.h>
|
||||
#include <block_session/rpc_object.h>
|
||||
#include <block/driver.h>
|
||||
|
||||
@ -36,8 +38,8 @@ class Block::Session_component : public Block::Session_rpc_object
|
||||
Driver &_driver;
|
||||
Ram_dataspace_capability _rq_ds;
|
||||
addr_t _rq_phys;
|
||||
Signal_dispatcher<Session_component> _sink_ack;
|
||||
Signal_dispatcher<Session_component> _sink_submit;
|
||||
Signal_rpc_member<Session_component> _sink_ack;
|
||||
Signal_rpc_member<Session_component> _sink_submit;
|
||||
bool _req_queue_full;
|
||||
bool _ack_queue_full;
|
||||
Packet_descriptor _p_to_handle;
|
||||
@ -146,20 +148,18 @@ class Block::Session_component : public Block::Session_rpc_object
|
||||
* \param driver block driver backend
|
||||
* \param driver_factory factory to create and destroy driver objects
|
||||
* \param ep entrypoint handling this session component
|
||||
* \param receiver signal receiver managing signals of the client
|
||||
*/
|
||||
Session_component(Ram_dataspace_capability rq_ds,
|
||||
Driver &driver,
|
||||
Driver_factory &driver_factory,
|
||||
Rpc_entrypoint &ep,
|
||||
Signal_receiver &receiver)
|
||||
: Session_rpc_object(rq_ds, ep),
|
||||
Server::Entrypoint &ep)
|
||||
: Session_rpc_object(rq_ds, ep.rpc_ep()),
|
||||
_driver_factory(driver_factory),
|
||||
_driver(driver),
|
||||
_rq_ds(rq_ds),
|
||||
_rq_phys(Dataspace_client(_rq_ds).phys_addr()),
|
||||
_sink_ack(receiver, *this, &Session_component::_ready_to_ack),
|
||||
_sink_submit(receiver, *this, &Session_component::_packet_avail),
|
||||
_sink_ack(ep, *this, &Session_component::_ready_to_ack),
|
||||
_sink_submit(ep, *this, &Session_component::_packet_avail),
|
||||
_req_queue_full(false),
|
||||
_p_in_fly(0)
|
||||
{
|
||||
@ -224,14 +224,13 @@ class Block::Session_component : public Block::Session_rpc_object
|
||||
/**
|
||||
* Root component, handling new session requests
|
||||
*/
|
||||
class Block::Root :
|
||||
public Genode::Root_component<Block::Session_component, Single_client>
|
||||
class Block::Root : public Genode::Root_component<Block::Session_component,
|
||||
Single_client>
|
||||
{
|
||||
private:
|
||||
|
||||
Driver_factory &_driver_factory;
|
||||
Rpc_entrypoint &_ep;
|
||||
Signal_receiver &_receiver;
|
||||
Driver_factory &_driver_factory;
|
||||
Server::Entrypoint &_ep;
|
||||
|
||||
protected:
|
||||
|
||||
@ -267,8 +266,7 @@ class Block::Root :
|
||||
Ram_dataspace_capability ds_cap;
|
||||
ds_cap = driver->alloc_dma_buffer(tx_buf_size);
|
||||
return new (md_alloc())
|
||||
Session_component(ds_cap, *driver, _driver_factory, _ep,
|
||||
_receiver);
|
||||
Session_component(ds_cap, *driver, _driver_factory, _ep);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -276,18 +274,15 @@ class Block::Root :
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param session_ep entrypoint handling this root component
|
||||
* \param ep entrypoint handling this root component
|
||||
* \param md_alloc allocator to allocate session components
|
||||
* \param driver_factory factory to create and destroy driver backend
|
||||
* \param receiver signal receiver managing signals of the client
|
||||
*/
|
||||
Root(Rpc_entrypoint *session_ep, Allocator *md_alloc,
|
||||
Driver_factory &driver_factory, Signal_receiver &receiver)
|
||||
:
|
||||
Root_component(session_ep, md_alloc),
|
||||
_driver_factory(driver_factory), _ep(*session_ep),
|
||||
_receiver(receiver)
|
||||
{ }
|
||||
Root(Server::Entrypoint &ep, Allocator *md_alloc,
|
||||
Driver_factory &driver_factory)
|
||||
: Root_component(&ep.rpc_ep(), md_alloc),
|
||||
_driver_factory(driver_factory), _ep(ep) { }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__BLOCK__COMPONENT_H_ */
|
||||
|
@ -53,18 +53,10 @@ struct Genode::Signal_rpc_dispatcher_base : Genode::Signal_dispatcher_base
|
||||
|
||||
Proxy_component _proxy;
|
||||
Capability<Proxy> _proxy_cap;
|
||||
unsigned _nesting_level;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* To be implemented by the derived class
|
||||
*/
|
||||
virtual void dispatch_at_entrypoint(unsigned num) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
Signal_rpc_dispatcher_base() : _proxy(*this), _nesting_level(0) { }
|
||||
Signal_rpc_dispatcher_base() : _proxy(*this) { }
|
||||
|
||||
Capability<Proxy> proxy_cap() { return _proxy_cap; }
|
||||
|
||||
@ -94,26 +86,13 @@ struct Genode::Signal_rpc_dispatcher_base : Genode::Signal_dispatcher_base
|
||||
/**
|
||||
* Interface of Signal_dispatcher_base
|
||||
*/
|
||||
void dispatch(unsigned num)
|
||||
{
|
||||
/*
|
||||
* Keep track of nesting levels to deal with nested signal
|
||||
* dispatching. When called from within the RPC entrypoint, any
|
||||
* attempt to perform a RPC call would lead to a deadlock. In
|
||||
* this case, we call the 'dispatch' function directly.
|
||||
*/
|
||||
_nesting_level++;
|
||||
void dispatch(unsigned num) {
|
||||
proxy_cap().call<Proxy::Rpc_handle_signal>(num); }
|
||||
|
||||
/* called from the signal-receiving thread */
|
||||
if (_nesting_level == 1)
|
||||
proxy_cap().call<Proxy::Rpc_handle_signal>(num);
|
||||
|
||||
/* called from the context of the RPC entrypoint */
|
||||
if (_nesting_level > 1)
|
||||
dispatch_at_entrypoint(num);
|
||||
|
||||
_nesting_level--;
|
||||
}
|
||||
/**
|
||||
* To be implemented by the derived class
|
||||
*/
|
||||
virtual void dispatch_at_entrypoint(unsigned num) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -17,40 +17,47 @@
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <cap_session/connection.h>
|
||||
#include <block/component.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include <ahci_driver.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("--- AHCI driver started ---\n");
|
||||
|
||||
struct Ahci_driver_factory : Block::Driver_factory
|
||||
struct Main
|
||||
{
|
||||
Server::Entrypoint &ep;
|
||||
|
||||
struct Factory : Block::Driver_factory
|
||||
{
|
||||
Block::Driver *create() {
|
||||
return new(env()->heap()) Ahci_driver(); }
|
||||
|
||||
void destroy(Block::Driver *driver) {
|
||||
Genode::destroy(env()->heap(), static_cast<Ahci_driver *>(driver)); }
|
||||
} driver_factory;
|
||||
} factory;
|
||||
|
||||
enum { STACK_SIZE = 8128 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "block_ep");
|
||||
Block::Root root;
|
||||
|
||||
static Signal_receiver receiver;
|
||||
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver);
|
||||
env()->parent()->announce(ep.manage(&block_root));
|
||||
Main(Server::Entrypoint &ep)
|
||||
: ep(ep), root(ep, Genode::env()->heap(), factory)
|
||||
{
|
||||
printf("--- AHCI driver started ---\n");
|
||||
|
||||
while (true) {
|
||||
Signal s = receiver.wait_for_signal();
|
||||
static_cast<Signal_dispatcher_base *>(s.context())->dispatch(s.num());
|
||||
Genode::env()->parent()->announce(ep.manage(root));
|
||||
}
|
||||
};
|
||||
|
||||
return 0;
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
namespace Server {
|
||||
char const *name() { return "ahci_ep"; }
|
||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = ahci
|
||||
LIBS += ahci
|
||||
LIBS += ahci server
|
||||
SRC_CC += empty.cc
|
||||
|
@ -13,9 +13,8 @@
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <os/config.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include "ata_device.h"
|
||||
@ -65,22 +64,24 @@ struct Factory : Block::Driver_factory
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
struct Main
|
||||
{
|
||||
enum { STACK_SIZE = 8192 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "atapi_ep");
|
||||
Server::Entrypoint &ep;
|
||||
struct Factory factory;
|
||||
Block::Root root;
|
||||
|
||||
static Signal_receiver receiver;
|
||||
static Factory driver_factory;
|
||||
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver);
|
||||
Main(Server::Entrypoint &ep)
|
||||
: ep(ep), root(ep, Genode::env()->heap(), factory) {
|
||||
Genode::env()->parent()->announce(ep.manage(root)); }
|
||||
};
|
||||
|
||||
env()->parent()->announce(ep.manage(&block_root));
|
||||
|
||||
while (true) {
|
||||
Signal s = receiver.wait_for_signal();
|
||||
static_cast<Signal_dispatcher_base *>(s.context())->dispatch(s.num());
|
||||
}
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
return 0;
|
||||
namespace Server {
|
||||
char const *name() { return "atapi_ep"; }
|
||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ TARGET = atapi_drv
|
||||
REQUIRES = x86
|
||||
SRC_CC = main.cc ata_device.cc atapi_device.cc io.cc ata_bus_master.cc
|
||||
SRC_C = mindrvr.c
|
||||
LIBS = base config
|
||||
LIBS = base config server
|
||||
|
||||
INC_DIR += $(PRG_DIR)/contrib $(PRG_DIR)
|
||||
|
||||
|
@ -13,52 +13,48 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <regulator_session/connection.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include <driver.h>
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
struct Main
|
||||
{
|
||||
using namespace Genode;
|
||||
Server::Entrypoint &ep;
|
||||
|
||||
printf("--- Arndale eMMC card driver ---\n");
|
||||
|
||||
/**
|
||||
* Factory used by 'Block::Root' at session creation/destruction time
|
||||
*/
|
||||
struct Driver_factory : Block::Driver_factory
|
||||
struct Factory : Block::Driver_factory
|
||||
{
|
||||
Block::Driver *create()
|
||||
{
|
||||
bool use_dma = true;
|
||||
return new (env()->heap()) Block::Exynos5_driver(use_dma);
|
||||
}
|
||||
Block::Driver *create() {
|
||||
return new (Genode::env()->heap()) Block::Exynos5_driver(true); }
|
||||
|
||||
void destroy(Block::Driver *driver)
|
||||
{
|
||||
Genode::destroy(env()->heap(),
|
||||
static_cast<Block::Exynos5_driver *>(driver));
|
||||
}
|
||||
void destroy(Block::Driver *driver) {
|
||||
Genode::destroy(Genode::env()->heap(),
|
||||
static_cast<Block::Exynos5_driver *>(driver)); }
|
||||
} factory;
|
||||
|
||||
} driver_factory;
|
||||
Regulator::Connection regulator;
|
||||
Block::Root root;
|
||||
|
||||
enum { STACK_SIZE = 8192 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "block_ep");
|
||||
static Regulator::Connection mmc0_regulator(Regulator::CLK_MMC0);
|
||||
mmc0_regulator.state(true);
|
||||
Main(Server::Entrypoint &ep)
|
||||
: ep(ep), regulator(Regulator::CLK_MMC0),
|
||||
root(ep, Genode::env()->heap(), factory)
|
||||
{
|
||||
Genode::printf("--- Arndale eMMC card driver ---\n");
|
||||
|
||||
static Signal_receiver receiver;
|
||||
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver);
|
||||
env()->parent()->announce(ep.manage(&block_root));
|
||||
|
||||
while (true) {
|
||||
Signal s = receiver.wait_for_signal();
|
||||
static_cast<Signal_dispatcher_base *>(s.context())->dispatch(s.num());
|
||||
Genode::env()->parent()->announce(ep.manage(root));
|
||||
regulator.state(true);
|
||||
}
|
||||
};
|
||||
|
||||
return 0;
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
namespace Server {
|
||||
char const *name() { return "sd_card_ep"; }
|
||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
TARGET = sd_card_drv
|
||||
REQUIRES = exynos5
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
LIBS = base server
|
||||
INC_DIR += $(PRG_DIR) $(PRG_DIR)/..
|
||||
|
@ -13,53 +13,45 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include <driver.h>
|
||||
|
||||
|
||||
/*
|
||||
* MMC1: IRQ 83
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
struct Main
|
||||
{
|
||||
using namespace Genode;
|
||||
Server::Entrypoint &ep;
|
||||
|
||||
printf("--- OMAP4 SD card driver ---\n");
|
||||
|
||||
/**
|
||||
* Factory used by 'Block::Root' at session creation/destruction time
|
||||
*/
|
||||
struct Driver_factory : Block::Driver_factory
|
||||
struct Factory : Block::Driver_factory
|
||||
{
|
||||
Block::Driver *create()
|
||||
{
|
||||
bool use_dma = true;
|
||||
return new (env()->heap()) Block::Omap4_driver(use_dma);
|
||||
}
|
||||
Block::Driver *create() {
|
||||
return new (Genode::env()->heap()) Block::Omap4_driver(true); }
|
||||
|
||||
void destroy(Block::Driver *driver)
|
||||
{
|
||||
Genode::destroy(env()->heap(),
|
||||
static_cast<Block::Omap4_driver *>(driver));
|
||||
}
|
||||
void destroy(Block::Driver *driver) {
|
||||
Genode::destroy(Genode::env()->heap(),
|
||||
static_cast<Block::Omap4_driver *>(driver)); }
|
||||
} factory;
|
||||
|
||||
} driver_factory;
|
||||
Block::Root root;
|
||||
|
||||
enum { STACK_SIZE = 4096 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "block_ep");
|
||||
Main(Server::Entrypoint &ep)
|
||||
: ep(ep), root(ep, Genode::env()->heap(), factory)
|
||||
{
|
||||
Genode::printf("--- OMAP4 SD card driver ---\n");
|
||||
|
||||
static Signal_receiver receiver;
|
||||
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver);
|
||||
env()->parent()->announce(ep.manage(&block_root));
|
||||
|
||||
while (true) {
|
||||
Signal s = receiver.wait_for_signal();
|
||||
static_cast<Signal_dispatcher_base *>(s.context())->dispatch(s.num());
|
||||
Genode::env()->parent()->announce(ep.manage(root));
|
||||
}
|
||||
};
|
||||
|
||||
return 0;
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
namespace Server {
|
||||
char const *name() { return "sd_card_ep"; }
|
||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
TARGET = sd_card_drv
|
||||
REQUIRES = omap4
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
LIBS = base server
|
||||
INC_DIR += $(PRG_DIR) $(PRG_DIR)/..
|
||||
|
@ -11,32 +11,28 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
#include <cap_session/connection.h>
|
||||
#include <block/component.h>
|
||||
#include <pl180_defs.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* local includes */
|
||||
#include <pl180_defs.h>
|
||||
#include "pl180.h"
|
||||
#include "sd_card.h"
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
struct Main
|
||||
{
|
||||
using namespace Genode;
|
||||
Server::Entrypoint &ep;
|
||||
|
||||
printf("--- PL180 MMC/SD card driver started ---\n");
|
||||
|
||||
/**
|
||||
* Factory used by 'Block::Root' at session creation/destruction time
|
||||
*/
|
||||
struct Pl180_driver_factory : Block::Driver_factory
|
||||
struct Factory : Block::Driver_factory
|
||||
{
|
||||
Block::Driver *create()
|
||||
{
|
||||
Pl180 *pl180 = new (env()->heap())
|
||||
Pl180 *pl180 = new (Genode::env()->heap())
|
||||
Pl180(PL180_PHYS, PL180_SIZE);
|
||||
Sd_card *sd_card = new (env()->heap())
|
||||
Sd_card *sd_card = new (Genode::env()->heap())
|
||||
Sd_card(*pl180);
|
||||
|
||||
return sd_card;
|
||||
@ -47,24 +43,29 @@ int main(int argc, char **argv)
|
||||
Sd_card *sd_card = static_cast<Sd_card *>(driver);
|
||||
Pl180 *pl180 = static_cast<Pl180 *>(&sd_card->host_driver());
|
||||
|
||||
Genode::destroy(env()->heap(), sd_card);
|
||||
Genode::destroy(env()->heap(), pl180);
|
||||
Genode::destroy(Genode::env()->heap(), sd_card);
|
||||
Genode::destroy(Genode::env()->heap(), pl180);
|
||||
}
|
||||
} factory;
|
||||
|
||||
} driver_factory;
|
||||
Block::Root root;
|
||||
|
||||
enum { STACK_SIZE = 4096 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "block_ep");
|
||||
Main(Server::Entrypoint &ep)
|
||||
: ep(ep), root(ep, Genode::env()->heap(), factory)
|
||||
{
|
||||
Genode::printf("--- PL180 MMC/SD card driver started ---\n");
|
||||
|
||||
static Signal_receiver receiver;
|
||||
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver);
|
||||
env()->parent()->announce(ep.manage(&block_root));
|
||||
|
||||
while (true) {
|
||||
Signal s = receiver.wait_for_signal();
|
||||
static_cast<Signal_dispatcher_base *>(s.context())->dispatch(s.num());
|
||||
Genode::env()->parent()->announce(ep.manage(root));
|
||||
}
|
||||
};
|
||||
|
||||
return 0;
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
namespace Server {
|
||||
char const *name() { return "sd_card_ep"; }
|
||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
TARGET = sd_card_drv
|
||||
REQUIRES = pl180
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
LIBS = base server
|
||||
|
||||
INC_DIR += $(PRG_DIR)
|
||||
|
@ -47,6 +47,36 @@ static Genode::Signal_receiver &global_sig_rec()
|
||||
}
|
||||
|
||||
|
||||
static void wait_and_dispatch_one_signal(bool entrypoint)
|
||||
{
|
||||
/*
|
||||
* We call the signal dispatcher outside of the scope of 'Signal'
|
||||
* object because we block the RPC interface in the input handler
|
||||
* when the kill mode gets actived. While kill mode is active, we
|
||||
* do not serve incoming RPC requests but we need to stay responsive
|
||||
* to user input. Hence, we wait for signals in the input dispatcher
|
||||
* in this case. An already existing 'Signal' object would lock the
|
||||
* signal receiver and thereby prevent this nested way of signal
|
||||
* handling.
|
||||
*/
|
||||
Signal_rpc_dispatcher_base *dispatcher = 0;
|
||||
unsigned num = 0;
|
||||
|
||||
{
|
||||
Signal sig = global_sig_rec().wait_for_signal();
|
||||
dispatcher = dynamic_cast<Signal_rpc_dispatcher_base *>(sig.context());
|
||||
num = sig.num();
|
||||
}
|
||||
|
||||
if (!dispatcher)
|
||||
return;
|
||||
|
||||
if (entrypoint)
|
||||
dispatcher->dispatch_at_entrypoint(num);
|
||||
else
|
||||
dispatcher->dispatch(num);
|
||||
}
|
||||
|
||||
Signal_context_capability Entrypoint::manage(Signal_rpc_dispatcher_base &dispatcher)
|
||||
{
|
||||
return dispatcher.manage(global_sig_rec(), global_rpc_ep());
|
||||
@ -62,30 +92,8 @@ void Server::Entrypoint::dissolve(Signal_rpc_dispatcher_base &dispatcher)
|
||||
Server::Entrypoint::Entrypoint() : _rpc_ep(global_rpc_ep()) { }
|
||||
|
||||
|
||||
void Server::wait_and_dispatch_one_signal()
|
||||
{
|
||||
/*
|
||||
* We call the signal dispatcher outside of the scope of 'Signal'
|
||||
* object because we block the RPC interface in the input handler
|
||||
* when the kill mode gets actived. While kill mode is active, we
|
||||
* do not serve incoming RPC requests but we need to stay responsive
|
||||
* to user input. Hence, we wait for signals in the input dispatcher
|
||||
* in this case. An already existing 'Signal' object would lock the
|
||||
* signal receiver and thereby prevent this nested way of signal
|
||||
* handling.
|
||||
*/
|
||||
Signal_dispatcher_base *dispatcher = 0;
|
||||
unsigned num = 0;
|
||||
|
||||
{
|
||||
Signal sig = global_sig_rec().wait_for_signal();
|
||||
dispatcher = dynamic_cast<Signal_dispatcher_base *>(sig.context());
|
||||
num = sig.num();
|
||||
}
|
||||
|
||||
if (dispatcher)
|
||||
dispatcher->dispatch(num);
|
||||
}
|
||||
void Server::wait_and_dispatch_one_signal() {
|
||||
::wait_and_dispatch_one_signal(true); }
|
||||
|
||||
|
||||
namespace Server {
|
||||
@ -116,10 +124,10 @@ int main(int argc, char **argv)
|
||||
|
||||
/* call Server::construct in the context of the entrypoint */
|
||||
Capability<Server::Constructor> constructor_cap = ep.manage(constructor);
|
||||
|
||||
|
||||
constructor_cap.call<Server::Constructor::Rpc_construct>();
|
||||
|
||||
/* process incoming signals */
|
||||
for (;;)
|
||||
Server::wait_and_dispatch_one_signal();
|
||||
wait_and_dispatch_one_signal(false);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <base/exception.h>
|
||||
#include <base/printf.h>
|
||||
#include <os/config.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <os/server.h>
|
||||
#include <rom_session/connection.h>
|
||||
#include <block/component.h>
|
||||
#include <block/driver.h>
|
||||
@ -81,50 +81,51 @@ class Rom_blk : public Block::Driver
|
||||
};
|
||||
|
||||
|
||||
struct Factory : Block::Driver_factory
|
||||
struct Main
|
||||
{
|
||||
Block::Driver *create()
|
||||
Server::Entrypoint &ep;
|
||||
|
||||
struct Factory : Block::Driver_factory
|
||||
{
|
||||
char file[64];
|
||||
size_t blk_sz = 512;
|
||||
Block::Driver *create()
|
||||
{
|
||||
char file[64];
|
||||
size_t blk_sz = 512;
|
||||
|
||||
try {
|
||||
config()->xml_node().attribute("file").value(file, sizeof(file));
|
||||
config()->xml_node().attribute("block_size").value(&blk_sz);
|
||||
try {
|
||||
config()->xml_node().attribute("file").value(file, sizeof(file));
|
||||
config()->xml_node().attribute("block_size").value(&blk_sz);
|
||||
}
|
||||
catch (...) { }
|
||||
|
||||
PINF("Using file=%s as device with block size %zx.", file, blk_sz);
|
||||
|
||||
try {
|
||||
return new (Genode::env()->heap()) Rom_blk(file, blk_sz);
|
||||
} catch(Rom_connection::Rom_connection_failed) {
|
||||
PERR("Cannot open file %s.", file);
|
||||
}
|
||||
throw Root::Unavailable();
|
||||
}
|
||||
catch (...) { }
|
||||
|
||||
PINF("Using file=%s as device with block size %zx.", file, blk_sz);
|
||||
void destroy(Block::Driver *driver) {
|
||||
Genode::destroy(env()->heap(), driver); }
|
||||
} factory;
|
||||
|
||||
try {
|
||||
return new (Genode::env()->heap()) Rom_blk(file, blk_sz);
|
||||
} catch(Rom_connection::Rom_connection_failed) {
|
||||
PERR("Cannot open file %s.", file);
|
||||
}
|
||||
throw Root::Unavailable();
|
||||
}
|
||||
Block::Root root;
|
||||
|
||||
void destroy(Block::Driver *driver) {
|
||||
Genode::destroy(env()->heap(), driver); }
|
||||
Main(Server::Entrypoint &ep)
|
||||
: ep(ep), root(ep, Genode::env()->heap(), factory) {
|
||||
Genode::env()->parent()->announce(ep.manage(root)); }
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
enum { STACK_SIZE = 8192 };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "rom_blk_ep");
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
static Signal_receiver receiver;
|
||||
static Factory driver_factory;
|
||||
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver);
|
||||
|
||||
env()->parent()->announce(ep.manage(&block_root));
|
||||
|
||||
while (true) {
|
||||
Signal s = receiver.wait_for_signal();
|
||||
static_cast<Signal_dispatcher_base *>(s.context())->dispatch(s.num());
|
||||
}
|
||||
|
||||
return 0;
|
||||
namespace Server {
|
||||
char const *name() { return "rom_blk_ep"; }
|
||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = rom_blk
|
||||
SRC_CC = main.cc
|
||||
LIBS = base config
|
||||
LIBS = base config server
|
||||
|
@ -32,11 +32,17 @@ class Driver : public Block::Driver
|
||||
Genode::size_t _number;
|
||||
Genode::size_t _size;
|
||||
Req_buffer _packets;
|
||||
Genode::Signal_dispatcher<Driver> _ack;
|
||||
Genode::Ram_dataspace_capability _blk_ds;
|
||||
unsigned char *_blk_buf;
|
||||
|
||||
void _handle_ack(unsigned)
|
||||
public:
|
||||
|
||||
Driver(Genode::size_t number, Genode::size_t size)
|
||||
: _number(number), _size(size),
|
||||
_blk_ds(Genode::env()->ram_session()->alloc(number*size)),
|
||||
_blk_buf(Genode::env()->rm_session()->attach(_blk_ds)) {}
|
||||
|
||||
void handler(unsigned)
|
||||
{
|
||||
while (!_packets.empty()) {
|
||||
Block::Packet_descriptor p = _packets.get();
|
||||
@ -44,17 +50,6 @@ class Driver : public Block::Driver
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Driver(Genode::size_t number, Genode::size_t size,
|
||||
Genode::Signal_receiver &receiver)
|
||||
: _number(number), _size(size),
|
||||
_ack(receiver, *this, &Driver::_handle_ack),
|
||||
_blk_ds(Genode::env()->ram_session()->alloc(number*size)),
|
||||
_blk_buf(Genode::env()->rm_session()->attach(_blk_ds)) {}
|
||||
|
||||
Genode::Signal_context_capability handler() { return _ack; }
|
||||
|
||||
|
||||
/*******************************
|
||||
** Block::Driver interface **
|
||||
@ -98,52 +93,54 @@ class Driver : public Block::Driver
|
||||
};
|
||||
|
||||
|
||||
struct Factory : Block::Driver_factory
|
||||
struct Main
|
||||
{
|
||||
Genode::Signal_receiver &receiver;
|
||||
::Driver *driver;
|
||||
Server::Entrypoint &ep;
|
||||
|
||||
Factory(Genode::Signal_receiver &r) : receiver(r)
|
||||
struct Factory : Block::Driver_factory
|
||||
{
|
||||
Genode::size_t blk_nr = 1024;
|
||||
Genode::size_t blk_sz = 512;
|
||||
::Driver *driver;
|
||||
|
||||
try {
|
||||
Genode::config()->xml_node().attribute("sectors").value(&blk_nr);
|
||||
Genode::config()->xml_node().attribute("block_size").value(&blk_sz);
|
||||
Factory()
|
||||
{
|
||||
Genode::size_t blk_nr = 1024;
|
||||
Genode::size_t blk_sz = 512;
|
||||
|
||||
try {
|
||||
Genode::config()->xml_node().attribute("sectors").value(&blk_nr);
|
||||
Genode::config()->xml_node().attribute("block_size").value(&blk_sz);
|
||||
}
|
||||
catch (...) { }
|
||||
|
||||
driver = new (Genode::env()->heap()) Driver(blk_nr, blk_sz);
|
||||
}
|
||||
catch (...) { }
|
||||
|
||||
driver = new (Genode::env()->heap()) Driver(blk_nr, blk_sz, receiver);
|
||||
}
|
||||
|
||||
Block::Driver *create() { return driver; }
|
||||
|
||||
void destroy(Block::Driver *driver) { }
|
||||
void destroy(Block::Driver *driver) { }
|
||||
} factory;
|
||||
|
||||
Block::Root root;
|
||||
Timer::Connection timer;
|
||||
Server::Signal_rpc_member<Driver> dispatcher = { ep, *factory.driver,
|
||||
&Driver::handler };
|
||||
|
||||
Main(Server::Entrypoint &ep)
|
||||
: ep(ep), root(ep, Genode::env()->heap(), factory)
|
||||
{
|
||||
timer.sigh(dispatcher);
|
||||
timer.trigger_periodic(10000);
|
||||
Genode::env()->parent()->announce(ep.manage(root));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace Genode;
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
enum { STACK_SIZE = 2048 * sizeof(Genode::addr_t) };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "test_blk_ep");
|
||||
|
||||
static Signal_receiver receiver;
|
||||
static Factory driver_factory(receiver);
|
||||
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver);
|
||||
|
||||
env()->parent()->announce(ep.manage(&block_root));
|
||||
|
||||
static Timer::Connection timer;
|
||||
timer.sigh(driver_factory.driver->handler());
|
||||
timer.trigger_periodic(10000);
|
||||
while (true) {
|
||||
Signal s = receiver.wait_for_signal();
|
||||
static_cast<Signal_dispatcher_base *>(s.context())->dispatch(s.num());
|
||||
}
|
||||
|
||||
return 0;
|
||||
namespace Server {
|
||||
char const *name() { return "blk_srv_ep"; }
|
||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = test-blk-srv
|
||||
SRC_CC = main.cc
|
||||
LIBS = base config
|
||||
LIBS = base config server
|
||||
|
@ -15,10 +15,8 @@
|
||||
*/
|
||||
|
||||
#include <base/printf.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <framebuffer_session/connection.h>
|
||||
#include <block/component.h>
|
||||
#include <block/driver.h>
|
||||
|
||||
class Driver : public Block::Driver
|
||||
{
|
||||
@ -109,24 +107,24 @@ struct Factory : Block::Driver_factory
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
struct Main
|
||||
{
|
||||
using namespace Genode;
|
||||
Server::Entrypoint &ep;
|
||||
struct Factory factory;
|
||||
Block::Root root;
|
||||
|
||||
enum { STACK_SIZE = 2048 * sizeof(Genode::addr_t) };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "fb_block_ep");
|
||||
Main(Server::Entrypoint &ep)
|
||||
: ep(ep), root(ep, Genode::env()->heap(), factory) {
|
||||
Genode::env()->parent()->announce(ep.manage(root)); }
|
||||
};
|
||||
|
||||
static Signal_receiver receiver;
|
||||
static Factory driver_factory;
|
||||
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver);
|
||||
|
||||
env()->parent()->announce(ep.manage(&block_root));
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
while (true) {
|
||||
Signal s = receiver.wait_for_signal();
|
||||
static_cast<Signal_dispatcher_base *>(s.context())->dispatch(s.num());
|
||||
}
|
||||
|
||||
return 0;
|
||||
namespace Server {
|
||||
char const *name() { return "fb_blk_ep"; }
|
||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = test-fb_blk_adapter
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
LIBS = base server
|
||||
|
Loading…
x
Reference in New Issue
Block a user