seoul: remove deprecated env and config usage

Issue #1987
This commit is contained in:
Alexander Boettcher 2017-01-03 11:41:42 +01:00 committed by Norman Feske
parent 7eb6ef226f
commit 537dde1f40
16 changed files with 598 additions and 604 deletions

View File

@ -26,7 +26,8 @@
#define _INCLUDE__VMM__GUEST_MEMORY_H_
/* Genode includes */
#include <os/attached_ram_dataspace.h>
#include <base/attached_ram_dataspace.h>
#include <base/env.h>
#include <rm_session/connection.h>
#include <region_map/client.h>
@ -48,9 +49,13 @@ namespace Vmm {
*/
struct Vmm::Virtual_reservation : private Rm_connection, Region_map_client
{
Virtual_reservation(addr_t vm_size)
Genode::Env &_env;
Virtual_reservation(Genode::Env &env, addr_t vm_size)
:
Region_map_client(Rm_connection::create(vm_size))
Rm_connection(env),
Region_map_client(Rm_connection::create(vm_size)),
_env(env)
{
try {
/*
@ -58,8 +63,8 @@ struct Vmm::Virtual_reservation : private Rm_connection, Region_map_client
* space. We leave out the very first page because core denies
* the attachment of anything at the zero page.
*/
env()->rm_session()->attach_at(Region_map_client::dataspace(),
PAGE_SIZE, 0, PAGE_SIZE);
env.rm().attach_at(Region_map_client::dataspace(), PAGE_SIZE, 0,
PAGE_SIZE);
} catch (Rm_session::Region_conflict) {
error("region conflict while attaching guest-physical memory");
@ -68,29 +73,9 @@ struct Vmm::Virtual_reservation : private Rm_connection, Region_map_client
~Virtual_reservation()
{
env()->rm_session()->detach((void *)PAGE_SIZE);
_env.rm().detach((void *)PAGE_SIZE);
}
};
/**
* Representation of guest memory
*
*/
struct Vmm::Guest_memory : Attached_ram_dataspace
{
/**
* Constructor
*
* \param backing_store_size number of bytes of physical RAM to be
* used as guest-physical and device memory,
* allocated from core's RAM service
*/
Guest_memory(size_t backing_store_size)
:
Attached_ram_dataspace(env()->ram_session(), backing_store_size)
{ }
};
#endif /* _INCLUDE__VMM__GUEST_MEMORY_H_ */

View File

@ -16,7 +16,6 @@
/* Genode includes */
#include <base/thread.h>
#include <cap_session/connection.h>
#include <cpu_session/connection.h>
#include <pd_session/connection.h>
#include <region_map/client.h>

View File

@ -27,8 +27,6 @@ set memory_vmm_vm "512M"
set vcpus_to_be_used 1
source ${genode_dir}/repos/ports/run/seoul.inc
if {[have_include power_on/qemu]} {
if {![file exists bin/seoul-disc.raw]} {
@ -41,4 +39,6 @@ if {[have_include power_on/qemu]} {
append_if $use_block_sata qemu_args " -drive id=disk,file=bin/seoul-disc.raw,format=raw,if=none -device ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0 -boot d"
}
source ${genode_dir}/repos/ports/run/seoul.inc
run_genode_until forever

View File

@ -33,7 +33,7 @@ set use_multiboot_modaddr 0x2800000
# Use a Genode run script of a 32bit platform and turn it into a bootable
# setup for Seoul - adjust build_dir and run_script variable accordingly
set run_script "printf"
set run_script "log"
set build_dir "."
set run_script_path "$build_dir/var/run/$run_script"
set genode_iso "$build_dir/var/run/$run_script.iso"
@ -44,7 +44,7 @@ if {[catch {exec cp $genode_iso bin/genode.iso}]} {
exit 1
}
set files_vm [exec cat $run_script_path/boot/grub/menu.lst]
set files_vm [exec isoinfo -i $genode_iso -x "/BOOT/GRUB/MENU.LST;1"]
set vm [split $files_vm "\n"]
set guest_os_binaries {}

View File

@ -26,7 +26,6 @@
#include <util/string.h>
#include <util/misc_math.h>
#include <util/xml_node.h>
#include <base/env.h>
#include <base/log.h>
#include <rom_session/connection.h>
@ -69,7 +68,7 @@ class Boot_module_provider
* \return module size in bytes, or 0 if module does not exist
* \throw Destination_buffer_too_small
*/
Genode::size_t data(int module_index,
Genode::size_t data(Genode::Env &env, int module_index,
void *dst, Genode::size_t dst_len) const
{
using namespace Genode;
@ -94,7 +93,7 @@ class Boot_module_provider
/*
* Open ROM session
*/
Rom_connection rom(name);
Rom_connection rom(env, name);
Dataspace_capability ds = rom.dataspace();
Genode::size_t const src_len = Dataspace_client(ds).size();
@ -103,7 +102,7 @@ class Boot_module_provider
throw Destination_buffer_too_small();
}
void * const src = env()->rm_session()->attach(ds);
void * const src = env.rm().attach(ds);
/*
* Copy content to destination buffer
@ -115,7 +114,7 @@ class Boot_module_provider
* session will be closed automatically when we leave the
* current scope and the 'rom' object gets destructed.
*/
env()->rm_session()->detach(src);
env.rm().detach(src);
return src_len;
} else if (mod_node.has_type("inline")) {

View File

@ -2,11 +2,12 @@
* \brief Manager of all VM requested console functionality
* \author Markus Partheymueller
* \author Norman Feske
* \author Alexander Boettcher
* \date 2012-07-31
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
* Copyright (C) 2011-2017 Genode Labs GmbH
* Copyright (C) 2012 Intel Corporation
*
* This file is distributed under the terms of the GNU General Public License
@ -19,30 +20,28 @@
* conditions of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/snprintf.h>
/* base includes */
#include <util/register.h>
/* nitpicker graphics backend */
#include <os/pixel_rgb565.h>
#include <nitpicker_gfx/text_painter.h>
#include <nul/motherboard.h>
/* local includes */
#include "console.h"
#include "keyboard.h"
using Genode::env;
using Genode::Dataspace_client;
using Genode::Surface;
using Genode::Pixel_rgb565;
typedef Text_painter::Font Font;
extern char _binary_mono_tff_start;
Font default_font(&_binary_mono_tff_start);
Text_painter::Font default_font(&_binary_mono_tff_start);
bool fb_active = true;
static struct {
Genode::uint64_t checksum1 = 0;
Genode::uint64_t checksum2 = 0;
unsigned unchanged = 0;
bool cmp_even = 1;
bool active = true;
bool revoked = false;
} fb_state;
/**
@ -82,7 +81,7 @@ static bool mouse_event(Input::Event const &ev)
*
* This function updates _left, _middle, and _right as a side effect.
*/
unsigned Vancouver_console::_input_to_ps2mouse(Input::Event const &ev)
unsigned Seoul::Console::_input_to_ps2mouse(Input::Event const &ev)
{
/* track state of mouse buttons */
using Input::Event;
@ -128,7 +127,7 @@ unsigned Vancouver_console::_input_to_ps2mouse(Input::Event const &ev)
/* bus callbacks */
bool Vancouver_console::receive(MessageConsole &msg)
bool Seoul::Console::receive(MessageConsole &msg)
{
if (msg.type == MessageConsole::TYPE_ALLOC_VIEW) {
_guest_fb = msg.ptr;
@ -197,182 +196,190 @@ bool Vancouver_console::receive(MessageConsole &msg)
}
bool Vancouver_console::receive(MessageMemRegion &msg)
bool Seoul::Console::receive(MessageMemRegion &msg)
{
if (msg.page >= 0xb8 && msg.page <= 0xbf) {
/* we had a fault in the text framebuffer */
if (!fb_active) fb_active = true;
if (!fb_state.active) fb_state.active = true;
Logging::printf("Reactivating text buffer loop.\n");
MessageTimer msg(_timer, _unsynchronized_motherboard.clock()->abstime(1, 1000));
_unsynchronized_motherboard.bus_timer.send(msg);
}
return false;
}
void Vancouver_console::entry()
unsigned Seoul::Console::_handle_fb()
{
/*
* Init sessions to the required external services
*/
enum { CONFIG_ALPHA = false };
if (!_guest_fb || !_regs)
return 0;
static Input::Connection input;
static Timer::Connection timer;
Framebuffer::Connection *framebuffer = 0;
enum { TEXT_MODE = 0 };
/* transfer text buffer content into chunky canvas */
if (_regs->mode == TEXT_MODE) {
if (fb_state.revoked || !fb_state.active)
return 0;
memset(_pixels, 0, _fb_size);
if (fb_state.cmp_even) fb_state.checksum1 = 0;
else fb_state.checksum2 = 0;
for (int j=0; j<25; j++) {
for (int i=0; i<80; i++) {
Genode::Surface_base::Point where(i*8, j*15);
char character = *((char *) (_guest_fb +(_regs->offset << 1) +j*80*2+i*2));
char colorvalue = *((char *) (_guest_fb+(_regs->offset << 1)+j*80*2+i*2+1));
char buffer[2]; buffer[0] = character; buffer[1] = 0;
char fg = colorvalue & 0xf;
if (fg == 0x8) fg = 0x7;
unsigned lum = ((fg & 0x8) >> 3)*127;
Genode::Color color(((fg & 0x4) >> 2)*127+lum, /* R+luminosity */
((fg & 0x2) >> 1)*127+lum, /* G+luminosity */
(fg & 0x1)*127+lum /* B+luminosity */);
Text_painter::paint(*_surface, where, default_font, color, buffer);
/* Checksum for comparing */
if (fb_state.cmp_even) fb_state.checksum1 += character;
else fb_state.checksum2 += character;
}
}
fb_state.cmp_even = !fb_state.cmp_even;
/* compare checksums to detect changed buffer */
if (fb_state.checksum1 != fb_state.checksum2) {
fb_state.unchanged = 0;
_framebuffer->refresh(0, 0, _fb_mode.width(), _fb_mode.height());
return 100;
}
if (++fb_state.unchanged < 10)
return fb_state.unchanged * 30;
/* if we copy the same data 10 times, unmap the text buffer from guest */
_env.rm().detach((void *)_guest_fb);
_env.rm().attach_at(_fb_ds, (Genode::addr_t)_guest_fb);
fb_state.unchanged = 0;
fb_state.active = false;
Logging::printf("Deactivated text buffer loop.\n");
return 0;
}
if (!fb_state.revoked) {
_env.rm().detach((void *)_guest_fb);
_env.rm().attach_at(_framebuffer->dataspace(),
(Genode::addr_t)_guest_fb);
/* if the VGA model expects a larger FB, pad to that size. */
if (_fb_size < _vm_fb_size) {
Genode::Ram_dataspace_capability _backup =
_env.ram().alloc(_vm_fb_size-_fb_size);
_env.rm().attach_at(_backup,
(Genode::addr_t) (_guest_fb+_fb_size));
}
fb_state.revoked = true;
}
_framebuffer->refresh(0, 0, _fb_mode.width(), _fb_mode.height());
return 10;
}
void Seoul::Console::_handle_input()
{
_input.for_each_event([&] (Input::Event const &ev) {
if (!fb_state.active) {
fb_state.active = true;
MessageTimer msg(_timer, _motherboard()->clock()->abstime(1, 1000));
_motherboard()->bus_timer.send(msg);
}
/* update mouse model (PS2) */
if (mouse_event(ev)) {
MessageInput msg(0x10001, _input_to_ps2mouse(ev));
_motherboard()->bus_input.send(msg);
}
if (ev.type() == Input::Event::PRESS) {
if (ev.code() <= 0xee) {
_vkeyb.handle_keycode_press(ev.code());
}
}
if (ev.type() == Input::Event::RELEASE) {
if (ev.code() <= 0xee) { /* keyboard event */
_vkeyb.handle_keycode_release(ev.code());
}
}
});
}
void Seoul::Console::register_host_operations(Motherboard &motherboard)
{
motherboard.bus_console .add(this, receive_static<MessageConsole>);
motherboard.bus_memregion.add(this, receive_static<MessageMemRegion>);
motherboard.bus_timeout .add(this, receive_static<MessageTimeout>);
MessageTimer msg;
if (!motherboard.bus_timer.send(msg))
Logging::panic("%s can't get a timer", __PRETTY_FUNCTION__);
_timer = msg.nr;
}
bool Seoul::Console::receive(MessageTimeout &msg) {
if (msg.nr != _timer)
return false;
unsigned next_timeout_ms = _handle_fb();
if (next_timeout_ms) {
MessageTimer msg_t(_timer, _unsynchronized_motherboard.clock()->abstime(next_timeout_ms, 1000));
_unsynchronized_motherboard.bus_timer.send(msg_t);
}
return true;
}
Seoul::Console::Console(Genode::Env &env, Synced_motherboard &mb,
Motherboard &unsynchronized_motherboard,
Genode::size_t vm_fb_size,
Genode::Dataspace_capability fb_ds)
:
_env(env),
_unsynchronized_motherboard(unsynchronized_motherboard),
_motherboard(mb), _fb_ds(fb_ds), _vm_fb_size(vm_fb_size)
{
_input.sigh(_signal_input);
try {
framebuffer = new (env()->heap()) Framebuffer::Connection();
using Framebuffer::Mode;
_framebuffer.construct(_env, Mode(0, 0, Mode::INVALID));
} catch (...) {
Genode::error("Headless mode - no framebuffer session available");
_startup_lock.unlock();
return;
}
_fb_size = Dataspace_client(framebuffer->dataspace()).size();
_fb_mode = framebuffer->mode();
_fb_size = Genode::Dataspace_client(_framebuffer->dataspace()).size();
_fb_mode = _framebuffer->mode();
_pixels = _env.rm().attach(_framebuffer->dataspace());
_pixels = env()->rm_session()->attach(framebuffer->dataspace());
Surface<Pixel_rgb565> surface((Pixel_rgb565 *) _pixels,
Genode::Surface_base::Area(_fb_mode.width(),
_fb_mode.height()));
/*
* Handle input events
*/
unsigned long count = 0;
bool revoked = false;
Vancouver_keyboard vkeyb(_motherboard);
Genode::uint64_t checksum1 = 0;
Genode::uint64_t checksum2 = 0;
unsigned unchanged = 0;
bool cmp_even = 1;
_startup_lock.unlock();
while (1) {
while (!input.pending()) {
/* transfer text buffer content into chunky canvas */
if (_regs && ++count % 10 == 0 && _regs->mode == 0
&& _guest_fb && !revoked && fb_active) {
memset(_pixels, 0, _fb_size);
if (cmp_even) checksum1 = 0;
else checksum2 = 0;
for (int j=0; j<25; j++) {
for (int i=0; i<80; i++) {
Genode::Surface_base::Point where(i*8, j*15);
char character = *((char *) (_guest_fb +(_regs->offset << 1) +j*80*2+i*2));
char colorvalue = *((char *) (_guest_fb+(_regs->offset << 1)+j*80*2+i*2+1));
char buffer[2]; buffer[0] = character; buffer[1] = 0;
char fg = colorvalue & 0xf;
if (fg == 0x8) fg = 0x7;
unsigned lum = ((fg & 0x8) >> 3)*127;
Genode::Color color(((fg & 0x4) >> 2)*127+lum, /* R+luminosity */
((fg & 0x2) >> 1)*127+lum, /* G+luminosity */
(fg & 0x1)*127+lum /* B+luminosity */);
Text_painter::paint(surface, where, default_font, color, buffer);
/* Checksum for comparing */
if (cmp_even) checksum1 += character;
else checksum2 += character;
}
}
/* compare checksums to detect idle buffer */
if (checksum1 == checksum2) {
unchanged++;
/* if we copy the same data 10 times, unmap the text buffer from guest */
if (unchanged == 10) {
Genode::Lock::Guard guard(_console_lock);
env()->rm_session()->detach((void *)_guest_fb);
env()->rm_session()->attach_at(_fb_ds, (Genode::addr_t)_guest_fb);
unchanged = 0;
fb_active = false;
Logging::printf("Deactivated text buffer loop.\n");
}
} else {
unchanged = 0;
framebuffer->refresh(0, 0, _fb_mode.width(), _fb_mode.height());
}
cmp_even = !cmp_even;
} else if (_regs && _guest_fb && _regs->mode != 0) {
if (!revoked) {
Genode::Lock::Guard guard(_console_lock);
env()->rm_session()->detach((void *)_guest_fb);
env()->rm_session()->attach_at(framebuffer->dataspace(),
(Genode::addr_t)_guest_fb);
/* if the VGA model expects a larger FB, pad to that size. */
if (_fb_size < _vm_fb_size) {
Genode::Ram_dataspace_capability _backup =
Genode::env()->ram_session()->alloc(_vm_fb_size-_fb_size);
env()->rm_session()->attach_at(_backup,
(Genode::addr_t) (_guest_fb+_fb_size));
}
revoked = true;
}
framebuffer->refresh(0, 0, _fb_mode.width(), _fb_mode.height());
}
timer.msleep(10);
}
input.for_each_event([&] (Input::Event const &ev) {
if (!fb_active) fb_active = true;
/* update mouse model (PS2) */
if (mouse_event(ev)) {
MessageInput msg(0x10001, _input_to_ps2mouse(ev));
_motherboard()->bus_input.send(msg);
}
if (ev.type() == Input::Event::PRESS) {
if (ev.code() <= 0xee) {
vkeyb.handle_keycode_press(ev.code());
}
}
if (ev.type() == Input::Event::RELEASE) {
if (ev.code() <= 0xee) { /* keyboard event */
vkeyb.handle_keycode_release(ev.code());
}
}
});
}
}
void Vancouver_console::register_host_operations(Motherboard &motherboard)
{
motherboard.bus_console. add(this, receive_static<MessageConsole>);
motherboard.bus_memregion.add(this, receive_static<MessageMemRegion>);
}
Vancouver_console::Vancouver_console(Synced_motherboard &mb,
Genode::size_t vm_fb_size,
Genode::Dataspace_capability fb_ds)
:
Thread_deprecated("vmm_console"),
_startup_lock(Genode::Lock::LOCKED),
_motherboard(mb), _pixels(0), _guest_fb(0), _fb_size(0),
_fb_ds(fb_ds), _vm_fb_size(vm_fb_size), _regs(0),
_left(false), _middle(false), _right(false)
{
start();
/* shake hands with console thread */
_startup_lock.lock();
_surface.construct(reinterpret_cast<Genode::Pixel_rgb565 *>(_pixels),
Genode::Surface_base::Area(_fb_mode.width(),
_fb_mode.height()));
}

View File

@ -21,59 +21,73 @@
#ifndef _CONSOLE_H_
#define _CONSOLE_H_
/* Genode includes */
/* base includes */
#include <base/env.h>
#include <dataspace/client.h>
#include <util/reconstructible.h>
#include <util/string.h>
/* os includes */
#include <framebuffer_session/connection.h>
#include <input/event.h>
#include <input_session/connection.h>
#include <timer_session/connection.h>
#include <dataspace/client.h>
#include <os/pixel_rgb565.h>
/* local includes */
#include "keyboard.h"
#include "synced_motherboard.h"
/* includes for I/O */
#include <base/env.h>
#include <util/list.h>
#include <input/event.h>
namespace Seoul {
class Console;
}
using Genode::List;
using Genode::Thread_deprecated;
class Vancouver_console : public Thread_deprecated<8192>, public StaticReceiver<Vancouver_console>
class Seoul::Console : public StaticReceiver<Seoul::Console>
{
private:
Genode::Lock _startup_lock;
Genode::Env &_env;
Motherboard &_unsynchronized_motherboard;
Synced_motherboard &_motherboard;
Genode::Lock _console_lock;
short *_pixels;
char *_guest_fb;
unsigned long _fb_size;
Genode::Constructible<Framebuffer::Connection> _framebuffer;
Genode::Constructible<Genode::Surface<Genode::Pixel_rgb565> > _surface;
Input::Connection _input = { _env };
Keyboard _vkeyb = { _motherboard };
short *_pixels = nullptr;
char *_guest_fb = nullptr;
unsigned long _fb_size = 0;
Genode::Dataspace_capability _fb_ds;
Genode::size_t _vm_fb_size;
VgaRegs *_regs;
VgaRegs *_regs = nullptr;
Framebuffer::Mode _fb_mode;
bool _left, _middle, _right;
bool _left = false;
bool _middle = false;
bool _right = false;
unsigned _timer;
unsigned _input_to_ps2mouse(Input::Event const &);
Genode::Signal_handler<Console> _signal_input
= { _env.ep(), *this, &Console::_handle_input };
void _handle_input();
unsigned _handle_fb();
public:
/* bus callbacks */
bool receive(MessageConsole &msg);
bool receive(MessageMemRegion &msg);
bool receive(MessageConsole &);
bool receive(MessageMemRegion &);
bool receive(MessageTimeout &);
void register_host_operations(Motherboard &);
/* initialisation */
void entry();
/**
* Constructor
*/
Vancouver_console(Synced_motherboard &,
Genode::size_t vm_fb_size,
Genode::Dataspace_capability fb_ds);
Console(Genode::Env &env, Synced_motherboard &, Motherboard &,
Genode::size_t vm_fb_size, Genode::Dataspace_capability fb_ds);
};
#endif /* _CONSOLE_H_ */

View File

@ -20,14 +20,9 @@
*/
/* Genode includes */
#include <base/allocator_avl.h>
#include <base/log.h>
#include <base/sleep.h>
#include <base/thread.h>
#include <block_session/connection.h>
#include <util/string.h>
#include <base/heap.h>
#include <base/lock.h>
/* VMM utility includes */
#include <vmm/utcb_guard.h>
@ -38,71 +33,52 @@
/* Seoul includes */
#include <host/dma.h>
static Genode::Signal_receiver* disk_receiver()
static Genode::Heap * disk_heap(Genode::Ram_session *ram = nullptr,
Genode::Region_map *rm = nullptr)
{
static Genode::Signal_receiver receiver;
return &receiver;
}
static Genode::Heap * disk_heap() {
using namespace Genode;
static Heap heap(env()->ram_session(), env()->rm_session());
static Genode::Heap heap(ram, rm);
return &heap;
}
static Genode::Heap * disk_heap_msg() {
using namespace Genode;
static Heap heap(env()->ram_session(), env()->rm_session(), 4096);
static Genode::Heap * disk_heap_msg(Genode::Env &env)
{
static Genode::Heap heap(&env.ram(), &env.rm(), 4096);
return &heap;
}
static Genode::Heap * disk_heap_avl() {
using namespace Genode;
static Heap heap(env()->ram_session(), env()->rm_session(), 4096);
static Genode::Heap * disk_heap_avl(Genode::Env &env)
{
static Genode::Heap heap(&env.ram(), &env.rm(), 4096);
return &heap;
}
Vancouver_disk::Vancouver_disk(Synced_motherboard &mb,
char * backing_store_base,
Genode::size_t backing_store_size)
Seoul::Disk::Disk(Genode::Env &env, Synced_motherboard &mb,
char * backing_store_base, Genode::size_t backing_store_size)
:
Thread_deprecated("vmm_disk"),
_env(env),
_motherboard(mb),
_backing_store_base(backing_store_base),
_backing_store_size(backing_store_size),
_tslab_msg(disk_heap_msg()),
_tslab_avl(disk_heap_avl())
_tslab_msg(disk_heap_msg(env)),
_tslab_avl(disk_heap_avl(env))
{
/* initialize disk heap */
disk_heap(&env.ram(), &env.rm());
/* initialize struct with 0 size */
for (int i=0; i < MAX_DISKS; i++) {
_diskcon[i].blk_size = 0;
}
start();
}
void Vancouver_disk::register_host_operations(Motherboard &motherboard)
void Seoul::Disk::register_host_operations(Motherboard &motherboard)
{
motherboard.bus_disk.add(this, receive_static<MessageDisk>);
}
void Seoul::Disk_signal::_signal() { _obj.handle_disk(_id); }
void Vancouver_disk::entry()
{
Logging::printf("Hello, this is Vancouver_disk.\n");
while (true) {
Genode::Signal signal = disk_receiver()->wait_for_signal();
Vancouver_disk_signal * disk_source =
reinterpret_cast<Vancouver_disk_signal *>(signal.context());
this->_signal_dispatch_entry(disk_source->disk_nr());
}
}
void Vancouver_disk::_signal_dispatch_entry(unsigned disknr)
void Seoul::Disk::handle_disk(unsigned disknr)
{
Block::Session::Tx::Source *source = _diskcon[disknr].blk_con->tx();
@ -179,7 +155,7 @@ void Vancouver_disk::_signal_dispatch_entry(unsigned disknr)
}
bool Vancouver_disk::receive(MessageDisk &msg)
bool Seoul::Disk::receive(MessageDisk &msg)
{
static Vmm::Utcb_guard::Utcb_backup utcb_backup;
Vmm::Utcb_guard guard(utcb_backup);
@ -191,23 +167,23 @@ bool Vancouver_disk::receive(MessageDisk &msg)
* If we receive a message for this disk the first time, create the
* structure for it.
*/
char label[16];
Genode::snprintf(label, 16, "VirtualDisk %u", msg.disknr);
Genode::String<16> label("VirtualDisk ", msg.disknr);
if (!_diskcon[msg.disknr].blk_size) {
try {
Genode::Allocator_avl * block_alloc =
new Genode::Allocator_avl(disk_heap());
new (disk_heap()) Genode::Allocator_avl(disk_heap());
_diskcon[msg.disknr].blk_con =
new Block::Connection(block_alloc, 4*512*1024, label);
_diskcon[msg.disknr].dispatcher =
new Vancouver_disk_signal(*disk_receiver(), *this,
&Vancouver_disk::_signal_dispatch_entry,
msg.disknr);
new (disk_heap()) Block::Connection(_env, block_alloc,
4*512*1024,
label.string());
_diskcon[msg.disknr].signal =
new (disk_heap()) Seoul::Disk_signal(_env.ep(), *this,
msg.disknr);
_diskcon[msg.disknr].blk_con->tx_channel()->sigh_ack_avail(
*_diskcon[msg.disknr].dispatcher);
_diskcon[msg.disknr].signal->sigh);
} catch (...) {
/* there is none. */
return false;
@ -234,8 +210,7 @@ bool Vancouver_disk::receive(MessageDisk &msg)
msg.params->sectors = _diskcon[msg.disknr].blk_cnt;
msg.params->sectorsize = _diskcon[msg.disknr].blk_size;
msg.params->maxrequestcount = _diskcon[msg.disknr].blk_cnt;
memcpy(msg.params->name, label, strlen(label));
msg.params->name[strlen(label)] = 0;
memcpy(msg.params->name, label.string(), label.length());
}
return true;
case MessageDisk::DISK_READ:
@ -328,7 +303,7 @@ bool Vancouver_disk::receive(MessageDisk &msg)
}
Vancouver_disk::~Vancouver_disk()
Seoul::Disk::~Disk()
{
/* XXX: Close all connections */
}

View File

@ -7,7 +7,7 @@
/*
* Copyright (C) 2012 Intel Corporation
* Copyright (C) 2013 Genode Labs GmbH
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
@ -19,13 +19,11 @@
* conditions of the GNU General Public License version 2.
*/
#ifndef _VANCOUVER_DISK_H_
#define _VANCOUVER_DISK_H_
#ifndef _DISK_H_
#define _DISK_H_
/* Genode includes */
#include <base/allocator_avl.h>
#include <base/printf.h>
#include <base/thread.h>
#include <block_session/connection.h>
#include <util/string.h>
#include <base/synced_allocator.h>
@ -33,31 +31,37 @@
/* local includes */
#include "synced_motherboard.h"
class Vancouver_disk;
namespace Seoul {
class Disk;
class Disk_signal;
}
class Vancouver_disk_signal : public Genode::Signal_dispatcher<Vancouver_disk>
class Seoul::Disk_signal
{
private:
unsigned _disk_nr;
Disk &_obj;
unsigned _id;
void _signal();
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) {}
Genode::Signal_handler<Disk_signal> const sigh;
unsigned disk_nr() { return _disk_nr; }
Disk_signal(Genode::Entrypoint &ep, Disk &obj, unsigned disk_nr)
:
_obj(obj), _id(disk_nr), sigh(ep, *this, &Disk_signal::_signal)
{ }
};
class Vancouver_disk : public Genode::Thread_deprecated<8192>, public StaticReceiver<Vancouver_disk>
class Seoul::Disk : public StaticReceiver<Seoul::Disk>
{
private:
Genode::Env &_env;
/* helper class to lookup a MessageDisk object */
class Avl_entry : public Genode::Avl_node<Avl_entry>
{
@ -91,7 +95,7 @@ class Vancouver_disk : public Genode::Thread_deprecated<8192>, public StaticRece
Block::Session::Operations ops;
Genode::size_t blk_size;
Block::sector_t blk_cnt;
Vancouver_disk_signal *dispatcher;
Disk_signal *signal;
} _diskcon[MAX_DISKS];
Synced_motherboard &_motherboard;
@ -113,25 +117,21 @@ class Vancouver_disk : public Genode::Thread_deprecated<8192>, public StaticRece
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);
Disk(Genode::Env &, Synced_motherboard &, char * backing_store_base,
Genode::size_t backing_store_size);
~Vancouver_disk();
~Disk();
void entry();
void handle_disk(unsigned);
bool receive(MessageDisk &msg);
void register_host_operations(Motherboard &);
};
#endif /* _VANCOUVER_DISK_H_ */
#endif /* _DISK_H_ */

View File

@ -26,14 +26,12 @@
#include <nul/vcpu.h>
Vancouver_keyboard::Vancouver_keyboard(Synced_motherboard &mb)
Seoul::Keyboard::Keyboard(Synced_motherboard &mb)
: _motherboard(mb), _flags(0) { }
void Vancouver_keyboard::handle_keycode_press(unsigned keycode)
bool Seoul::Keyboard::_map_keycode(unsigned &keycode, bool press)
{
unsigned orig_keycode = keycode;
switch (keycode) {
/* modifiers */
@ -43,9 +41,12 @@ void Vancouver_keyboard::handle_keycode_press(unsigned keycode)
case Input::KEY_RIGHTALT: _flags |= KBFLAG_RALT; keycode = 0x11; break;
case Input::KEY_LEFTCTRL: _flags |= KBFLAG_LCTRL; keycode = 0x14; break;
case Input::KEY_RIGHTCTRL: _flags |= KBFLAG_RCTRL; keycode = 0x14; break;
case Input::KEY_LEFTMETA: _flags |= KBFLAG_LWIN; keycode = 0x1f; return;
case Input::KEY_RIGHTMETA: _flags |= KBFLAG_RWIN; keycode = 0x27; return;
case Input::KEY_LEFTMETA: _flags |= KBFLAG_LWIN; keycode = 0x1f;
if (press) return false;
break;
case Input::KEY_RIGHTMETA: _flags |= KBFLAG_RWIN; keycode = 0x27;
if (press) return false;
break;
case Input::KEY_KPSLASH: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x35); break;
case Input::KEY_KPENTER: _flags |= KBFLAG_EXTEND0;
@ -80,9 +81,20 @@ void Vancouver_keyboard::handle_keycode_press(unsigned keycode)
if (keycode <= 0x53) {
keycode = GenericKeyboard::translate_sc1_to_sc2(keycode);
break;
} else return;
} else return false;
}
return true;
}
void Seoul::Keyboard::handle_keycode_press(unsigned keycode)
{
unsigned orig_keycode = keycode;
if (!_map_keycode(keycode, true))
return;
MessageInput msg(0x10000, _flags | keycode);
/* debug */
@ -108,58 +120,12 @@ void Vancouver_keyboard::handle_keycode_press(unsigned keycode)
}
void Vancouver_keyboard::handle_keycode_release(unsigned keycode)
void Seoul::Keyboard::handle_keycode_release(unsigned keycode)
{
_flags |= KBFLAG_RELEASE;
switch (keycode) {
/* modifiers */
case Input::KEY_LEFTSHIFT: _flags |= KBFLAG_LSHIFT; keycode = 0x12; break;
case Input::KEY_RIGHTSHIFT: _flags |= KBFLAG_RSHIFT; keycode = 0x59; break;
case Input::KEY_LEFTALT: _flags |= KBFLAG_LALT; keycode = 0x11; break;
case Input::KEY_RIGHTALT: _flags |= KBFLAG_RALT; keycode = 0x11; break;
case Input::KEY_LEFTCTRL: _flags |= KBFLAG_LCTRL; keycode = 0x14; break;
case Input::KEY_RIGHTCTRL: _flags |= KBFLAG_RCTRL; keycode = 0x14; break;
case Input::KEY_LEFTMETA: _flags |= KBFLAG_LWIN; keycode = 0x1f; break;
case Input::KEY_RIGHTMETA: _flags |= KBFLAG_RWIN; keycode = 0x27; break;
case Input::KEY_KPSLASH: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x35); break;
case Input::KEY_KPENTER: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x1c); break;
case Input::KEY_F11: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x57); break;
case Input::KEY_F12: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x58); break;
case Input::KEY_INSERT: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x52); break;
case Input::KEY_DELETE: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x53); break;
case Input::KEY_HOME: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x47); break;
case Input::KEY_END: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x4f); break;
case Input::KEY_PAGEUP: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x49); break;
case Input::KEY_PAGEDOWN: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x51); break;
case Input::KEY_LEFT: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x4b); break;
case Input::KEY_RIGHT: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x4d); break;
case Input::KEY_UP: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x48); break;
case Input::KEY_DOWN: _flags |= KBFLAG_EXTEND0;
keycode = GenericKeyboard::translate_sc1_to_sc2(0x50); break;
/* up to 0x53, the Genode key codes correspond to scan code set 1 */
default:
if (keycode <= 0x53) {
keycode = GenericKeyboard::translate_sc1_to_sc2(keycode);
break;
} else return;
}
if (!_map_keycode(keycode, false))
return;
MessageInput msg(0x10000, _flags | keycode);
_motherboard()->bus_input.send(msg);

