block layer: transition to new API

Ref #1987
Fix #2058
This commit is contained in:
Stefan Kalkowski 2016-08-12 15:10:50 +02:00 committed by Christian Helmuth
parent acd2a40076
commit 7f8f0f50ea
39 changed files with 473 additions and 530 deletions

View File

@ -223,7 +223,7 @@ void scsi_add_device(struct scsi_device *sdev)
*/
if (!announce) {
PREPARE_WORK(&delayed, ack_packet);
static Block::Root root(_signal->ep(), &Lx::Malloc::mem(), factory);
static Block::Root root(_signal->ep(), Lx::Malloc::mem(), factory);
_signal->parent().announce(_signal->ep().rpc_ep().manage(&root));
announce = true;
}

View File

@ -22,43 +22,31 @@
struct Main
{
Server::Entrypoint &ep;
Genode::Env &env;
Genode::Heap heap { env.ram(), env.rm() };
struct Factory : Block::Driver_factory
{
Server::Entrypoint &ep;
Genode::Entrypoint &ep;
Genode::Heap &heap;
Factory(Server::Entrypoint &ep) : ep(ep) { }
Factory(Genode::Entrypoint &ep, Genode::Heap &heap)
: ep(ep), heap(heap) { }
Block::Driver *create()
{
return new (Genode::env()->heap()) Driver(ep);
}
Block::Driver *create() {
return new (&heap) Driver(ep); }
void destroy(Block::Driver *driver)
{
Genode::destroy(Genode::env()->heap(), driver);
}
void destroy(Block::Driver *driver) {
Genode::destroy(&heap, driver); }
} factory;
} factory { env.ep(), heap };
Block::Root root;
Block::Root root { env.ep(), heap, factory };
Main(Server::Entrypoint &ep)
:
ep(ep), factory(ep), root(ep, Genode::env()->heap(), factory)
{
Genode::env()->parent()->announce(ep.manage(root));
}
Main(Genode::Env &env) : env(env) {
env.parent().announce(env.ep().manage(root)); }
};
/**********************
** Server framework **
**********************/
namespace Server {
char const *name() { return "rump_cgd_ep"; }
size_t stack_size() { return 4 * 1024 * sizeof(long); }
void construct(Entrypoint &ep) { static Main inst(ep); }
}
Genode::size_t Component::stack_size() { return 4 * 1024 * sizeof(long); }
void Component::construct(Genode::Env &env) { static Main inst(env); }

View File

@ -1,4 +1,4 @@
TARGET = rump_cgd
SRC_CC = cgd.cc main.cc random.cc
LIBS = rump rump_cgd server startup jitterentropy
LIBS = rump rump_cgd startup jitterentropy

View File

@ -12,7 +12,7 @@
*/
#include <base/child.h>
#include <base/printf.h>
#include <base/log.h>
#include <base/sleep.h>
#include <lwip/genode.h>
#include <nic/packet_allocator.h>
@ -27,11 +27,6 @@
using namespace Genode;
/*
* Debugging output
*/
static const int verbose = 0;
enum {
/* HTTP status codes */
HTTP_SUCC_OK = 200,
@ -62,7 +57,7 @@ void Http::cmd_head()
int length = snprintf(_http_buf, HTTP_BUF, http_templ, "HEAD", _path, _host);
if (write(_fd, _http_buf, length) != length) {
PERR("Write error");
error("Write error");
throw Http::Socket_error();
}
}
@ -72,12 +67,12 @@ void Http::connect()
{
_fd = socket(AF_INET, SOCK_STREAM, 0);
if (_fd < 0) {
PERR("No socket avaiable");
error("No socket avaiable");
throw Http::Socket_error();
}
if (::connect(_fd, _info->ai_addr, sizeof(*(_info->ai_addr))) < 0) {
PERR("Connect failed");
error("Connect failed");
throw Http::Socket_error();
}
}
@ -90,11 +85,11 @@ void Http::resolve_uri()
{
struct addrinfo *info;
if (getaddrinfo(_host, _port, 0, &info)) {
PERR("Error: Host %s not found", _host);
error("Error: Host ", (const char*)_host, " not found");
throw Http::Uri_error();
}
env()->heap()->alloc(sizeof(struct addrinfo), &_info);
_heap.alloc(sizeof(struct addrinfo), (void**)&_info);
Genode::memcpy(_info, info, sizeof(struct addrinfo));
}
@ -114,7 +109,7 @@ Genode::size_t Http::read_header()
header = false;
if (++i >= HTTP_BUF) {
PERR("Buffer overflow");
error("Buffer overflow");
throw Http::Socket_error();
}
}
@ -155,10 +150,6 @@ void Http::get_capacity()
if (key) {
ascii_to(t.start(), _size);
if (verbose)
PDBG("File size: %zu bytes", _size);
break;
}
@ -181,21 +172,19 @@ void Http::do_read(void * buf, size_t size)
int part;
if ((part = read(_fd, (void *)((addr_t)buf + buf_fill),
size - buf_fill)) <= 0) {
PERR("Error: Reading data (%d)", errno);
error("Error: Reading data (", errno, ")");
throw Http::Socket_error();
}
buf_fill += part;
}
if (verbose)
PDBG("Read %zu/%zu", buf_fill, size);
}
Http::Http(char *uri) : _port((char *)"80")
Http::Http(Genode::Heap &heap, ::String &uri)
: _heap(heap), _port((char *)"80")
{
env()->heap()->alloc(HTTP_BUF, &_http_buf);
_heap.alloc(HTTP_BUF, (void**)&_http_buf);
/* parse URI */
parse_uri(uri);
@ -213,17 +202,18 @@ Http::Http(char *uri) : _port((char *)"80")
Http::~Http()
{
env()->heap()->free(_host, Genode::strlen(_host) + 1);
env()->heap()->free(_path, Genode::strlen(_path) + 2);
env()->heap()->free(_http_buf, HTTP_BUF);
env()->heap()->free(_info, sizeof(struct addrinfo));
_heap.free(_host, Genode::strlen(_host) + 1);
_heap.free(_path, Genode::strlen(_path) + 2);
_heap.free(_http_buf, HTTP_BUF);
_heap.free(_info, sizeof(struct addrinfo));
}
void Http::parse_uri(char *uri)
void Http::parse_uri(::String & u)
{
/* strip possible http prefix */
const char *http = "http://";
char * uri = const_cast<char*>(u.string());
size_t length = Genode::strlen(uri);
size_t http_len = Genode::strlen(http);
if (!strcmp(http, uri, http_len)) {
@ -235,10 +225,10 @@ void Http::parse_uri(char *uri)
size_t i;
for (i = 0; i < length && uri[i] != '/'; i++) ;
env()->heap()->alloc(i + 1, &_host);
_heap.alloc(i + 1, (void**)&_host);
Genode::strncpy(_host, uri, i + 1);
env()->heap()->alloc(length - i + 1, &_path);
_heap.alloc(length - i + 1, (void**)&_path);
Genode::strncpy(_path, uri + i, length - i + 1);
/* look for port */
@ -248,18 +238,11 @@ void Http::parse_uri(char *uri)
_port = &_host[i + 1];
_host[i] = '\0';
}
if (verbose)
PDBG("Port: %s", _port);
}
void Http::cmd_get(size_t file_offset, size_t size, addr_t buffer)
{
if (verbose)
PDBG("Read: offs %zu size: %zu I/O buffer: %lx", file_offset, size, buffer);
while (true) {
const char *http_templ = "GET %s HTTP/1.1\r\n"
@ -287,7 +270,7 @@ void Http::cmd_get(size_t file_offset, size_t size, addr_t buffer)
}
if (_http_ret != HTTP_SUCC_PARTIAL) {
PERR("Error: Server returned %u", _http_ret);
error("Error: Server returned ", _http_ret);
throw Http::Server_error();
}

View File

@ -18,6 +18,7 @@
struct addrinfo;
using String = Genode::String<64>;
class Http
{
typedef Genode::size_t size_t;
@ -26,6 +27,7 @@ class Http
private:
Genode::Heap &_heap;
size_t _size; /* number of bytes in file */
char *_host; /* host name */
char *_port; /* host port */
@ -54,7 +56,7 @@ class Http
/*
* Set URI of remote file
*/
void parse_uri(char *uri);
void parse_uri(::String &uri);
/*
* Resolve host
@ -81,7 +83,7 @@ class Http
/*
* Constructor (default host port is 80
*/
Http(char *uri);
Http(Genode::Heap &heap, ::String &uri);
/*
* Destructor

View File

@ -13,9 +13,9 @@
*/
/* Genode includes */
#include <cap_session/connection.h>
#include <base/attached_rom_dataspace.h>
#include <base/log.h>
#include <block/component.h>
#include <os/config.h>
/* local includes */
#include "http.h"
@ -31,8 +31,8 @@ class Driver : public Block::Driver
public:
Driver(size_t block_size, char *uri)
: _block_size(block_size), _http(uri) {}
Driver(Heap &heap, size_t block_size, ::String &uri)
: _block_size(block_size), _http(heap, uri) {}
/*******************************
@ -65,48 +65,46 @@ class Factory : public Block::Driver_factory
{
private:
char _uri[64];
size_t _blk_sz;
Env &_env;
Heap &_heap;
Attached_rom_dataspace _config { _env, "config" };
::String _uri;
size_t _blk_sz;
public:
Factory() : _blk_sz(512)
Factory(Env &env, Heap &heap)
: _env(env), _heap(heap), _blk_sz(512)
{
try {
config()->xml_node().attribute("uri").value(_uri, sizeof(_uri));
config()->xml_node().attribute("block_size").value(&_blk_sz);
_config.xml().attribute("uri").value(&_uri);
_config.xml().attribute("block_size").value(&_blk_sz);
}
catch (...) { }
PINF("Using file=%s as device with block size %zx.", _uri, _blk_sz);
log("Using file=", _uri, " as device with block size ",
Hex(_blk_sz, Hex::OMIT_PREFIX), ".");
}
Block::Driver *create() {
return new (env()->heap()) Driver(_blk_sz, _uri); }
return new (&_heap) Driver(_heap, _blk_sz, _uri); }
void destroy(Block::Driver *driver) {
Genode::destroy(env()->heap(), driver); }
Genode::destroy(&_heap, driver); }
};
struct Main
{
Server::Entrypoint &ep;
struct Factory factory;
Block::Root root;
Env &env;
Heap heap { env.ram(), env.rm() };
Factory factory { env, heap };
Block::Root root { env.ep(), heap, factory };
Main(Server::Entrypoint &ep)
: ep(ep), root(ep, Genode::env()->heap(), factory) {
Genode::env()->parent()->announce(ep.manage(root)); }
Main(Env &env) : env(env) {
env.parent().announce(env.ep().manage(root)); }
};
/************
** Server **
************/
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); }
}
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
void Component::construct(Genode::Env &env) { static Main m(env); }

