From 88118b133af380b9c58a31f248dd5efb6a29890a Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Fri, 20 May 2022 14:11:48 +0200 Subject: [PATCH] intel_fb: request copy of Intel opregion acpica and the Intel display driver tries to use the Intel Opregion simultaneously on Genode, which is not supported nor wanted for IO_MEM region as which it is handled. Attempts to remove the access to the region was not successful, since some SSDT table contains ACPI AML code which is executed regularly and read/write the Opregion. The patch adds support to read in a copy of the Intel Opregion done by the acpi_drv component. The copy was sufficient to make the Intel display driver working to find and lookup the Intel VBT (video bios table) information to setup all connectors on a Fujitsu U7411 docking station. Fixes #4531 --- repos/base/run/platform_drv.inc | 1 + repos/pc/run/intel_fb.run | 3 + .../drivers/framebuffer/intel/pc/lx_emul.c | 5 +- .../drivers/framebuffer/intel/pc/lx_emul.h | 1 + .../framebuffer/intel/pc/opregion_io_mem.cc | 70 +++++++++++++++++++ .../drivers/framebuffer/intel/pc/target.inc | 1 + 6 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 repos/pc/src/drivers/framebuffer/intel/pc/opregion_io_mem.cc 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))