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:
Stefan Kalkowski
2014-01-13 13:44:33 +01:00
committed by Christian Helmuth
parent 2e99c19601
commit 6a076ff621
34 changed files with 415 additions and 461 deletions

View File

@ -4,9 +4,12 @@
* \date 2013-02-20 * \date 2013-02-20
*/ */
int main() #include <os/server.h>
{
extern void start_usb_driver(); extern void start_usb_driver(Server::Entrypoint &e);
start_usb_driver();
return 0; 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); }
} }

View File

@ -1,3 +1,3 @@
TARGET = usb_drv TARGET = usb_drv
SRC_CC = main.cc SRC_CC = main.cc
LIBS = usb LIBS = usb server

View File

@ -246,12 +246,11 @@ namespace Nic {
*/ */
Session_component(Dataspace_capability tx_ds, Session_component(Dataspace_capability tx_ds,
Dataspace_capability rx_ds, Dataspace_capability rx_ds,
Rpc_entrypoint &ep, Server::Entrypoint &ep,
Signal_receiver *sig_rec,
::Device *device) ::Device *device)
: :
Nic::Packet_allocator(Genode::env()->heap()), 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)), _device(static_cast<Device *>(device)),
_tx_sink(Session_rpc_object::_tx.sink()), _tx_sink(Session_rpc_object::_tx.sink()),
_tx_alloc(true) _tx_alloc(true)
@ -296,10 +295,9 @@ namespace Nic {
{ {
public: public:
Root(Rpc_entrypoint *session_ep, Allocator *md_alloc, Root(Server::Entrypoint &ep, Allocator *md_alloc,
Signal_receiver *sig_rec, Device *device) Device *device)
: : Packet_root(ep, md_alloc, device) { }
Packet_root(session_ep, md_alloc, sig_rec, device) { }
}; };
} }

View File

@ -43,6 +43,7 @@ class Routine : public Genode::List<Routine>::Element
char *_stack; /* stack pointer */ char *_stack; /* stack pointer */
static Routine *_current; /* currently scheduled object */ static Routine *_current; /* currently scheduled object */
static Routine *_dead; /* object to remove */ static Routine *_dead; /* object to remove */
static Routine *_main; /* main routine */
static bool _all; /* true when all objects must be scheduled */ 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. * 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; return;
Routine *next = _next(all); if (_current == _main)
all = true;
Routine *next = main ? _main : _next(all);
if (next == _current) { if (next == _current) {
_check_dead(); _check_dead();
@ -184,6 +189,22 @@ class Routine : public Genode::List<Routine>::Element
schedule(); 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 * True when 'schedule_all' has been called and is still in progress
*/ */

View File

@ -17,19 +17,17 @@
#include <base/env.h> #include <base/env.h>
#include <base/printf.h> #include <base/printf.h>
#include <base/signal.h> #include <base/signal.h>
#include <os/server.h>
#include "routine.h" #include "routine.h"
/** /**
* This singelton currently received all signals * This singleton currently received all signals
*/ */
class Service_handler class Service_handler
{ {
private: private:
Genode::Signal_receiver *_receiver;
Service_handler() { } Service_handler() { }
public: public:
@ -40,8 +38,6 @@ class Service_handler
return &_s; return &_s;
} }
void receiver(Genode::Signal_receiver *recv) { _receiver = recv; }
/** /**
* Dispatch for wait for signal * Dispatch for wait for signal
*/ */
@ -52,68 +48,54 @@ class Service_handler
return; return;
} }
check_signal(); Routine::schedule_main();
}
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;
}
} }
}; };
/** /**
* Helper that holds sender and receiver * Helper that holds sender and entrypoint
*/ */
class Signal_helper class Signal_helper
{ {
private: private:
Genode::Signal_receiver *_receiver; Server::Entrypoint &_ep;
Genode::Signal_transmitter *_sender; Genode::Signal_transmitter _sender;
public: public:
Signal_helper(Genode::Signal_receiver *recv) Signal_helper(Server::Entrypoint &ep) : _ep(ep) { }
: _receiver(recv),
_sender(new (Genode::env()->heap()) Genode::Signal_transmitter()) { }
Genode::Signal_receiver *receiver() const { return _receiver; } Server::Entrypoint &ep() { return _ep; }
Genode::Signal_transmitter *sender() const { return _sender; } Genode::Signal_transmitter &sender() { return _sender; }
}; };
namespace Timer namespace Timer
{ {
void init(Genode::Signal_receiver *recv); void init(Server::Entrypoint &ep);
} }
namespace Irq namespace Irq
{ {
void init(Genode::Signal_receiver *recv); void init(Server::Entrypoint &ep);
void check_irq(); void check_irq();
} }
namespace Event namespace Event
{ {
void init(Genode::Signal_receiver *recv); void init(Server::Entrypoint &ep);
} }
namespace Storage namespace Storage
{ {
void init(Genode::Signal_receiver *recv); void init(Server::Entrypoint &ep);
} }
namespace Nic namespace Nic
{ {
void init(Genode::Signal_receiver *recv); void init(Server::Entrypoint &ep);
} }
#endif /* _SIGNAL_H_ */ #endif /* _SIGNAL_H_ */

View File