View File

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

View File

@ -6,7 +6,7 @@
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
* Copyright (C) 2011-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
@ -15,9 +15,9 @@
#ifndef _INCLUDE__BLOCK__COMPONENT_H_
#define _INCLUDE__BLOCK__COMPONENT_H_
#include <base/log.h>
#include <base/component.h>
#include <root/component.h>
#include <os/signal_rpc_dispatcher.h>
#include <os/server.h>
#include <block/driver.h>
namespace Block {
@ -67,13 +67,13 @@ class Block::Session_component : public Block::Session_component_base,
{
private:
addr_t _rq_phys;
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;
unsigned _p_in_fly;
addr_t _rq_phys;
Signal_handler<Session_component> _sink_ack;
Signal_handler<Session_component> _sink_submit;
bool _req_queue_full;
bool _ack_queue_full;
Packet_descriptor _p_to_handle;
unsigned _p_in_fly;
/**
* Acknowledge a packet already handled
@ -81,7 +81,7 @@ class Block::Session_component : public Block::Session_component_base,
inline void _ack_packet(Packet_descriptor &packet)
{
if (!tx_sink()->ready_to_ack())
PERR("Not ready to ack!");
error("Not ready to ack!");
tx_sink()->acknowledge_packet(packet);
_p_in_fly--;
@ -148,9 +148,9 @@ class Block::Session_component : public Block::Session_component_base,
}
/**
* Triggered when a packet was placed into the empty submit queue
* Called whenever a signal from the packet-stream interface triggered
*/
void _packet_avail(unsigned)
void _signal()
{
/*
* as long as more packets are available, and we're able to ack
@ -164,28 +164,23 @@ class Block::Session_component : public Block::Session_component_base,
_handle_packet(tx_sink()->get_packet());
}
/**
* Triggered when an ack got removed from the full ack queue
*/
void _ready_to_ack(unsigned) { _packet_avail(0); }
public:
/**
* Constructor
*
* \param rq_ds shared dataspace for packet stream
* \param driver block driver backend
* \param driver_factory factory to create and destroy driver objects
* \param ep entrypoint handling this session component
* \param buf_size size of packet-stream payload buffer
*/
Session_component(Driver_factory &driver_factory,
Server::Entrypoint &ep, size_t buf_size)
Session_component(Driver_factory &driver_factory,
Genode::Entrypoint &ep,
size_t buf_size)
: Session_component_base(driver_factory, buf_size),
Driver_session(_rq_ds, ep.rpc_ep()),
_rq_phys(Dataspace_client(_rq_ds).phys_addr()),
_sink_ack(ep, *this, &Session_component::_ready_to_ack),
_sink_submit(ep, *this, &Session_component::_packet_avail),
_sink_ack(ep, *this, &Session_component::_signal),
_sink_submit(ep, *this, &Session_component::_signal),
_req_queue_full(false),
_p_in_fly(0)
{
@ -223,7 +218,7 @@ class Block::Session_component : public Block::Session_component_base,
}
/* resume packet processing */
_packet_avail(0);
_signal();
}
@ -252,7 +247,7 @@ class Block::Root : public Genode::Root_component<Block::Session_component,
private:
Driver_factory &_driver_factory;
Server::Entrypoint &_ep;
Genode::Entrypoint &_ep;
protected:
@ -279,8 +274,8 @@ class Block::Root : public Genode::Root_component<Block::Session_component,
* to handle a possible overflow of the sum of both sizes.
*/
if (tx_buf_size > ram_quota - session_size) {
PERR("insufficient 'ram_quota', got %zd, need %zd",
ram_quota, tx_buf_size + session_size);
error("insufficient 'ram_quota', got ", ram_quota, ", need ",
tx_buf_size + session_size);
throw Root::Quota_exceeded();
}
@ -296,11 +291,11 @@ class Block::Root : public Genode::Root_component<Block::Session_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(Server::Entrypoint &ep, Allocator *md_alloc,
Root(Genode::Entrypoint &ep,
Allocator &md_alloc,
Driver_factory &driver_factory)
: Root_component(&ep.rpc_ep(), md_alloc),
: Root_component(ep, md_alloc),
_driver_factory(driver_factory), _ep(ep) { }
};

View File

@ -26,15 +26,15 @@ class Usb::Packet_handler
Usb::Connection &_connection;
Genode::Entrypoint &_ep;
Signal_rpc_member<Packet_handler> _rpc_ack_avail =
Signal_handler<Packet_handler> _rpc_ack_avail =
{_ep, *this, &Packet_handler::_packet_handler };
Signal_rpc_member<Packet_handler> _rpc_ready_submit =
Signal_handler<Packet_handler> _rpc_ready_submit =
{ _ep, *this, &Packet_handler::_ready_handler };
bool _ready_submit = true;
void _packet_handler(unsigned)
void _packet_handler()
{
if (!_ready_submit)
return;
@ -49,7 +49,7 @@ class Usb::Packet_handler
}
}
void _ready_handler(unsigned)
void _ready_handler()
{
_ready_submit = true;
};
@ -76,7 +76,7 @@ class Usb::Packet_handler
void wait_for_packet()
{
packet_avail() ? _packet_handler(0) : _ep.wait_and_dispatch_one_signal();
packet_avail() ? _packet_handler() : _ep.wait_and_dispatch_one_signal();
}
Packet_descriptor alloc(size_t size)
@ -117,7 +117,7 @@ class Usb::Packet_handler
* retrieve packets.
*/
if (packet_avail())
_packet_handler(0);
_packet_handler();
}
void *content(Packet_descriptor &p)