View File

@ -30,19 +30,25 @@
/* local includes */
#include "synced_motherboard.h"
class Vancouver_keyboard
namespace Seoul {
class Keyboard;
}
class Seoul::Keyboard
{
private:
Synced_motherboard &_motherboard;
unsigned _flags;
bool _map_keycode(unsigned &, bool);
public:
/**
* Constructor
*/
Vancouver_keyboard(Synced_motherboard &);
Keyboard(Synced_motherboard &);
void handle_keycode_press(unsigned keycode);
void handle_keycode_release(unsigned keycode);

View File

@ -18,7 +18,7 @@
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
* Copyright (C) 2011-2017 Genode Labs GmbH
* Copyright (C) 2012 Intel Corporation
*
* This file is distributed under the terms of the GNU General Public License
@ -31,19 +31,21 @@
* conditions of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/component.h>
#include <util/touch.h>
#include <base/rpc_server.h>
#include <util/misc_math.h>
#include <rom_session/connection.h>
#include <rm_session/connection.h>
/* base includes */
#include <base/allocator_avl.h>
#include <base/attached_rom_dataspace.h>
#include <base/component.h>
#include <base/heap.h>
#include <base/rpc_server.h>
#include <base/synced_interface.h>
#include <rm_session/connection.h>
#include <rom_session/connection.h>
#include <util/touch.h>
#include <util/misc_math.h>
/* os includes */
#include <nic_session/connection.h>
#include <nic/packet_allocator.h>
#include <os/config.h>
#include <os/alarm.h>
#include <base/synced_interface.h>
#include <timer_session/connection.h>
#include <rtc_session/connection.h>
@ -88,57 +90,71 @@ Genode::Lock *utcb_lock()
}
/* timer service */
using Genode::Thread_deprecated;
using Genode::Alarm_scheduler;
using Genode::Alarm;
using Genode::Attached_rom_dataspace;
typedef Genode::Synced_interface<TimeoutList<32, void> > Synced_timeout_list;
class Alarm_thread : Thread_deprecated<4096>, public Alarm_scheduler
class Timeouts
{
private:
Timer::Connection _timer;
Alarm::Time _curr_time; /* jiffies value */
Synced_motherboard &_motherboard;
Synced_timeout_list &_timeouts;
/**
* Thread entry function
*/
void entry()
Genode::Signal_handler<Timeouts> _timeout_sigh;
void check_timeouts()
{
while (true) {
unsigned long long now = _motherboard()->clock()->time();
unsigned nr;
timevalue const now = _motherboard()->clock()->time();
while ((nr = _timeouts()->trigger(now))) {
unsigned nr;
MessageTimeout msg(nr, _timeouts()->timeout());
while ((nr = _timeouts()->trigger(now))) {
if (_timeouts()->cancel(nr) < 0)
Logging::printf("Timeout not cancelled.\n");
MessageTimeout msg(nr, _timeouts()->timeout());
_motherboard()->bus_timeout.send(msg);
}
if (_timeouts()->cancel(nr) < 0)
Logging::printf("Timeout not cancelled.\n");
_timer.usleep(1000);
_motherboard()->bus_timeout.send(msg);
}
unsigned long long next = _timeouts()->timeout();
if (next == ~0ULL)
return;
timevalue rel_timeout_us = _motherboard()->clock()->delta(next, 1000 * 1000);
if (rel_timeout_us == 0)
rel_timeout_us = 1;
_timer.trigger_once(rel_timeout_us);
}
public:
void reprogram()
{
Genode::Signal_transmitter(_timeout_sigh).submit();
}
/**
* Constructor
*/
Alarm_thread(Synced_motherboard &mb, Synced_timeout_list &timeouts)
: Thread_deprecated("alarm"), _curr_time(0), _motherboard(mb), _timeouts(timeouts)
{ start(); }
Timeouts(Genode::Env &env, Synced_motherboard &mb,
Synced_timeout_list &timeouts)
:
_timer(env),
_motherboard(mb),
_timeouts(timeouts),
_timeout_sigh(env.ep(), *this, &Timeouts::check_timeouts)
{
_timer.sigh(_timeout_sigh);
}
Alarm::Time curr_time() { return _curr_time; }
unsigned long long curr_time_long() { return _motherboard()->clock()->time(); }
};
@ -160,8 +176,9 @@ class Guest_memory
{
private:
Genode::Ram_dataspace_capability _ds;
Genode::Ram_dataspace_capability _fb_ds;
Genode::Env &_env;
Genode::Ram_dataspace_capability _ds;
Genode::Ram_dataspace_capability _fb_ds;
Genode::size_t _backing_store_size;
Genode::size_t _fb_size;
@ -192,10 +209,12 @@ class Guest_memory
* used as guest-physical and device memory,
* allocated from core's RAM service
*/
Guest_memory(Genode::size_t backing_store_size, Genode::size_t fb_size)
Guest_memory(Genode::Env &env, Genode::size_t backing_store_size,
Genode::size_t fb_size)
:
_ds(Genode::env()->ram_session()->alloc(backing_store_size-fb_size)),
_fb_ds(Genode::env()->ram_session()->alloc(fb_size)),
_env(env),
_ds(env.ram().alloc(backing_store_size-fb_size)),
_fb_ds(env.ram().alloc(fb_size)),
_backing_store_size(backing_store_size),
_fb_size(fb_size),
_local_addr(0),
@ -206,8 +225,8 @@ class Guest_memory
/*
* RAM used as backing store for guest-physical memory
*/
_local_addr = Genode::env()->rm_session()->attach(_ds);
_fb_addr = Genode::env()->rm_session()->attach_at(_fb_ds,
_local_addr = env.rm().attach(_ds);
_fb_addr = env.rm().attach_at(_fb_ds,
((Genode::addr_t) _local_addr)+backing_store_size-fb_size);
} catch (Genode::Rm_session::Region_conflict) {
@ -218,11 +237,11 @@ class Guest_memory
~Guest_memory()
{
/* detach and free backing store */
Genode::env()->rm_session()->detach((void *)_local_addr);
Genode::env()->ram_session()->free(_ds);
_env.rm().detach((void *)_local_addr);
_env.ram().free(_ds);
Genode::env()->rm_session()->detach((void *)_fb_addr);
Genode::env()->ram_session()->free(_fb_ds);
_env.rm().detach((void *)_fb_addr);
_env.ram().free(_fb_ds);
}
/**
@ -842,15 +861,15 @@ class Vcpu_dispatcher : public Vcpu_handler,
};
const void * _forward_pkt;
class Machine : public StaticReceiver<Machine>
{
private:
Genode::Env &_env;;
Genode::Rom_connection _hip_rom;
Genode::Env &_env;
Genode::Heap &_heap;
Attached_rom_dataspace _hip_rom = { _env, "hypervisor_info_page" };
Genode::Cpu_connection _cpu_session = { _env, "Seoul vCPUs", Genode::Cpu_session::PRIORITY_LIMIT / 16 };
Hip * const _hip;
Clock _clock;
Genode::Lock _motherboard_lock;
@ -861,15 +880,14 @@ class Machine : public StaticReceiver<Machine>
Synced_timeout_list _timeouts;
Guest_memory &_guest_memory;
Boot_module_provider &_boot_modules;
Alarm_thread *_alarm_thread;
Genode::Pd_connection *_pd_vcpus = nullptr;
bool _alloc_fb_mem; /* For detecting FB alloc message */
Timeouts _alarm_thread = { _env, _motherboard, _timeouts };
bool _colocate_vm_vmm;
unsigned short _vcpus_up;
unsigned short _vcpus_up = 0;
Nic::Session *_nic;
Rtc::Session *_rtc;
bool _alloc_fb_mem = false; /* For detecting FB alloc message */
Genode::Pd_connection *_pd_vcpus = nullptr;
Seoul::Network *_nic = nullptr;
Rtc::Session *_rtc = nullptr;
public:
@ -943,19 +961,17 @@ class Machine : public StaticReceiver<Machine>
_vcpus_up ++;
long const prio = Genode::Cpu_session::PRIORITY_LIMIT / 16;
static Genode::Cpu_connection * cpu_session = new (Genode::env()->heap()) Genode::Cpu_connection("Seoul vCPUs", prio);
Genode::Affinity::Space cpu_space = cpu_session->affinity_space();
Genode::Affinity::Space cpu_space = _cpu_session.affinity_space();
Genode::Affinity::Location location = cpu_space.location_of_index(_vcpus_up);
Vmm::Vcpu_thread * vcpu_thread;
if (_colocate_vm_vmm)
vcpu_thread = new Vmm::Vcpu_same_pd(cpu_session, location, _env.pd_session_cap(), Vcpu_dispatcher::STACK_SIZE);
vcpu_thread = new Vmm::Vcpu_same_pd(&_cpu_session, location, _env.pd_session_cap(), Vcpu_dispatcher::STACK_SIZE);
else {
if (!_pd_vcpus)
_pd_vcpus = new Genode::Pd_connection("VM");
_pd_vcpus = new Genode::Pd_connection(_env, "VM");
vcpu_thread = new Vmm::Vcpu_other_pd(cpu_session, location, *_pd_vcpus);
vcpu_thread = new Vmm::Vcpu_other_pd(&_cpu_session, location, *_pd_vcpus);
}
Vcpu_dispatcher *vcpu_dispatcher =
@ -967,7 +983,7 @@ class Machine : public StaticReceiver<Machine>
_hip->has_feature_svm(),
_hip->has_feature_vmx(),
vcpu_thread,
cpu_session,
&_cpu_session,
location);
msg.value = vcpu_dispatcher->sel_sm_ec();
@ -1020,7 +1036,8 @@ class Machine : public StaticReceiver<Machine>
*/
Genode::size_t data_len = 0;
try {
data_len = _boot_modules.data(index, data_dst, dst_len);
data_len = _boot_modules.data(_env, index,
data_dst, dst_len);
} catch (Boot_module_provider::Destination_buffer_too_small) {
Logging::panic("could not load module, destination buffer too small\n");
return false;
@ -1069,45 +1086,37 @@ class Machine : public StaticReceiver<Machine>
}
case MessageHostOp::OP_GET_MAC:
{
Nic::Packet_allocator *tx_block_alloc =
new (Genode::env()->heap()) Nic::Packet_allocator(Genode::env()->heap());
enum {
PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
BUF_SIZE = Nic::Session::QUEUE_SIZE * PACKET_SIZE,
};
try {
_nic = new Nic::Connection(tx_block_alloc, BUF_SIZE, BUF_SIZE);
} catch (...) {
Logging::printf("No NIC connection possible!\n");
if (_nic) {
Logging::printf("Solely one network connection supported\n");
return false;
}
Logging::printf("Our mac address is %2x:%2x:%2x:%2x:%2x:%2x\n",
_nic->mac_address().addr[0],
_nic->mac_address().addr[1],
_nic->mac_address().addr[2],
_nic->mac_address().addr[3],
_nic->mac_address().addr[4],
_nic->mac_address().addr[5]
);
msg.mac = ((Genode::uint64_t)_nic->mac_address().addr[0] & 0xff) << 40 |
((Genode::uint64_t)_nic->mac_address().addr[1] & 0xff) << 32 |
((Genode::uint64_t)_nic->mac_address().addr[2] & 0xff) << 24 |
((Genode::uint64_t)_nic->mac_address().addr[3] & 0xff) << 16 |
((Genode::uint64_t)_nic->mac_address().addr[4] & 0xff) << 8 |
((Genode::uint64_t)_nic->mac_address().addr[5] & 0xff);
try {
_nic = new (_heap) Seoul::Network(_env, _heap,
_motherboard);
} catch (...) {
Logging::printf("Creating network connection failed\n");
return false;
}
/* start receiver thread for this MAC */
Vancouver_network * netreceiver = new Vancouver_network(_motherboard, _nic);
assert(netreceiver);
Nic::Mac_address mac = _nic->mac_address();
Logging::printf("Mac address: %2x:%2x:%2x:%2x:%2x:%2x\n",
mac.addr[0], mac.addr[1], mac.addr[2],
mac.addr[3], mac.addr[4], mac.addr[5]);
msg.mac = ((Genode::uint64_t)mac.addr[0] & 0xff) << 40 |
((Genode::uint64_t)mac.addr[1] & 0xff) << 32 |
((Genode::uint64_t)mac.addr[2] & 0xff) << 24 |
((Genode::uint64_t)mac.addr[3] & 0xff) << 16 |
((Genode::uint64_t)mac.addr[4] & 0xff) << 8 |
((Genode::uint64_t)mac.addr[5] & 0xff);
return true;
}
default:
PWRN("HostOp %d not implemented", msg.type);
Logging::printf("HostOp %d not implemented\n", msg.type);
return false;
}
}
@ -1127,22 +1136,21 @@ class Machine : public StaticReceiver<Machine>
if (verbose_debug)
Logging::printf("TIMER_NEW\n");
if (_alarm_thread == NULL) {
Logging::printf("Creating alarm thread\n");
_alarm_thread = new Alarm_thread(_motherboard, _timeouts);
}
msg.nr = _timeouts()->alloc();
return true;
case MessageTimer::TIMER_REQUEST_TIMEOUT:
if (_timeouts()->request(msg.nr, msg.abstime) < 0)
{
int res = _timeouts()->request(msg.nr, msg.abstime);
if (res == 0)
_alarm_thread.reprogram();
else
if (res < 0)
Logging::printf("Could not program timeout.\n");
return true;
}
default:
return false;
};
@ -1157,7 +1165,7 @@ class Machine : public StaticReceiver<Machine>
if (!_rtc) {
try {
_rtc = new Rtc::Connection;
_rtc = new Rtc::Connection(_env);
} catch (...) {
Logging::printf("No RTC present, returning dummy time.\n");
msg.wallclocktime = msg.timestamp = 0;
@ -1185,44 +1193,14 @@ class Machine : public StaticReceiver<Machine>
{
if (msg.type != MessageNetwork::PACKET) return false;
if (!_nic)
return false;
Genode::Lock::Guard guard(*utcb_lock());
Vmm::Utcb_guard utcb_guard(utcb_backup);
if (msg.buffer == _forward_pkt) {
/* don't end in an endless forwarding loop */
return false;
}
/* allocate transmit packet */
Nic::Packet_descriptor tx_packet;
try {
tx_packet = _nic->tx()->alloc_packet(msg.len);
} catch (Nic::Session::Tx::Source::Packet_alloc_failed) {
Logging::printf("error: tx packet alloc failed\n");
return false;
}
/* fill packet with content */
char *tx_content = _nic->tx()->packet_content(tx_packet);
_forward_pkt = tx_content;
for (unsigned i = 0; i < msg.len; i++) {
tx_content[i] = msg.buffer[i];
}
_nic->tx()->submit_packet(tx_packet);
/* wait for acknowledgement */
Nic::Packet_descriptor ack_tx_packet = _nic->tx()->get_acked_packet();
if (ack_tx_packet.size() != tx_packet.size()
|| ack_tx_packet.offset() != tx_packet.offset()) {
Logging::printf("error: unexpected acked packet\n");
}
/* release sent packet to free the space in the tx communication buffer */
_nic->tx()->release_packet(tx_packet);
return true;
return _nic->transmit(msg.buffer, msg.len);
}
bool receive(MessagePciConfig &msg)
@ -1251,12 +1229,12 @@ class Machine : public StaticReceiver<Machine>
/**
* Constructor
*/
Machine(Genode::Env &env, Boot_module_provider &boot_modules,
Machine(Genode::Env &env, Genode::Heap &heap,
Boot_module_provider &boot_modules,
Guest_memory &guest_memory, bool colocate)
:
_env(env),
_hip_rom(_env, "hypervisor_info_page"),
_hip(Genode::env()->rm_session()->attach(_hip_rom.dataspace())),
_env(env), _heap(heap),
_hip(_hip_rom.local_addr<Hip>()),
_clock(_hip->tsc_freq*1000),
_motherboard_lock(Genode::Lock::LOCKED),
_unsynchronized_motherboard(&_clock, _hip),
@ -1264,8 +1242,7 @@ class Machine : public StaticReceiver<Machine>
_timeouts(_timeouts_lock, &_unsynchronized_timeouts),
_guest_memory(guest_memory),
_boot_modules(boot_modules),
_colocate_vm_vmm(colocate),
_vcpus_up(0)
_colocate_vm_vmm(colocate)
{
_timeouts()->init();
@ -1307,11 +1284,12 @@ class Machine : public StaticReceiver<Machine>
char name[MODEL_NAME_MAX_LEN];
node.type_name(name, sizeof(name));
PINF("device: %s", name);
Genode::log("device: ", (char const *)name);
Device_model_info *dmi = device_model_registry()->lookup(name);
if (!dmi) {
PERR("configuration error: device model '%s' does not exist", name);
Genode::error("configuration error: device model '",
(char const *)name, "' does not exist");
throw Config_error();
}
@ -1330,7 +1308,7 @@ class Machine : public StaticReceiver<Machine>
Xml_node::Attribute arg = node.attribute(dmi->arg_names[i]);
arg.value(&argv[i]);
PINF(" arg[%d]: 0x%x", i, (int)argv[i]);
Genode::log(" arg[", i, "]: ", Genode::Hex(argv[i]));
}
catch (Xml_node::Nonexistent_attribute) { }
}
@ -1353,9 +1331,10 @@ class Machine : public StaticReceiver<Machine>
*/
void boot()
{
PINF("VM and VMM are %s. VM is starting with %u %s.",
_colocate_vm_vmm ? "co-located" : "not co-located",
_vcpus_up, _vcpus_up > 1 ? "vCPUs" : "vCPU");
Genode::log("VM and VMM are ",
_colocate_vm_vmm ? "co-located" : "not co-located",
". VM is starting with ", _vcpus_up, " vCPU",
_vcpus_up > 1 ? "s" : "");
/* init VCPUs */
for (VCpu *vcpu = _unsynchronized_motherboard.last_vcpu; vcpu; vcpu = vcpu->get_last()) {
@ -1395,19 +1374,13 @@ class Machine : public StaticReceiver<Machine>
Synced_motherboard &motherboard() { return _motherboard; }
Motherboard &unsynchronized_motherboard() { return _unsynchronized_motherboard; }
Genode::Lock &motherboard_lock() { return _motherboard_lock; }
~Machine()
{
Genode::env()->rm_session()->detach(_hip);
}
};
extern unsigned long _prog_img_beg; /* begin of program image (link address) */
extern unsigned long _prog_img_end; /* end of program image */
extern void heap_init_env(Genode::Heap *);
void Component::construct(Genode::Env &env)
{
@ -1415,6 +1388,8 @@ void Component::construct(Genode::Env &env)
Genode::addr_t vm_size;
unsigned colocate = 1; /* by default co-locate VM and VMM in same PD */
static Attached_rom_dataspace config(env, "config");
{
/*
* Reserve complete lower address space so that nobody else can take
@ -1423,13 +1398,12 @@ void Component::construct(Genode::Env &env)
* reservation will be dropped when this scope is left and re-acquired
* with the actual VM size which is determined below inside this scope.
*/
Vmm::Virtual_reservation
reservation(Genode::Thread::stack_area_virtual_base());
Vmm::Virtual_reservation reservation(env, Genode::Thread::stack_area_virtual_base());
Genode::printf("--- Vancouver VMM starting ---\n");
Genode::log("--- Vancouver VMM starting ---");
/* request max available memory */
vm_size = Genode::env()->ram_session()->avail();
vm_size = env.ram().avail();
/* reserve some memory for the VMM */
vm_size -= 8 * 1024 * 1024;
/* calculate max memory for the VM */
@ -1437,7 +1411,7 @@ void Component::construct(Genode::Env &env)
/* Find out framebuffer size (default: 4 MiB) */
try {
Genode::Xml_node node = Genode::config()->xml_node().sub_node("machine").sub_node("vga");
Genode::Xml_node node = config.xml().sub_node("machine").sub_node("vga");
Genode::Xml_node::Attribute arg = node.attribute("fb_size");
unsigned long val = 0;
@ -1447,76 +1421,83 @@ void Component::construct(Genode::Env &env)
/* read out whether VM and VMM should be colocated or not */
try {
Genode::config()->xml_node().attribute("colocate").value(&colocate);
config.xml().attribute("colocate").value(&colocate);
} catch (...) { }
}
if (colocate)
/* re-adjust reservation to actual VM size */
static Vmm::Virtual_reservation reservation(vm_size);
static Vmm::Virtual_reservation reservation(env, vm_size);
/* setup guest memory */
static Guest_memory guest_memory(vm_size, fb_size);
static Guest_memory guest_memory(env, vm_size, fb_size);
typedef Genode::Hex_range<unsigned long> Hex_range;
/* diagnostic messages */
if (colocate)
Genode::printf("[0x%012lx, 0x%012lx) - %lu MiB - VM accessible "
"memory\n", 0UL, vm_size, vm_size / 1024 / 1024);
Genode::log(Hex_range(0UL, vm_size), " - ", vm_size / 1024 / 1024,
" MiB - VM accessible memory");
if (guest_memory.backing_store_local_base())
Genode::printf("[0x%12p, 0x%12p) - %lu MiB - VMM accessible shadow "
"mapping of VM memory \n",
guest_memory.backing_store_local_base(),
guest_memory.backing_store_local_base() +
guest_memory.remaining_size, vm_size / 1024 / 1024);
Genode::log(Hex_range((unsigned long)guest_memory.backing_store_local_base(),
guest_memory.remaining_size),
" - ", vm_size / 1024 / 1024, " MiB",
" - VMM accessible shadow mapping of VM memory");
if (guest_memory.backing_store_fb_local_base())
Genode::printf("[0x%12p, 0x%12p) - %lu MiB - VMM accessible "
"framebuffer memory of VM\n",
guest_memory.backing_store_fb_local_base(),
guest_memory.backing_store_fb_local_base() + fb_size,
fb_size / 1024 / 1024);
Genode::log(Hex_range((unsigned long)guest_memory.backing_store_fb_local_base(),
fb_size),
" - ", fb_size / 1024 / 1024, " MiB"
" - VMM accessible framebuffer memory of VM");
Genode::printf("[0x%012lx, 0x%012lx) - Genode stack area\n",
Genode::Thread::stack_area_virtual_base(),
Genode::Thread::stack_area_virtual_base() +
Genode::Thread::stack_area_virtual_size());
Genode::log(Hex_range(Genode::Thread::stack_area_virtual_base(),
Genode::Thread::stack_area_virtual_size()),
" - Genode stack area");
Genode::printf("[0x%012lx, 0x%012lx) - VMM program image\n",
(Genode::addr_t)&_prog_img_beg,
(Genode::addr_t)&_prog_img_end);
Genode::log(Hex_range((Genode::addr_t)&_prog_img_beg,
(Genode::addr_t)&_prog_img_end -
(Genode::addr_t)&_prog_img_beg),
" - VMM program image");
if (!guest_memory.backing_store_local_base() ||
!guest_memory.backing_store_fb_local_base()) {
PERR("Not enough space left for %s - exit",
guest_memory.backing_store_local_base() ? "framebuffer" : "VMM");
Genode::error("Not enough space left for ",
guest_memory.backing_store_local_base() ? "framebuffer"
: "VMM");
env.parent().exit(-1);
return;
}
Genode::printf("\n--- Setup VM ---\n");
Genode::log("\n--- Setup VM ---");
static Genode::Heap heap(env.ram(), env.rm());
heap_init_env(&heap);
static Boot_module_provider
boot_modules(Genode::config()->xml_node().sub_node("multiboot"));
boot_modules(config.xml().sub_node("multiboot"));
/* create the PC machine based on the configuration given */
static Machine machine(env, boot_modules, guest_memory, colocate);
static Machine machine(env, heap, boot_modules, guest_memory, colocate);
/* create console thread */
static Vancouver_console vcon(machine.motherboard(), fb_size, guest_memory.fb_ds());
static Seoul::Console vcon(env, machine.motherboard(),
machine.unsynchronized_motherboard(), fb_size,
guest_memory.fb_ds());
vcon.register_host_operations(machine.unsynchronized_motherboard());
/* create disk thread */
static Vancouver_disk vdisk(machine.motherboard(),
guest_memory.backing_store_local_base(),
guest_memory.backing_store_size());
static Seoul::Disk vdisk(env, machine.motherboard(),
guest_memory.backing_store_local_base(),
guest_memory.backing_store_size());
vdisk.register_host_operations(machine.unsynchronized_motherboard());
machine.setup_devices(Genode::config()->xml_node().sub_node("machine"));
machine.setup_devices(config.xml().sub_node("machine"));
Genode::printf("\n--- Booting VM ---\n");
Genode::log("\n--- Booting VM ---");
machine.boot();
}

View File

@ -1,12 +1,13 @@
/*
* \brief Network receive handler per MAC address
* \author Markus Partheymueller
* \author Alexander Boettcher
* \date 2012-07-31
*/
/*
* Copyright (C) 2012 Intel Corporation
* Copyright (C) 2013 Genode Labs GmbH
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
@ -21,29 +22,68 @@
/* local includes */
#include "network.h"
extern const void * _forward_pkt;
Vancouver_network::Vancouver_network(Synced_motherboard &mb, Nic::Session *nic)
: Thread_deprecated("vmm_network"), _motherboard(mb), _nic(nic)
Seoul::Network::Network(Genode::Env &env, Genode::Heap &heap,
Synced_motherboard &mb)
:
_motherboard(mb), _tx_block_alloc(&heap),
_nic(env, &_tx_block_alloc, BUF_SIZE, BUF_SIZE),
_packet_avail(env.ep(), *this, &Network::_handle_packets)
{
start();
_nic.rx_channel()->sigh_packet_avail(_packet_avail);
}
void Vancouver_network::entry()
void Seoul::Network::_handle_packets()
{
while (true) {
Nic::Packet_descriptor rx_packet = _nic->rx()->get_packet();
while (_nic.rx()->packet_avail()) {
Nic::Packet_descriptor rx_packet = _nic.rx()->get_packet();
/* send it to the network bus */
char * rx_content = _nic->rx()->packet_content(rx_packet);
char * rx_content = _nic.rx()->packet_content(rx_packet);
_forward_pkt = rx_content;
MessageNetwork msg((unsigned char *)rx_content, rx_packet.size(), 0);
_motherboard()->bus_network.send(msg);
_forward_pkt = 0;
/* acknowledge received packet */
_nic->rx()->acknowledge_packet(rx_packet);
_nic.rx()->acknowledge_packet(rx_packet);
}
}
bool Seoul::Network::transmit(void const * const packet, Genode::size_t len)
{
if (packet == _forward_pkt)
/* don't end in an endless forwarding loop */
return false;
/* allocate transmit packet */
Nic::Packet_descriptor tx_packet;
try {
tx_packet = _nic.tx()->alloc_packet(len);
} catch (Nic::Session::Tx::Source::Packet_alloc_failed) {
Logging::printf("error: tx packet alloc failed\n");
return false;
}
/* fill packet with content */
char * const tx_content = _nic.tx()->packet_content(tx_packet);
_forward_pkt = tx_content;
memcpy(tx_content, packet, len);
_nic.tx()->submit_packet(tx_packet);
/* wait for acknowledgement */
Nic::Packet_descriptor ack_tx_packet = _nic.tx()->get_acked_packet();
if (ack_tx_packet.size() != tx_packet.size() ||
ack_tx_packet.offset() != tx_packet.offset())
Logging::printf("error: unexpected acked packet\n");
/* release sent packet to free the space in the tx communication buffer */
_nic.tx()->release_packet(tx_packet);
return true;
}

View File

@ -1,12 +1,13 @@
/*
* \brief Network receive handler per MAC address
* \author Markus Partheymueller
* \author Alexander Boettcher
* \date 2012-07-31
*/
/*
* Copyright (C) 2012 Intel Corporation
* Copyright (C) 2013 Genode Labs GmbH
* Copyright (C) 2013-2017 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
@ -21,31 +22,45 @@
#ifndef _NETWORK_H_
#define _NETWORK_H_
/* Genode includes */
/* base includes */
#include <base/heap.h>
/* os includes */
#include <nic_session/connection.h>
#include <nic/packet_allocator.h>
/* local includes */
#include "synced_motherboard.h"
using Genode::List;
using Genode::Thread_deprecated;
namespace Seoul {
class Network;
}
class Vancouver_network : public Thread_deprecated<4096>
class Seoul::Network
{
private:
Synced_motherboard &_motherboard;
Nic::Session *_nic;
enum {
PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
BUF_SIZE = Nic::Session::QUEUE_SIZE * PACKET_SIZE,
};
Synced_motherboard &_motherboard;
Nic::Packet_allocator _tx_block_alloc;
Nic::Connection _nic;
Genode::Signal_handler<Network> const _packet_avail;
void const * _forward_pkt = nullptr;
void _handle_packets();
public:
/* initialisation */
void entry();
Network(Genode::Env &, Genode::Heap &, Synced_motherboard &);
/**
* Constructor
*/
Vancouver_network(Synced_motherboard &, Nic::Session *);
Nic::Mac_address mac_address() { return _nic.mac_address(); }
bool transmit(void const * const packet, Genode::size_t len);
};
#endif /* _NETWORK_H_ */

View File

@ -14,6 +14,7 @@
/* Genode includes */
#include <base/printf.h>
#include <base/env.h>
#include <base/heap.h>
#include <base/sleep.h>
#include <base/thread.h>
@ -65,7 +66,7 @@ void Logging::vprintf(const char *format, va_list &ap)
Genode::printf("VMM: ");
Genode::printf(format);
PWRN("Logging::vprintf not implemented");
Genode::error("Logging::vprintf not implemented");
*(Utcb_backup *)Genode::Thread::myself()->utcb() = utcb_backup;
}
@ -86,25 +87,31 @@ void Logging::panic(const char *format, ...)
Genode::sleep_forever();
}
static Genode::Allocator * heap = nullptr;
void heap_init_env(Genode::Heap *h)
{
heap = h;
}
static void *heap_alloc(size_t size)
{
void *res = Genode::env()->heap()->alloc(size);
void *res = heap->alloc(size);
if (res)
return res;
PERR("out of memory");
Genode::error("out of memory");
Genode::sleep_forever();
}
static void heap_free(void * ptr)
{
if (Genode::env()->heap()->need_size_for_free()) {
PWRN("leaking memory");
if (heap->need_size_for_free()) {
Genode::warning("leaking memory");
return;
}
Genode::env()->heap()->free(ptr, 0);
heap->free(ptr, 0);
}
@ -141,7 +148,7 @@ void *operator new (size_t size)
void operator delete[](void *ptr)
{
if (verbose_memory_leak)
PWRN("delete[] not implemented");
Genode::warning("delete[] not implemented ", ptr);
}
void operator delete (void * ptr)

View File

@ -5,7 +5,7 @@ SEOUL_GENODE_DIR = $(SEOUL_CONTRIB_DIR)/genode
REQUIRES += nova
LIBS += base-nova blit alarm seoul_libc_support config
LIBS += base-nova blit seoul_libc_support
SRC_CC = main.cc nova_user_env.cc device_model_registry.cc
SRC_CC += console.cc keyboard.cc network.cc disk.cc
SRC_BIN = mono.tff