@ -27,7 +27,7 @@ class Packet_session_component : public RPC
{ {
private: private:
Genode::Signal_dispatcher<Packet_session_component> _process_packet_dispatcher; Genode::Signal_rpc_member<Packet_session_component> _dispatcher;
protected: protected:
@ -36,37 +36,31 @@ class Packet_session_component : public RPC
public: public:
Packet_session_component(Genode::Dataspace_capability tx_ds, Packet_session_component(Genode::Dataspace_capability tx_ds,
Genode::Rpc_entrypoint &ep, Server::Entrypoint &ep)
Genode::Signal_receiver *sig_rec) : RPC(tx_ds, ep.rpc_ep()),
: _dispatcher(ep, *this, &Packet_session_component::_process_packets)
RPC(tx_ds, ep), {
_process_packet_dispatcher(*sig_rec, *this,
&Packet_session_component::_process_packets)
{
/* /*
* Register '_process_packets' dispatch function as signal * Register '_process_packets' dispatch function as signal
* handler for packet-avail and ready-to-ack signals. * handler for packet-avail and ready-to-ack signals.
*/ */
RPC::_tx.sigh_packet_avail(_process_packet_dispatcher); RPC::_tx.sigh_packet_avail(_dispatcher);
RPC::_tx.sigh_ready_to_ack(_process_packet_dispatcher); RPC::_tx.sigh_ready_to_ack(_dispatcher);
} }
Packet_session_component(Genode::Dataspace_capability tx_ds, Packet_session_component(Genode::Dataspace_capability tx_ds,
Genode::Dataspace_capability rx_ds, Genode::Dataspace_capability rx_ds,
Genode::Range_allocator *rx_buffer_alloc, Genode::Range_allocator *rx_buffer_alloc,
Genode::Rpc_entrypoint &ep, Server::Entrypoint &ep)
Genode::Signal_receiver *sig_rec) : RPC(tx_ds, rx_ds, rx_buffer_alloc, ep.rpc_ep()),
: _dispatcher(ep, *this, &Packet_session_component::_process_packets)
RPC(tx_ds, rx_ds, rx_buffer_alloc, ep), {
_process_packet_dispatcher(*sig_rec, *this,
&Packet_session_component::_process_packets)
{
/* /*
* Register '_process_packets' dispatch function as signal * Register '_process_packets' dispatch function as signal
* handler for packet-avail and ready-to-ack signals. * handler for packet-avail and ready-to-ack signals.
*/ */
RPC::_tx.sigh_packet_avail(_process_packet_dispatcher); RPC::_tx.sigh_packet_avail(_dispatcher);
RPC::_tx.sigh_ready_to_ack(_process_packet_dispatcher); RPC::_tx.sigh_ready_to_ack(_dispatcher);
} }
}; };
@ -85,9 +79,8 @@ class Packet_session_component : public RPC
{ {
private: private:
Genode::Rpc_entrypoint &_ep; Server::Entrypoint &_ep;
Genode::Signal_receiver *_sig_rec; Device *_device;
Device *_device;
protected: protected:
@ -125,17 +118,15 @@ class Packet_session_component : public RPC
return new (ROOT_COMPONENT::md_alloc()) return new (ROOT_COMPONENT::md_alloc())
SESSION_COMPONENT(Backend_memory::alloc(tx_buf_size, CACHED), SESSION_COMPONENT(Backend_memory::alloc(tx_buf_size, CACHED),
Backend_memory::alloc(rx_buf_size, CACHED), Backend_memory::alloc(rx_buf_size, CACHED),
_ep, _sig_rec, _device); _ep, _device);
} }
public: public:
Packet_root(Genode::Rpc_entrypoint *session_ep, Genode::Allocator *md_alloc, Packet_root(Server::Entrypoint &ep, Genode::Allocator *md_alloc,
Genode::Signal_receiver *sig_rec, Device *device) Device *device)
: : ROOT_COMPONENT(&ep.rpc_ep(), md_alloc),
ROOT_COMPONENT(session_ep, md_alloc), _ep(ep), _device(device) { }
_ep(*session_ep), _sig_rec(sig_rec), _device(device)
{ }
}; };
#endif /* _SIGNAL__DISPATCHER_H_ */ #endif /* _SIGNAL__DISPATCHER_H_ */

View File

@ -14,11 +14,9 @@
/* Genode */ /* Genode */
#include <base/rpc_server.h>
#include <base/printf.h> #include <base/printf.h>
#include <base/sleep.h> #include <base/sleep.h>
#include <cap_session/connection.h> #include <os/server.h>
#include <nic_session/nic_session.h> #include <nic_session/nic_session.h>
/* Local */ /* Local */
@ -45,6 +43,7 @@ extern "C" void start_input_service(void *ep);
Routine *Routine::_current = 0; Routine *Routine::_current = 0;
Routine *Routine::_dead = 0; Routine *Routine::_dead = 0;
Routine *Routine::_main = 0;
bool Routine::_all = false; bool Routine::_all = false;
void breakpoint() { PDBG("BREAK"); } 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; Services services;
if (services.hid) if (services.hid)
start_input_service(&ep_hid); start_input_service(&ep.rpc_ep());
Timer::init(&recv); Timer::init(ep);
Irq::init(&recv); Irq::init(ep);
Event::init(&recv); Event::init(ep);
Service_handler::s()->receiver(&recv); Storage::init(ep);
Storage::init(&recv); Nic::init(ep);
Nic::init(&recv);
Routine::add(0, 0, "Main", true); Routine::add(0, 0, "Main", true);
Routine::current_use_first(); Routine::current_use_first();
init(&services); init(&services);
Routine::remove(); Routine::main();
/* will never be reached */
sleep_forever();
} }