View File

@ -7,7 +7,7 @@
#
# Build
#
build { core init drivers/timer test/blk lib/trace/policy/rpc_name }
build { core init drivers/timer test/blk }
create_boot_directory
#
@ -46,7 +46,7 @@ install_config {
#
# Boot modules
#
build_boot_image { core init timer test-blk-srv test-blk-cli rpc_name }
build_boot_image { core init timer test-blk-srv test-blk-cli }
append qemu_args " -nographic -m 64 "
run_genode_until "Tests finished successfully.*\n" 100

View File

@ -49,17 +49,15 @@ struct Ahci
Port_driver *ports[MAX_PORTS];
bool port_claimed[MAX_PORTS];
Signal_rpc_member<Ahci> irq;
Signal_rpc_member<Ahci> device_ready;
unsigned ready_count = 0;
bool enable_atapi;
Signal_handler<Ahci> irq;
unsigned ready_count = 0;
bool enable_atapi;
Ahci(Genode::Env &env, Genode::Allocator &alloc,
Ahci_root &root, bool support_atapi)
:
env(env), alloc(alloc),
root(root), irq(root.entrypoint(), *this, &Ahci::handle_irq),
device_ready(root.entrypoint(), *this, &Ahci::ready),
enable_atapi(support_atapi)
{
info();
@ -87,7 +85,7 @@ struct Ahci
/**
* Forward IRQs to ports
*/
void handle_irq(unsigned)
void handle_irq()
{
unsigned port_list = hba.read<Hba::Is>();
while (port_list) {
@ -104,17 +102,6 @@ struct Ahci
platform_hba.ack_irq();
}
void ready(unsigned cnt)
{
ready_count -= cnt;
if (ready_count)
return;
/* announce service */
root.announce();
}
void info()
{
PINF("\tversion: %x.%04x", hba.read<Hba::Version::Major>(),
@ -158,14 +145,14 @@ struct Ahci
switch (sig) {
case ATA_SIG:
ports[i] = new (&alloc) Ata_driver(alloc, port, device_ready);
ready_count++;
ports[i] = new (&alloc) Ata_driver(alloc, port, root,
ready_count);
break;
case ATAPI_SIG:
case ATAPI_SIG_QEMU:
ports[i] = new (&alloc) Atapi_driver(port, device_ready);
ready_count++;
ports[i] = new (&alloc) Atapi_driver(port, root,
ready_count);
break;
default:

View File

@ -29,7 +29,7 @@ namespace Platform {
struct Ahci_root
{
virtual Server::Entrypoint &entrypoint() = 0;
virtual Genode::Entrypoint &entrypoint() = 0;
virtual void announce() = 0;
};
@ -792,15 +792,22 @@ struct Port : Genode::Mmio
struct Port_driver : Port, Block::Driver
{
Genode::Signal_context_capability state_change_cap;
Ahci_root &root;
unsigned &sem;
Port_driver(Port &port, Genode::Signal_context_capability state_change_cap)
: Port(port), state_change_cap(state_change_cap)
{ }
Port_driver(Port &port, Ahci_root &root, unsigned &sem)
: Port(port), root(root), sem(sem) {
sem++; }
virtual void handle_irq() = 0;
void state_change() { Genode::Signal_transmitter(state_change_cap).submit(); }
void state_change()
{
if (--sem) return;
/* announce service */
root.announce();
}
void sanity_check(Block::sector_t block_number, Genode::size_t count)
{

View File

@ -188,8 +188,8 @@ struct Ata_driver : Port_driver
Block::Packet_descriptor pending[32];
Ata_driver(Genode::Allocator &alloc,
Port &port, Signal_context_capability state_change)
: Port_driver(port, state_change), alloc(alloc)
Port &port, Ahci_root &root, unsigned &sem)
: Port_driver(port, root, sem), alloc(alloc)
{
Port::init();
identify_device();

View File

@ -24,8 +24,8 @@ struct Atapi_driver : Port_driver
unsigned sense_tries = 0;
Block::Packet_descriptor pending;
Atapi_driver(Port &port, Signal_context_capability state_change)
: Port_driver(port, state_change)
Atapi_driver(Port &port, Ahci_root &root, unsigned &sem)
: Port_driver(port, root, sem)
{
Port::init();
Port::write<Cmd::Atapi>(1);

View File

@ -52,8 +52,9 @@ class Session_component : public Block::Session_component
{
public:
Session_component(Block::Driver_factory &driver_factory,
Server::Entrypoint &ep, Genode::size_t buf_size)
Session_component(Block::Driver_factory &driver_factory,
Genode::Entrypoint &ep,
Genode::size_t buf_size)
: Block::Session_component(driver_factory, ep, buf_size) { }
Block::Driver_factory &factory() { return _driver_factory; }

View File

@ -12,9 +12,9 @@
*/
/* Genode includes */
#include <base/printf.h>
#include <base/component.h>
#include <base/log.h>
#include <regulator_session/connection.h>
#include <os/server.h>
/* local includes */
#include <driver.h>
@ -22,43 +22,37 @@
struct Main
{
Server::Entrypoint &ep;
Genode::Env &env;
Genode::Heap heap { env.ram(), env.rm() };
struct Factory : Block::Driver_factory
{
Server::Entrypoint &ep;
Genode::Entrypoint &ep;
Genode::Heap &heap;
Factory(Server::Entrypoint &ep) : ep(ep) { }
Factory(Genode::Entrypoint &ep, Genode::Heap &heap)
: ep(ep), heap(heap) { }
Block::Driver *create() {
return new (Genode::env()->heap()) Block::Exynos5_driver(ep, true); }
return new (&heap) Block::Exynos5_driver(ep, true); }
void destroy(Block::Driver *driver) {
Genode::destroy(Genode::env()->heap(),
Genode::destroy(&heap,
static_cast<Block::Exynos5_driver *>(driver)); }
} factory;
} factory { env.ep(), heap };
Regulator::Connection regulator;
Block::Root root;
Regulator::Connection regulator { env, Regulator::CLK_MMC0 };
Block::Root root { env.ep(), heap, factory };
Main(Server::Entrypoint &ep)
: ep(ep), factory(ep), regulator(Regulator::CLK_MMC0),
root(ep, Genode::env()->heap(), factory)
Main(Genode::Env &env) : env(env)
{
Genode::printf("--- Arndale eMMC card driver ---\n");
Genode::log("--- Arndale eMMC card driver ---");
Genode::env()->parent()->announce(ep.manage(root));
env.parent().announce(env.ep().manage(root));
regulator.state(true);
}
};
/************
** 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); }
}
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
void Component::construct(Genode::Env &env) { static Main m(env); }

View File

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

View File

@ -12,8 +12,8 @@
*/
/* Genode includes */
#include <base/printf.h>
#include <os/server.h>
#include <base/component.h>
#include <base/log.h>
/* local includes */
#include <driver.h>
@ -21,40 +21,35 @@
struct Main
{
Server::Entrypoint &ep;
Genode::Env &env;
Genode::Heap heap { env.ram(), env.rm() };
struct Factory : Block::Driver_factory
{
Server::Entrypoint &ep;
Genode::Entrypoint &ep;
Genode::Heap &heap;
Factory(Server::Entrypoint &ep) : ep(ep) { }
Factory(Genode::Entrypoint &ep, Genode::Heap &heap)
: ep(ep), heap(heap) { }
Block::Driver *create() {
return new (Genode::env()->heap()) Block::Imx53_driver(true); }
return new (&heap) Block::Imx53_driver(true); }
void destroy(Block::Driver *driver) {
Genode::destroy(Genode::env()->heap(),
static_cast<Block::Imx53_driver *>(driver)); }
} factory;
Genode::destroy(&heap,
static_cast<Block::Imx53_driver*>(driver)); }
} factory { env.ep(), heap };
Block::Root root;
Block::Root root { env.ep(), heap, factory };
Main(Server::Entrypoint &ep)
: ep(ep), factory(ep), root(ep, Genode::env()->heap(), factory)
Main(Genode::Env &env) : env(env)
{
Genode::printf("--- Imx53 SD card driver ---\n");
Genode::log("--- Imx53 SD card driver ---");
Genode::env()->parent()->announce(ep.manage(root));
env.parent().announce(env.ep().manage(root));
}
};
/************
** 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); }
}
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
void Component::construct(Genode::Env &env) { static Main m(env); }

View File

@ -4,6 +4,5 @@ SRC_CC += main.cc
SRC_CC += adma2.cc
SRC_CC += esdhcv2.cc
LIBS += base
LIBS += server
INC_DIR += $(PRG_DIR)
INC_DIR += $(PRG_DIR)/../../

View File

@ -12,8 +12,8 @@
*/
/* Genode includes */
#include <base/printf.h>
#include <os/server.h>
#include <base/component.h>
#include <base/log.h>
/* local includes */
#include <driver.h>
@ -21,40 +21,35 @@
struct Main
{
Server::Entrypoint &ep;
Genode::Env &env;
Genode::Heap heap { env.ram(), env.rm() };
struct Factory : Block::Driver_factory
{
Server::Entrypoint &ep;
Genode::Entrypoint &ep;
Genode::Heap &heap;
Factory(Server::Entrypoint &ep) : ep(ep) { }
Factory(Genode::Entrypoint &ep, Genode::Heap &heap)
: ep(ep), heap(heap) { }
Block::Driver *create() {
return new (Genode::env()->heap()) Block::Omap4_driver(true); }
return new (&heap) Block::Omap4_driver(true); }
void destroy(Block::Driver *driver) {
Genode::destroy(Genode::env()->heap(),
static_cast<Block::Omap4_driver *>(driver)); }
} factory;
Genode::destroy(&heap,
static_cast<Block::Omap4_driver*>(driver)); }
} factory { env.ep(), heap };
Block::Root root;
Block::Root root { env.ep(), heap, factory };
Main(Server::Entrypoint &ep)
: ep(ep), factory(ep), root(ep, Genode::env()->heap(), factory)
Main(Genode::Env &env) : env(env)
{
Genode::printf("--- OMAP4 SD card driver ---\n");
Genode::log("--- OMAP4 SD card driver ---");
Genode::env()->parent()->announce(ep.manage(root));
env.parent().announce(env.ep().manage(root));
}
};
/************
** 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); }
}
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
void Component::construct(Genode::Env &env) { static Main m(env); }

View File

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

View File

@ -12,9 +12,9 @@
*/
/* Genode includes */
#include <base/printf.h>
#include <base/component.h>
#include <base/log.h>
#include <block/component.h>
#include <os/server.h>
/* local includes */
#include <pl180_defs.h>
@ -24,12 +24,18 @@
struct Main
{
Server::Entrypoint &ep;
Genode::Env &env;
Genode::Heap heap { env.ram(), env.rm() };
struct Factory : Block::Driver_factory
{
Block::Driver *create()
{
Genode::Entrypoint &ep;
Genode::Heap &heap;
Factory(Genode::Entrypoint &ep, Genode::Heap &heap)
: ep(ep), heap(heap) { }
Block::Driver *create() {
Pl180 *pl180 = new (Genode::env()->heap())
Pl180(PL180_PHYS, PL180_SIZE);
Sd_card *sd_card = new (Genode::env()->heap())
@ -46,26 +52,17 @@ struct Main
Genode::destroy(Genode::env()->heap(), sd_card);
Genode::destroy(Genode::env()->heap(), pl180);
}
} factory;
} factory { env.ep(), heap };
Block::Root root;
Block::Root root { env.ep(), heap, factory };
Main(Server::Entrypoint &ep)
: ep(ep), root(ep, Genode::env()->heap(), factory)
Main(Genode::Env &env) : env(env)
{
Genode::printf("--- PL180 MMC/SD card driver started ---\n");
Genode::log("--- PL180 MMC/SD card driver started ---");
Genode::env()->parent()->announce(ep.manage(root));
env.parent().announce(env.ep().manage(root));
}
};
/************
** 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); }
}
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
void Component::construct(Genode::Env &env) { static Main m(env); }

View File

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

View File

@ -12,8 +12,8 @@
*/
/* Genode includes */
#include <base/printf.h>
#include <os/server.h>
#include <base/component.h>
#include <base/log.h>
#include <platform_session/connection.h>
/* local includes */
@ -22,42 +22,39 @@
struct Main
{
Server::Entrypoint &ep;
Platform::Connection platform;
Genode::Env &env;
Genode::Heap heap { env.ram(), env.rm() };
Platform::Connection platform { env };
struct Factory : Block::Driver_factory
{
Genode::Entrypoint &ep;
Genode::Heap &heap;
Factory(Genode::Entrypoint &ep, Genode::Heap &heap)
: ep(ep), heap(heap) { }
Block::Driver *create() {
return new (Genode::env()->heap()) Block::Sdhci_driver(false); }
return new (&heap) Block::Sdhci_driver(false); }
void destroy(Block::Driver *driver) {
Genode::destroy(Genode::env()->heap(),
static_cast<Block::Sdhci_driver *>(driver)); }
} factory;
Genode::destroy(&heap,
static_cast<Block::Sdhci_driver*>(driver)); }
} factory { env.ep(), heap };
Block::Root root;
Block::Root root { env.ep(), heap, factory };
Main(Server::Entrypoint &ep)
: ep(ep), root(ep, Genode::env()->heap(), factory)
Main(Genode::Env &env) : env(env)
{
Genode::printf("--- SD card driver ---\n");
Genode::log("--- SD card driver ---");
while (platform.power_state(Platform::Session::POWER_SDHCI) == 0)
platform.power_state(Platform::Session::POWER_SDHCI, true);
Genode::env()->parent()->announce(ep.manage(root));
env.parent().announce(env.ep().manage(root));
}
};
/************
** 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); }
}
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
void Component::construct(Genode::Env &env) { static Main m(env); }

View File

@ -1,5 +1,5 @@
TARGET = sd_card_drv
REQUIRES = rpi
SRC_CC = main.cc
LIBS = base server
LIBS = base
INC_DIR += $(PRG_DIR) $(REP_DIR)/src/drivers/sd_card

View File

@ -816,7 +816,7 @@ struct Usb::Main
};
Factory factory { env, heap, announce_dispatcher };
Block::Root root { env.ep(), &heap, factory };
Block::Root root { env.ep(), heap, factory };
Main(Env &env) : env(env) { }
};

View File

@ -11,7 +11,7 @@
* under the terms of the GNU General Public License version 2.
*/
#include <base/printf.h>
#include <base/log.h>
#include <block_session/connection.h>
#include <block/component.h>
#include <os/packet_allocator.h>
@ -114,8 +114,7 @@ class Driver : public Block::Driver
private:
static Driver *_instance; /* singleton instance */
Genode::Env &_env;
Genode::Tslab<Request, SLAB_SZ> _r_slab; /* slab for requests */
Genode::List<Request> _r_list; /* list of requests */
Genode::Packet_allocator _alloc; /* packet allocator */
@ -124,9 +123,9 @@ class Driver : public Block::Driver
Genode::size_t _blk_sz; /* block size */
Block::sector_t _blk_cnt; /* block count */
Chunk_level_0 _cache; /* chunk hierarchy */
Genode::Signal_rpc_member<Driver> _source_ack;
Genode::Signal_rpc_member<Driver> _source_submit;
Genode::Signal_rpc_member<Driver> _yield;
Genode::Signal_handler<Driver> _source_ack;
Genode::Signal_handler<Driver> _source_submit;
Genode::Signal_handler<Driver> _yield;
Driver(Driver const&); /* singleton pattern */
Driver& operator=(Driver const&); /* singleton pattern */
@ -166,16 +165,17 @@ class Driver : public Block::Driver
write(r->cli.block_number(), r->cli.block_count(),
r->buffer, r->cli);
} catch(Block::Driver::Request_congestion) {
PWRN("cli (%lld %zu) srv (%lld %zu)",
r->cli.block_number(), r->cli.block_count(),
r->srv.block_number(), r->srv.block_count());
Genode::warning("cli (", r->cli.block_number(),
" ", r->cli.block_count(),
") srv (", r->srv.block_number(),
" ", r->srv.block_count(), ")");
}
}
/*
* Handle acknowledgements from the backend device
*/
void _ack_avail(unsigned)
void _ack_avail()
{
while (_blk.tx()->ack_avail()) {
Block::Packet_descriptor p = _blk.tx()->get_acked_packet();
@ -204,7 +204,7 @@ class Driver : public Block::Driver
/*
* Handle that the backend device is ready to receive again
*/
void _ready_to_submit(unsigned) { }
void _ready_to_submit() { }
/*
* Setup a request to the backend device
@ -232,7 +232,7 @@ class Driver : public Block::Driver
/* it doesn't pay, we've to send a request to the device */
if (!_blk.tx()->ready_to_submit()) {
PWRN("not ready_to_submit");
Genode::warning("not ready_to_submit");
throw Request_congestion();
}
@ -279,7 +279,7 @@ class Driver : public Block::Driver
*/
off = e.off;
len = _blk_sz * _blk_cnt - off;
Server::wait_and_dispatch_one_signal();
_env.ep().wait_and_dispatch_one_signal();
}
}
}
@ -312,7 +312,7 @@ class Driver : public Block::Driver
/*
* Signal handler for yield requests of the parent
*/
void _parent_yield(unsigned)
void _parent_yield()
{
using namespace Genode;
@ -322,33 +322,38 @@ class Driver : public Block::Driver
/* flush the requested amount of RAM from cache */
POLICY::flush(requested_ram_quota);
env()->parent()->yield_response();
_env.parent().yield_response();
}
public:
/*
* Constructor
*
* \param ep server entrypoint
*/
Driver(Server::Entrypoint &ep)
: _r_slab(Genode::env()->heap()),
_alloc(Genode::env()->heap(), CACHE_BLK_SIZE),
Driver(Genode::Env &env, Genode::Heap &heap)
: _env(env),
_r_slab(&heap),
_alloc(&heap, CACHE_BLK_SIZE),
_blk(&_alloc, Block::Session::TX_QUEUE_SIZE*CACHE_BLK_SIZE),
_blk_sz(0),
_blk_cnt(0),
_cache(*Genode::env()->heap(), 0),
_source_ack(ep, *this, &Driver::_ack_avail),
_source_submit(ep, *this, &Driver::_ready_to_submit),
_yield(ep, *this, &Driver::_parent_yield)
_cache(heap, 0),
_source_ack(env.ep(), *this, &Driver::_ack_avail),
_source_submit(env.ep(), *this, &Driver::_ready_to_submit),
_yield(env.ep(), *this, &Driver::_parent_yield)
{
using namespace Genode;
_blk.info(&_blk_cnt, &_blk_sz, &_ops);
_blk.tx_channel()->sigh_ack_avail(_source_ack);
_blk.tx_channel()->sigh_ready_to_submit(_source_submit);
Genode::env()->parent()->yield_sigh(_yield);
env.parent().yield_sigh(_yield);
if (CACHE_BLK_SIZE % _blk_sz) {
PERR("only devices that block size is divider of %x supported",
CACHE_BLK_SIZE);
error("only devices that block size is divider of ",
Hex(CACHE_BLK_SIZE, Hex::OMIT_PREFIX) ," supported");
throw Io_error();
}
@ -356,8 +361,6 @@ class Driver : public Block::Driver
_cache.truncate(_blk_sz*_blk_cnt);
}
public:
~Driver()
{
/* when session gets closed, synchronize and flush the cache */
@ -365,19 +368,6 @@ class Driver : public Block::Driver
POLICY::flush();
}
static Driver* instance(Server::Entrypoint &ep) {
_instance = new (Genode::env()->heap()) Driver(ep);
return _instance;
}
static Driver* instance() { return _instance; }
static void destroy()
{
Genode::destroy(Genode::env()->heap(), _instance);
_instance = 0;
}
Block::Session_client* blk() { return &_blk; }
Genode::size_t blk_sz() { return _blk_sz; }

