diff --git a/repos/ports/run/seoul-auto.run b/repos/ports/run/seoul-auto.run index 07fdd8984a..bb7ecb3146 100644 --- a/repos/ports/run/seoul-auto.run +++ b/repos/ports/run/seoul-auto.run @@ -71,7 +71,7 @@ foreach binary $guest_os_binaries { source ${genode_dir}/repos/ports/run/seoul.inc -append qemu_args " -cpu phenom " +append qemu_args " -cpu phenom -smp 2 " append qemu_args " -net nic,model=e1000 " append qemu_args " -nographic " diff --git a/repos/ports/run/seoul.inc b/repos/ports/run/seoul.inc index c69eebad1b..1c7b511924 100644 --- a/repos/ports/run/seoul.inc +++ b/repos/ports/run/seoul.inc @@ -74,7 +74,7 @@ build $build_components # write Seoul config file set vm_cfg_fd [open "bin/vm_seoul.cfg" w] puts $vm_cfg_fd "" -puts $vm_cfg_fd { +puts $vm_cfg_fd { diff --git a/repos/ports/src/app/seoul/component.cc b/repos/ports/src/app/seoul/component.cc index d966095d5a..40018f5ec0 100644 --- a/repos/ports/src/app/seoul/component.cc +++ b/repos/ports/src/app/seoul/component.cc @@ -785,7 +785,9 @@ class Machine : public StaticReceiver Seoul::Network *_nic { nullptr }; Rtc::Session *_rtc { nullptr }; - Vcpu * _vcpus[32] { nullptr }; + enum { MAX_CPUS = 8 }; + Vcpu * _vcpus[MAX_CPUS] { nullptr }; + Genode::Bit_array<64> _vcpus_active { }; /* * Noncopyable @@ -907,6 +909,8 @@ class Machine : public StaticReceiver ep_name->string(), location); + _vcpus_active.set(_vcpus_up, 1); + Vcpu * vcpu = new Vcpu(*ep, _vm_con, _heap, _env, _motherboard_lock, msg.vcpu, _guest_memory, _motherboard, @@ -956,12 +960,26 @@ class Machine : public StaticReceiver if (!_vcpus[vcpu_id]) return false; + _vcpus_active.clear(vcpu_id, 1); + + if (!_vcpus_active.get(0, 64)) { + MessageConsole msgcon(MessageConsole::Type::TYPE_KILL); + _unsynchronized_motherboard.bus_console.send(msgcon); + } + _motherboard_lock.unlock(); _vcpus[vcpu_id]->block(); _motherboard_lock.lock(); + if (!_vcpus_active.get(0, 64)) { + MessageConsole msgcon(MessageConsole::Type::TYPE_RESET); + _unsynchronized_motherboard.bus_console.send(msgcon); + } + + _vcpus_active.set(vcpu_id, 1); + return true; } @@ -1218,6 +1236,8 @@ class Machine : public StaticReceiver { using namespace Genode; + bool const verbose = machine_node.attribute_value("verbose", false); + Xml_node node = machine_node.sub_node(); for (;; node = node.next()) { @@ -1225,7 +1245,9 @@ class Machine : public StaticReceiver char name[MODEL_NAME_MAX_LEN]; node.type_name(name, sizeof(name)); - Genode::log("device: ", (char const *)name); + if (verbose) + Genode::log("device: ", (char const *)name); + Device_model_info *dmi = device_model_registry()->lookup(name); if (!dmi) { @@ -1249,7 +1271,8 @@ class Machine : public StaticReceiver Xml_node::Attribute arg = node.attribute(dmi->arg_names[i]); arg.value(&argv[i]); - Genode::log(" arg[", i, "]: ", Genode::Hex(argv[i])); + if (verbose) + Genode::log(" arg[", i, "]: ", Genode::Hex(argv[i])); } catch (Xml_node::Nonexistent_attribute) { } } diff --git a/repos/ports/src/app/seoul/console.cc b/repos/ports/src/app/seoul/console.cc index 5e89e54ab3..398181a346 100644 --- a/repos/ports/src/app/seoul/console.cc +++ b/repos/ports/src/app/seoul/console.cc @@ -38,13 +38,13 @@ static Tff_font::Static_glyph_buffer<4096> glyph_buffer { }; static Tff_font default_font(_binary_mono_tff_start, glyph_buffer); static struct { - Genode::uint64_t checksum1 = 0; - Genode::uint64_t checksum2 = 0; - unsigned unchanged = 0; - bool cmp_even = 1; - bool active = false; - bool revoked = false; - bool vga_update= false; /* update indirectly by vbios */ + Genode::uint64_t checksum1 = 0; + Genode::uint64_t checksum2 = 0; + unsigned unchanged = 0; + bool cmp_even = 1; + bool active = false; + bool vga_revoked = false; + bool vga_update = false; /* update indirectly by vbios */ } fb_state; @@ -153,15 +153,17 @@ unsigned Seoul::Console::_input_to_ps2wheel(Input::Event const &ev) bool Seoul::Console::receive(MessageConsole &msg) { - if (msg.type == MessageConsole::TYPE_ALLOC_VIEW) { + switch (msg.type) { + case MessageConsole::TYPE_ALLOC_VIEW : _guest_fb = msg.ptr; _regs = msg.regs; msg.view = 0; - } else if (msg.type == MessageConsole::TYPE_SWITCH_VIEW) { + return true; + case MessageConsole::TYPE_SWITCH_VIEW: /* XXX: For now, we only have one view. */ - } else if (msg.type == MessageConsole::TYPE_GET_MODEINFO) { - + return true; + case MessageConsole::TYPE_GET_MODEINFO: enum { MEMORY_MODEL_TEXT = 0, MEMORY_MODEL_DIRECT_COLOR = 6, @@ -210,9 +212,18 @@ bool Seoul::Console::receive(MessageConsole &msg) msg.info->phys_base = 0xe0000000; msg.info->_phys_size = _fb_mode.width()*_fb_mode.height()*2; return true; - } else return false; + } + return false; + case MessageConsole::TYPE_KILL: /* all CPUs go idle */ + _handle_fb(); /* refresh before going to sleep */ + fb_state.active = false; + return true; + case MessageConsole::TYPE_RESET: /* first of all sleeping CPUs woke up */ + _reactivate(); + return true; + default: + return true; } - return true; } void Screen::vga_updated() @@ -220,6 +231,14 @@ void Screen::vga_updated() fb_state.vga_update = true; } +void Seoul::Console::_reactivate() +{ + fb_state.active = true; + + MessageTimer msg(_timer, _unsynchronized_motherboard.clock()->abstime(1, 1000)); + _unsynchronized_motherboard.bus_timer.send(msg); +} + bool Seoul::Console::receive(MessageMemRegion &msg) { /* we had a fault in the text framebuffer */ @@ -234,11 +253,11 @@ bool Seoul::Console::receive(MessageMemRegion &msg) } if (reactivate) { - if (!fb_state.active) fb_state.active = true; + fb_state.vga_revoked = false; + Logging::printf("Reactivating text buffer loop.\n"); - MessageTimer msg(_timer, _unsynchronized_motherboard.clock()->abstime(1, 1000)); - _unsynchronized_motherboard.bus_timer.send(msg); + _reactivate(); } return false; } @@ -254,8 +273,7 @@ unsigned Seoul::Console::_handle_fb() /* transfer text buffer content into chunky canvas */ if (_regs->mode == TEXT_MODE) { - if (fb_state.revoked || !fb_state.active) - return 0; + if (fb_state.vga_revoked || !fb_state.active) return 0; memset(_pixels, 0, _fb_size); @@ -299,24 +317,32 @@ unsigned Seoul::Console::_handle_fb() _memory.detach(PHYS_FRAME_VGA_COLOR << 12, FRAME_COUNT_COLOR << 12); + fb_state.vga_revoked = true; fb_state.unchanged = 0; - fb_state.active = false; + _framebuffer.refresh(0, 0, _fb_mode.width(), _fb_mode.height()); Logging::printf("Deactivated text buffer loop.\n"); return 0; } - if (!fb_state.revoked) { - + if (!fb_state.vga_revoked) { _memory.detach(PHYS_FRAME_VGA_COLOR << 12, FRAME_COUNT_COLOR << 12); - fb_state.revoked = true; + fb_state.vga_revoked = true; + } + + if (!fb_state.active) { + fb_state.unchanged = 0; + return 0; } _framebuffer.refresh(0, 0, _fb_mode.width(), _fb_mode.height()); - return 10; + + fb_state.unchanged++; + + return (fb_state.unchanged > 4) ? 4 * 10 : fb_state.unchanged * 10; } diff --git a/repos/ports/src/app/seoul/console.h b/repos/ports/src/app/seoul/console.h index bde96fbfcb..9463896310 100644 --- a/repos/ports/src/app/seoul/console.h +++ b/repos/ports/src/app/seoul/console.h @@ -25,6 +25,7 @@ #include #include #include +#include /* os includes */ #include @@ -64,13 +65,13 @@ class Seoul::Console : public StaticReceiver Genode::addr_t const _vm_phys_fb; short *_pixels; Genode::Surface _surface; + unsigned _timer { 0 }; Keyboard _vkeyb { _motherboard }; char *_guest_fb { nullptr }; VgaRegs *_regs { nullptr }; bool _left { false }; bool _middle { false }; bool _right { false }; - unsigned _timer { 0 }; unsigned _input_to_ps2mouse(Input::Event const &); unsigned _input_to_ps2wheel(Input::Event const &); @@ -81,6 +82,8 @@ class Seoul::Console : public StaticReceiver void _handle_input(); unsigned _handle_fb(); + void _reactivate(); + /* * Noncopyable */