View File

@ -283,8 +283,8 @@ class Nic_device : public Nic::Device
static Nic_device *_nic = 0; static Nic_device *_nic = 0;
void Nic::init(Genode::Signal_receiver *recv) { void Nic::init(Server::Entrypoint &ep) {
_signal = new (Genode::env()->heap()) Signal_helper(recv); } _signal = new (Genode::env()->heap()) Signal_helper(ep); }
/*********************** /***********************
@ -301,9 +301,7 @@ int register_netdev(struct net_device *ndev)
/* XXX: move to 'main' */ /* XXX: move to 'main' */
if (!announce) { if (!announce) {
static Cap_connection cap_nic; static Nic::Root root(_signal->ep(), env()->heap(), nic);
static Rpc_entrypoint ep_nic(&cap_nic, 4096, "usb_nic_ep");
static Nic::Root root(&ep_nic, env()->heap(), _signal->receiver(), nic);
announce = true; announce = true;
@ -321,7 +319,7 @@ int register_netdev(struct net_device *ndev)
ndev->netdev_ops->ndo_change_mtu(ndev, 4000); ndev->netdev_ops->ndo_change_mtu(ndev, 4000);
*/ */
_nic = nic; _nic = nic;
env()->parent()->announce(ep_nic.manage(&root)); env()->parent()->announce(_signal->ep().rpc_ep().manage(&root));
} }
return err; return err;

View File

@ -23,14 +23,14 @@ class Event_context
{ {
private: private:
Genode::Signal_dispatcher<Event_context> _dispatcher; Genode::Signal_rpc_member<Event_context> _dispatcher;
void _handle(unsigned) { void _handle(unsigned) {
Routine::schedule_all(); } Routine::schedule_all(); }
Event_context() Event_context()
: _dispatcher(*_signal->receiver(), *this, &Event_context::_handle) { : _dispatcher(_signal->ep(), *this, &Event_context::_handle) {
_signal->sender()->context(_dispatcher); } _signal->sender().context(_dispatcher); }
public: public:
@ -41,14 +41,14 @@ class Event_context
} }
void submit() { void submit() {
_signal->sender()->submit(); } _signal->sender().submit(); }
char const *debug() { return "Event_context"; } char const *debug() { return "Event_context"; }
}; };
void Event::init(Genode::Signal_receiver *recv) { void Event::init(Server::Entrypoint &ep) {
_signal = new (Genode::env()->heap()) Signal_helper(recv); } _signal = new (Genode::env()->heap()) Signal_helper(ep); }
/** /**

View File

@ -48,7 +48,7 @@ class Irq_context : public Genode::List<Irq_context>::Element
unsigned int _irq; /* IRQ number */ unsigned int _irq; /* IRQ number */
Genode::List<Irq_handler> _handler_list; /* List of registered handlers */ 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() 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); Irq_context *ctx = static_cast<Irq_context *>(irq);
/* set context & submit signal */ /* set context & submit signal */
_signal->sender()->context(ctx->_dispatcher); _signal->sender().context(ctx->_dispatcher);
_signal->sender()->submit(); _signal->sender().submit();
/* wait for interrupt to get acked at device side */ /* wait for interrupt to get acked at device side */
_irq_sync.lock(); _irq_sync.lock();
@ -122,7 +122,7 @@ class Irq_context : public Genode::List<Irq_context>::Element
/* report IRQ to all clients */ /* report IRQ to all clients */
for (Irq_handler *h = _handler_list.first(); h; h = h->next()) { for (Irq_handler *h = _handler_list.first(); h; h = h->next()) {
if (_handle_one(h)) if ((handled = _handle_one(h)))
break; break;
dde_kit_log(DEBUG_IRQ, "IRQ: %u ret: %u h: %p dev: %p", _irq, handled, h->handler, h->dev); 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_context(unsigned int irq)
: _irq(irq), : _irq(irq),
_dispatcher(*_signal->receiver(), *this, &Irq_context::_handle) _dispatcher(_signal->ep(), *this, &Irq_context::_handle)
{ {
/* register at DDE (shared) */ /* register at DDE (shared) */
int ret = dde_kit_interrupt_attach(_irq, 0, 0, _dde_handler, this); 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) { void Irq::init(Server::Entrypoint &ep) {
_signal = new (Genode::env()->heap()) Signal_helper(recv); } _signal = new (Genode::env()->heap()) Signal_helper(ep); }
void Irq::check_irq() void Irq::check_irq()

View File

@ -33,7 +33,7 @@ class Timer_context
timer_list *_timer; /* Linux timer */ timer_list *_timer; /* Linux timer */
dde_kit_timer *_dde_timer; /* DDE kit 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 */ /* call timer function */
void _handle(unsigned) { _timer->function(_timer->data); } void _handle(unsigned) { _timer->function(_timer->data); }
@ -42,7 +42,7 @@ class Timer_context
Timer_context(timer_list *timer) Timer_context(timer_list *timer)
: _timer(timer), _dde_timer(0), : _timer(timer), _dde_timer(0),
_dispatcher(*_signal->receiver(), *this, &Timer_context::_handle) {} _dispatcher(_signal->ep(), *this, &Timer_context::_handle) {}
/* schedule next timeout */ /* schedule next timeout */
void schedule(unsigned long expires) void schedule(unsigned long expires)
@ -93,13 +93,13 @@ static void handler(void *timer)
Timer_context *t = static_cast<Timer_context *>(timer); Timer_context *t = static_cast<Timer_context *>(timer);
/* set context and submit */ /* set context and submit */
_signal->sender()->context(t->cap()); _signal->sender().context(t->cap());
_signal->sender()->submit(); _signal->sender().submit();
} }
void Timer::init(Genode::Signal_receiver *recv) { void Timer::init(Server::Entrypoint &ep) {
_signal = new (Genode::env()->heap()) Signal_helper(recv); } _signal = new (Genode::env()->heap()) Signal_helper(ep); }
/******************* /*******************

View File

@ -180,8 +180,8 @@ class Storage_device : public Genode::List<Storage_device>::Element,
}; };
void Storage::init(Genode::Signal_receiver *recv) { void Storage::init(Server::Entrypoint &ep) {
_signal = new (Genode::env()->heap()) Signal_helper(recv); } _signal = new (Genode::env()->heap()) Signal_helper(ep); }
struct Factory : Block::Driver_factory struct Factory : Block::Driver_factory
@ -206,11 +206,8 @@ void scsi_add_device(struct scsi_device *sdev)
* XXX move to 'main' * XXX move to 'main'
*/ */
if (!announce) { if (!announce) {
enum { STACK_SIZE = 1024 * sizeof(addr_t) }; static Block::Root root(_signal->ep(), env()->heap(), factory);
static Cap_connection cap_stor; env()->parent()->announce(_signal->ep().rpc_ep().manage(&root));
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));
announce = true; announce = true;
} }
} }

