acpica: report last completed action

triggered by the "system" ROM change. With this information the consumers
of the sleep_states report can determine, when the operation is finished.

Issue #5180
This commit is contained in:
Alexander Boettcher 2024-04-12 15:52:16 +02:00 committed by Christian Helmuth
parent 3471fce672
commit 94b3e30f90
5 changed files with 30 additions and 15 deletions

View File

@ -15,6 +15,7 @@
<rom label="acpica"/>
</content>
<config reset="yes" poweroff="yes" report="yes" report_period_ms="20000" use_gpe="false"/>
<config reset="yes" poweroff="yes" report="yes" report_period_ms="20000"
use_gpe="no" sleep="yes"/>
</runtime>

View File

@ -729,8 +729,8 @@ append config {
<!--
TODO: for a real OS scenario, e.g. Sculpt OS -
wait until s3_prepare is done, e.g. evaluate an
ACPICA report !?
waits until s3_prepare is done, e.g. evaluate the
ACPICA sleep_state report!
-->
<inline description="suspend system">

View File

@ -52,15 +52,19 @@ using namespace Genode;
struct Acpica::Statechange
{
Signal_handler<Acpica::Statechange> _dispatcher;
Attached_rom_dataspace _system_state;
Attached_rom_dataspace _system_state;
Expanding_reporter &_report_sleep_states;
bool _enable_reset;
bool _enable_poweroff;
bool _enable_sleep;
Statechange(Env &env, bool reset, bool poweroff, bool sleep)
Statechange(Env &env, bool reset, bool poweroff, bool sleep,
Expanding_reporter &report)
:
_dispatcher(env.ep(), *this, &Statechange::state_changed),
_system_state(env, "system"),
_report_sleep_states(report),
_enable_reset(reset), _enable_poweroff(poweroff), _enable_sleep(sleep)
{
_system_state.sigh(_dispatcher);
@ -68,8 +72,7 @@ struct Acpica::Statechange
state_changed();
}
template <typename T>
void suspend_prepare_check(T const &state)
void suspend_prepare_check(auto const &state)
{
if (!_enable_sleep)
return;
@ -90,10 +93,13 @@ struct Acpica::Statechange
if (ACPI_FAILURE(res))
Genode::error("AcpiEnterSleepStatePrep failed ",
res, " ", AcpiFormatException(res));
_report_sleep_states.generate([&] (auto & xml) {
Acpica::generate_suspend_report(xml, state);
});
}
template <typename T>
void resume_check(T const &state)
void resume_check(auto const &state)
{
if (!_enable_sleep)
return;
@ -117,6 +123,10 @@ struct Acpica::Statechange
if (ACPI_FAILURE(res))
Genode::error("AcpiLeaveSleepState failed ",
res, " ", AcpiFormatException(res));
_report_sleep_states.generate([&] (auto & xml) {
Acpica::generate_suspend_report(xml, state);
});
}
void state_changed() {
@ -216,7 +226,7 @@ struct Acpica::Main
if (enable_reset || enable_poweroff || enable_sleep)
new (heap) Acpica::Statechange(env, enable_reset, enable_poweroff,
enable_sleep);
enable_sleep, report_sleep_states);
if (periodic_ms) {
timer.sigh(timer_trigger);
@ -422,7 +432,7 @@ void Acpica::Main::init_acpica(bool const use_gpe)
/* report S0-S5 support and the SLP_TYPa/b values to be used by kernel(s) */
report_sleep_states.generate([&] (auto &xml) {
Acpica::generate_suspend_report(xml);
Acpica::generate_suspend_report(xml, "S0");
});
/* use dbg level to steer error reporting in pci.cc */

View File

@ -17,10 +17,14 @@
using namespace Acpica;
using Genode::Reporter;
void Acpica::generate_suspend_report(Reporter::Xml_generator &xml)
void Acpica::generate_suspend_report(Reporter::Xml_generator &xml,
String<32> const &state)
{
static unsigned version = 0;
xml.attribute("version" , version++);
xml.attribute("complete" , state);
for (unsigned sleep_state = 1; sleep_state < ACPI_S_STATE_COUNT; sleep_state ++) {
UINT8 slp_typa {};
UINT8 slp_typb {};

View File

@ -31,7 +31,7 @@ namespace Acpica {
template <typename H, typename S, typename F, typename FSIZE>
void for_each_element(H const head, S *, F const &fn, FSIZE const &fn_size);
void generate_suspend_report(Genode::Reporter::Xml_generator &);
void generate_suspend_report(Reporter::Xml_generator &, String<32> const &);
void init_printf(Env &);
}