diff --git a/repos/ports/run/seoul.inc b/repos/ports/run/seoul.inc index 89589e4bb..13184aa8a 100644 --- a/repos/ports/run/seoul.inc +++ b/repos/ports/run/seoul.inc @@ -69,7 +69,7 @@ puts $vm_cfg_fd { - } + } if {!$use_multiboot} { puts $vm_cfg_fd { diff --git a/repos/ports/src/app/seoul/console.cc b/repos/ports/src/app/seoul/console.cc index c425f9a9e..c7fcadaac 100644 --- a/repos/ports/src/app/seoul/console.cc +++ b/repos/ports/src/app/seoul/console.cc @@ -133,10 +133,6 @@ bool Seoul::Console::receive(MessageConsole &msg) { if (msg.type == MessageConsole::TYPE_ALLOC_VIEW) { _guest_fb = msg.ptr; - - if (msg.size < _fb_size) - _fb_size = msg.size; - _regs = msg.regs; msg.view = 0; @@ -256,7 +252,7 @@ unsigned Seoul::Console::_handle_fb() ((fg & 0x2) >> 1)*127+lum, /* G+luminosity */ (fg & 0x1)*127+lum /* B+luminosity */); - Text_painter::paint(*_surface, where, default_font, color, buffer); + Text_painter::paint(_surface, where, default_font, color, buffer); /* Checksum for comparing */ if (fb_state.cmp_even) fb_state.checksum1 += character; @@ -269,7 +265,7 @@ unsigned Seoul::Console::_handle_fb() /* 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()); + _framebuffer.refresh(0, 0, _fb_mode.width(), _fb_mode.height()); return 100; } @@ -278,7 +274,7 @@ unsigned Seoul::Console::_handle_fb() /* 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); + _env.rm().attach_at(_guest_fb_ds, (Genode::addr_t)_guest_fb); fb_state.unchanged = 0; fb_state.active = false; @@ -291,21 +287,12 @@ unsigned Seoul::Console::_handle_fb() if (!fb_state.revoked) { _env.rm().detach((void *)_guest_fb); - _env.rm().attach_at(_framebuffer->dataspace(), + _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()); + _framebuffer.refresh(0, 0, _fb_mode.width(), _fb_mode.height()); return 10; } @@ -372,28 +359,20 @@ bool Seoul::Console::receive(MessageTimeout &msg) { Seoul::Console::Console(Genode::Env &env, Synced_motherboard &mb, Motherboard &unsynchronized_motherboard, - Genode::size_t vm_fb_size, - Genode::Dataspace_capability fb_ds) + Framebuffer::Connection &framebuffer, + Genode::Dataspace_capability guest_fb_ds) : _env(env), _unsynchronized_motherboard(unsynchronized_motherboard), - _motherboard(mb), _fb_ds(fb_ds), _vm_fb_size(vm_fb_size) + _motherboard(mb), + _framebuffer(framebuffer), + _guest_fb_ds(guest_fb_ds), + _fb_mode(_framebuffer.mode()), + _fb_size(Genode::Dataspace_client(_framebuffer.dataspace()).size()), + _pixels(_env.rm().attach(_framebuffer.dataspace())), + _surface(reinterpret_cast(_pixels), + Genode::Surface_base::Area(_fb_mode.width(), + _fb_mode.height())) { _input.sigh(_signal_input); - - try { - using Framebuffer::Mode; - _framebuffer.construct(_env, Mode(0, 0, Mode::INVALID)); - } catch (...) { - Genode::error("Headless mode - no framebuffer session available"); - return; - } - - _fb_size = Genode::Dataspace_client(_framebuffer->dataspace()).size(); - _fb_mode = _framebuffer->mode(); - _pixels = _env.rm().attach(_framebuffer->dataspace()); - - _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 1e8d87c11..85e13446e 100644 --- a/repos/ports/src/app/seoul/console.h +++ b/repos/ports/src/app/seoul/console.h @@ -24,7 +24,6 @@ /* base includes */ #include #include -#include #include /* os includes */ @@ -41,7 +40,6 @@ namespace Seoul { class Console; - using Genode::Constructible; using Genode::Pixel_rgb565; } @@ -52,17 +50,16 @@ class Seoul::Console : public StaticReceiver Genode::Env &_env; Motherboard &_unsynchronized_motherboard; Synced_motherboard &_motherboard; - Constructible _framebuffer { }; - Constructible > _surface { }; + Framebuffer::Connection &_framebuffer; + Genode::Dataspace_capability _guest_fb_ds; + Framebuffer::Mode _fb_mode; + size_t _fb_size; + short *_pixels; + Genode::Surface _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 { nullptr }; - Framebuffer::Mode _fb_mode { }; bool _left { false }; bool _middle { false }; bool _right { false }; @@ -95,7 +92,7 @@ class Seoul::Console : public StaticReceiver * Constructor */ Console(Genode::Env &env, Synced_motherboard &, Motherboard &, - Genode::size_t vm_fb_size, Genode::Dataspace_capability fb_ds); + Framebuffer::Connection &, Genode::Dataspace_capability fb_ds); }; #endif /* _CONSOLE_H_ */ diff --git a/repos/ports/src/app/seoul/device_model_registry.cc b/repos/ports/src/app/seoul/device_model_registry.cc index e2dbad2d0..d37987ecd 100644 --- a/repos/ports/src/app/seoul/device_model_registry.cc +++ b/repos/ports/src/app/seoul/device_model_registry.cc @@ -76,8 +76,9 @@ MODEL_INFO(keyb, "ps2_port", "host_keyboard") MODEL_INFO(mouse, "ps2_port", "host_mouse") MODEL_INFO(rtc, "io_base", "irq") MODEL_INFO(serial, "io_base", "irq", "host_serial") -MODEL_INFO(vga, "io_base", "fb_size") MODEL_INFO(pmtimer, "io_port") +MODEL_INFO(vga, "io_base", "fb_size") +MODEL_INFO(vga_fbsize, "fb_size") MODEL_INFO(pcihostbridge, "bus_num", "bus_count", "io_base", "mem_base") MODEL_INFO(intel82576vf, "promisc", "mem_mmio", "mem_msix", "txpoll_us", "rx_map") diff --git a/repos/ports/src/app/seoul/main.cc b/repos/ports/src/app/seoul/main.cc index cb6051943..24ea90d88 100644 --- a/repos/ports/src/app/seoul/main.cc +++ b/repos/ports/src/app/seoul/main.cc @@ -44,10 +44,11 @@ #include /* os includes */ +#include #include #include -#include #include +#include /* VMM utilities includes */ #include @@ -180,11 +181,11 @@ class Guest_memory Genode::Ram_dataspace_capability _ds; Genode::Ram_dataspace_capability _fb_ds; - Genode::size_t _backing_store_size; - Genode::size_t _fb_size; + Genode::size_t const _backing_store_size; + Genode::size_t const _fb_size; - char *_local_addr; - char *_fb_addr; + Genode::addr_t _local_addr; + Genode::addr_t _fb_addr; /* * Noncopyable @@ -228,19 +229,20 @@ class Guest_memory remaining_size(backing_store_size-fb_size) { try { + /* reserve some contiguous memory region */ + Genode::Rm_connection rm_conn(env); + Genode::Region_map_client rm(rm_conn.create(_backing_store_size)); + Genode::addr_t const local_addr = env.rm().attach(rm.dataspace()); + env.rm().detach(local_addr); /* * RAM used as backing store for guest-physical memory */ - enum { - MAX_SIZE = 0, OFFSET = 0, ANY_LOCAL_ADDRESS = false, - EXECUTABLE = true - }; + env.rm().attach_executable(_ds, local_addr); + _local_addr = local_addr; - _local_addr = env.rm().attach(_ds, MAX_SIZE, OFFSET, - ANY_LOCAL_ADDRESS, nullptr, - EXECUTABLE); - _fb_addr = env.rm().attach_at(_fb_ds, - ((Genode::addr_t) _local_addr)+backing_store_size-fb_size); + Genode::addr_t const fb_addr = local_addr + remaining_size; + env.rm().attach_at(_fb_ds, fb_addr); + _fb_addr = fb_addr; } catch (Genode::Region_map::Region_conflict) { Genode::error("region conflict"); } @@ -261,7 +263,7 @@ class Guest_memory */ char *backing_store_local_base() { - return _local_addr; + return reinterpret_cast(_local_addr); } Genode::size_t backing_store_size() @@ -274,7 +276,7 @@ class Guest_memory */ char *backing_store_fb_local_base() { - return _fb_addr; + return reinterpret_cast(_fb_addr); } Genode::size_t fb_size() { return _fb_size; } @@ -1246,7 +1248,8 @@ class Machine : public StaticReceiver */ Machine(Genode::Env &env, Genode::Heap &heap, Boot_module_provider &boot_modules, - Guest_memory &guest_memory, bool colocate) + Guest_memory &guest_memory, bool colocate, + size_t const fb_size) : _env(env), _heap(heap), _clock(Attached_rom_dataspace(env, "platform_info").xml().sub_node("hardware").sub_node("tsc").attribute_value("freq_khz", 0ULL) * 1000ULL), @@ -1269,6 +1272,13 @@ class Machine : public StaticReceiver _unsynchronized_motherboard.bus_hwpcicfg.add(this, receive_static); _unsynchronized_motherboard.bus_acpi.add (this, receive_static); _unsynchronized_motherboard.bus_legacy.add (this, receive_static); + + /* tell vga model about available framebuffer memory */ + Device_model_info *dmi = device_model_registry()->lookup("vga_fbsize"); + if (dmi) { + unsigned long argv[2] = { fb_size >> 10, ~0UL }; + dmi->create(_unsynchronized_motherboard, argv, "", 0); + } } @@ -1398,7 +1408,6 @@ extern void heap_init_env(Genode::Heap *); void Component::construct(Genode::Env &env) { - Genode::addr_t fb_size = 4*1024*1024; Genode::addr_t vm_size; unsigned colocate = 1; /* by default co-locate VM and VMM in same PD */ @@ -1423,16 +1432,6 @@ void Component::construct(Genode::Env &env) /* calculate max memory for the VM */ vm_size = vm_size & ~((1UL << Vmm::PAGE_SIZE_LOG2) - 1); - /* Find out framebuffer size (default: 4 MiB) */ - try { - 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; - arg.value(&val); - fb_size = val*1024; - } catch (...) { } - /* read out whether VM and VMM should be colocated or not */ try { config.xml().attribute("colocate").value(&colocate); @@ -1443,6 +1442,13 @@ void Component::construct(Genode::Env &env) /* re-adjust reservation to actual VM size */ static Vmm::Virtual_reservation reservation(env, vm_size); + /* setup framebuffer memory for guest */ + static Framebuffer::Connection framebuffer(env, Framebuffer::Mode(0, 0, Framebuffer::Mode::INVALID)); + Framebuffer::Mode const fb_mode = framebuffer.mode(); + size_t const fb_size = Genode::align_addr(fb_mode.width() * + fb_mode.height() * + fb_mode.bytes_per_pixel(), 12); + /* setup guest memory */ static Guest_memory guest_memory(env, vm_size, fb_size); @@ -1493,11 +1499,12 @@ void Component::construct(Genode::Env &env) boot_modules(config.xml().sub_node("multiboot")); /* create the PC machine based on the configuration given */ - static Machine machine(env, heap, boot_modules, guest_memory, colocate); + static Machine machine(env, heap, boot_modules, guest_memory, colocate, fb_size); /* create console thread */ static Seoul::Console vcon(env, machine.motherboard(), - machine.unsynchronized_motherboard(), fb_size, + machine.unsynchronized_motherboard(), + framebuffer, guest_memory.fb_ds()); vcon.register_host_operations(machine.unsynchronized_motherboard());