View File

@ -27,7 +27,7 @@ void tx_test() {
while (1) { while (1) {
sk_buff *skb = alloc_skb(1066 + HEAD_ROOM, 0); sk_buff *skb = alloc_skb(1066 + HEAD_ROOM, 0);
if (!skb) { if (!skb) {
Service_handler::s()->check_signal(true); Service_handler::s()->check_signal();
continue; continue;
} }
skb->len = 1066; skb->len = 1066;

View File

@ -89,22 +89,24 @@ class Factory : public Block::Driver_factory
}; };
int main() struct Main
{ {
enum { STACK_SIZE = 4*1024 }; Server::Entrypoint &ep;
static Cap_connection cap; struct Factory factory;
static Rpc_entrypoint ep(&cap, STACK_SIZE, "http_block_ep"); Block::Root root;
static Signal_receiver receiver; Main(Server::Entrypoint &ep)
static Factory driver_factory; : ep(ep), root(ep, Genode::env()->heap(), factory) {
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver); Genode::env()->parent()->announce(ep.manage(root)); }
};
env()->parent()->announce(ep.manage(&block_root));
while (true) { /************
Signal s = receiver.wait_for_signal(); ** Server **
static_cast<Signal_dispatcher_base *>(s.context())->dispatch(s.num()); ************/
}
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); }
} }

View File

@ -1,4 +1,4 @@
TARGET = http_blk TARGET = http_blk
SRC_CC = main.cc http.cc SRC_CC = main.cc http.cc
LIBS = libc libc_lwip_nic_dhcp LIBS = libc libc_lwip_nic_dhcp server

View File