View File

@ -5,19 +5,19 @@
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
* Copyright (C) 2013-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <os/server.h>
#include <base/component.h>
#include "lru.h"
#include "driver.h"
template <typename POLICY> Driver<POLICY>* Driver<POLICY>::_instance = 0;
using Policy = Lru_policy;
static Driver<Policy> * driver = nullptr;
/**
@ -29,15 +29,16 @@ void Driver<POLICY>::Policy::sync(const typename POLICY::Element *e, char *dst)
Cache::offset_t off =
static_cast<const Driver<POLICY>::Chunk_level_4*>(e)->base_offset();
if (!Driver::instance()->blk()->tx()->ready_to_submit())
if (!driver) throw Write_failed(off);
if (!driver->blk()->tx()->ready_to_submit())
throw Write_failed(off);
try {
Block::Packet_descriptor
p(Driver::instance()->blk()->dma_alloc_packet(Driver::CACHE_BLK_SIZE),
Block::Packet_descriptor::WRITE,
off / Driver::instance()->blk_sz(),
Driver::CACHE_BLK_SIZE / Driver::instance()->blk_sz());
Driver::instance()->blk()->tx()->submit_packet(p);
p(driver->blk()->dma_alloc_packet(Driver::CACHE_BLK_SIZE),
Block::Packet_descriptor::WRITE, off / driver->blk_sz(),
Driver::CACHE_BLK_SIZE / driver->blk_sz());
driver->blk()->tx()->submit_packet(p);
} catch(Block::Session::Tx::Source::Packet_alloc_failed) {
throw Write_failed(off);
}
@ -46,39 +47,44 @@ void Driver<POLICY>::Policy::sync(const typename POLICY::Element *e, char *dst)
struct Main
{
Server::Entrypoint &ep;
template <typename T>
struct Factory : Block::Driver_factory
{
Server::Entrypoint &ep;
Genode::Env &env;
Genode::Heap &heap;
Factory(Server::Entrypoint &ep) : ep(ep) {}
Factory(Genode::Env &env, Genode::Heap &heap) : env(env), heap(heap) {}
Block::Driver *create() { return Driver<Lru_policy>::instance(ep); }
void destroy(Block::Driver *driver) { Driver<Lru_policy>::destroy(); }
} factory;
Block::Driver *create()
{
driver = new (&heap) ::Driver<T>(env, heap);
return driver;
}
void resource_handler(unsigned) { }
void destroy(Block::Driver *driver) {
Genode::destroy(&heap, static_cast<::Driver<T>*>(driver)); }
};
Block::Root root;
Server::Signal_rpc_member<Main> resource_dispatcher;
void resource_handler() { }
Main(Server::Entrypoint &ep)
: ep(ep), factory(ep), root(ep, Genode::env()->heap(), factory),
resource_dispatcher(ep, *this, &Main::resource_handler)
Genode::Env &env;
Genode::Heap heap { env.ram(), env.rm() };
Factory<Lru_policy> factory { env, heap };
Block::Root root { env.ep(), heap, factory };
Genode::Signal_handler<Main> resource_dispatcher {
env.ep(), *this, &Main::resource_handler };
Main(Genode::Env &env) : env(env)
{
Genode::env()->parent()->announce(ep.manage(root));
Genode::env()->parent()->resource_avail_sigh(resource_dispatcher);
env.parent().announce(env.ep().manage(root));
env.parent().resource_avail_sigh(resource_dispatcher);
}
};
/************
** Server **
************/
Genode::size_t Component::stack_size() {
return 2048*sizeof(Genode::addr_t); }
namespace Server {
char const *name() { return "blk_cache_ep"; }
size_t stack_size() { return 2*1024*sizeof(long); }
void construct(Entrypoint &ep) { static Main server(ep); }
}
void Component::construct(Genode::Env &env) {
static Main server(env); }

