diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/README b/repos/pc/src/drivers/framebuffer/intel/pc/README
index bb951c161a..9154856e12 100644
--- a/repos/pc/src/drivers/framebuffer/intel/pc/README
+++ b/repos/pc/src/drivers/framebuffer/intel/pc/README
@@ -49,6 +49,16 @@ The virtual resolution can be enforced by:
!
!
+The amount of memory used by the driver for the accounting of its available
+buffer space is set by:
+
+!
+!
+
+The default and minimal value is '64M' and suffices for resolutions of at
+least '3840x2160'. How much actual memory is used depends on the configured
+resolution.
+
To present all available connectors and their possible resolutions to the user,
the driver is able to deliver a corresponding report, which can be enabled
in the configuration as follows:
diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc b/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc
index 429e5c9500..55c718b869 100644
--- a/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc
+++ b/repos/pc/src/drivers/framebuffer/intel/pc/emul.cc
@@ -17,6 +17,8 @@
/* local includes */
#include "lx_emul.h"
+extern unsigned long long driver_max_framebuffer_memory(void);
+
unsigned short emul_intel_gmch_control_reg()
{
@@ -39,5 +41,5 @@ unsigned short emul_intel_gmch_control_reg()
unsigned long long emul_avail_ram()
{
- return Lx_kit::env().env.pd().avail_ram().value;
+ return driver_max_framebuffer_memory();
}
diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/main.cc b/repos/pc/src/drivers/framebuffer/intel/pc/main.cc
index f8a57f2d01..fe5690ce43 100644
--- a/repos/pc/src/drivers/framebuffer/intel/pc/main.cc
+++ b/repos/pc/src/drivers/framebuffer/intel/pc/main.cc
@@ -164,6 +164,43 @@ struct Framebuffer::Driver
if (force_width && force_height)
fn(force_width, force_height);
}
+
+ unsigned long long max_framebuffer_memory()
+ {
+ /*
+ * The max framebuffer memory is virtual in nature and denotes how
+ * the driver sizes its buffer space. When actual memory is used and
+ * the available RAM quota is not enough the component will issue a
+ * resource request.
+ *
+ * As the available memory is used during the initialization of the
+ * driver and is not queried afterwards it is safe to acquired it
+ * only once. Since it is used to size the GEM buffer pool set the amount
+ * of memory so that it includes the currently anticipated resolutions
+ * (e.g. 3840x2160) and is in line with the default value of the Intel GPU
+ * multiplexer.
+ */
+ static unsigned long long _framebuffer_memory = 0;
+
+ if (_framebuffer_memory)
+ return _framebuffer_memory;
+
+ enum : unsigned { DEFAULT_FB_MEMORY = 64u << 20, };
+ auto framebuffer_memory = Number_of_bytes(DEFAULT_FB_MEMORY);
+ if (config.valid())
+ framebuffer_memory =
+ config.xml().attribute_value("max_framebuffer_memory",
+ framebuffer_memory);
+
+ if (framebuffer_memory < DEFAULT_FB_MEMORY) {
+ warning("configured framebuffer memory too small, use default of ",
+ Number_of_bytes(DEFAULT_FB_MEMORY));
+ framebuffer_memory = Number_of_bytes(DEFAULT_FB_MEMORY);
+ }
+ _framebuffer_memory = framebuffer_memory;
+
+ return _framebuffer_memory;
+ }
};
@@ -267,6 +304,13 @@ void Framebuffer::Driver::lookup_config(char const * const name,
}
+unsigned long long driver_max_framebuffer_memory(void)
+{
+ Genode::Env &env = Lx_kit::env().env;
+ return driver(env).max_framebuffer_memory();
+}
+
+
/**
* Can be called already as side-effect of `lx_emul_start_kernel`,
* that's why the Driver object needs to be constructed already here.