From 224b766eb1ec13b4c829b3ea39cbaf0f610d9841 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Mon, 1 Aug 2022 17:14:10 +0200 Subject: [PATCH] add acpi suspend test scenario Test to trigger periodically ACPI suspend and resume and periodically trying to restart graphic driver. Tested successfully with X201 and T420. Issue #4669 --- repos/libports/run/acpi_suspend.run | 381 +++++++++++++++++++ repos/libports/src/test/suspend/component.cc | 124 ++++++ repos/libports/src/test/suspend/target.mk | 5 + 3 files changed, 510 insertions(+) create mode 100644 repos/libports/run/acpi_suspend.run create mode 100644 repos/libports/src/test/suspend/component.cc create mode 100644 repos/libports/src/test/suspend/target.mk diff --git a/repos/libports/run/acpi_suspend.run b/repos/libports/run/acpi_suspend.run new file mode 100644 index 0000000000..d564adf64b --- /dev/null +++ b/repos/libports/run/acpi_suspend.run @@ -0,0 +1,381 @@ +# +# Test to trigger periodically ACPI suspend and resume and periodically +# trying to restart graphic driver. +# +# The pc_intel_fb_drv is restarting on X201 successfully after resume. +# On Qemu the restart of vesa_fb_drv after resume does not work up to now. +# +# Intel AMT SOL most the time does not work after resume. +# PCMCIA Serial card worked reliable on X201 after resume. +# + +assert_spec x86 +assert_spec nova + +# non Intel machines has no GPU support, e.g. Qemu and AMD +set board_non_intel [expr [have_include "power_on/qemu"]] + +if {$board_non_intel} { + set fb_platform_service "platform_drv" +} else { + set fb_platform_service "intel_gpu_drv" +} + + +proc display_config { } { + global board_non_intel + + if {$board_non_intel} { + return { + + + + + + + + } + } + + return { + + + + + + + } +} + +proc gpu_config { } { + global board_non_intel + + if {$board_non_intel} return + + return { + + + + + + + + + + + + + + + + + + + + + + + + } +} + + +set build_components { + core timer init + server/report_rom + server/dynamic_rom + server/rom_filter + drivers/acpi + drivers/platform + drivers/framebuffer/intel/pc + drivers/framebuffer/vesa + drivers/framebuffer/boot + drivers/gpu/intel + app/acpica + app/pci_decode + test/framebuffer + test/suspend +} + +build $build_components + +create_boot_directory + +set config "" +append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } [gpu_config] { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } [display_config] { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +install_config $config + +# non PCI devices for platform_drv, e.g. ps2/pit +file copy [select_from_repositories board/[board]/devices] [run_dir]/genode/devices + +set boot_modules { + core ld.lib.so init timer + report_rom dynamic_rom rom_filter + acpi_drv pc_platform_drv pci_decode + pc_intel_fb_drv test-framebuffer vesa_fb_drv intel_gpu_drv boot_fb_drv + acpica + test-suspend +} + +build_boot_image $boot_modules + +# qemu machine model q35 and multiple CPUs don't work with NOVA kernel +# +# src/lapic.cpp Acpi::delay(2) spins on PM_TMR forever +# +# According to qemu monitor "info mtree", +# +# address-space: I/O +# 0000000000000000-000000000000ffff (prio 0, i/o): io +# ... +# 0000000000000600-000000000000067f (prio 0, i/o): ich9-pm +# 0000000000000600-0000000000000603 (prio 0, i/o): acpi-evt +# 0000000000000604-0000000000000605 (prio 0, i/o): acpi-cnt +# 0000000000000608-000000000000060b (prio 0, i/o): acpi-tmr +# 0000000000000620-000000000000062f (prio 0, i/o): acpi-gpe0 +# 0000000000000630-0000000000000637 (prio 0, i/o): acpi-smi +# 0000000000000660-000000000000067f (prio 0, i/o): sm-tco +# +# address-space: I/O +# 0000000000000000-000000000000ffff (prio 0, i/o): io +# 0000000000000000-0000000000000003 (prio 0, i/o): acpi-evt +# 0000000000000004-0000000000000005 (prio 0, i/o): acpi-cnt +# 0000000000000008-000000000000000b (prio 0, i/o): acpi-tmr +# 0000000000000020-000000000000002f (prio 0, i/o): acpi-gpe0 +# 0000000000000030-0000000000000037 (prio 0, i/o): acpi-smi +# 0000000000000060-000000000000007f (prio 0, i/o): sm-tco +# +# the "ich9-pm" device behind/attached on a LPC PCI device +# +# ./hw/isa/lpc_ich9.c +# ./hw/acpi/ich9.c: memory_region_init(&pm->io, OBJECT(lpc_pci), "ich9-pm", ICH9_PMIO_SIZE) +# +# is not at the right i/o space right location anymore. It seems that the +# parent of ich9-pm stays disabled ... +# +# Further debugging shows: +# +# qemu/roms/seabios/src/resume.c s3_resume -> pci_resume +# qemu/roms/seabios/src/fw/pciinit.c pci_resume +# +# In pci_resume the mmcfg and q35 and ich9-pm for PCIe is tried to be +# re-enabled, but actually the calls never hit in Qemu. +# It seems that mch_mmconfig_setup should use I/O PCI access in order to +# enable MMIO PCI MMCFG access. +# +append qemu_args "-smp 1" + +run_genode_until forever diff --git a/repos/libports/src/test/suspend/component.cc b/repos/libports/src/test/suspend/component.cc new file mode 100644 index 0000000000..6b7b90d5e1 --- /dev/null +++ b/repos/libports/src/test/suspend/component.cc @@ -0,0 +1,124 @@ +/* + * \brief Test to trigger ACPI S3 suspend via Pd::managing_system() + * \author Alexander Boettcher + * \date 2022-08-01 + * + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#include +#include +#include + + +using namespace Genode; + + +class Suspend +{ + private: + + Env &_env; + Attached_rom_dataspace _system_rom { _env, "system" }; + Attached_rom_dataspace _sleep_support { _env, "sleep_states" }; + Signal_handler _handler { _env.ep(), *this, + &Suspend::system_update }; + + uint8_t s3_sleep_typea { }; + uint8_t s3_sleep_typeb { }; + bool s3_sleep_valid { }; + + void suspend() + { + /* + * S0: normal power on + * S1: low wake latency sleeping - cpu caches off - no reset vector used on resume in kernel ! + * S2: low wake latency sleep - start from reset vector + * S3: low wake latency sleep - some parts powered off -> "suspend to RAM" + * S4: long wake latency sleep - "suspend to disk" + * S5: soft off state + */ + + if (!s3_sleep_valid) { + warning("suspend ... denied"); + return; + } + + log("suspend S3 (", s3_sleep_typea, ",", s3_sleep_typeb, ") ..."); + + Pd_session::Managing_system_state in, out; + + in.trapno = Pd_session::Managing_system_state::ACPI_SUSPEND_REQUEST; + in.ip = s3_sleep_typea; + in.sp = s3_sleep_typeb; + + out = _env.pd().managing_system (in); + + if (!out.trapno) + log("suspend failed"); + else + log("resumed from S3"); + } + + void system_update() + { + _system_rom.update(); + _sleep_support.update(); + + if (_system_rom.valid()) { + auto state = _system_rom.xml().attribute_value("state", + String<16>("")); + + log("system update requested to '", state, "'"); + + if (state == "suspend") + suspend(); + } + + if (_sleep_support.valid()) { + _sleep_support.xml().with_optional_sub_node("S3", [&] (auto const &node) { + auto const typea = "SLP_TYPa"; + auto const typeb = "SLP_TYPb"; + + s3_sleep_valid = node.attribute_value("supported", false) && + node.has_attribute(typea) && + node.has_attribute(typeb); + + if (s3_sleep_valid) { + unsigned tmpa = node.attribute_value(typea, 0u); + unsigned tmpb = node.attribute_value(typeb, 0u); + if (tmpa < 256) + s3_sleep_typea = uint8_t(node.attribute_value(typea, 0u)); + else + s3_sleep_valid = false; + + if (tmpb < 256) + s3_sleep_typeb = uint8_t(node.attribute_value(typeb, 0u)); + else + s3_sleep_valid = false; + } + }); + } + } + + public: + + Suspend(Env &env) : _env(env) + { + _system_rom.sigh(_handler); + _sleep_support.sigh(_handler); + + system_update(); + } +}; + +void Component::construct(Genode::Env &env) +{ + static Suspend suspend(env); +} diff --git a/repos/libports/src/test/suspend/target.mk b/repos/libports/src/test/suspend/target.mk new file mode 100644 index 0000000000..b8548910ae --- /dev/null +++ b/repos/libports/src/test/suspend/target.mk @@ -0,0 +1,5 @@ +TARGET = test-suspend +SRC_CC = component.cc +LIBS = base + +REQUIRES := x86