View File

@ -1,3 +1,3 @@
TARGET = blk_cache
LIBS = base server
LIBS = base
SRC_CC = main.cc lru.cc

View File

@ -194,7 +194,7 @@ struct Main
Genode::destroy(&alloc, driver); }
} factory { env, heap, config_rom.xml() };
Block::Root root { env.ep(), &heap, factory };
Block::Root root { env.ep(), heap, factory };
Main(Env &env) : env(env)
{

View File

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

View File

@ -5,19 +5,17 @@
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
* Copyright (C) 2010-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <base/exception.h>
#include <base/printf.h>
#include <os/config.h>
#include <os/server.h>
#include <rom_session/connection.h>
#include <base/attached_rom_dataspace.h>
#include <base/component.h>
#include <base/log.h>
#include <block/component.h>
#include <block/driver.h>
#include <rom_session/connection.h>
using namespace Genode;
@ -25,29 +23,27 @@ class Rom_blk : public Block::Driver
{
private:
Env &_env;
Rom_connection _rom;
Dataspace_capability _file_cap; /* rom-file capability */
addr_t _file_addr; /* start address of attached file */
size_t _file_sz; /* file size */
size_t _blk_sz; /* block size */
size_t _blk_cnt; /* block count */
size_t _blk_sz;
Dataspace_capability _file_cap = _rom.dataspace();
addr_t _file_addr = _env.rm().attach(_file_cap);
size_t _file_sz = Dataspace_client(_file_cap).size();
size_t _blk_cnt = _file_sz / _blk_sz;
public:
Rom_blk(const char *name, size_t blk_sz)
: _rom(name),
_file_cap(_rom.dataspace()),
_file_addr(env()->rm_session()->attach(_file_cap)),
_file_sz(Dataspace_client(_file_cap).size()),
_blk_sz(blk_sz),
_blk_cnt(_file_sz/_blk_sz) { }
using String = Genode::String<64UL>;
Rom_blk(Env &env, String &name, size_t blk_sz)
: _env(env), _rom(env, name.string()), _blk_sz(blk_sz) {}
/****************************
** Block-driver interface **
****************************/
Genode::size_t block_size() { return _blk_sz; }
size_t block_size() { return _blk_sz; }
Block::sector_t block_count() { return _blk_cnt; }
Block::Session::Operations ops()
@ -57,16 +53,16 @@ class Rom_blk : public Block::Driver
return o;
}
void read(Block::sector_t block_number,
Genode::size_t block_count,
char* buffer,
void read(Block::sector_t block_number,
size_t block_count,
char* buffer,
Block::Packet_descriptor &packet)
{
/* sanity check block number */
if ((block_number + block_count > _file_sz / _blk_sz)
|| block_number < 0) {
PWRN("requested blocks %lld-%lld out of range!",
block_number, block_number + block_count);
warning("requested blocks ", block_number, "-",
block_number + block_count, " out of range!");
return;
}
@ -83,49 +79,50 @@ class Rom_blk : public Block::Driver
struct Main
{
Server::Entrypoint &ep;
Env &env;
Heap heap { env.ram(), env.rm() };
struct Factory : Block::Driver_factory
{
Env &env;
Heap &heap;
Factory(Env &env, Heap &heap)
: env(env), heap(heap) {}
Block::Driver *create()
{
char file[64];
Rom_blk::String file;
size_t blk_sz = 512;
try {
config()->xml_node().attribute("file").value(file, sizeof(file));
config()->xml_node().attribute("block_size").value(&blk_sz);
Attached_rom_dataspace config(env, "config");
config.xml().attribute("file").value(&file);
config.xml().attribute("block_size").value(&blk_sz);
}
catch (...) { }
PINF("Using file=%s as device with block size %zx.", file, blk_sz);
log("Using file=", file, " as device with block size ",
blk_sz, ".");
try {
return new (Genode::env()->heap()) Rom_blk(file, blk_sz);
return new (&heap) Rom_blk(env, file, blk_sz);
} catch(Rom_connection::Rom_connection_failed) {
PERR("Cannot open file %s.", file);
error("Cannot open file ", file, ".");
}
throw Root::Unavailable();
}
void destroy(Block::Driver *driver) {
Genode::destroy(env()->heap(), driver); }
} factory;
Genode::destroy(&heap, driver); }
} factory { env, heap };
Block::Root root;
Block::Root root { env.ep(), heap, factory };
Main(Server::Entrypoint &ep)
: ep(ep), root(ep, Genode::env()->heap(), factory) {
Genode::env()->parent()->announce(ep.manage(root)); }
Main(Env &env) : env(env) {
env.parent().announce(env.ep().manage(root)); }
};
/************
** Server **
************/
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); }
}
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
void Component::construct(Genode::Env &env) { static Main server(env); }

