mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-25 11:12:50 +00:00
parent
acd2a40076
commit
7f8f0f50ea
@ -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;
|
||||
}
|
||||
|
@ -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); }
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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); }
|
||||
|
@ -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
|
||||
|
||||
|
@ -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) { }
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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; }
|
||||
|
@ -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); }
|
||||
|
@ -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
|
||||
|
@ -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); }
|
||||
|
@ -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)/../../
|
||||
|
@ -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); }
|
||||
|
@ -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
|
||||
|
@ -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); }
|
||||
|
@ -1,6 +1,6 @@
|
||||
TARGET = sd_card_drv
|
||||
REQUIRES = pl180
|
||||
SRC_CC = main.cc
|
||||
LIBS = base server
|
||||
LIBS = base
|
||||
|
||||
INC_DIR += $(PRG_DIR)
|
||||
|
@ -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); }
|
||||
|
@ -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
|
||||
|
@ -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) { }
|
||||
};
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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); }
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = blk_cache
|
||||
LIBS = base server
|
||||
LIBS = base
|
||||
SRC_CC = main.cc lru.cc
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = ram_blk
|
||||
SRC_CC = main.cc
|
||||
LIBS = base config
|
||||
LIBS = base
|
||||
|
@ -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); }
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = rom_blk
|
||||
SRC_CC = main.cc
|
||||
LIBS = base config server
|
||||
LIBS = base
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = test-blk-cli
|
||||
SRC_CC = main.cc
|
||||
LIBS = base config
|
||||
LIBS = base
|
||||
|
@ -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); }
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = test-blk-srv
|
||||
SRC_CC = main.cc
|
||||
LIBS = base config server
|
||||
LIBS = base
|
||||
|
@ -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); }
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = test-fb_blk_adapter
|
||||
SRC_CC = main.cc
|
||||
LIBS = base server
|
||||
LIBS = base
|
||||
|
Loading…
x
Reference in New Issue
Block a user