@ -16,6 +16,8 @@
#define _INCLUDE__BLOCK__COMPONENT_H_ #define _INCLUDE__BLOCK__COMPONENT_H_
#include <root/component.h> #include <root/component.h>
#include <os/signal_rpc_dispatcher.h>
#include <os/server.h>
#include <block_session/rpc_object.h> #include <block_session/rpc_object.h>
#include <block/driver.h> #include <block/driver.h>
@ -36,8 +38,8 @@ class Block::Session_component : public Block::Session_rpc_object
Driver &_driver; Driver &_driver;
Ram_dataspace_capability _rq_ds; Ram_dataspace_capability _rq_ds;
addr_t _rq_phys; addr_t _rq_phys;
Signal_dispatcher<Session_component> _sink_ack; Signal_rpc_member<Session_component> _sink_ack;
Signal_dispatcher<Session_component> _sink_submit; Signal_rpc_member<Session_component> _sink_submit;
bool _req_queue_full; bool _req_queue_full;
bool _ack_queue_full; bool _ack_queue_full;
Packet_descriptor _p_to_handle; 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 block driver backend
* \param driver_factory factory to create and destroy driver objects * \param driver_factory factory to create and destroy driver objects
* \param ep entrypoint handling this session component * \param ep entrypoint handling this session component
* \param receiver signal receiver managing signals of the client
*/ */
Session_component(Ram_dataspace_capability rq_ds, Session_component(Ram_dataspace_capability rq_ds,
Driver &driver, Driver &driver,
Driver_factory &driver_factory, Driver_factory &driver_factory,
Rpc_entrypoint &ep, Server::Entrypoint &ep)
Signal_receiver &receiver) : Session_rpc_object(rq_ds, ep.rpc_ep()),
: Session_rpc_object(rq_ds, ep),
_driver_factory(driver_factory), _driver_factory(driver_factory),
_driver(driver), _driver(driver),
_rq_ds(rq_ds), _rq_ds(rq_ds),
_rq_phys(Dataspace_client(_rq_ds).phys_addr()), _rq_phys(Dataspace_client(_rq_ds).phys_addr()),
_sink_ack(receiver, *this, &Session_component::_ready_to_ack), _sink_ack(ep, *this, &Session_component::_ready_to_ack),
_sink_submit(receiver, *this, &Session_component::_packet_avail), _sink_submit(ep, *this, &Session_component::_packet_avail),
_req_queue_full(false), _req_queue_full(false),
_p_in_fly(0) _p_in_fly(0)
{ {
@ -224,14 +224,13 @@ class Block::Session_component : public Block::Session_rpc_object
/** /**
* Root component, handling new session requests * Root component, handling new session requests
*/ */
class Block::Root : class Block::Root : public Genode::Root_component<Block::Session_component,
public Genode::Root_component<Block::Session_component, Single_client> Single_client>
{ {
private: private:
Driver_factory &_driver_factory; Driver_factory &_driver_factory;
Rpc_entrypoint &_ep; Server::Entrypoint &_ep;
Signal_receiver &_receiver;
protected: protected:
@ -267,8 +266,7 @@ class Block::Root :
Ram_dataspace_capability ds_cap; Ram_dataspace_capability ds_cap;
ds_cap = driver->alloc_dma_buffer(tx_buf_size); ds_cap = driver->alloc_dma_buffer(tx_buf_size);
return new (md_alloc()) return new (md_alloc())
Session_component(ds_cap, *driver, _driver_factory, _ep, Session_component(ds_cap, *driver, _driver_factory, _ep);
_receiver);
} }
public: public:
@ -276,18 +274,15 @@ class Block::Root :
/** /**
* Constructor * 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 md_alloc allocator to allocate session components
* \param driver_factory factory to create and destroy driver backend * \param driver_factory factory to create and destroy driver backend
* \param receiver signal receiver managing signals of the client * \param receiver signal receiver managing signals of the client
*/ */
Root(Rpc_entrypoint *session_ep, Allocator *md_alloc, Root(Server::Entrypoint &ep, Allocator *md_alloc,
Driver_factory &driver_factory, Signal_receiver &receiver) Driver_factory &driver_factory)
: : Root_component(&ep.rpc_ep(), md_alloc),
Root_component(session_ep, md_alloc), _driver_factory(driver_factory), _ep(ep) { }
_driver_factory(driver_factory), _ep(*session_ep),
_receiver(receiver)
{ }
}; };
#endif /* _INCLUDE__BLOCK__COMPONENT_H_ */ #endif /* _INCLUDE__BLOCK__COMPONENT_H_ */

View File

@ -53,18 +53,10 @@ struct Genode::Signal_rpc_dispatcher_base : Genode::Signal_dispatcher_base
Proxy_component _proxy; Proxy_component _proxy;
Capability<Proxy> _proxy_cap; Capability<Proxy> _proxy_cap;
unsigned _nesting_level;
private:
/**
* To be implemented by the derived class
*/
virtual void dispatch_at_entrypoint(unsigned num) = 0;
protected: protected:
Signal_rpc_dispatcher_base() : _proxy(*this), _nesting_level(0) { } Signal_rpc_dispatcher_base() : _proxy(*this) { }
Capability<Proxy> proxy_cap() { return _proxy_cap; } 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 * Interface of Signal_dispatcher_base
*/ */
void dispatch(unsigned num) void dispatch(unsigned num) {
{ proxy_cap().call<Proxy::Rpc_handle_signal>(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++;
/* called from the signal-receiving thread */ /**
if (_nesting_level == 1) * To be implemented by the derived class
proxy_cap().call<Proxy::Rpc_handle_signal>(num); */
virtual void dispatch_at_entrypoint(unsigned num) = 0;
/* called from the context of the RPC entrypoint */
if (_nesting_level > 1)
dispatch_at_entrypoint(num);
_nesting_level--;
}
}; };

View File

@ -17,40 +17,47 @@
*/ */
/* Genode includes */ /* Genode includes */
#include <cap_session/connection.h>
#include <block/component.h> #include <block/component.h>
#include <os/server.h>
/* local includes */ /* local includes */
#include <ahci_driver.h> #include <ahci_driver.h>
using namespace Genode; 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() { Block::Driver *create() {
return new(env()->heap()) Ahci_driver(); } return new(env()->heap()) Ahci_driver(); }
void destroy(Block::Driver *driver) { void destroy(Block::Driver *driver) {
Genode::destroy(env()->heap(), static_cast<Ahci_driver *>(driver)); } Genode::destroy(env()->heap(), static_cast<Ahci_driver *>(driver)); }
} driver_factory; } factory;
enum { STACK_SIZE = 8128 }; Block::Root root;
static Cap_connection cap;
static Rpc_entrypoint ep(&cap, STACK_SIZE, "block_ep");
static Signal_receiver receiver; Main(Server::Entrypoint &ep)
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver); : ep(ep), root(ep, Genode::env()->heap(), factory)
env()->parent()->announce(ep.manage(&block_root)); {
printf("--- AHCI driver started ---\n");
while (true) { Genode::env()->parent()->announce(ep.manage(root));
Signal s = receiver.wait_for_signal();
static_cast<Signal_dispatcher_base *>(s.context())->dispatch(s.num());
} }
};
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); }
} }