View File

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

View File

@ -5,9 +5,12 @@
*/
#include <base/allocator_avl.h>
#include <base/attached_rom_dataspace.h>
#include <base/component.h>
#include <base/heap.h>
#include <base/log.h>
#include <block_session/connection.h>
#include <timer_session/connection.h>
#include <os/config.h>
#include <os/ring_buffer.h>
static Genode::size_t blk_sz; /* block size of the device */
@ -42,30 +45,34 @@ class Test
bool write)
: _nr(nr), _cnt(cnt), _write(write) {}
virtual void print_error() {
PINF("couldn't %s block %lld - %lld",
_write ? "write" : "read", _nr, _nr+_cnt); }
virtual void print_error()
{
Genode::error("couldn't ", _write ? "write" : "read",
" block ", _nr, " - ", _nr+_cnt);
}
};
struct Submit_queue_full : Exception {
void print_error() { PINF("The submit queue is full!"); } };
void print_error() {
Genode::error("The submit queue is full!"); } };
struct Timeout : Exception {
void print_error() { PINF("Test timed out!"); } };
void print_error() {
Genode::error("Test timed out!"); } };
virtual void perform() = 0;
virtual void ack_avail() = 0;
protected:
Genode::Allocator_avl _alloc;
Block::Connection _session;
Genode::Signal_receiver _receiver;
Genode::Signal_dispatcher<Test> _disp_ack;
Genode::Signal_dispatcher<Test> _disp_submit;
Genode::Signal_dispatcher<Test> _disp_timeout;
Timer::Connection _timer;
bool _handle;
Genode::Entrypoint &_ep;
Genode::Allocator_avl _alloc;
Block::Connection _session;
Genode::Signal_handler<Test> _disp_ack;
Genode::Signal_handler<Test> _disp_submit;
Genode::Signal_handler<Test> _disp_timeout;
Timer::Connection _timer;
bool _handle;
Genode::size_t _shared_buffer_size(Genode::size_t bulk)
{
@ -75,17 +82,20 @@ class Test
(1 << Block::Packet_descriptor::PACKET_ALIGNMENT) - 1;
}
void _ack_avail(unsigned) { ack_avail(); }
void _ready_to_submit(unsigned) { _handle = false; }
void _timeout(unsigned) { throw Timeout(); }
void _ack_avail() { ack_avail(); }
void _ready_to_submit() { _handle = false; }
void _timeout() { throw Timeout(); }
Test(Genode::size_t bulk_buffer_size,
Test(Genode::Entrypoint &ep,
Genode::Heap &heap,
Genode::size_t bulk_buffer_size,
unsigned timeout_ms)
: _alloc(Genode::env()->heap()),
: _ep(ep),
_alloc(&heap),
_session(&_alloc, _shared_buffer_size(bulk_buffer_size)),
_disp_ack(_receiver, *this, &Test::_ack_avail),
_disp_submit(_receiver, *this, &Test::_ready_to_submit),
_disp_timeout(_receiver, *this, &Test::_timeout)
_disp_ack(ep, *this, &Test::_ack_avail),
_disp_submit(ep, *this, &Test::_ready_to_submit),
_disp_timeout(ep, *this, &Test::_timeout)
{
_session.tx_channel()->sigh_ack_avail(_disp_ack);
_session.tx_channel()->sigh_ready_to_submit(_disp_submit);
@ -99,12 +109,7 @@ class Test
void _handle_signal()
{
_handle = true;
while (_handle) {
Genode::Signal s = _receiver.wait_for_signal();
static_cast<Genode::Signal_dispatcher_base *>
(s.context())->dispatch(s.num());
}
while (_handle) _ep.wait_and_dispatch_one_signal();
}
};
@ -114,13 +119,13 @@ struct Read_test : Test
{
bool done;
Read_test(unsigned timeo_ms)
: Test(BULK_BLK_NR*blk_sz, timeo_ms), done(false) { }
Read_test(Genode::Entrypoint &ep, Genode::Heap &heap, unsigned timeo_ms)
: Test(ep, heap, BULK_BLK_NR*blk_sz, timeo_ms), done(false) { }
void perform()
{
PINF("reading block 0 - %llu, %u per request",
test_cnt - 1, NR_PER_REQ);
Genode::log("reading block 0 - ", test_cnt - 1, ", ", NR_PER_REQ,
" per request");
for (Block::sector_t nr = 0, cnt = NR_PER_REQ; nr < test_cnt;
nr += cnt) {
@ -169,15 +174,19 @@ template <unsigned BULK_BLK_NR, unsigned NR_PER_REQ, unsigned BATCH>
struct Write_test : Test
{
struct Invalid_dimensions : Exception {
void print_error() { PINF("Invalid bulk buffer, or batch size!"); } };
void print_error() {
Genode::error("Invalid bulk buffer, or batch size!"); } };
struct Integrity_exception : Block_exception
{
Integrity_exception(Block::sector_t nr, Genode::size_t cnt)
: Block_exception(nr, cnt, false) {}
void print_error() {
PINF("Integrity check failed: block %lld - %lld", _nr, _nr+_cnt); }
void print_error()
{
Genode::error("Integrity check failed: block ", _nr, " - ",
_nr+_cnt);
}
};
typedef Genode::Ring_buffer<Block::Packet_descriptor, BATCH+1,
@ -186,8 +195,8 @@ struct Write_test : Test
Req_buffer read_packets;
Req_buffer write_packets;
Write_test(unsigned timeo_ms)
: Test(BULK_BLK_NR*blk_sz, timeo_ms)
Write_test(Genode::Entrypoint &ep, Genode::Heap &heap, unsigned timeo_ms)
: Test(ep, heap, BULK_BLK_NR*blk_sz, timeo_ms)
{
if (BULK_BLK_NR < BATCH*NR_PER_REQ ||
BATCH > Block::Session::TX_QUEUE_SIZE ||
@ -272,8 +281,8 @@ struct Write_test : Test
if (!blk_ops.supported(Block::Packet_descriptor::WRITE))
return;
PINF("read/write/compare block 0 - %llu, %u per request",
test_cnt - 1, NR_PER_REQ);
Genode::log("read/write/compare block 0 - ", test_cnt - 1,
", ", NR_PER_REQ, " per request");
for (Block::sector_t nr = 0, cnt = BATCH*NR_PER_REQ; nr < test_cnt;
nr += cnt,
@ -304,21 +313,25 @@ struct Write_test : Test
struct Violation_test : Test
{
struct Write_on_read_only : Exception {
void print_error() { PINF("write on read-only device succeeded!"); } };
void print_error() {
Genode::error("write on read-only device succeeded!"); } };
struct Range_check_failed : Block_exception
{
Range_check_failed(Block::sector_t nr, Genode::size_t cnt)
: Block_exception(nr, cnt, false) {}
void print_error() {
PINF("Range check failed: access to block %lld - %lld succeeded",
_nr, _nr+_cnt); }
void print_error()
{
Genode::error("Range check failed: access to block ", _nr,
" - ", _nr+_cnt, " succeeded");
}
};
int p_in_fly;
Violation_test(unsigned timeo) : Test(20*blk_sz, timeo), p_in_fly(0) {}
Violation_test(Genode::Entrypoint &ep, Genode::Heap &heap, unsigned timeo)
: Test(ep, heap, 20*blk_sz, timeo), p_in_fly(0) {}
void req(Block::sector_t nr, Genode::size_t cnt, bool write)
{
@ -361,55 +374,63 @@ struct Violation_test : Test
template <typename TEST>
void perform(unsigned timeo_ms = 0)
void perform(Genode::Entrypoint &ep, Genode::Heap &heap, unsigned timeo_ms = 0)
{
TEST t(timeo_ms);
t.perform();
TEST * test = new (&heap) TEST(ep, heap, timeo_ms);
test->perform();
destroy(&heap, test);
}
int main()
Genode::size_t Component::stack_size() {
return 2048*sizeof(Genode::addr_t); }
void Component::construct(Genode::Env &env)
{
using namespace Genode;
try {
static Heap heap(env.ram(), env.rm());
/**
* First we ask for the block size of the driver to dimension
* the queue size for our tests. Moreover, we implicitely test,
* whether closing and opening again works for the driver
*/
{
Genode::Allocator_avl alloc(Genode::env()->heap());
Allocator_avl alloc(&heap);
Block::Connection blk(&alloc);
blk.info(&blk_cnt, &blk_sz, &blk_ops);
}
try {
Genode::Number_of_bytes test_size;;
Genode::config()->xml_node().attribute("test_size").value(&test_size);
Genode::Attached_rom_dataspace config { env, "config" };
config.xml().attribute("test_size").value(&test_size);
test_cnt = Genode::min(test_size / blk_sz, blk_cnt);
} catch (...) { test_cnt = blk_cnt; }
/* must be multiple of 16 */
test_cnt &= ~0xfLLU;
PINF("block device with block size %zd sector count %lld (testing %lld sectors)",
blk_sz, blk_cnt, test_cnt);
log("block device with block size ", blk_sz, " sector count ",
blk_cnt, " (testing ", test_cnt, " sectors)");
perform<Read_test<Block::Session::TX_QUEUE_SIZE-10,
Block::Session::TX_QUEUE_SIZE-10> >();
perform<Read_test<Block::Session::TX_QUEUE_SIZE*5, 1> >();
perform<Read_test<Block::Session::TX_QUEUE_SIZE, 1> >();
perform<Write_test<Block::Session::TX_QUEUE_SIZE, 8, 16> >();
perform<Violation_test>(1000);
Block::Session::TX_QUEUE_SIZE-10> >(env.ep(), heap);
perform<Read_test<Block::Session::TX_QUEUE_SIZE*5, 1> >(env.ep(), heap);
perform<Read_test<Block::Session::TX_QUEUE_SIZE, 1> >(env.ep(), heap);
perform<Write_test<Block::Session::TX_QUEUE_SIZE, 8, 16> >(env.ep(), heap);
perform<Violation_test>(env.ep(), heap, 1000);
PINF("Tests finished successfully!");
log("Tests finished successfully!");
} catch(Genode::Parent::Service_denied) {
PERR("Opening block session was denied!");
return -1;
error("Opening block session was denied!");
} catch(Test::Exception &e) {
PERR("Test failed!");
error("Test failed!");
e.print_error();
return -2;
}
return 0;
}

View File

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

View File

@ -5,19 +5,17 @@
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
* Copyright (C) 2013-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <base/printf.h>
#include <cap_session/connection.h>
#include <timer_session/connection.h>
#include <base/attached_rom_dataspace.h>
#include <block/component.h>
#include <block/driver.h>
#include <os/config.h>
#include <os/ring_buffer.h>
#include <timer_session/connection.h>
class Driver : public Block::Driver
@ -37,12 +35,12 @@ class Driver : public Block::Driver
public:
Driver(Genode::size_t number, Genode::size_t size)
Driver(Genode::Env &env, 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)) {}
_blk_ds(env.ram().alloc(number*size)),
_blk_buf(env.rm().attach(_blk_ds)) {}
void handler(unsigned)
void handler()
{
while (!_packets.empty()) {
Block::Packet_descriptor p = _packets.get();
@ -98,52 +96,50 @@ class Driver : public Block::Driver
struct Main
{
Server::Entrypoint &ep;
Genode::Env &env;
Genode::Heap heap { env.ram(), env.rm() };
struct Factory : Block::Driver_factory
{
::Driver *driver;
Factory()
Factory(Genode::Env &env, Genode::Heap &heap)
{
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);
Genode::Attached_rom_dataspace config { env, "config" };
config.xml().attribute("sectors").value(&blk_nr);
config.xml().attribute("block_size").value(&blk_sz);
}
catch (...) { }
driver = new (Genode::env()->heap()) Driver(blk_nr, blk_sz);
driver = new (&heap) Driver(env, blk_nr, blk_sz);
}
Block::Driver *create() { return driver; }
void destroy(Block::Driver *driver) { }
} factory;
} factory { env, heap };
Block::Root root;
Timer::Connection timer;
Server::Signal_rpc_member<Driver> dispatcher = { ep, *factory.driver,
&Driver::handler };
Block::Root root { env.ep(), heap, factory };
Timer::Connection timer;
Genode::Signal_handler<Driver> dispatcher { env.ep(), *factory.driver,
&Driver::handler };
Main(Server::Entrypoint &ep)
: ep(ep), root(ep, Genode::env()->heap(), factory)
Main(Genode::Env &env) : env(env)
{
timer.sigh(dispatcher);
timer.trigger_periodic(10000);
Genode::env()->parent()->announce(ep.manage(root));
env.parent().announce(env.ep().manage(root));
}
};
/************
** Server **
************/
Genode::size_t Component::stack_size() {
return 2048*sizeof(Genode::addr_t); }
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); }
}
void Component::construct(Genode::Env &env) {
static Main server(env); }

View File

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

View File

@ -99,32 +99,27 @@ class Driver : public Block::Driver
struct Factory : Block::Driver_factory
{
Block::Driver *create() {
return new (Genode::env()->heap()) Driver(); }
Genode::Heap &heap;
void destroy(Block::Driver *driver) {
Genode::destroy(Genode::env()->heap(), driver); }
Factory(Genode::Heap &heap) : heap(heap) {}
Block::Driver *create() { return new (&heap) Driver(); }
void destroy(Block::Driver *driver) { Genode::destroy(&heap, driver); }
};
struct Main
{
Server::Entrypoint &ep;
struct Factory factory;
Block::Root root;
Genode::Env &env;
Genode::Heap heap { env.ram(), env.rm() };
struct Factory factory { heap };
Block::Root root { env.ep(), heap, factory };
Main(Server::Entrypoint &ep)
: ep(ep), root(ep, Genode::env()->heap(), factory) {
Genode::env()->parent()->announce(ep.manage(root)); }
Main(Genode::Env &env) : env(env) {
env.parent().announce(env.ep().manage(root)); }
};
/************
** Server **
************/
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); }
}
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
void Component::construct(Genode::Env &env) { static Main m(env); }

View File

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