genode/ports/src/vancouver/disk.h
Norman Feske 1df48b8331 ports: common utilities for building VMMs on NOVA
To ease the creation of custom virtual machine monitors on top of
NOVA, this patch moves generic utilities from vancouver resp. seoul to the
public include location 'ports/include/vmm'. As a nice side effect,
this change simplifies 'vancouver/main.cc'.

Issue #949
2013-11-25 12:12:31 +01:00

143 lines
3.7 KiB
C++

/*
* \brief Block interface
* \author Markus Partheymueller
* \author Alexander Boettcher
* \date 2012-09-15
*/
/*
* Copyright (C) 2012 Intel Corporation
* Copyright (C) 2013 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.
*
* The code is partially based on the Vancouver VMM, which is distributed
* under the terms of the GNU General Public License version 2.
*
* Modifications by Intel Corporation are contributed under the terms and
* conditions of the GNU General Public License version 2.
*/
#ifndef _VANCOUVER_DISK_H_
#define _VANCOUVER_DISK_H_
/* Genode includes */
#include <base/allocator_avl.h>
#include <base/printf.h>
#include <base/sleep.h>
#include <base/thread.h>
#include <block_session/connection.h>
#include <util/string.h>
#include <base/sync_allocator.h>
/* local includes */
#include <synced_motherboard.h>
class Vancouver_disk;
class Vancouver_disk_signal : public Genode::Signal_dispatcher<Vancouver_disk>
{
private:
unsigned _disk_nr;
public:
Vancouver_disk_signal(Genode::Signal_receiver &sig_rec,
Vancouver_disk &obj,
void (Vancouver_disk::*member)(unsigned),
unsigned disk_nr)
: Genode::Signal_dispatcher<Vancouver_disk>(sig_rec, obj, member),
_disk_nr(disk_nr) {}
unsigned disk_nr() { return _disk_nr; }
};
class Vancouver_disk : public Genode::Thread<8192>, public StaticReceiver<Vancouver_disk>
{
private:
/* helper class to lookup a MessageDisk object */
class Avl_entry : public Genode::Avl_node<Avl_entry>
{
private:
Genode::addr_t _key;
MessageDisk * _msg;
public:
Avl_entry(void * key, MessageDisk * msg)
: _key(reinterpret_cast<Genode::addr_t>(key)), _msg(msg) { }
bool higher(Avl_entry *e) { return e->_key > _key; }
Avl_entry *find(Genode::addr_t ptr)
{
if (ptr == _key) return this;
Avl_entry *obj = this->child(ptr > _key);
return obj ? obj->find(ptr) : 0;
}
MessageDisk * msg() { return _msg; }
};
/* block session used by disk models of VMM */
enum { MAX_DISKS = 4 };
struct {
Block::Connection *blk_con;
Block::Session::Operations ops;
Genode::size_t blk_size;
Genode::size_t blk_cnt;
Vancouver_disk_signal *dispatcher;
} _diskcon[MAX_DISKS];
Synced_motherboard &_motherboard;
char * const _backing_store_base;
size_t const _backing_store_size;
/* slabs for temporary holding DMADescriptor and MessageDisk objects */
typedef Genode::Tslab<MessageDisk, 128> MessageDisk_Slab;
typedef Genode::Synchronized_allocator<MessageDisk_Slab> MessageDisk_Slab_Sync;
typedef Genode::Tslab<DmaDescriptor, 256> DmaDesc_Slab;
typedef Genode::Synchronized_allocator<DmaDesc_Slab> DmaDesc_Slab_Sync;
MessageDisk_Slab_Sync _tslab_msg;
DmaDesc_Slab_Sync _tslab_dma;
/* Structure to find back the MessageDisk object out of a Block Ack */
typedef Genode::Tslab<Avl_entry, 128> Avl_entry_slab;
typedef Genode::Synchronized_allocator<Avl_entry_slab> Avl_entry_slab_sync;
Avl_entry_slab_sync _tslab_avl;
Genode::Avl_tree<Avl_entry> _lookup_msg;
Genode::Lock _lookup_msg_lock;
/* entry function if signal must be dispatched */
void _signal_dispatch_entry(unsigned);
public:
/**
* Constructor
*/
Vancouver_disk(Synced_motherboard &,
char * backing_store_base,
Genode::size_t backing_store_size);
~Vancouver_disk();
void entry();
bool receive(MessageDisk &msg);
void register_host_operations(Motherboard &);
};
#endif /* _VANCOUVER_DISK_H_ */