seoul: adjust vga model to framebuffer host size
Configure the available vga/vesa memory based on the given Genode framebuffer size and not the way around. Issue #2715
This commit is contained in:
parent
bb768c2cab
commit
57fcd5e0c4
|
@ -69,7 +69,7 @@ puts $vm_cfg_fd {<config colocate="1" >
|
||||||
<rtc io_base="0x70" irq="8"/>
|
<rtc io_base="0x70" irq="8"/>
|
||||||
<serial io_base="0x3f8" irq="0x4" host_serial="0x4711"/>
|
<serial io_base="0x3f8" irq="0x4" host_serial="0x4711"/>
|
||||||
<hostsink host_dev="0x4712" buffer="80"/>
|
<hostsink host_dev="0x4712" buffer="80"/>
|
||||||
<vga io_base="0x03c0" fb_size="4096" readonly="1"/>}
|
<vga io_base="0x03c0"/>}
|
||||||
|
|
||||||
if {!$use_multiboot} {
|
if {!$use_multiboot} {
|
||||||
puts $vm_cfg_fd {
|
puts $vm_cfg_fd {
|
||||||
|
|
|
@ -133,10 +133,6 @@ bool Seoul::Console::receive(MessageConsole &msg)
|
||||||
{
|
{
|
||||||
if (msg.type == MessageConsole::TYPE_ALLOC_VIEW) {
|
if (msg.type == MessageConsole::TYPE_ALLOC_VIEW) {
|
||||||
_guest_fb = msg.ptr;
|
_guest_fb = msg.ptr;
|
||||||
|
|
||||||
if (msg.size < _fb_size)
|
|
||||||
_fb_size = msg.size;
|
|
||||||
|
|
||||||
_regs = msg.regs;
|
_regs = msg.regs;
|
||||||
|
|
||||||
msg.view = 0;
|
msg.view = 0;
|
||||||
|
@ -256,7 +252,7 @@ unsigned Seoul::Console::_handle_fb()
|
||||||
((fg & 0x2) >> 1)*127+lum, /* G+luminosity */
|
((fg & 0x2) >> 1)*127+lum, /* G+luminosity */
|
||||||
(fg & 0x1)*127+lum /* B+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 */
|
/* Checksum for comparing */
|
||||||
if (fb_state.cmp_even) fb_state.checksum1 += character;
|
if (fb_state.cmp_even) fb_state.checksum1 += character;
|
||||||
|
@ -269,7 +265,7 @@ unsigned Seoul::Console::_handle_fb()
|
||||||
/* compare checksums to detect changed buffer */
|
/* compare checksums to detect changed buffer */
|
||||||
if (fb_state.checksum1 != fb_state.checksum2) {
|
if (fb_state.checksum1 != fb_state.checksum2) {
|
||||||
fb_state.unchanged = 0;
|
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;
|
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 */
|
/* if we copy the same data 10 times, unmap the text buffer from guest */
|
||||||
_env.rm().detach((void *)_guest_fb);
|
_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.unchanged = 0;
|
||||||
fb_state.active = false;
|
fb_state.active = false;
|
||||||
|
@ -291,21 +287,12 @@ unsigned Seoul::Console::_handle_fb()
|
||||||
if (!fb_state.revoked) {
|
if (!fb_state.revoked) {
|
||||||
|
|
||||||
_env.rm().detach((void *)_guest_fb);
|
_env.rm().detach((void *)_guest_fb);
|
||||||
_env.rm().attach_at(_framebuffer->dataspace(),
|
_env.rm().attach_at(_framebuffer.dataspace(),
|
||||||
(Genode::addr_t)_guest_fb);
|
(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;
|
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;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,28 +359,20 @@ bool Seoul::Console::receive(MessageTimeout &msg) {
|
||||||
|
|
||||||
Seoul::Console::Console(Genode::Env &env, Synced_motherboard &mb,
|
Seoul::Console::Console(Genode::Env &env, Synced_motherboard &mb,
|
||||||
Motherboard &unsynchronized_motherboard,
|
Motherboard &unsynchronized_motherboard,
|
||||||
Genode::size_t vm_fb_size,
|
Framebuffer::Connection &framebuffer,
|
||||||
Genode::Dataspace_capability fb_ds)
|
Genode::Dataspace_capability guest_fb_ds)
|
||||||
:
|
:
|
||||||
_env(env),
|
_env(env),
|
||||||
_unsynchronized_motherboard(unsynchronized_motherboard),
|
_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<Genode::Pixel_rgb565 *>(_pixels),
|
||||||
|
Genode::Surface_base::Area(_fb_mode.width(),
|
||||||
|
_fb_mode.height()))
|
||||||
{
|
{
|
||||||
_input.sigh(_signal_input);
|
_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<Genode::Pixel_rgb565 *>(_pixels),
|
|
||||||
Genode::Surface_base::Area(_fb_mode.width(),
|
|
||||||
_fb_mode.height()));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
/* base includes */
|
/* base includes */
|
||||||
#include <base/env.h>
|
#include <base/env.h>
|
||||||
#include <dataspace/client.h>
|
#include <dataspace/client.h>
|
||||||
#include <util/reconstructible.h>
|
|
||||||
#include <util/string.h>
|
#include <util/string.h>
|
||||||
|
|
||||||
/* os includes */
|
/* os includes */
|
||||||
|
@ -41,7 +40,6 @@
|
||||||
|
|
||||||
namespace Seoul {
|
namespace Seoul {
|
||||||
class Console;
|
class Console;
|
||||||
using Genode::Constructible;
|
|
||||||
using Genode::Pixel_rgb565;
|
using Genode::Pixel_rgb565;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,17 +50,16 @@ class Seoul::Console : public StaticReceiver<Seoul::Console>
|
||||||
Genode::Env &_env;
|
Genode::Env &_env;
|
||||||
Motherboard &_unsynchronized_motherboard;
|
Motherboard &_unsynchronized_motherboard;
|
||||||
Synced_motherboard &_motherboard;
|
Synced_motherboard &_motherboard;
|
||||||
Constructible<Framebuffer::Connection> _framebuffer { };
|
Framebuffer::Connection &_framebuffer;
|
||||||
Constructible<Genode::Surface<Pixel_rgb565> > _surface { };
|
Genode::Dataspace_capability _guest_fb_ds;
|
||||||
|
Framebuffer::Mode _fb_mode;
|
||||||
|
size_t _fb_size;
|
||||||
|
short *_pixels;
|
||||||
|
Genode::Surface<Pixel_rgb565> _surface;
|
||||||
Input::Connection _input { _env };
|
Input::Connection _input { _env };
|
||||||
Keyboard _vkeyb { _motherboard };
|
Keyboard _vkeyb { _motherboard };
|
||||||
short *_pixels { nullptr };
|
|
||||||
char *_guest_fb { nullptr };
|
char *_guest_fb { nullptr };
|
||||||
unsigned long _fb_size { 0 };
|
|
||||||
Genode::Dataspace_capability _fb_ds;
|
|
||||||
Genode::size_t _vm_fb_size;
|
|
||||||
VgaRegs *_regs { nullptr };
|
VgaRegs *_regs { nullptr };
|
||||||
Framebuffer::Mode _fb_mode { };
|
|
||||||
bool _left { false };
|
bool _left { false };
|
||||||
bool _middle { false };
|
bool _middle { false };
|
||||||
bool _right { false };
|
bool _right { false };
|
||||||
|
@ -95,7 +92,7 @@ class Seoul::Console : public StaticReceiver<Seoul::Console>
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
Console(Genode::Env &env, Synced_motherboard &, Motherboard &,
|
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_ */
|
#endif /* _CONSOLE_H_ */
|
||||||
|
|
|
@ -76,8 +76,9 @@ MODEL_INFO(keyb, "ps2_port", "host_keyboard")
|
||||||
MODEL_INFO(mouse, "ps2_port", "host_mouse")
|
MODEL_INFO(mouse, "ps2_port", "host_mouse")
|
||||||
MODEL_INFO(rtc, "io_base", "irq")
|
MODEL_INFO(rtc, "io_base", "irq")
|
||||||
MODEL_INFO(serial, "io_base", "irq", "host_serial")
|
MODEL_INFO(serial, "io_base", "irq", "host_serial")
|
||||||
MODEL_INFO(vga, "io_base", "fb_size")
|
|
||||||
MODEL_INFO(pmtimer, "io_port")
|
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(pcihostbridge, "bus_num", "bus_count", "io_base", "mem_base")
|
||||||
MODEL_INFO(intel82576vf, "promisc", "mem_mmio", "mem_msix", "txpoll_us", "rx_map")
|
MODEL_INFO(intel82576vf, "promisc", "mem_mmio", "mem_msix", "txpoll_us", "rx_map")
|
||||||
|
|
|
@ -44,10 +44,11 @@
|
||||||
#include <util/misc_math.h>
|
#include <util/misc_math.h>
|
||||||
|
|
||||||
/* os includes */
|
/* os includes */
|
||||||
|
#include <framebuffer_session/connection.h>
|
||||||
#include <nic_session/connection.h>
|
#include <nic_session/connection.h>
|
||||||
#include <nic/packet_allocator.h>
|
#include <nic/packet_allocator.h>
|
||||||
#include <timer_session/connection.h>
|
|
||||||
#include <rtc_session/connection.h>
|
#include <rtc_session/connection.h>
|
||||||
|
#include <timer_session/connection.h>
|
||||||
|
|
||||||
/* VMM utilities includes */
|
/* VMM utilities includes */
|
||||||
#include <vmm/guest_memory.h>
|
#include <vmm/guest_memory.h>
|
||||||
|
@ -180,11 +181,11 @@ class Guest_memory
|
||||||
Genode::Ram_dataspace_capability _ds;
|
Genode::Ram_dataspace_capability _ds;
|
||||||
Genode::Ram_dataspace_capability _fb_ds;
|
Genode::Ram_dataspace_capability _fb_ds;
|
||||||
|
|
||||||
Genode::size_t _backing_store_size;
|
Genode::size_t const _backing_store_size;
|
||||||
Genode::size_t _fb_size;
|
Genode::size_t const _fb_size;
|
||||||
|
|
||||||
char *_local_addr;
|
Genode::addr_t _local_addr;
|
||||||
char *_fb_addr;
|
Genode::addr_t _fb_addr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Noncopyable
|
* Noncopyable
|
||||||
|
@ -228,19 +229,20 @@ class Guest_memory
|
||||||
remaining_size(backing_store_size-fb_size)
|
remaining_size(backing_store_size-fb_size)
|
||||||
{
|
{
|
||||||
try {
|
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
|
* RAM used as backing store for guest-physical memory
|
||||||
*/
|
*/
|
||||||
enum {
|
env.rm().attach_executable(_ds, local_addr);
|
||||||
MAX_SIZE = 0, OFFSET = 0, ANY_LOCAL_ADDRESS = false,
|
_local_addr = local_addr;
|
||||||
EXECUTABLE = true
|
|
||||||
};
|
|
||||||
|
|
||||||
_local_addr = env.rm().attach(_ds, MAX_SIZE, OFFSET,
|
Genode::addr_t const fb_addr = local_addr + remaining_size;
|
||||||
ANY_LOCAL_ADDRESS, nullptr,
|
env.rm().attach_at(_fb_ds, fb_addr);
|
||||||
EXECUTABLE);
|
_fb_addr = fb_addr;
|
||||||
_fb_addr = env.rm().attach_at(_fb_ds,
|
|
||||||
((Genode::addr_t) _local_addr)+backing_store_size-fb_size);
|
|
||||||
}
|
}
|
||||||
catch (Genode::Region_map::Region_conflict) {
|
catch (Genode::Region_map::Region_conflict) {
|
||||||
Genode::error("region conflict"); }
|
Genode::error("region conflict"); }
|
||||||
|
@ -261,7 +263,7 @@ class Guest_memory
|
||||||
*/
|
*/
|
||||||
char *backing_store_local_base()
|
char *backing_store_local_base()
|
||||||
{
|
{
|
||||||
return _local_addr;
|
return reinterpret_cast<char *>(_local_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::size_t backing_store_size()
|
Genode::size_t backing_store_size()
|
||||||
|
@ -274,7 +276,7 @@ class Guest_memory
|
||||||
*/
|
*/
|
||||||
char *backing_store_fb_local_base()
|
char *backing_store_fb_local_base()
|
||||||
{
|
{
|
||||||
return _fb_addr;
|
return reinterpret_cast<char *>(_fb_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::size_t fb_size() { return _fb_size; }
|
Genode::size_t fb_size() { return _fb_size; }
|
||||||
|
@ -1246,7 +1248,8 @@ class Machine : public StaticReceiver<Machine>
|
||||||
*/
|
*/
|
||||||
Machine(Genode::Env &env, Genode::Heap &heap,
|
Machine(Genode::Env &env, Genode::Heap &heap,
|
||||||
Boot_module_provider &boot_modules,
|
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),
|
_env(env), _heap(heap),
|
||||||
_clock(Attached_rom_dataspace(env, "platform_info").xml().sub_node("hardware").sub_node("tsc").attribute_value("freq_khz", 0ULL) * 1000ULL),
|
_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<Machine>
|
||||||
_unsynchronized_motherboard.bus_hwpcicfg.add(this, receive_static<MessageHwPciConfig>);
|
_unsynchronized_motherboard.bus_hwpcicfg.add(this, receive_static<MessageHwPciConfig>);
|
||||||
_unsynchronized_motherboard.bus_acpi.add (this, receive_static<MessageAcpi>);
|
_unsynchronized_motherboard.bus_acpi.add (this, receive_static<MessageAcpi>);
|
||||||
_unsynchronized_motherboard.bus_legacy.add (this, receive_static<MessageLegacy>);
|
_unsynchronized_motherboard.bus_legacy.add (this, receive_static<MessageLegacy>);
|
||||||
|
|
||||||
|
/* 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)
|
void Component::construct(Genode::Env &env)
|
||||||
{
|
{
|
||||||
Genode::addr_t fb_size = 4*1024*1024;
|
|
||||||
Genode::addr_t vm_size;
|
Genode::addr_t vm_size;
|
||||||
unsigned colocate = 1; /* by default co-locate VM and VMM in same PD */
|
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 */
|
/* calculate max memory for the VM */
|
||||||
vm_size = vm_size & ~((1UL << Vmm::PAGE_SIZE_LOG2) - 1);
|
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 */
|
/* read out whether VM and VMM should be colocated or not */
|
||||||
try {
|
try {
|
||||||
config.xml().attribute("colocate").value(&colocate);
|
config.xml().attribute("colocate").value(&colocate);
|
||||||
|
@ -1443,6 +1442,13 @@ void Component::construct(Genode::Env &env)
|
||||||
/* re-adjust reservation to actual VM size */
|
/* re-adjust reservation to actual VM size */
|
||||||
static Vmm::Virtual_reservation reservation(env, 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 */
|
/* setup guest memory */
|
||||||
static Guest_memory guest_memory(env, vm_size, fb_size);
|
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"));
|
boot_modules(config.xml().sub_node("multiboot"));
|
||||||
|
|
||||||
/* create the PC machine based on the configuration given */
|
/* 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 */
|
/* create console thread */
|
||||||
static Seoul::Console vcon(env, machine.motherboard(),
|
static Seoul::Console vcon(env, machine.motherboard(),
|
||||||
machine.unsynchronized_motherboard(), fb_size,
|
machine.unsynchronized_motherboard(),
|
||||||
|
framebuffer,
|
||||||
guest_memory.fb_ds());
|
guest_memory.fb_ds());
|
||||||
|
|
||||||
vcon.register_host_operations(machine.unsynchronized_motherboard());
|
vcon.register_host_operations(machine.unsynchronized_motherboard());
|
||||||
|
|
Loading…
Reference in New Issue