View File

@ -1,3 +1,3 @@
TARGET = ahci TARGET = ahci
LIBS += ahci LIBS += ahci server
SRC_CC += empty.cc SRC_CC += empty.cc

View File

@ -13,9 +13,8 @@
*/ */
/* Genode includes */ /* Genode includes */
#include <base/thread.h>
#include <cap_session/connection.h>
#include <os/config.h> #include <os/config.h>
#include <os/server.h>
/* local includes */ /* local includes */
#include "ata_device.h" #include "ata_device.h"
@ -65,22 +64,24 @@ struct Factory : Block::Driver_factory
}; };
int main() struct Main
{ {
enum { STACK_SIZE = 8192 }; Server::Entrypoint &ep;
static Cap_connection cap; struct Factory factory;
static Rpc_entrypoint ep(&cap, STACK_SIZE, "atapi_ep"); Block::Root root;
static Signal_receiver receiver; Main(Server::Entrypoint &ep)
static Factory driver_factory; : ep(ep), root(ep, Genode::env()->heap(), factory) {
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver); Genode::env()->parent()->announce(ep.manage(root)); }
};
env()->parent()->announce(ep.manage(&block_root));
while (true) { /************
Signal s = receiver.wait_for_signal(); ** Server **
static_cast<Signal_dispatcher_base *>(s.context())->dispatch(s.num()); ************/
}
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); }
} }

View File

@ -2,7 +2,7 @@ TARGET = atapi_drv
REQUIRES = x86 REQUIRES = x86
SRC_CC = main.cc ata_device.cc atapi_device.cc io.cc ata_bus_master.cc SRC_CC = main.cc ata_device.cc atapi_device.cc io.cc ata_bus_master.cc
SRC_C = mindrvr.c SRC_C = mindrvr.c
LIBS = base config LIBS = base config server
INC_DIR += $(PRG_DIR)/contrib $(PRG_DIR) INC_DIR += $(PRG_DIR)/contrib $(PRG_DIR)

View File

