mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-25 19:21:39 +00:00
parent
acd2a40076
commit
7f8f0f50ea
@ -223,7 +223,7 @@ void scsi_add_device(struct scsi_device *sdev)
|
|||||||
*/
|
*/
|
||||||
if (!announce) {
|
if (!announce) {
|
||||||
PREPARE_WORK(&delayed, ack_packet);
|
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));
|
_signal->parent().announce(_signal->ep().rpc_ep().manage(&root));
|
||||||
announce = true;
|
announce = true;
|
||||||
}
|
}
|
||||||
|
@ -22,43 +22,31 @@
|
|||||||
|
|
||||||
struct Main
|
struct Main
|
||||||
{
|
{
|
||||||
Server::Entrypoint &ep;
|
Genode::Env &env;
|
||||||
|
Genode::Heap heap { env.ram(), env.rm() };
|
||||||
|
|
||||||
struct Factory : Block::Driver_factory
|
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()
|
Block::Driver *create() {
|
||||||
{
|
return new (&heap) Driver(ep); }
|
||||||
return new (Genode::env()->heap()) Driver(ep);
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy(Block::Driver *driver)
|
void destroy(Block::Driver *driver) {
|
||||||
{
|
Genode::destroy(&heap, driver); }
|
||||||
Genode::destroy(Genode::env()->heap(), driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
} factory;
|
} factory { env.ep(), heap };
|
||||||
|
|
||||||
Block::Root root;
|
Block::Root root { env.ep(), heap, factory };
|
||||||
|
|
||||||
Main(Server::Entrypoint &ep)
|
Main(Genode::Env &env) : env(env) {
|
||||||
:
|
env.parent().announce(env.ep().manage(root)); }
|
||||||
ep(ep), factory(ep), root(ep, Genode::env()->heap(), factory)
|
|
||||||
{
|
|
||||||
Genode::env()->parent()->announce(ep.manage(root));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**********************
|
Genode::size_t Component::stack_size() { return 4 * 1024 * sizeof(long); }
|
||||||
** Server framework **
|
void Component::construct(Genode::Env &env) { static Main inst(env); }
|
||||||
**********************/
|
|
||||||
|
|
||||||
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); }
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
TARGET = rump_cgd
|
TARGET = rump_cgd
|
||||||
|
|
||||||
SRC_CC = cgd.cc main.cc random.cc
|
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/child.h>
|
||||||
#include <base/printf.h>
|
#include <base/log.h>
|
||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
#include <lwip/genode.h>
|
#include <lwip/genode.h>
|
||||||
#include <nic/packet_allocator.h>
|
#include <nic/packet_allocator.h>
|
||||||
@ -27,11 +27,6 @@
|
|||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
/*
|
|
||||||
* Debugging output
|
|
||||||
*/
|
|
||||||
static const int verbose = 0;
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
/* HTTP status codes */
|
/* HTTP status codes */
|
||||||
HTTP_SUCC_OK = 200,
|
HTTP_SUCC_OK = 200,
|
||||||
@ -62,7 +57,7 @@ void Http::cmd_head()
|
|||||||
int length = snprintf(_http_buf, HTTP_BUF, http_templ, "HEAD", _path, _host);
|
int length = snprintf(_http_buf, HTTP_BUF, http_templ, "HEAD", _path, _host);
|
||||||
|
|
||||||
if (write(_fd, _http_buf, length) != length) {
|
if (write(_fd, _http_buf, length) != length) {
|
||||||
PERR("Write error");
|
error("Write error");
|
||||||
throw Http::Socket_error();
|
throw Http::Socket_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,12 +67,12 @@ void Http::connect()
|
|||||||
{
|
{
|
||||||
_fd = socket(AF_INET, SOCK_STREAM, 0);
|
_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (_fd < 0) {
|
if (_fd < 0) {
|
||||||
PERR("No socket avaiable");
|
error("No socket avaiable");
|
||||||
throw Http::Socket_error();
|
throw Http::Socket_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (::connect(_fd, _info->ai_addr, sizeof(*(_info->ai_addr))) < 0) {
|
if (::connect(_fd, _info->ai_addr, sizeof(*(_info->ai_addr))) < 0) {
|
||||||
PERR("Connect failed");
|
error("Connect failed");
|
||||||
throw Http::Socket_error();
|
throw Http::Socket_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,11 +85,11 @@ void Http::resolve_uri()
|
|||||||
{
|
{
|
||||||
struct addrinfo *info;
|
struct addrinfo *info;
|
||||||
if (getaddrinfo(_host, _port, 0, &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();
|
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));
|
Genode::memcpy(_info, info, sizeof(struct addrinfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +109,7 @@ Genode::size_t Http::read_header()
|
|||||||
header = false;
|
header = false;
|
||||||
|
|
||||||
if (++i >= HTTP_BUF) {
|
if (++i >= HTTP_BUF) {
|
||||||
PERR("Buffer overflow");
|
error("Buffer overflow");
|
||||||
throw Http::Socket_error();
|
throw Http::Socket_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,10 +150,6 @@ void Http::get_capacity()
|
|||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
ascii_to(t.start(), _size);
|
ascii_to(t.start(), _size);
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
PDBG("File size: %zu bytes", _size);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,21 +172,19 @@ void Http::do_read(void * buf, size_t size)
|
|||||||
int part;
|
int part;
|
||||||
if ((part = read(_fd, (void *)((addr_t)buf + buf_fill),
|
if ((part = read(_fd, (void *)((addr_t)buf + buf_fill),
|
||||||
size - buf_fill)) <= 0) {
|
size - buf_fill)) <= 0) {
|
||||||
PERR("Error: Reading data (%d)", errno);
|
error("Error: Reading data (", errno, ")");
|
||||||
throw Http::Socket_error();
|
throw Http::Socket_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
buf_fill += part;
|
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 */
|
||||||
parse_uri(uri);
|
parse_uri(uri);
|
||||||
@ -213,17 +202,18 @@ Http::Http(char *uri) : _port((char *)"80")
|
|||||||
|
|
||||||
Http::~Http()
|
Http::~Http()
|
||||||
{
|
{
|
||||||
env()->heap()->free(_host, Genode::strlen(_host) + 1);
|
_heap.free(_host, Genode::strlen(_host) + 1);
|
||||||
env()->heap()->free(_path, Genode::strlen(_path) + 2);
|
_heap.free(_path, Genode::strlen(_path) + 2);
|
||||||
env()->heap()->free(_http_buf, HTTP_BUF);
|
_heap.free(_http_buf, HTTP_BUF);
|
||||||
env()->heap()->free(_info, sizeof(struct addrinfo));
|
_heap.free(_info, sizeof(struct addrinfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Http::parse_uri(char *uri)
|
void Http::parse_uri(::String & u)
|
||||||
{
|
{
|
||||||
/* strip possible http prefix */
|
/* strip possible http prefix */
|
||||||
const char *http = "http://";
|
const char *http = "http://";
|
||||||
|
char * uri = const_cast<char*>(u.string());
|
||||||
size_t length = Genode::strlen(uri);
|
size_t length = Genode::strlen(uri);
|
||||||
size_t http_len = Genode::strlen(http);
|
size_t http_len = Genode::strlen(http);
|
||||||
if (!strcmp(http, uri, http_len)) {
|
if (!strcmp(http, uri, http_len)) {
|
||||||
@ -235,10 +225,10 @@ void Http::parse_uri(char *uri)
|
|||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < length && uri[i] != '/'; 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);
|
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);
|
Genode::strncpy(_path, uri + i, length - i + 1);
|
||||||
|
|
||||||
/* look for port */
|
/* look for port */
|
||||||
@ -248,18 +238,11 @@ void Http::parse_uri(char *uri)
|
|||||||
_port = &_host[i + 1];
|
_port = &_host[i + 1];
|
||||||
_host[i] = '\0';
|
_host[i] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
PDBG("Port: %s", _port);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Http::cmd_get(size_t file_offset, size_t size, addr_t buffer)
|
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) {
|
while (true) {
|
||||||
|
|
||||||
const char *http_templ = "GET %s HTTP/1.1\r\n"
|
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) {
|
if (_http_ret != HTTP_SUCC_PARTIAL) {
|
||||||
PERR("Error: Server returned %u", _http_ret);
|
error("Error: Server returned ", _http_ret);
|
||||||
throw Http::Server_error();
|
throw Http::Server_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
struct addrinfo;
|
struct addrinfo;
|
||||||
|
|
||||||
|
using String = Genode::String<64>;
|
||||||
class Http
|
class Http
|
||||||
{
|
{
|
||||||
typedef Genode::size_t size_t;
|
typedef Genode::size_t size_t;
|
||||||
@ -26,6 +27,7 @@ class Http
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Genode::Heap &_heap;
|
||||||
size_t _size; /* number of bytes in file */
|
size_t _size; /* number of bytes in file */
|
||||||
char *_host; /* host name */
|
char *_host; /* host name */
|
||||||
char *_port; /* host port */
|
char *_port; /* host port */
|
||||||
@ -54,7 +56,7 @@ class Http
|
|||||||
/*
|
/*
|
||||||
* Set URI of remote file
|
* Set URI of remote file
|
||||||
*/
|
*/
|
||||||
void parse_uri(char *uri);
|
void parse_uri(::String &uri);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Resolve host
|
* Resolve host
|
||||||
@ -81,7 +83,7 @@ class Http
|
|||||||
/*
|
/*
|
||||||
* Constructor (default host port is 80
|
* Constructor (default host port is 80
|
||||||
*/
|
*/
|
||||||
Http(char *uri);
|
Http(Genode::Heap &heap, ::String &uri);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Destructor
|
* Destructor
|
||||||
|
@ -13,9 +13,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <cap_session/connection.h>
|
#include <base/attached_rom_dataspace.h>
|
||||||
|
#include <base/log.h>
|
||||||
#include <block/component.h>
|
#include <block/component.h>
|
||||||
#include <os/config.h>
|
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
@ -31,8 +31,8 @@ class Driver : public Block::Driver
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Driver(size_t block_size, char *uri)
|
Driver(Heap &heap, size_t block_size, ::String &uri)
|
||||||
: _block_size(block_size), _http(uri) {}
|
: _block_size(block_size), _http(heap, uri) {}
|
||||||
|
|
||||||
|
|
||||||
/*******************************
|
/*******************************
|
||||||
@ -65,48 +65,46 @@ class Factory : public Block::Driver_factory
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
char _uri[64];
|
Env &_env;
|
||||||
|
Heap &_heap;
|
||||||
|
Attached_rom_dataspace _config { _env, "config" };
|
||||||
|
::String _uri;
|
||||||
size_t _blk_sz;
|
size_t _blk_sz;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Factory() : _blk_sz(512)
|
Factory(Env &env, Heap &heap)
|
||||||
|
: _env(env), _heap(heap), _blk_sz(512)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
config()->xml_node().attribute("uri").value(_uri, sizeof(_uri));
|
_config.xml().attribute("uri").value(&_uri);
|
||||||
config()->xml_node().attribute("block_size").value(&_blk_sz);
|
_config.xml().attribute("block_size").value(&_blk_sz);
|
||||||
}
|
}
|
||||||
catch (...) { }
|
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() {
|
Block::Driver *create() {
|
||||||
return new (env()->heap()) Driver(_blk_sz, _uri); }
|
return new (&_heap) Driver(_heap, _blk_sz, _uri); }
|
||||||
|
|
||||||
void destroy(Block::Driver *driver) {
|
void destroy(Block::Driver *driver) {
|
||||||
Genode::destroy(env()->heap(), driver); }
|
Genode::destroy(&_heap, driver); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Main
|
struct Main
|
||||||
{
|
{
|
||||||
Server::Entrypoint &ep;
|
Env &env;
|
||||||
struct Factory factory;
|
Heap heap { env.ram(), env.rm() };
|
||||||
Block::Root root;
|
Factory factory { env, heap };
|
||||||
|
Block::Root root { env.ep(), heap, factory };
|
||||||
|
|
||||||
Main(Server::Entrypoint &ep)
|
Main(Env &env) : env(env) {
|
||||||
: ep(ep), root(ep, Genode::env()->heap(), factory) {
|
env.parent().announce(env.ep().manage(root)); }
|
||||||
Genode::env()->parent()->announce(ep.manage(root)); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/************
|
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
|
||||||
** Server **
|
void Component::construct(Genode::Env &env) { static Main m(env); }
|
||||||
************/
|
|
||||||
|
|
||||||
namespace Server {
|
|
||||||
char const *name() { return "http_blk_ep"; }
|
|
||||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
|
||||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
TARGET = http_blk
|
TARGET = http_blk
|
||||||
SRC_CC = main.cc http.cc
|
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
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
@ -15,9 +15,9 @@
|
|||||||
#ifndef _INCLUDE__BLOCK__COMPONENT_H_
|
#ifndef _INCLUDE__BLOCK__COMPONENT_H_
|
||||||
#define _INCLUDE__BLOCK__COMPONENT_H_
|
#define _INCLUDE__BLOCK__COMPONENT_H_
|
||||||
|
|
||||||
|
#include <base/log.h>
|
||||||
|
#include <base/component.h>
|
||||||
#include <root/component.h>
|
#include <root/component.h>
|
||||||
#include <os/signal_rpc_dispatcher.h>
|
|
||||||
#include <os/server.h>
|
|
||||||
#include <block/driver.h>
|
#include <block/driver.h>
|
||||||
|
|
||||||
namespace Block {
|
namespace Block {
|
||||||
@ -68,8 +68,8 @@ class Block::Session_component : public Block::Session_component_base,
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
addr_t _rq_phys;
|
addr_t _rq_phys;
|
||||||
Signal_rpc_member<Session_component> _sink_ack;
|
Signal_handler<Session_component> _sink_ack;
|
||||||
Signal_rpc_member<Session_component> _sink_submit;
|
Signal_handler<Session_component> _sink_submit;
|
||||||
bool _req_queue_full;
|
bool _req_queue_full;
|
||||||
bool _ack_queue_full;
|
bool _ack_queue_full;
|
||||||
Packet_descriptor _p_to_handle;
|
Packet_descriptor _p_to_handle;
|
||||||
@ -81,7 +81,7 @@ class Block::Session_component : public Block::Session_component_base,
|
|||||||
inline void _ack_packet(Packet_descriptor &packet)
|
inline void _ack_packet(Packet_descriptor &packet)
|
||||||
{
|
{
|
||||||
if (!tx_sink()->ready_to_ack())
|
if (!tx_sink()->ready_to_ack())
|
||||||
PERR("Not ready to ack!");
|
error("Not ready to ack!");
|
||||||
|
|
||||||
tx_sink()->acknowledge_packet(packet);
|
tx_sink()->acknowledge_packet(packet);
|
||||||
_p_in_fly--;
|
_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
|
* 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());
|
_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:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* 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 driver_factory factory to create and destroy driver objects
|
||||||
* \param ep entrypoint handling this session component
|
* \param ep entrypoint handling this session component
|
||||||
|
* \param buf_size size of packet-stream payload buffer
|
||||||
*/
|
*/
|
||||||
Session_component(Driver_factory &driver_factory,
|
Session_component(Driver_factory &driver_factory,
|
||||||
Server::Entrypoint &ep, size_t buf_size)
|
Genode::Entrypoint &ep,
|
||||||
|
size_t buf_size)
|
||||||
: Session_component_base(driver_factory, buf_size),
|
: Session_component_base(driver_factory, buf_size),
|
||||||
Driver_session(_rq_ds, ep.rpc_ep()),
|
Driver_session(_rq_ds, ep.rpc_ep()),
|
||||||
_rq_phys(Dataspace_client(_rq_ds).phys_addr()),
|
_rq_phys(Dataspace_client(_rq_ds).phys_addr()),
|
||||||
_sink_ack(ep, *this, &Session_component::_ready_to_ack),
|
_sink_ack(ep, *this, &Session_component::_signal),
|
||||||
_sink_submit(ep, *this, &Session_component::_packet_avail),
|
_sink_submit(ep, *this, &Session_component::_signal),
|
||||||
_req_queue_full(false),
|
_req_queue_full(false),
|
||||||
_p_in_fly(0)
|
_p_in_fly(0)
|
||||||
{
|
{
|
||||||
@ -223,7 +218,7 @@ class Block::Session_component : public Block::Session_component_base,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* resume packet processing */
|
/* resume packet processing */
|
||||||
_packet_avail(0);
|
_signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -252,7 +247,7 @@ class Block::Root : public Genode::Root_component<Block::Session_component,
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
Driver_factory &_driver_factory;
|
Driver_factory &_driver_factory;
|
||||||
Server::Entrypoint &_ep;
|
Genode::Entrypoint &_ep;
|
||||||
|
|
||||||
protected:
|
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.
|
* to handle a possible overflow of the sum of both sizes.
|
||||||
*/
|
*/
|
||||||
if (tx_buf_size > ram_quota - session_size) {
|
if (tx_buf_size > ram_quota - session_size) {
|
||||||
PERR("insufficient 'ram_quota', got %zd, need %zd",
|
error("insufficient 'ram_quota', got ", ram_quota, ", need ",
|
||||||
ram_quota, tx_buf_size + session_size);
|
tx_buf_size + session_size);
|
||||||
throw Root::Quota_exceeded();
|
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 ep entrypoint handling this root component
|
||||||
* \param md_alloc allocator to allocate session components
|
* \param md_alloc allocator to allocate session components
|
||||||
* \param driver_factory factory to create and destroy driver backend
|
* \param driver_factory factory to create and destroy driver backend
|
||||||
* \param receiver signal receiver managing signals of the client
|
|
||||||
*/
|
*/
|
||||||
Root(Server::Entrypoint &ep, Allocator *md_alloc,
|
Root(Genode::Entrypoint &ep,
|
||||||
|
Allocator &md_alloc,
|
||||||
Driver_factory &driver_factory)
|
Driver_factory &driver_factory)
|
||||||
: Root_component(&ep.rpc_ep(), md_alloc),
|
: Root_component(ep, md_alloc),
|
||||||
_driver_factory(driver_factory), _ep(ep) { }
|
_driver_factory(driver_factory), _ep(ep) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,15 +26,15 @@ class Usb::Packet_handler
|
|||||||
Usb::Connection &_connection;
|
Usb::Connection &_connection;
|
||||||
Genode::Entrypoint &_ep;
|
Genode::Entrypoint &_ep;
|
||||||
|
|
||||||
Signal_rpc_member<Packet_handler> _rpc_ack_avail =
|
Signal_handler<Packet_handler> _rpc_ack_avail =
|
||||||
{_ep, *this, &Packet_handler::_packet_handler };
|
{_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 };
|
{ _ep, *this, &Packet_handler::_ready_handler };
|
||||||
|
|
||||||
bool _ready_submit = true;
|
bool _ready_submit = true;
|
||||||
|
|
||||||
void _packet_handler(unsigned)
|
void _packet_handler()
|
||||||
{
|
{
|
||||||
if (!_ready_submit)
|
if (!_ready_submit)
|
||||||
return;
|
return;
|
||||||
@ -49,7 +49,7 @@ class Usb::Packet_handler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _ready_handler(unsigned)
|
void _ready_handler()
|
||||||
{
|
{
|
||||||
_ready_submit = true;
|
_ready_submit = true;
|
||||||
};
|
};
|
||||||
@ -76,7 +76,7 @@ class Usb::Packet_handler
|
|||||||
|
|
||||||
void wait_for_packet()
|
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)
|
Packet_descriptor alloc(size_t size)
|
||||||
@ -117,7 +117,7 @@ class Usb::Packet_handler
|
|||||||
* retrieve packets.
|
* retrieve packets.
|
||||||
*/
|
*/
|
||||||
if (packet_avail())
|
if (packet_avail())
|
||||||
_packet_handler(0);
|
_packet_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
void *content(Packet_descriptor &p)
|
void *content(Packet_descriptor &p)
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#
|
#
|
||||||
# Build
|
# Build
|
||||||
#
|
#
|
||||||
build { core init drivers/timer test/blk lib/trace/policy/rpc_name }
|
build { core init drivers/timer test/blk }
|
||||||
create_boot_directory
|
create_boot_directory
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -46,7 +46,7 @@ install_config {
|
|||||||
#
|
#
|
||||||
# Boot modules
|
# 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 "
|
append qemu_args " -nographic -m 64 "
|
||||||
run_genode_until "Tests finished successfully.*\n" 100
|
run_genode_until "Tests finished successfully.*\n" 100
|
||||||
|
@ -49,8 +49,7 @@ struct Ahci
|
|||||||
Port_driver *ports[MAX_PORTS];
|
Port_driver *ports[MAX_PORTS];
|
||||||
bool port_claimed[MAX_PORTS];
|
bool port_claimed[MAX_PORTS];
|
||||||
|
|
||||||
Signal_rpc_member<Ahci> irq;
|
Signal_handler<Ahci> irq;
|
||||||
Signal_rpc_member<Ahci> device_ready;
|
|
||||||
unsigned ready_count = 0;
|
unsigned ready_count = 0;
|
||||||
bool enable_atapi;
|
bool enable_atapi;
|
||||||
|
|
||||||
@ -59,7 +58,6 @@ struct Ahci
|
|||||||
:
|
:
|
||||||
env(env), alloc(alloc),
|
env(env), alloc(alloc),
|
||||||
root(root), irq(root.entrypoint(), *this, &Ahci::handle_irq),
|
root(root), irq(root.entrypoint(), *this, &Ahci::handle_irq),
|
||||||
device_ready(root.entrypoint(), *this, &Ahci::ready),
|
|
||||||
enable_atapi(support_atapi)
|
enable_atapi(support_atapi)
|
||||||
{
|
{
|
||||||
info();
|
info();
|
||||||
@ -87,7 +85,7 @@ struct Ahci
|
|||||||
/**
|
/**
|
||||||
* Forward IRQs to ports
|
* Forward IRQs to ports
|
||||||
*/
|
*/
|
||||||
void handle_irq(unsigned)
|
void handle_irq()
|
||||||
{
|
{
|
||||||
unsigned port_list = hba.read<Hba::Is>();
|
unsigned port_list = hba.read<Hba::Is>();
|
||||||
while (port_list) {
|
while (port_list) {
|
||||||
@ -104,17 +102,6 @@ struct Ahci
|
|||||||
platform_hba.ack_irq();
|
platform_hba.ack_irq();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ready(unsigned cnt)
|
|
||||||
{
|
|
||||||
ready_count -= cnt;
|
|
||||||
if (ready_count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* announce service */
|
|
||||||
root.announce();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void info()
|
void info()
|
||||||
{
|
{
|
||||||
PINF("\tversion: %x.%04x", hba.read<Hba::Version::Major>(),
|
PINF("\tversion: %x.%04x", hba.read<Hba::Version::Major>(),
|
||||||
@ -158,14 +145,14 @@ struct Ahci
|
|||||||
switch (sig) {
|
switch (sig) {
|
||||||
|
|
||||||
case ATA_SIG:
|
case ATA_SIG:
|
||||||
ports[i] = new (&alloc) Ata_driver(alloc, port, device_ready);
|
ports[i] = new (&alloc) Ata_driver(alloc, port, root,
|
||||||
ready_count++;
|
ready_count);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ATAPI_SIG:
|
case ATAPI_SIG:
|
||||||
case ATAPI_SIG_QEMU:
|
case ATAPI_SIG_QEMU:
|
||||||
ports[i] = new (&alloc) Atapi_driver(port, device_ready);
|
ports[i] = new (&alloc) Atapi_driver(port, root,
|
||||||
ready_count++;
|
ready_count);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -29,7 +29,7 @@ namespace Platform {
|
|||||||
|
|
||||||
struct Ahci_root
|
struct Ahci_root
|
||||||
{
|
{
|
||||||
virtual Server::Entrypoint &entrypoint() = 0;
|
virtual Genode::Entrypoint &entrypoint() = 0;
|
||||||
virtual void announce() = 0;
|
virtual void announce() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -792,15 +792,22 @@ struct Port : Genode::Mmio
|
|||||||
|
|
||||||
struct Port_driver : Port, Block::Driver
|
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_driver(Port &port, Ahci_root &root, unsigned &sem)
|
||||||
: Port(port), state_change_cap(state_change_cap)
|
: Port(port), root(root), sem(sem) {
|
||||||
{ }
|
sem++; }
|
||||||
|
|
||||||
virtual void handle_irq() = 0;
|
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)
|
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];
|
Block::Packet_descriptor pending[32];
|
||||||
|
|
||||||
Ata_driver(Genode::Allocator &alloc,
|
Ata_driver(Genode::Allocator &alloc,
|
||||||
Port &port, Signal_context_capability state_change)
|
Port &port, Ahci_root &root, unsigned &sem)
|
||||||
: Port_driver(port, state_change), alloc(alloc)
|
: Port_driver(port, root, sem), alloc(alloc)
|
||||||
{
|
{
|
||||||
Port::init();
|
Port::init();
|
||||||
identify_device();
|
identify_device();
|
||||||
|
@ -24,8 +24,8 @@ struct Atapi_driver : Port_driver
|
|||||||
unsigned sense_tries = 0;
|
unsigned sense_tries = 0;
|
||||||
Block::Packet_descriptor pending;
|
Block::Packet_descriptor pending;
|
||||||
|
|
||||||
Atapi_driver(Port &port, Signal_context_capability state_change)
|
Atapi_driver(Port &port, Ahci_root &root, unsigned &sem)
|
||||||
: Port_driver(port, state_change)
|
: Port_driver(port, root, sem)
|
||||||
{
|
{
|
||||||
Port::init();
|
Port::init();
|
||||||
Port::write<Cmd::Atapi>(1);
|
Port::write<Cmd::Atapi>(1);
|
||||||
|
@ -53,7 +53,8 @@ class Session_component : public Block::Session_component
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
Session_component(Block::Driver_factory &driver_factory,
|
Session_component(Block::Driver_factory &driver_factory,
|
||||||
Server::Entrypoint &ep, Genode::size_t buf_size)
|
Genode::Entrypoint &ep,
|
||||||
|
Genode::size_t buf_size)
|
||||||
: Block::Session_component(driver_factory, ep, buf_size) { }
|
: Block::Session_component(driver_factory, ep, buf_size) { }
|
||||||
|
|
||||||
Block::Driver_factory &factory() { return _driver_factory; }
|
Block::Driver_factory &factory() { return _driver_factory; }
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/printf.h>
|
#include <base/component.h>
|
||||||
|
#include <base/log.h>
|
||||||
#include <regulator_session/connection.h>
|
#include <regulator_session/connection.h>
|
||||||
#include <os/server.h>
|
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <driver.h>
|
#include <driver.h>
|
||||||
@ -22,43 +22,37 @@
|
|||||||
|
|
||||||
struct Main
|
struct Main
|
||||||
{
|
{
|
||||||
Server::Entrypoint &ep;
|
Genode::Env &env;
|
||||||
|
Genode::Heap heap { env.ram(), env.rm() };
|
||||||
|
|
||||||
struct Factory : Block::Driver_factory
|
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() {
|
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) {
|
void destroy(Block::Driver *driver) {
|
||||||
Genode::destroy(Genode::env()->heap(),
|
Genode::destroy(&heap,
|
||||||
static_cast<Block::Exynos5_driver *>(driver)); }
|
static_cast<Block::Exynos5_driver *>(driver)); }
|
||||||
} factory;
|
} factory { env.ep(), heap };
|
||||||
|
|
||||||
Regulator::Connection regulator;
|
Regulator::Connection regulator { env, Regulator::CLK_MMC0 };
|
||||||
Block::Root root;
|
Block::Root root { env.ep(), heap, factory };
|
||||||
|
|
||||||
Main(Server::Entrypoint &ep)
|
Main(Genode::Env &env) : env(env)
|
||||||
: ep(ep), factory(ep), regulator(Regulator::CLK_MMC0),
|
|
||||||
root(ep, Genode::env()->heap(), factory)
|
|
||||||
{
|
{
|
||||||
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);
|
regulator.state(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/************
|
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
|
||||||
** Server **
|
void Component::construct(Genode::Env &env) { static Main m(env); }
|
||||||
************/
|
|
||||||
|
|
||||||
namespace Server {
|
|
||||||
char const *name() { return "sd_card_ep"; }
|
|
||||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
|
||||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
TARGET = sd_card_drv
|
TARGET = sd_card_drv
|
||||||
REQUIRES = exynos5
|
REQUIRES = exynos5
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
LIBS = base server
|
LIBS = base
|
||||||
INC_DIR += $(PRG_DIR) $(REP_DIR)/src/drivers/sd_card
|
INC_DIR += $(PRG_DIR) $(REP_DIR)/src/drivers/sd_card
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/printf.h>
|
#include <base/component.h>
|
||||||
#include <os/server.h>
|
#include <base/log.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <driver.h>
|
#include <driver.h>
|
||||||
@ -21,40 +21,35 @@
|
|||||||
|
|
||||||
struct Main
|
struct Main
|
||||||
{
|
{
|
||||||
Server::Entrypoint &ep;
|
Genode::Env &env;
|
||||||
|
Genode::Heap heap { env.ram(), env.rm() };
|
||||||
|
|
||||||
struct Factory : Block::Driver_factory
|
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() {
|
Block::Driver *create() {
|
||||||
return new (Genode::env()->heap()) Block::Imx53_driver(true); }
|
return new (&heap) Block::Imx53_driver(true); }
|
||||||
|
|
||||||
void destroy(Block::Driver *driver) {
|
void destroy(Block::Driver *driver) {
|
||||||
Genode::destroy(Genode::env()->heap(),
|
Genode::destroy(&heap,
|
||||||
static_cast<Block::Imx53_driver *>(driver)); }
|
static_cast<Block::Imx53_driver*>(driver)); }
|
||||||
} factory;
|
} factory { env.ep(), heap };
|
||||||
|
|
||||||
Block::Root root;
|
Block::Root root { env.ep(), heap, factory };
|
||||||
|
|
||||||
Main(Server::Entrypoint &ep)
|
Main(Genode::Env &env) : env(env)
|
||||||
: ep(ep), factory(ep), root(ep, Genode::env()->heap(), factory)
|
|
||||||
{
|
{
|
||||||
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));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/************
|
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
|
||||||
** Server **
|
void Component::construct(Genode::Env &env) { static Main m(env); }
|
||||||
************/
|
|
||||||
|
|
||||||
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); }
|
|
||||||
}
|
|
||||||
|
@ -4,6 +4,5 @@ SRC_CC += main.cc
|
|||||||
SRC_CC += adma2.cc
|
SRC_CC += adma2.cc
|
||||||
SRC_CC += esdhcv2.cc
|
SRC_CC += esdhcv2.cc
|
||||||
LIBS += base
|
LIBS += base
|
||||||
LIBS += server
|
|
||||||
INC_DIR += $(PRG_DIR)
|
INC_DIR += $(PRG_DIR)
|
||||||
INC_DIR += $(PRG_DIR)/../../
|
INC_DIR += $(PRG_DIR)/../../
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/printf.h>
|
#include <base/component.h>
|
||||||
#include <os/server.h>
|
#include <base/log.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <driver.h>
|
#include <driver.h>
|
||||||
@ -21,40 +21,35 @@
|
|||||||
|
|
||||||
struct Main
|
struct Main
|
||||||
{
|
{
|
||||||
Server::Entrypoint &ep;
|
Genode::Env &env;
|
||||||
|
Genode::Heap heap { env.ram(), env.rm() };
|
||||||
|
|
||||||
struct Factory : Block::Driver_factory
|
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() {
|
Block::Driver *create() {
|
||||||
return new (Genode::env()->heap()) Block::Omap4_driver(true); }
|
return new (&heap) Block::Omap4_driver(true); }
|
||||||
|
|
||||||
void destroy(Block::Driver *driver) {
|
void destroy(Block::Driver *driver) {
|
||||||
Genode::destroy(Genode::env()->heap(),
|
Genode::destroy(&heap,
|
||||||
static_cast<Block::Omap4_driver *>(driver)); }
|
static_cast<Block::Omap4_driver*>(driver)); }
|
||||||
} factory;
|
} factory { env.ep(), heap };
|
||||||
|
|
||||||
Block::Root root;
|
Block::Root root { env.ep(), heap, factory };
|
||||||
|
|
||||||
Main(Server::Entrypoint &ep)
|
Main(Genode::Env &env) : env(env)
|
||||||
: ep(ep), factory(ep), root(ep, Genode::env()->heap(), factory)
|
|
||||||
{
|
{
|
||||||
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));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/************
|
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
|
||||||
** Server **
|
void Component::construct(Genode::Env &env) { static Main m(env); }
|
||||||
************/
|
|
||||||
|
|
||||||
namespace Server {
|
|
||||||
char const *name() { return "sd_card_ep"; }
|
|
||||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
|
||||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
TARGET = sd_card_drv
|
TARGET = sd_card_drv
|
||||||
REQUIRES = omap4
|
REQUIRES = omap4
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
LIBS = base server
|
LIBS = base
|
||||||
INC_DIR += $(PRG_DIR) $(REP_DIR)/src/drivers/sd_card
|
INC_DIR += $(PRG_DIR) $(REP_DIR)/src/drivers/sd_card
|
||||||
|
@ -12,9 +12,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/printf.h>
|
#include <base/component.h>
|
||||||
|
#include <base/log.h>
|
||||||
#include <block/component.h>
|
#include <block/component.h>
|
||||||
#include <os/server.h>
|
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <pl180_defs.h>
|
#include <pl180_defs.h>
|
||||||
@ -24,12 +24,18 @@
|
|||||||
|
|
||||||
struct Main
|
struct Main
|
||||||
{
|
{
|
||||||
Server::Entrypoint &ep;
|
Genode::Env &env;
|
||||||
|
Genode::Heap heap { env.ram(), env.rm() };
|
||||||
|
|
||||||
struct Factory : Block::Driver_factory
|
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 = new (Genode::env()->heap())
|
||||||
Pl180(PL180_PHYS, PL180_SIZE);
|
Pl180(PL180_PHYS, PL180_SIZE);
|
||||||
Sd_card *sd_card = new (Genode::env()->heap())
|
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(), sd_card);
|
||||||
Genode::destroy(Genode::env()->heap(), pl180);
|
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)
|
Main(Genode::Env &env) : env(env)
|
||||||
: ep(ep), root(ep, Genode::env()->heap(), factory)
|
|
||||||
{
|
{
|
||||||
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));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
|
||||||
/************
|
void Component::construct(Genode::Env &env) { static Main m(env); }
|
||||||
** Server **
|
|
||||||
************/
|
|
||||||
|
|
||||||
namespace Server {
|
|
||||||
char const *name() { return "sd_card_ep"; }
|
|
||||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
|
||||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
TARGET = sd_card_drv
|
TARGET = sd_card_drv
|
||||||
REQUIRES = pl180
|
REQUIRES = pl180
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
LIBS = base server
|
LIBS = base
|
||||||
|
|
||||||
INC_DIR += $(PRG_DIR)
|
INC_DIR += $(PRG_DIR)
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/printf.h>
|
#include <base/component.h>
|
||||||
#include <os/server.h>
|
#include <base/log.h>
|
||||||
#include <platform_session/connection.h>
|
#include <platform_session/connection.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
@ -22,42 +22,39 @@
|
|||||||
|
|
||||||
struct Main
|
struct Main
|
||||||
{
|
{
|
||||||
Server::Entrypoint &ep;
|
Genode::Env &env;
|
||||||
|
Genode::Heap heap { env.ram(), env.rm() };
|
||||||
Platform::Connection platform;
|
Platform::Connection platform { env };
|
||||||
|
|
||||||
struct Factory : Block::Driver_factory
|
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() {
|
Block::Driver *create() {
|
||||||
return new (Genode::env()->heap()) Block::Sdhci_driver(false); }
|
return new (&heap) Block::Sdhci_driver(false); }
|
||||||
|
|
||||||
void destroy(Block::Driver *driver) {
|
void destroy(Block::Driver *driver) {
|
||||||
Genode::destroy(Genode::env()->heap(),
|
Genode::destroy(&heap,
|
||||||
static_cast<Block::Sdhci_driver *>(driver)); }
|
static_cast<Block::Sdhci_driver*>(driver)); }
|
||||||
} factory;
|
} factory { env.ep(), heap };
|
||||||
|
|
||||||
Block::Root root;
|
Block::Root root { env.ep(), heap, factory };
|
||||||
|
|
||||||
Main(Server::Entrypoint &ep)
|
Main(Genode::Env &env) : env(env)
|
||||||
: ep(ep), root(ep, Genode::env()->heap(), factory)
|
|
||||||
{
|
{
|
||||||
Genode::printf("--- SD card driver ---\n");
|
Genode::log("--- SD card driver ---");
|
||||||
|
|
||||||
while (platform.power_state(Platform::Session::POWER_SDHCI) == 0)
|
while (platform.power_state(Platform::Session::POWER_SDHCI) == 0)
|
||||||
platform.power_state(Platform::Session::POWER_SDHCI, true);
|
platform.power_state(Platform::Session::POWER_SDHCI, true);
|
||||||
|
|
||||||
Genode::env()->parent()->announce(ep.manage(root));
|
env.parent().announce(env.ep().manage(root));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/************
|
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
|
||||||
** Server **
|
void Component::construct(Genode::Env &env) { static Main m(env); }
|
||||||
************/
|
|
||||||
|
|
||||||
namespace Server {
|
|
||||||
char const *name() { return "sd_card_ep"; }
|
|
||||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
|
||||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
TARGET = sd_card_drv
|
TARGET = sd_card_drv
|
||||||
REQUIRES = rpi
|
REQUIRES = rpi
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
LIBS = base server
|
LIBS = base
|
||||||
INC_DIR += $(PRG_DIR) $(REP_DIR)/src/drivers/sd_card
|
INC_DIR += $(PRG_DIR) $(REP_DIR)/src/drivers/sd_card
|
||||||
|
@ -816,7 +816,7 @@ struct Usb::Main
|
|||||||
};
|
};
|
||||||
|
|
||||||
Factory factory { env, heap, announce_dispatcher };
|
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) { }
|
Main(Env &env) : env(env) { }
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* under the terms of the GNU General Public License version 2.
|
* 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_session/connection.h>
|
||||||
#include <block/component.h>
|
#include <block/component.h>
|
||||||
#include <os/packet_allocator.h>
|
#include <os/packet_allocator.h>
|
||||||
@ -114,8 +114,7 @@ class Driver : public Block::Driver
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static Driver *_instance; /* singleton instance */
|
Genode::Env &_env;
|
||||||
|
|
||||||
Genode::Tslab<Request, SLAB_SZ> _r_slab; /* slab for requests */
|
Genode::Tslab<Request, SLAB_SZ> _r_slab; /* slab for requests */
|
||||||
Genode::List<Request> _r_list; /* list of requests */
|
Genode::List<Request> _r_list; /* list of requests */
|
||||||
Genode::Packet_allocator _alloc; /* packet allocator */
|
Genode::Packet_allocator _alloc; /* packet allocator */
|
||||||
@ -124,9 +123,9 @@ class Driver : public Block::Driver
|
|||||||
Genode::size_t _blk_sz; /* block size */
|
Genode::size_t _blk_sz; /* block size */
|
||||||
Block::sector_t _blk_cnt; /* block count */
|
Block::sector_t _blk_cnt; /* block count */
|
||||||
Chunk_level_0 _cache; /* chunk hierarchy */
|
Chunk_level_0 _cache; /* chunk hierarchy */
|
||||||
Genode::Signal_rpc_member<Driver> _source_ack;
|
Genode::Signal_handler<Driver> _source_ack;
|
||||||
Genode::Signal_rpc_member<Driver> _source_submit;
|
Genode::Signal_handler<Driver> _source_submit;
|
||||||
Genode::Signal_rpc_member<Driver> _yield;
|
Genode::Signal_handler<Driver> _yield;
|
||||||
|
|
||||||
Driver(Driver const&); /* singleton pattern */
|
Driver(Driver const&); /* singleton pattern */
|
||||||
Driver& operator=(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(),
|
write(r->cli.block_number(), r->cli.block_count(),
|
||||||
r->buffer, r->cli);
|
r->buffer, r->cli);
|
||||||
} catch(Block::Driver::Request_congestion) {
|
} catch(Block::Driver::Request_congestion) {
|
||||||
PWRN("cli (%lld %zu) srv (%lld %zu)",
|
Genode::warning("cli (", r->cli.block_number(),
|
||||||
r->cli.block_number(), r->cli.block_count(),
|
" ", r->cli.block_count(),
|
||||||
r->srv.block_number(), r->srv.block_count());
|
") srv (", r->srv.block_number(),
|
||||||
|
" ", r->srv.block_count(), ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle acknowledgements from the backend device
|
* Handle acknowledgements from the backend device
|
||||||
*/
|
*/
|
||||||
void _ack_avail(unsigned)
|
void _ack_avail()
|
||||||
{
|
{
|
||||||
while (_blk.tx()->ack_avail()) {
|
while (_blk.tx()->ack_avail()) {
|
||||||
Block::Packet_descriptor p = _blk.tx()->get_acked_packet();
|
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
|
* 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
|
* 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 */
|
/* it doesn't pay, we've to send a request to the device */
|
||||||
if (!_blk.tx()->ready_to_submit()) {
|
if (!_blk.tx()->ready_to_submit()) {
|
||||||
PWRN("not ready_to_submit");
|
Genode::warning("not ready_to_submit");
|
||||||
throw Request_congestion();
|
throw Request_congestion();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +279,7 @@ class Driver : public Block::Driver
|
|||||||
*/
|
*/
|
||||||
off = e.off;
|
off = e.off;
|
||||||
len = _blk_sz * _blk_cnt - 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
|
* Signal handler for yield requests of the parent
|
||||||
*/
|
*/
|
||||||
void _parent_yield(unsigned)
|
void _parent_yield()
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
@ -322,33 +322,38 @@ class Driver : public Block::Driver
|
|||||||
|
|
||||||
/* flush the requested amount of RAM from cache */
|
/* flush the requested amount of RAM from cache */
|
||||||
POLICY::flush(requested_ram_quota);
|
POLICY::flush(requested_ram_quota);
|
||||||
env()->parent()->yield_response();
|
_env.parent().yield_response();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* \param ep server entrypoint
|
* \param ep server entrypoint
|
||||||
*/
|
*/
|
||||||
Driver(Server::Entrypoint &ep)
|
Driver(Genode::Env &env, Genode::Heap &heap)
|
||||||
: _r_slab(Genode::env()->heap()),
|
: _env(env),
|
||||||
_alloc(Genode::env()->heap(), CACHE_BLK_SIZE),
|
_r_slab(&heap),
|
||||||
|
_alloc(&heap, CACHE_BLK_SIZE),
|
||||||
_blk(&_alloc, Block::Session::TX_QUEUE_SIZE*CACHE_BLK_SIZE),
|
_blk(&_alloc, Block::Session::TX_QUEUE_SIZE*CACHE_BLK_SIZE),
|
||||||
_blk_sz(0),
|
_blk_sz(0),
|
||||||
_blk_cnt(0),
|
_blk_cnt(0),
|
||||||
_cache(*Genode::env()->heap(), 0),
|
_cache(heap, 0),
|
||||||
_source_ack(ep, *this, &Driver::_ack_avail),
|
_source_ack(env.ep(), *this, &Driver::_ack_avail),
|
||||||
_source_submit(ep, *this, &Driver::_ready_to_submit),
|
_source_submit(env.ep(), *this, &Driver::_ready_to_submit),
|
||||||
_yield(ep, *this, &Driver::_parent_yield)
|
_yield(env.ep(), *this, &Driver::_parent_yield)
|
||||||
{
|
{
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
_blk.info(&_blk_cnt, &_blk_sz, &_ops);
|
_blk.info(&_blk_cnt, &_blk_sz, &_ops);
|
||||||
_blk.tx_channel()->sigh_ack_avail(_source_ack);
|
_blk.tx_channel()->sigh_ack_avail(_source_ack);
|
||||||
_blk.tx_channel()->sigh_ready_to_submit(_source_submit);
|
_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) {
|
if (CACHE_BLK_SIZE % _blk_sz) {
|
||||||
PERR("only devices that block size is divider of %x supported",
|
error("only devices that block size is divider of ",
|
||||||
CACHE_BLK_SIZE);
|
Hex(CACHE_BLK_SIZE, Hex::OMIT_PREFIX) ," supported");
|
||||||
throw Io_error();
|
throw Io_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,8 +361,6 @@ class Driver : public Block::Driver
|
|||||||
_cache.truncate(_blk_sz*_blk_cnt);
|
_cache.truncate(_blk_sz*_blk_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
~Driver()
|
~Driver()
|
||||||
{
|
{
|
||||||
/* when session gets closed, synchronize and flush the cache */
|
/* when session gets closed, synchronize and flush the cache */
|
||||||
@ -365,19 +368,6 @@ class Driver : public Block::Driver
|
|||||||
POLICY::flush();
|
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; }
|
Block::Session_client* blk() { return &_blk; }
|
||||||
Genode::size_t blk_sz() { return _blk_sz; }
|
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
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <os/server.h>
|
#include <base/component.h>
|
||||||
|
|
||||||
#include "lru.h"
|
#include "lru.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
|
|
||||||
|
using Policy = Lru_policy;
|
||||||
template <typename POLICY> Driver<POLICY>* Driver<POLICY>::_instance = 0;
|
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 =
|
Cache::offset_t off =
|
||||||
static_cast<const Driver<POLICY>::Chunk_level_4*>(e)->base_offset();
|
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);
|
throw Write_failed(off);
|
||||||
try {
|
try {
|
||||||
Block::Packet_descriptor
|
Block::Packet_descriptor
|
||||||
p(Driver::instance()->blk()->dma_alloc_packet(Driver::CACHE_BLK_SIZE),
|
p(driver->blk()->dma_alloc_packet(Driver::CACHE_BLK_SIZE),
|
||||||
Block::Packet_descriptor::WRITE,
|
Block::Packet_descriptor::WRITE, off / driver->blk_sz(),
|
||||||
off / Driver::instance()->blk_sz(),
|
Driver::CACHE_BLK_SIZE / driver->blk_sz());
|
||||||
Driver::CACHE_BLK_SIZE / Driver::instance()->blk_sz());
|
driver->blk()->tx()->submit_packet(p);
|
||||||
Driver::instance()->blk()->tx()->submit_packet(p);
|
|
||||||
} catch(Block::Session::Tx::Source::Packet_alloc_failed) {
|
} catch(Block::Session::Tx::Source::Packet_alloc_failed) {
|
||||||
throw Write_failed(off);
|
throw Write_failed(off);
|
||||||
}
|
}
|
||||||
@ -46,39 +47,44 @@ void Driver<POLICY>::Policy::sync(const typename POLICY::Element *e, char *dst)
|
|||||||
|
|
||||||
struct Main
|
struct Main
|
||||||
{
|
{
|
||||||
Server::Entrypoint &ep;
|
template <typename T>
|
||||||
|
|
||||||
struct Factory : Block::Driver_factory
|
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); }
|
Block::Driver *create()
|
||||||
void destroy(Block::Driver *driver) { Driver<Lru_policy>::destroy(); }
|
|
||||||
} factory;
|
|
||||||
|
|
||||||
void resource_handler(unsigned) { }
|
|
||||||
|
|
||||||
Block::Root root;
|
|
||||||
Server::Signal_rpc_member<Main> resource_dispatcher;
|
|
||||||
|
|
||||||
Main(Server::Entrypoint &ep)
|
|
||||||
: ep(ep), factory(ep), root(ep, Genode::env()->heap(), factory),
|
|
||||||
resource_dispatcher(ep, *this, &Main::resource_handler)
|
|
||||||
{
|
{
|
||||||
Genode::env()->parent()->announce(ep.manage(root));
|
driver = new (&heap) ::Driver<T>(env, heap);
|
||||||
Genode::env()->parent()->resource_avail_sigh(resource_dispatcher);
|
return driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy(Block::Driver *driver) {
|
||||||
|
Genode::destroy(&heap, static_cast<::Driver<T>*>(driver)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
void 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)
|
||||||
|
{
|
||||||
|
env.parent().announce(env.ep().manage(root));
|
||||||
|
env.parent().resource_avail_sigh(resource_dispatcher);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/************
|
Genode::size_t Component::stack_size() {
|
||||||
** Server **
|
return 2048*sizeof(Genode::addr_t); }
|
||||||
************/
|
|
||||||
|
|
||||||
namespace Server {
|
|
||||||
char const *name() { return "blk_cache_ep"; }
|
void Component::construct(Genode::Env &env) {
|
||||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
static Main server(env); }
|
||||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
|
||||||
}
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
TARGET = blk_cache
|
TARGET = blk_cache
|
||||||
LIBS = base server
|
LIBS = base
|
||||||
SRC_CC = main.cc lru.cc
|
SRC_CC = main.cc lru.cc
|
||||||
|
@ -194,7 +194,7 @@ struct Main
|
|||||||
Genode::destroy(&alloc, driver); }
|
Genode::destroy(&alloc, driver); }
|
||||||
} factory { env, heap, config_rom.xml() };
|
} 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)
|
Main(Env &env) : env(env)
|
||||||
{
|
{
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
TARGET = ram_blk
|
TARGET = ram_blk
|
||||||
SRC_CC = main.cc
|
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
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <base/exception.h>
|
#include <base/attached_rom_dataspace.h>
|
||||||
#include <base/printf.h>
|
#include <base/component.h>
|
||||||
#include <os/config.h>
|
#include <base/log.h>
|
||||||
#include <os/server.h>
|
|
||||||
#include <rom_session/connection.h>
|
|
||||||
#include <block/component.h>
|
#include <block/component.h>
|
||||||
#include <block/driver.h>
|
#include <rom_session/connection.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
@ -25,29 +23,27 @@ class Rom_blk : public Block::Driver
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Env &_env;
|
||||||
Rom_connection _rom;
|
Rom_connection _rom;
|
||||||
Dataspace_capability _file_cap; /* rom-file capability */
|
size_t _blk_sz;
|
||||||
addr_t _file_addr; /* start address of attached file */
|
Dataspace_capability _file_cap = _rom.dataspace();
|
||||||
size_t _file_sz; /* file size */
|
addr_t _file_addr = _env.rm().attach(_file_cap);
|
||||||
size_t _blk_sz; /* block size */
|
size_t _file_sz = Dataspace_client(_file_cap).size();
|
||||||
size_t _blk_cnt; /* block count */
|
size_t _blk_cnt = _file_sz / _blk_sz;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Rom_blk(const char *name, size_t blk_sz)
|
using String = Genode::String<64UL>;
|
||||||
: _rom(name),
|
|
||||||
_file_cap(_rom.dataspace()),
|
Rom_blk(Env &env, String &name, size_t blk_sz)
|
||||||
_file_addr(env()->rm_session()->attach(_file_cap)),
|
: _env(env), _rom(env, name.string()), _blk_sz(blk_sz) {}
|
||||||
_file_sz(Dataspace_client(_file_cap).size()),
|
|
||||||
_blk_sz(blk_sz),
|
|
||||||
_blk_cnt(_file_sz/_blk_sz) { }
|
|
||||||
|
|
||||||
|
|
||||||
/****************************
|
/****************************
|
||||||
** Block-driver interface **
|
** 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::sector_t block_count() { return _blk_cnt; }
|
||||||
|
|
||||||
Block::Session::Operations ops()
|
Block::Session::Operations ops()
|
||||||
@ -58,15 +54,15 @@ class Rom_blk : public Block::Driver
|
|||||||
}
|
}
|
||||||
|
|
||||||
void read(Block::sector_t block_number,
|
void read(Block::sector_t block_number,
|
||||||
Genode::size_t block_count,
|
size_t block_count,
|
||||||
char* buffer,
|
char* buffer,
|
||||||
Block::Packet_descriptor &packet)
|
Block::Packet_descriptor &packet)
|
||||||
{
|
{
|
||||||
/* sanity check block number */
|
/* sanity check block number */
|
||||||
if ((block_number + block_count > _file_sz / _blk_sz)
|
if ((block_number + block_count > _file_sz / _blk_sz)
|
||||||
|| block_number < 0) {
|
|| block_number < 0) {
|
||||||
PWRN("requested blocks %lld-%lld out of range!",
|
warning("requested blocks ", block_number, "-",
|
||||||
block_number, block_number + block_count);
|
block_number + block_count, " out of range!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,49 +79,50 @@ class Rom_blk : public Block::Driver
|
|||||||
|
|
||||||
struct Main
|
struct Main
|
||||||
{
|
{
|
||||||
Server::Entrypoint &ep;
|
Env &env;
|
||||||
|
Heap heap { env.ram(), env.rm() };
|
||||||
|
|
||||||
struct Factory : Block::Driver_factory
|
struct Factory : Block::Driver_factory
|
||||||
{
|
{
|
||||||
|
Env &env;
|
||||||
|
Heap &heap;
|
||||||
|
|
||||||
|
Factory(Env &env, Heap &heap)
|
||||||
|
: env(env), heap(heap) {}
|
||||||
|
|
||||||
Block::Driver *create()
|
Block::Driver *create()
|
||||||
{
|
{
|
||||||
char file[64];
|
Rom_blk::String file;
|
||||||
size_t blk_sz = 512;
|
size_t blk_sz = 512;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
config()->xml_node().attribute("file").value(file, sizeof(file));
|
Attached_rom_dataspace config(env, "config");
|
||||||
config()->xml_node().attribute("block_size").value(&blk_sz);
|
config.xml().attribute("file").value(&file);
|
||||||
|
config.xml().attribute("block_size").value(&blk_sz);
|
||||||
}
|
}
|
||||||
catch (...) { }
|
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 {
|
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) {
|
} catch(Rom_connection::Rom_connection_failed) {
|
||||||
PERR("Cannot open file %s.", file);
|
error("Cannot open file ", file, ".");
|
||||||
}
|
}
|
||||||
throw Root::Unavailable();
|
throw Root::Unavailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy(Block::Driver *driver) {
|
void destroy(Block::Driver *driver) {
|
||||||
Genode::destroy(env()->heap(), driver); }
|
Genode::destroy(&heap, driver); }
|
||||||
} factory;
|
} factory { env, heap };
|
||||||
|
|
||||||
Block::Root root;
|
Block::Root root { env.ep(), heap, factory };
|
||||||
|
|
||||||
Main(Server::Entrypoint &ep)
|
Main(Env &env) : env(env) {
|
||||||
: ep(ep), root(ep, Genode::env()->heap(), factory) {
|
env.parent().announce(env.ep().manage(root)); }
|
||||||
Genode::env()->parent()->announce(ep.manage(root)); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/************
|
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
|
||||||
** Server **
|
void Component::construct(Genode::Env &env) { static Main server(env); }
|
||||||
************/
|
|
||||||
|
|
||||||
namespace Server {
|
|
||||||
char const *name() { return "rom_blk_ep"; }
|
|
||||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
|
||||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
|
||||||
}
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
TARGET = rom_blk
|
TARGET = rom_blk
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
LIBS = base config server
|
LIBS = base
|
||||||
|
@ -5,9 +5,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <base/allocator_avl.h>
|
#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 <block_session/connection.h>
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
#include <os/config.h>
|
|
||||||
#include <os/ring_buffer.h>
|
#include <os/ring_buffer.h>
|
||||||
|
|
||||||
static Genode::size_t blk_sz; /* block size of the device */
|
static Genode::size_t blk_sz; /* block size of the device */
|
||||||
@ -42,28 +45,32 @@ class Test
|
|||||||
bool write)
|
bool write)
|
||||||
: _nr(nr), _cnt(cnt), _write(write) {}
|
: _nr(nr), _cnt(cnt), _write(write) {}
|
||||||
|
|
||||||
virtual void print_error() {
|
virtual void print_error()
|
||||||
PINF("couldn't %s block %lld - %lld",
|
{
|
||||||
_write ? "write" : "read", _nr, _nr+_cnt); }
|
Genode::error("couldn't ", _write ? "write" : "read",
|
||||||
|
" block ", _nr, " - ", _nr+_cnt);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Submit_queue_full : Exception {
|
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 {
|
struct Timeout : Exception {
|
||||||
void print_error() { PINF("Test timed out!"); } };
|
void print_error() {
|
||||||
|
Genode::error("Test timed out!"); } };
|
||||||
|
|
||||||
virtual void perform() = 0;
|
virtual void perform() = 0;
|
||||||
virtual void ack_avail() = 0;
|
virtual void ack_avail() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
Genode::Entrypoint &_ep;
|
||||||
Genode::Allocator_avl _alloc;
|
Genode::Allocator_avl _alloc;
|
||||||
Block::Connection _session;
|
Block::Connection _session;
|
||||||
Genode::Signal_receiver _receiver;
|
Genode::Signal_handler<Test> _disp_ack;
|
||||||
Genode::Signal_dispatcher<Test> _disp_ack;
|
Genode::Signal_handler<Test> _disp_submit;
|
||||||
Genode::Signal_dispatcher<Test> _disp_submit;
|
Genode::Signal_handler<Test> _disp_timeout;
|
||||||
Genode::Signal_dispatcher<Test> _disp_timeout;
|
|
||||||
Timer::Connection _timer;
|
Timer::Connection _timer;
|
||||||
bool _handle;
|
bool _handle;
|
||||||
|
|
||||||
@ -75,17 +82,20 @@ class Test
|
|||||||
(1 << Block::Packet_descriptor::PACKET_ALIGNMENT) - 1;
|
(1 << Block::Packet_descriptor::PACKET_ALIGNMENT) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _ack_avail(unsigned) { ack_avail(); }
|
void _ack_avail() { ack_avail(); }
|
||||||
void _ready_to_submit(unsigned) { _handle = false; }
|
void _ready_to_submit() { _handle = false; }
|
||||||
void _timeout(unsigned) { throw Timeout(); }
|
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)
|
unsigned timeout_ms)
|
||||||
: _alloc(Genode::env()->heap()),
|
: _ep(ep),
|
||||||
|
_alloc(&heap),
|
||||||
_session(&_alloc, _shared_buffer_size(bulk_buffer_size)),
|
_session(&_alloc, _shared_buffer_size(bulk_buffer_size)),
|
||||||
_disp_ack(_receiver, *this, &Test::_ack_avail),
|
_disp_ack(ep, *this, &Test::_ack_avail),
|
||||||
_disp_submit(_receiver, *this, &Test::_ready_to_submit),
|
_disp_submit(ep, *this, &Test::_ready_to_submit),
|
||||||
_disp_timeout(_receiver, *this, &Test::_timeout)
|
_disp_timeout(ep, *this, &Test::_timeout)
|
||||||
{
|
{
|
||||||
_session.tx_channel()->sigh_ack_avail(_disp_ack);
|
_session.tx_channel()->sigh_ack_avail(_disp_ack);
|
||||||
_session.tx_channel()->sigh_ready_to_submit(_disp_submit);
|
_session.tx_channel()->sigh_ready_to_submit(_disp_submit);
|
||||||
@ -99,12 +109,7 @@ class Test
|
|||||||
void _handle_signal()
|
void _handle_signal()
|
||||||
{
|
{
|
||||||
_handle = true;
|
_handle = true;
|
||||||
|
while (_handle) _ep.wait_and_dispatch_one_signal();
|
||||||
while (_handle) {
|
|
||||||
Genode::Signal s = _receiver.wait_for_signal();
|
|
||||||
static_cast<Genode::Signal_dispatcher_base *>
|
|
||||||
(s.context())->dispatch(s.num());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -114,13 +119,13 @@ struct Read_test : Test
|
|||||||
{
|
{
|
||||||
bool done;
|
bool done;
|
||||||
|
|
||||||
Read_test(unsigned timeo_ms)
|
Read_test(Genode::Entrypoint &ep, Genode::Heap &heap, unsigned timeo_ms)
|
||||||
: Test(BULK_BLK_NR*blk_sz, timeo_ms), done(false) { }
|
: Test(ep, heap, BULK_BLK_NR*blk_sz, timeo_ms), done(false) { }
|
||||||
|
|
||||||
void perform()
|
void perform()
|
||||||
{
|
{
|
||||||
PINF("reading block 0 - %llu, %u per request",
|
Genode::log("reading block 0 - ", test_cnt - 1, ", ", NR_PER_REQ,
|
||||||
test_cnt - 1, NR_PER_REQ);
|
" per request");
|
||||||
|
|
||||||
for (Block::sector_t nr = 0, cnt = NR_PER_REQ; nr < test_cnt;
|
for (Block::sector_t nr = 0, cnt = NR_PER_REQ; nr < test_cnt;
|
||||||
nr += cnt) {
|
nr += cnt) {
|
||||||
@ -169,15 +174,19 @@ template <unsigned BULK_BLK_NR, unsigned NR_PER_REQ, unsigned BATCH>
|
|||||||
struct Write_test : Test
|
struct Write_test : Test
|
||||||
{
|
{
|
||||||
struct Invalid_dimensions : Exception {
|
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
|
struct Integrity_exception : Block_exception
|
||||||
{
|
{
|
||||||
Integrity_exception(Block::sector_t nr, Genode::size_t cnt)
|
Integrity_exception(Block::sector_t nr, Genode::size_t cnt)
|
||||||
: Block_exception(nr, cnt, false) {}
|
: Block_exception(nr, cnt, false) {}
|
||||||
|
|
||||||
void print_error() {
|
void print_error()
|
||||||
PINF("Integrity check failed: block %lld - %lld", _nr, _nr+_cnt); }
|
{
|
||||||
|
Genode::error("Integrity check failed: block ", _nr, " - ",
|
||||||
|
_nr+_cnt);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Genode::Ring_buffer<Block::Packet_descriptor, BATCH+1,
|
typedef Genode::Ring_buffer<Block::Packet_descriptor, BATCH+1,
|
||||||
@ -186,8 +195,8 @@ struct Write_test : Test
|
|||||||
Req_buffer read_packets;
|
Req_buffer read_packets;
|
||||||
Req_buffer write_packets;
|
Req_buffer write_packets;
|
||||||
|
|
||||||
Write_test(unsigned timeo_ms)
|
Write_test(Genode::Entrypoint &ep, Genode::Heap &heap, unsigned timeo_ms)
|
||||||
: Test(BULK_BLK_NR*blk_sz, timeo_ms)
|
: Test(ep, heap, BULK_BLK_NR*blk_sz, timeo_ms)
|
||||||
{
|
{
|
||||||
if (BULK_BLK_NR < BATCH*NR_PER_REQ ||
|
if (BULK_BLK_NR < BATCH*NR_PER_REQ ||
|
||||||
BATCH > Block::Session::TX_QUEUE_SIZE ||
|
BATCH > Block::Session::TX_QUEUE_SIZE ||
|
||||||
@ -272,8 +281,8 @@ struct Write_test : Test
|
|||||||
if (!blk_ops.supported(Block::Packet_descriptor::WRITE))
|
if (!blk_ops.supported(Block::Packet_descriptor::WRITE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PINF("read/write/compare block 0 - %llu, %u per request",
|
Genode::log("read/write/compare block 0 - ", test_cnt - 1,
|
||||||
test_cnt - 1, NR_PER_REQ);
|
", ", NR_PER_REQ, " per request");
|
||||||
|
|
||||||
for (Block::sector_t nr = 0, cnt = BATCH*NR_PER_REQ; nr < test_cnt;
|
for (Block::sector_t nr = 0, cnt = BATCH*NR_PER_REQ; nr < test_cnt;
|
||||||
nr += cnt,
|
nr += cnt,
|
||||||
@ -304,21 +313,25 @@ struct Write_test : Test
|
|||||||
struct Violation_test : Test
|
struct Violation_test : Test
|
||||||
{
|
{
|
||||||
struct Write_on_read_only : Exception {
|
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
|
struct Range_check_failed : Block_exception
|
||||||
{
|
{
|
||||||
Range_check_failed(Block::sector_t nr, Genode::size_t cnt)
|
Range_check_failed(Block::sector_t nr, Genode::size_t cnt)
|
||||||
: Block_exception(nr, cnt, false) {}
|
: Block_exception(nr, cnt, false) {}
|
||||||
|
|
||||||
void print_error() {
|
void print_error()
|
||||||
PINF("Range check failed: access to block %lld - %lld succeeded",
|
{
|
||||||
_nr, _nr+_cnt); }
|
Genode::error("Range check failed: access to block ", _nr,
|
||||||
|
" - ", _nr+_cnt, " succeeded");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int p_in_fly;
|
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)
|
void req(Block::sector_t nr, Genode::size_t cnt, bool write)
|
||||||
{
|
{
|
||||||
@ -361,55 +374,63 @@ struct Violation_test : Test
|
|||||||
|
|
||||||
|
|
||||||
template <typename 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);
|
TEST * test = new (&heap) TEST(ep, heap, timeo_ms);
|
||||||
t.perform();
|
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 {
|
try {
|
||||||
|
|
||||||
|
static Heap heap(env.ram(), env.rm());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* First we ask for the block size of the driver to dimension
|
* First we ask for the block size of the driver to dimension
|
||||||
* the queue size for our tests. Moreover, we implicitely test,
|
* the queue size for our tests. Moreover, we implicitely test,
|
||||||
* whether closing and opening again works for the driver
|
* whether closing and opening again works for the driver
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
Genode::Allocator_avl alloc(Genode::env()->heap());
|
Allocator_avl alloc(&heap);
|
||||||
Block::Connection blk(&alloc);
|
Block::Connection blk(&alloc);
|
||||||
blk.info(&blk_cnt, &blk_sz, &blk_ops);
|
blk.info(&blk_cnt, &blk_sz, &blk_ops);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Genode::Number_of_bytes test_size;;
|
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);
|
test_cnt = Genode::min(test_size / blk_sz, blk_cnt);
|
||||||
} catch (...) { test_cnt = blk_cnt; }
|
} catch (...) { test_cnt = blk_cnt; }
|
||||||
|
|
||||||
/* must be multiple of 16 */
|
/* must be multiple of 16 */
|
||||||
test_cnt &= ~0xfLLU;
|
test_cnt &= ~0xfLLU;
|
||||||
|
|
||||||
PINF("block device with block size %zd sector count %lld (testing %lld sectors)",
|
log("block device with block size ", blk_sz, " sector count ",
|
||||||
blk_sz, blk_cnt, test_cnt);
|
blk_cnt, " (testing ", test_cnt, " sectors)");
|
||||||
|
|
||||||
perform<Read_test<Block::Session::TX_QUEUE_SIZE-10,
|
perform<Read_test<Block::Session::TX_QUEUE_SIZE-10,
|
||||||
Block::Session::TX_QUEUE_SIZE-10> >();
|
Block::Session::TX_QUEUE_SIZE-10> >(env.ep(), heap);
|
||||||
perform<Read_test<Block::Session::TX_QUEUE_SIZE*5, 1> >();
|
perform<Read_test<Block::Session::TX_QUEUE_SIZE*5, 1> >(env.ep(), heap);
|
||||||
perform<Read_test<Block::Session::TX_QUEUE_SIZE, 1> >();
|
perform<Read_test<Block::Session::TX_QUEUE_SIZE, 1> >(env.ep(), heap);
|
||||||
perform<Write_test<Block::Session::TX_QUEUE_SIZE, 8, 16> >();
|
perform<Write_test<Block::Session::TX_QUEUE_SIZE, 8, 16> >(env.ep(), heap);
|
||||||
perform<Violation_test>(1000);
|
perform<Violation_test>(env.ep(), heap, 1000);
|
||||||
|
|
||||||
PINF("Tests finished successfully!");
|
log("Tests finished successfully!");
|
||||||
} catch(Genode::Parent::Service_denied) {
|
} catch(Genode::Parent::Service_denied) {
|
||||||
PERR("Opening block session was denied!");
|
error("Opening block session was denied!");
|
||||||
return -1;
|
|
||||||
} catch(Test::Exception &e) {
|
} catch(Test::Exception &e) {
|
||||||
PERR("Test failed!");
|
error("Test failed!");
|
||||||
e.print_error();
|
e.print_error();
|
||||||
return -2;
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
TARGET = test-blk-cli
|
TARGET = test-blk-cli
|
||||||
SRC_CC = main.cc
|
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
|
* This file is part of the Genode OS framework, which is distributed
|
||||||
* under the terms of the GNU General Public License version 2.
|
* under the terms of the GNU General Public License version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <base/printf.h>
|
#include <base/attached_rom_dataspace.h>
|
||||||
#include <cap_session/connection.h>
|
|
||||||
#include <timer_session/connection.h>
|
|
||||||
#include <block/component.h>
|
#include <block/component.h>
|
||||||
#include <block/driver.h>
|
#include <block/driver.h>
|
||||||
#include <os/config.h>
|
|
||||||
#include <os/ring_buffer.h>
|
#include <os/ring_buffer.h>
|
||||||
|
#include <timer_session/connection.h>
|
||||||
|
|
||||||
|
|
||||||
class Driver : public Block::Driver
|
class Driver : public Block::Driver
|
||||||
@ -37,12 +35,12 @@ class Driver : public Block::Driver
|
|||||||
|
|
||||||
public:
|
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),
|
: _number(number), _size(size),
|
||||||
_blk_ds(Genode::env()->ram_session()->alloc(number*size)),
|
_blk_ds(env.ram().alloc(number*size)),
|
||||||
_blk_buf(Genode::env()->rm_session()->attach(_blk_ds)) {}
|
_blk_buf(env.rm().attach(_blk_ds)) {}
|
||||||
|
|
||||||
void handler(unsigned)
|
void handler()
|
||||||
{
|
{
|
||||||
while (!_packets.empty()) {
|
while (!_packets.empty()) {
|
||||||
Block::Packet_descriptor p = _packets.get();
|
Block::Packet_descriptor p = _packets.get();
|
||||||
@ -98,52 +96,50 @@ class Driver : public Block::Driver
|
|||||||
|
|
||||||
struct Main
|
struct Main
|
||||||
{
|
{
|
||||||
Server::Entrypoint &ep;
|
Genode::Env &env;
|
||||||
|
Genode::Heap heap { env.ram(), env.rm() };
|
||||||
|
|
||||||
struct Factory : Block::Driver_factory
|
struct Factory : Block::Driver_factory
|
||||||
{
|
{
|
||||||
::Driver *driver;
|
::Driver *driver;
|
||||||
|
|
||||||
Factory()
|
Factory(Genode::Env &env, Genode::Heap &heap)
|
||||||
{
|
{
|
||||||
Genode::size_t blk_nr = 1024;
|
Genode::size_t blk_nr = 1024;
|
||||||
Genode::size_t blk_sz = 512;
|
Genode::size_t blk_sz = 512;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Genode::config()->xml_node().attribute("sectors").value(&blk_nr);
|
Genode::Attached_rom_dataspace config { env, "config" };
|
||||||
Genode::config()->xml_node().attribute("block_size").value(&blk_sz);
|
config.xml().attribute("sectors").value(&blk_nr);
|
||||||
|
config.xml().attribute("block_size").value(&blk_sz);
|
||||||
}
|
}
|
||||||
catch (...) { }
|
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; }
|
Block::Driver *create() { return driver; }
|
||||||
|
|
||||||
void destroy(Block::Driver *driver) { }
|
void destroy(Block::Driver *driver) { }
|
||||||
} factory;
|
} factory { env, heap };
|
||||||
|
|
||||||
Block::Root root;
|
Block::Root root { env.ep(), heap, factory };
|
||||||
Timer::Connection timer;
|
Timer::Connection timer;
|
||||||
Server::Signal_rpc_member<Driver> dispatcher = { ep, *factory.driver,
|
Genode::Signal_handler<Driver> dispatcher { env.ep(), *factory.driver,
|
||||||
&Driver::handler };
|
&Driver::handler };
|
||||||
|
|
||||||
Main(Server::Entrypoint &ep)
|
Main(Genode::Env &env) : env(env)
|
||||||
: ep(ep), root(ep, Genode::env()->heap(), factory)
|
|
||||||
{
|
{
|
||||||
timer.sigh(dispatcher);
|
timer.sigh(dispatcher);
|
||||||
timer.trigger_periodic(10000);
|
timer.trigger_periodic(10000);
|
||||||
Genode::env()->parent()->announce(ep.manage(root));
|
env.parent().announce(env.ep().manage(root));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/************
|
Genode::size_t Component::stack_size() {
|
||||||
** Server **
|
return 2048*sizeof(Genode::addr_t); }
|
||||||
************/
|
|
||||||
|
|
||||||
namespace Server {
|
|
||||||
char const *name() { return "blk_srv_ep"; }
|
void Component::construct(Genode::Env &env) {
|
||||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
static Main server(env); }
|
||||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
|
||||||
}
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
TARGET = test-blk-srv
|
TARGET = test-blk-srv
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
LIBS = base config server
|
LIBS = base
|
||||||
|
@ -99,32 +99,27 @@ class Driver : public Block::Driver
|
|||||||
|
|
||||||
struct Factory : Block::Driver_factory
|
struct Factory : Block::Driver_factory
|
||||||
{
|
{
|
||||||
Block::Driver *create() {
|
Genode::Heap &heap;
|
||||||
return new (Genode::env()->heap()) Driver(); }
|
|
||||||
|
|
||||||
void destroy(Block::Driver *driver) {
|
Factory(Genode::Heap &heap) : heap(heap) {}
|
||||||
Genode::destroy(Genode::env()->heap(), driver); }
|
|
||||||
|
Block::Driver *create() { return new (&heap) Driver(); }
|
||||||
|
|
||||||
|
void destroy(Block::Driver *driver) { Genode::destroy(&heap, driver); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Main
|
struct Main
|
||||||
{
|
{
|
||||||
Server::Entrypoint &ep;
|
Genode::Env &env;
|
||||||
struct Factory factory;
|
Genode::Heap heap { env.ram(), env.rm() };
|
||||||
Block::Root root;
|
struct Factory factory { heap };
|
||||||
|
Block::Root root { env.ep(), heap, factory };
|
||||||
|
|
||||||
Main(Server::Entrypoint &ep)
|
Main(Genode::Env &env) : env(env) {
|
||||||
: ep(ep), root(ep, Genode::env()->heap(), factory) {
|
env.parent().announce(env.ep().manage(root)); }
|
||||||
Genode::env()->parent()->announce(ep.manage(root)); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/************
|
Genode::size_t Component::stack_size() { return 2*1024*sizeof(long); }
|
||||||
** Server **
|
void Component::construct(Genode::Env &env) { static Main m(env); }
|
||||||
************/
|
|
||||||
|
|
||||||
namespace Server {
|
|
||||||
char const *name() { return "fb_blk_ep"; }
|
|
||||||
size_t stack_size() { return 2*1024*sizeof(long); }
|
|
||||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
|
||||||
}
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
TARGET = test-fb_blk_adapter
|
TARGET = test-fb_blk_adapter
|
||||||
SRC_CC = main.cc
|
SRC_CC = main.cc
|
||||||
LIBS = base server
|
LIBS = base
|
||||||
|
Loading…
x
Reference in New Issue
Block a user