diff --git a/repos/ports/include/vmm/guest_memory.h b/repos/ports/include/vmm/guest_memory.h index 114c87a7d3..a6515141d6 100644 --- a/repos/ports/include/vmm/guest_memory.h +++ b/repos/ports/include/vmm/guest_memory.h @@ -26,7 +26,8 @@ #define _INCLUDE__VMM__GUEST_MEMORY_H_ /* Genode includes */ -#include +#include +#include #include #include @@ -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_ */ diff --git a/repos/ports/include/vmm/vcpu_thread.h b/repos/ports/include/vmm/vcpu_thread.h index 20a6a5e6d7..e3a26e5a2b 100644 --- a/repos/ports/include/vmm/vcpu_thread.h +++ b/repos/ports/include/vmm/vcpu_thread.h @@ -16,7 +16,6 @@ /* Genode includes */ #include -#include #include #include #include diff --git a/repos/ports/run/seoul-disc.run b/repos/ports/run/seoul-disc.run index 82fb29fb05..de132f7403 100644 --- a/repos/ports/run/seoul-disc.run +++ b/repos/ports/run/seoul-disc.run @@ -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 diff --git a/repos/ports/run/seoul-genode.run b/repos/ports/run/seoul-genode.run index 9a07ec2799..ddc9814c17 100644 --- a/repos/ports/run/seoul-genode.run +++ b/repos/ports/run/seoul-genode.run @@ -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 {} diff --git a/repos/ports/src/app/seoul/boot_module_provider.h b/repos/ports/src/app/seoul/boot_module_provider.h index d5e554501f..5e239c41fc 100644 --- a/repos/ports/src/app/seoul/boot_module_provider.h +++ b/repos/ports/src/app/seoul/boot_module_provider.h @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -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")) { diff --git a/repos/ports/src/app/seoul/console.cc b/repos/ports/src/app/seoul/console.cc index 22438ad654..4ae97ef9d5 100644 --- a/repos/ports/src/app/seoul/console.cc +++ b/repos/ports/src/app/seoul/console.cc @@ -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 includes */ #include /* nitpicker graphics backend */ -#include #include #include /* 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); + motherboard.bus_memregion.add(this, receive_static); + motherboard.bus_timeout .add(this, receive_static); + + 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 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); - motherboard.bus_memregion.add(this, receive_static); -} - - -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(_pixels), + Genode::Surface_base::Area(_fb_mode.width(), + _fb_mode.height())); } diff --git a/repos/ports/src/app/seoul/console.h b/repos/ports/src/app/seoul/console.h index 5eff4648e8..06c5b30bd2 100644 --- a/repos/ports/src/app/seoul/console.h +++ b/repos/ports/src/app/seoul/console.h @@ -21,59 +21,73 @@ #ifndef _CONSOLE_H_ #define _CONSOLE_H_ -/* Genode includes */ +/* base includes */ +#include +#include +#include #include + +/* os includes */ #include +#include #include #include -#include + +#include /* local includes */ +#include "keyboard.h" #include "synced_motherboard.h" -/* includes for I/O */ -#include -#include -#include +namespace Seoul { + class Console; +} -using Genode::List; -using Genode::Thread_deprecated; - -class Vancouver_console : public Thread_deprecated<8192>, public StaticReceiver +class Seoul::Console : public StaticReceiver { 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; + Genode::Constructible > _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 _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_ */ diff --git a/repos/ports/src/app/seoul/disk.cc b/repos/ports/src/app/seoul/disk.cc index 4ee4f49bc6..edb0df574f 100644 --- a/repos/ports/src/app/seoul/disk.cc +++ b/repos/ports/src/app/seoul/disk.cc @@ -20,14 +20,9 @@ */ /* Genode includes */ -#include #include -#include -#include #include -#include #include -#include /* VMM utility includes */ #include @@ -38,71 +33,52 @@ /* Seoul includes */ #include -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); } +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(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 */ } diff --git a/repos/ports/src/app/seoul/disk.h b/repos/ports/src/app/seoul/disk.h index 66cfc80a01..26ae7864a6 100644 --- a/repos/ports/src/app/seoul/disk.h +++ b/repos/ports/src/app/seoul/disk.h @@ -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 -#include -#include #include #include #include @@ -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 +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(sig_rec, obj, member), - _disk_nr(disk_nr) {} + Genode::Signal_handler 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 +class Seoul::Disk : public StaticReceiver { private: + Genode::Env &_env; + /* helper class to lookup a MessageDisk object */ class Avl_entry : public Genode::Avl_node { @@ -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 _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_ */ diff --git a/repos/ports/src/app/seoul/keyboard.cc b/repos/ports/src/app/seoul/keyboard.cc index 0e3601bd0d..c4508393af 100644 --- a/repos/ports/src/app/seoul/keyboard.cc +++ b/repos/ports/src/app/seoul/keyboard.cc @@ -26,14 +26,12 @@ #include -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); diff --git a/repos/ports/src/app/seoul/keyboard.h b/repos/ports/src/app/seoul/keyboard.h index d125d3d258..742056651e 100644 --- a/repos/ports/src/app/seoul/keyboard.h +++ b/repos/ports/src/app/seoul/keyboard.h @@ -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); diff --git a/repos/ports/src/app/seoul/main.cc b/repos/ports/src/app/seoul/main.cc index 707619014f..b3849c28ba 100644 --- a/repos/ports/src/app/seoul/main.cc +++ b/repos/ports/src/app/seoul/main.cc @@ -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 -#include -#include -#include -#include -#include +/* base includes */ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* os includes */ #include #include -#include -#include -#include #include #include @@ -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 > 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 _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 { 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 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 _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 _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 */ 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 } 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 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 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 { 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 /** * 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()), _clock(_hip->tsc_freq*1000), _motherboard_lock(Genode::Lock::LOCKED), _unsynchronized_motherboard(&_clock, _hip), @@ -1264,8 +1242,7 @@ class Machine : public StaticReceiver _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 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 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 */ 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 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 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(); } diff --git a/repos/ports/src/app/seoul/network.cc b/repos/ports/src/app/seoul/network.cc index 1d3b9f617b..330a8ece2f 100644 --- a/repos/ports/src/app/seoul/network.cc +++ b/repos/ports/src/app/seoul/network.cc @@ -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; +} diff --git a/repos/ports/src/app/seoul/network.h b/repos/ports/src/app/seoul/network.h index 83aab368ea..4154ffcaef 100644 --- a/repos/ports/src/app/seoul/network.h +++ b/repos/ports/src/app/seoul/network.h @@ -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 + +/* os includes */ #include +#include /* 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 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_ */ diff --git a/repos/ports/src/app/seoul/nova_user_env.cc b/repos/ports/src/app/seoul/nova_user_env.cc index d863f87681..87e7960321 100644 --- a/repos/ports/src/app/seoul/nova_user_env.cc +++ b/repos/ports/src/app/seoul/nova_user_env.cc @@ -14,6 +14,7 @@ /* Genode includes */ #include #include +#include #include #include @@ -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) diff --git a/repos/ports/src/app/seoul/target.inc b/repos/ports/src/app/seoul/target.inc index f4a63b1154..bd4b3c1d25 100644 --- a/repos/ports/src/app/seoul/target.inc +++ b/repos/ports/src/app/seoul/target.inc @@ -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