@ -13,52 +13,48 @@
/* Genode includes */ /* Genode includes */
#include <base/printf.h> #include <base/printf.h>
#include <cap_session/connection.h>
#include <regulator_session/connection.h> #include <regulator_session/connection.h>
#include <os/server.h>
/* local includes */ /* local includes */
#include <driver.h> #include <driver.h>
int main(int argc, char **argv) struct Main
{ {
using namespace Genode; Server::Entrypoint &ep;
printf("--- Arndale eMMC card driver ---\n"); struct Factory : Block::Driver_factory
/**
* Factory used by 'Block::Root' at session creation/destruction time
*/
struct Driver_factory : Block::Driver_factory
{ {
Block::Driver *create() Block::Driver *create() {
{ return new (Genode::env()->heap()) Block::Exynos5_driver(true); }
bool use_dma = true;
return new (env()->heap()) Block::Exynos5_driver(use_dma);
}
void destroy(Block::Driver *driver) void destroy(Block::Driver *driver) {
{ Genode::destroy(Genode::env()->heap(),
Genode::destroy(env()->heap(), static_cast<Block::Exynos5_driver *>(driver)); }
static_cast<Block::Exynos5_driver *>(driver)); } factory;
}
} driver_factory; Regulator::Connection regulator;
Block::Root root;
enum { STACK_SIZE = 8192 }; Main(Server::Entrypoint &ep)
static Cap_connection cap; : ep(ep), regulator(Regulator::CLK_MMC0),
static Rpc_entrypoint ep(&cap, STACK_SIZE, "block_ep"); root(ep, Genode::env()->heap(), factory)
static Regulator::Connection mmc0_regulator(Regulator::CLK_MMC0); {
mmc0_regulator.state(true); Genode::printf("--- Arndale eMMC card driver ---\n");
static Signal_receiver receiver; Genode::env()->parent()->announce(ep.manage(root));
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver); regulator.state(true);
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;
/************
** 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); }
} }

View File

@ -1,5 +1,5 @@
TARGET = sd_card_drv TARGET = sd_card_drv
REQUIRES = exynos5 REQUIRES = exynos5
SRC_CC = main.cc SRC_CC = main.cc
LIBS = base LIBS = base server
INC_DIR += $(PRG_DIR) $(PRG_DIR)/.. INC_DIR += $(PRG_DIR) $(PRG_DIR)/..

View File

@ -13,53 +13,45 @@
/* Genode includes */ /* Genode includes */
#include <base/printf.h> #include <base/printf.h>
#include <cap_session/connection.h> #include <os/server.h>
/* local includes */ /* local includes */
#include <driver.h> #include <driver.h>
/* struct Main
* MMC1: IRQ 83
*/
int main(int argc, char **argv)
{ {
using namespace Genode; Server::Entrypoint &ep;
printf("--- OMAP4 SD card driver ---\n"); struct Factory : Block::Driver_factory
/**
* Factory used by 'Block::Root' at session creation/destruction time
*/
struct Driver_factory : Block::Driver_factory
{ {
Block::Driver *create() Block::Driver *create() {
{ return new (Genode::env()->heap()) Block::Omap4_driver(true); }
bool use_dma = true;
return new (env()->heap()) Block::Omap4_driver(use_dma);
}
void destroy(Block::Driver *driver) void destroy(Block::Driver *driver) {
{ Genode::destroy(Genode::env()->heap(),
Genode::destroy(env()->heap(), static_cast<Block::Omap4_driver *>(driver)); }
static_cast<Block::Omap4_driver *>(driver)); } factory;
}
} driver_factory; Block::Root root;
enum { STACK_SIZE = 4096 }; Main(Server::Entrypoint &ep)
static Cap_connection cap; : ep(ep), root(ep, Genode::env()->heap(), factory)
static Rpc_entrypoint ep(&cap, STACK_SIZE, "block_ep"); {
Genode::printf("--- OMAP4 SD card driver ---\n");
static Signal_receiver receiver; Genode::env()->parent()->announce(ep.manage(root));
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;
/************
** 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); }
} }

View File

@ -1,5 +1,5 @@
TARGET = sd_card_drv TARGET = sd_card_drv
REQUIRES = omap4 REQUIRES = omap4
SRC_CC = main.cc SRC_CC = main.cc
LIBS = base LIBS = base server
INC_DIR += $(PRG_DIR) $(PRG_DIR)/.. INC_DIR += $(PRG_DIR) $(PRG_DIR)/..

View File

@ -11,32 +11,28 @@
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
*/ */
/* Genode includes */
#include <base/printf.h> #include <base/printf.h>
#include <cap_session/connection.h>
#include <block/component.h> #include <block/component.h>
#include <pl180_defs.h> #include <os/server.h>
/* local includes */
#include <pl180_defs.h>
#include "pl180.h" #include "pl180.h"
#include "sd_card.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"); struct Factory : Block::Driver_factory
/**
* Factory used by 'Block::Root' at session creation/destruction time
*/
struct Pl180_driver_factory : Block::Driver_factory
{ {
Block::Driver *create() Block::Driver *create()
{ {
Pl180 *pl180 = new (env()->heap()) Pl180 *pl180 = new (Genode::env()->heap())
Pl180(PL180_PHYS, PL180_SIZE); Pl180(PL180_PHYS, PL180_SIZE);
Sd_card *sd_card = new (env()->heap()) Sd_card *sd_card = new (Genode::env()->heap())
Sd_card(*pl180); Sd_card(*pl180);
return sd_card; return sd_card;
@ -47,24 +43,29 @@ int main(int argc, char **argv)
Sd_card *sd_card = static_cast<Sd_card *>(driver); Sd_card *sd_card = static_cast<Sd_card *>(driver);
Pl180 *pl180 = static_cast<Pl180 *>(&sd_card->host_driver()); Pl180 *pl180 = static_cast<Pl180 *>(&sd_card->host_driver());
Genode::destroy(env()->heap(), sd_card); Genode::destroy(Genode::env()->heap(), sd_card);
Genode::destroy(env()->heap(), pl180); Genode::destroy(Genode::env()->heap(), pl180);
} }
} factory;
} driver_factory; Block::Root root;
enum { STACK_SIZE = 4096 }; Main(Server::Entrypoint &ep)
static Cap_connection cap; : ep(ep), root(ep, Genode::env()->heap(), factory)
static Rpc_entrypoint ep(&cap, STACK_SIZE, "block_ep"); {
Genode::printf("--- PL180 MMC/SD card driver started ---\n");
static Signal_receiver receiver; Genode::env()->parent()->announce(ep.manage(root));
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;
/************
** 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); }
} }

View File

@ -1,6 +1,6 @@
TARGET = sd_card_drv TARGET = sd_card_drv
REQUIRES = pl180 REQUIRES = pl180
SRC_CC = main.cc SRC_CC = main.cc
LIBS = base LIBS = base server
INC_DIR += $(PRG_DIR) INC_DIR += $(PRG_DIR)

View File

@ -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) Signal_context_capability Entrypoint::manage(Signal_rpc_dispatcher_base &dispatcher)
{ {
return dispatcher.manage(global_sig_rec(), global_rpc_ep()); 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()) { } Server::Entrypoint::Entrypoint() : _rpc_ep(global_rpc_ep()) { }
void Server::wait_and_dispatch_one_signal() void Server::wait_and_dispatch_one_signal() {
{ ::wait_and_dispatch_one_signal(true); }
/*
* 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);
}
namespace Server { namespace Server {
@ -116,10 +124,10 @@ int main(int argc, char **argv)
/* call Server::construct in the context of the entrypoint */ /* call Server::construct in the context of the entrypoint */
Capability<Server::Constructor> constructor_cap = ep.manage(constructor); Capability<Server::Constructor> constructor_cap = ep.manage(constructor);
constructor_cap.call<Server::Constructor::Rpc_construct>(); constructor_cap.call<Server::Constructor::Rpc_construct>();
/* process incoming signals */ /* process incoming signals */
for (;;) for (;;)
Server::wait_and_dispatch_one_signal(); wait_and_dispatch_one_signal(false);
} }

View File

@ -14,7 +14,7 @@
#include <base/exception.h> #include <base/exception.h>
#include <base/printf.h> #include <base/printf.h>
#include <os/config.h> #include <os/config.h>
#include <cap_session/connection.h> #include <os/server.h>
#include <rom_session/connection.h> #include <rom_session/connection.h>
#include <block/component.h> #include <block/component.h>
#include <block/driver.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]; Block::Driver *create()
size_t blk_sz = 512; {
char file[64];
size_t blk_sz = 512;
try { try {
config()->xml_node().attribute("file").value(file, sizeof(file)); config()->xml_node().attribute("file").value(file, sizeof(file));
config()->xml_node().attribute("block_size").value(&blk_sz); 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 { Block::Root root;
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();
}
void destroy(Block::Driver *driver) { Main(Server::Entrypoint &ep)
Genode::destroy(env()->heap(), driver); } : ep(ep), root(ep, Genode::env()->heap(), factory) {
Genode::env()->parent()->announce(ep.manage(root)); }
}; };
int main() /************
{ ** Server **
enum { STACK_SIZE = 8192 }; ************/
static Cap_connection cap;
static Rpc_entrypoint ep(&cap, STACK_SIZE, "rom_blk_ep");
static Signal_receiver receiver; namespace Server {
static Factory driver_factory; char const *name() { return "rom_blk_ep"; }
static Block::Root block_root(&ep, env()->heap(), driver_factory, receiver); size_t stack_size() { return 2*1024*sizeof(long); }
void construct(Entrypoint &ep) { static Main server(ep); }
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;
} }

View File

@ -1,3 +1,3 @@
TARGET = rom_blk TARGET = rom_blk
SRC_CC = main.cc SRC_CC = main.cc
LIBS = base config LIBS = base config server

View File

@ -32,11 +32,17 @@ class Driver : public Block::Driver
Genode::size_t _number; Genode::size_t _number;
Genode::size_t _size; Genode::size_t _size;
Req_buffer _packets; Req_buffer _packets;
Genode::Signal_dispatcher<Driver> _ack;
Genode::Ram_dataspace_capability _blk_ds; Genode::Ram_dataspace_capability _blk_ds;
unsigned char *_blk_buf; 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()) { while (!_packets.empty()) {
Block::Packet_descriptor p = _packets.get(); 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 ** ** Block::Driver interface **
@ -98,52 +93,54 @@ class Driver : public Block::Driver
}; };
struct Factory : Block::Driver_factory struct Main
{ {
Genode::Signal_receiver &receiver; Server::Entrypoint &ep;
::Driver *driver;
Factory(Genode::Signal_receiver &r) : receiver(r) struct Factory : Block::Driver_factory
{ {
Genode::size_t blk_nr = 1024; ::Driver *driver;
Genode::size_t blk_sz = 512;
try { Factory()
Genode::config()->xml_node().attribute("sectors").value(&blk_nr); {
Genode::config()->xml_node().attribute("block_size").value(&blk_sz); 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; } 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() /************
{ ** Server **
using namespace Genode; ************/
enum { STACK_SIZE = 2048 * sizeof(Genode::addr_t) }; namespace Server {
static Cap_connection cap; char const *name() { return "blk_srv_ep"; }
static Rpc_entrypoint ep(&cap, STACK_SIZE, "test_blk_ep"); size_t stack_size() { return 2*1024*sizeof(long); }
void construct(Entrypoint &ep) { static Main server(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;
} }

View File

@ -1,3 +1,3 @@
TARGET = test-blk-srv TARGET = test-blk-srv
SRC_CC = main.cc SRC_CC = main.cc
LIBS = base config LIBS = base config server

View File

@ -15,10 +15,8 @@
*/ */
#include <base/printf.h> #include <base/printf.h>
#include <cap_session/connection.h>
#include <framebuffer_session/connection.h> #include <framebuffer_session/connection.h>
#include <block/component.h> #include <block/component.h>
#include <block/driver.h>
class Driver : public Block::Driver 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) }; Main(Server::Entrypoint &ep)
static Cap_connection cap; : ep(ep), root(ep, Genode::env()->heap(), factory) {
static Rpc_entrypoint ep(&cap, STACK_SIZE, "fb_block_ep"); 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) { namespace Server {
Signal s = receiver.wait_for_signal(); char const *name() { return "fb_blk_ep"; }
static_cast<Signal_dispatcher_base *>(s.context())->dispatch(s.num()); size_t stack_size() { return 2*1024*sizeof(long); }
} void construct(Entrypoint &ep) { static Main server(ep); }
return 0;
} }

View File

@ -1,3 +1,3 @@
TARGET = test-fb_blk_adapter TARGET = test-fb_blk_adapter
SRC_CC = main.cc SRC_CC = main.cc
LIBS = base LIBS = base server