diff --git a/repos/base/run/platform_drv.inc b/repos/base/run/platform_drv.inc
index c442dff71d..3da9f74d87 100644
--- a/repos/base/run/platform_drv.inc
+++ b/repos/base/run/platform_drv.inc
@@ -188,6 +188,7 @@ proc platform_drv_config {} {
+
}
diff --git a/repos/pc/run/intel_fb.run b/repos/pc/run/intel_fb.run
index 0ae21947d4..7265214d59 100644
--- a/repos/pc/run/intel_fb.run
+++ b/repos/pc/run/intel_fb.run
@@ -68,6 +68,9 @@ append config {
+
+
+
diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.c b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.c
index afb1f8ec99..2c0c20a3b3 100644
--- a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.c
+++ b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.c
@@ -215,6 +215,9 @@ void intel_gt_init_early(struct intel_gt * gt, struct drm_i915_private * i915)
init_llist_head(>->watchdog.list);
lx_emul_trace(__func__);
+
+ /* disable panel self refresh (required for FUJITSU S937/S938) */
+ i915->params.enable_psr = 0;
}
@@ -242,7 +245,7 @@ void * memremap(resource_size_t offset, size_t size, unsigned long flags)
{
lx_emul_trace(__func__);
- return NULL;
+ return intel_io_mem_map(offset, size);
}
diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h
index b6444c51c0..7dc6902aa1 100644
--- a/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h
+++ b/repos/pc/src/drivers/framebuffer/intel/pc/lx_emul.h
@@ -39,6 +39,7 @@ unsigned int lx_emul_io_port_inl(unsigned short port);
void *emul_alloc_shmem_file_buffer(unsigned long);
+void * intel_io_mem_map(unsigned long offset, unsigned long size);
#include "lx_i915.h"
diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc b/repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc
new file mode 100644
index 0000000000..b97e7d56d5
--- /dev/null
+++ b/repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc
@@ -0,0 +1,70 @@
+/*
+ * \brief Linux emulation environment specific to this driver - Intel opregion
+ * \author Alexander Boettcher
+ * \date 2022-01-21
+ */
+
+/*
+ * Copyright (C) 2022 Genode Labs GmbH
+ *
+ * This file is distributed under the terms of the GNU General Public License
+ * version 2.
+ */
+
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+
+extern "C" void * intel_io_mem_map(unsigned long const phys,
+ unsigned long const size)
+{
+ using namespace Genode;
+
+ static Constructible rom_opregion { };
+ static addr_t opregion_start = 0;
+ static addr_t opregion_size = 0;
+
+ if (!rom_opregion.constructed()) {
+ try {
+ rom_opregion.construct(Lx_kit::env().env, "intel_opregion");
+
+ Dataspace_client ds_client(rom_opregion->cap());
+
+ auto mem_local = rom_opregion->local_addr();
+ opregion_start = *(addr_t*)(mem_local + ds_client.size() - sizeof(addr_t) * 2);
+ opregion_size = *(addr_t*)(mem_local + ds_client.size() - sizeof(addr_t));
+
+ if (opregion_size > ds_client.size())
+ opregion_size = ds_client.size();
+ } catch (...) {
+ error("Intel opregion ROM lookup failed");
+ if (rom_opregion.constructed())
+ rom_opregion.destruct();
+ return nullptr;
+ }
+ }
+
+ if ((opregion_start <= phys) &&
+ (phys + size <= opregion_start + opregion_size)) {
+
+ try {
+ auto ptr = ((addr_t)rom_opregion->local_addr())
+ + (phys - opregion_start) + (phys & 0xffful);
+ return (void *)ptr;
+ } catch (...) {
+ error("Intel opregion lookup failed");
+ return nullptr;
+ }
+ }
+
+ warning("Unknown memremap range ", Hex_range(phys, size));
+
+ return nullptr;
+}
diff --git a/repos/pc/src/drivers/framebuffer/intel/pc/target.inc b/repos/pc/src/drivers/framebuffer/intel/pc/target.inc
index ef119180c2..235ce2e1b5 100644
--- a/repos/pc/src/drivers/framebuffer/intel/pc/target.inc
+++ b/repos/pc/src/drivers/framebuffer/intel/pc/target.inc
@@ -11,6 +11,7 @@ INC_DIR += $(REL_PRG_DIR)/shadow
SRC_CC += main.cc
SRC_CC += misc.cc
SRC_CC += emul.cc
+SRC_CC += opregion_io_mem.cc
SRC_C += dummies.c
SRC_C += lx_emul.c
SRC_C += $(notdir $(wildcard $(REL_PRG_DIR)/generated_dummies.c))