mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 15:32:25 +00:00
parent
924e1d741d
commit
c5bdc1ccbe
@ -72,8 +72,8 @@ set config {
|
|||||||
</start>}
|
</start>}
|
||||||
|
|
||||||
append_if [expr !$use_acpica_as_acpi_drv] config {
|
append_if [expr !$use_acpica_as_acpi_drv] config {
|
||||||
<start name="acpica" caps="150">
|
<start name="acpica" caps="200">
|
||||||
<resource name="RAM" quantum="5M"/>
|
<resource name="RAM" quantum="8M"/>
|
||||||
<config ld_verbose="yes" reset="no" poweroff="no" report="yes" acpi_ready="yes">
|
<config ld_verbose="yes" reset="no" poweroff="no" report="yes" acpi_ready="yes">
|
||||||
</config>
|
</config>
|
||||||
<route>
|
<route>
|
||||||
@ -178,9 +178,9 @@ append config {
|
|||||||
<map acpi="ec" value="25" to_key="KEY_VENDOR"/>
|
<map acpi="ec" value="25" to_key="KEY_VENDOR"/>
|
||||||
<map acpi="ec" value="20" to_key="KEY_BRIGHTNESSUP"/>
|
<map acpi="ec" value="20" to_key="KEY_BRIGHTNESSUP"/>
|
||||||
<map acpi="ec" value="21" to_key="KEY_BRIGHTNESSDOWN"/>
|
<map acpi="ec" value="21" to_key="KEY_BRIGHTNESSDOWN"/>
|
||||||
<map acpi="fixed" value="0" to_key="KEY_POWER" as="PRESS_RELEASE"/>
|
<map acpi="fixed" value="0" to_key="KEY_POWER" as="PRESS_RELEASE"/>
|
||||||
<map acpi="lid" value="CLOSED" to_key="KEY_SLEEP" as="PRESS"/>
|
<map acpi="lid" value="CLOSED" to_key="KEY_SLEEP" as="PRESS_RELEASE"/>
|
||||||
<map acpi="lid" value="OPEN" to_key="KEY_SLEEP" as="RELEASE"/>
|
<map acpi="lid" value="OPEN" to_key="KEY_SLEEP" as="PRESS_RELEASE"/>
|
||||||
<map acpi="ac" value="ONLINE" to_key="KEY_WAKEUP"/>
|
<map acpi="ac" value="ONLINE" to_key="KEY_WAKEUP"/>
|
||||||
<map acpi="ac" value="OFFLINE" to_key="KEY_SLEEP"/>
|
<map acpi="ac" value="OFFLINE" to_key="KEY_SLEEP"/>
|
||||||
<map acpi="battery" value="0" to_key="KEY_BATTERY"/>
|
<map acpi="battery" value="0" to_key="KEY_BATTERY"/>
|
||||||
@ -225,4 +225,30 @@ build_boot_image $boot_modules
|
|||||||
|
|
||||||
append qemu_args "-nographic "
|
append qemu_args "-nographic "
|
||||||
|
|
||||||
run_genode_until {\[init -\> acpi.*SCI IRQ:.*\n} 30
|
if {![have_include "power_on/qemu"]} {
|
||||||
|
run_genode_until {\[init -\> acpi.*SCI IRQ:.*\n} 30
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
run_genode_until {.*PS2 uses IRQ, vector 0xc.*} 30
|
||||||
|
|
||||||
|
set spawn_id $qemu_spawn_id
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
# send Ctrl-a+c to enter Qemu's monitor mode
|
||||||
|
send "\x01\x63"
|
||||||
|
|
||||||
|
# wait for monitor to become ready
|
||||||
|
run_genode_until {(qemu)} 20 $spawn_id
|
||||||
|
|
||||||
|
|
||||||
|
for {set i 0} {$i < 3} {incr i} {
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
send "system_powerdown\n"
|
||||||
|
run_genode_until {.*key count: 0.*} 3 $spawn_id
|
||||||
|
}
|
||||||
|
|
||||||
|
puts "\nTest succeeded\n"
|
||||||
|
exit 0
|
||||||
|
@ -81,7 +81,7 @@ class Ec : Acpica::Callback<Ec> {
|
|||||||
State::access_t state = ec->ec_cmdsta->inb(ec->ec_port_cmdsta);
|
State::access_t state = ec->ec_cmdsta->inb(ec->ec_port_cmdsta);
|
||||||
|
|
||||||
if (!State::Sci_evt::get(state)) {
|
if (!State::Sci_evt::get(state)) {
|
||||||
Genode::error("unknown status ", Genode::Hex(state));
|
Genode::error("unknown status ", Genode::Hex(state));
|
||||||
return ACPI_REENABLE_GPE; /* gpe is acked and re-enabled */
|
return ACPI_REENABLE_GPE; /* gpe is acked and re-enabled */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +116,9 @@ struct Acpica::Main
|
|||||||
|
|
||||||
static struct Irq_handler {
|
static struct Irq_handler {
|
||||||
UINT32 irq;
|
UINT32 irq;
|
||||||
|
Genode::Irq_session::Trigger trigger;
|
||||||
|
Genode::Irq_session::Polarity polarity;
|
||||||
|
|
||||||
ACPI_OSD_HANDLER handler;
|
ACPI_OSD_HANDLER handler;
|
||||||
void *context;
|
void *context;
|
||||||
} irq_handler;
|
} irq_handler;
|
||||||
@ -152,9 +155,10 @@ struct Acpica::Main
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sci_conn.construct(env, irq_handler.irq);
|
sci_conn.construct(env, irq_handler.irq, irq_handler.trigger, irq_handler.polarity);
|
||||||
|
|
||||||
Genode::log("SCI IRQ: ", irq_handler.irq);
|
Genode::log("SCI IRQ: ", irq_handler.irq,
|
||||||
|
" (", irq_handler.trigger, "-", irq_handler.polarity, ")");
|
||||||
|
|
||||||
sci_conn->sigh(sci_irq);
|
sci_conn->sigh(sci_irq);
|
||||||
sci_conn->ack_irq();
|
sci_conn->ack_irq();
|
||||||
@ -276,6 +280,67 @@ void Acpica::Main::init_acpica(Wait_acpi_ready wait_acpi_ready,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
using Genode::Irq_session;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ACPI Spec 2.1 General ACPI Terminology
|
||||||
|
*
|
||||||
|
* System Control Interrupt (SCI) A system interrupt used by hardware
|
||||||
|
* to notify the OS of ACPI events. The SCI is an active, low,
|
||||||
|
* shareable, level interrupt.
|
||||||
|
*/
|
||||||
|
irq_handler.irq = AcpiGbl_FADT.SciInterrupt;
|
||||||
|
irq_handler.trigger = Irq_session::TRIGGER_LEVEL;
|
||||||
|
irq_handler.polarity = Irq_session::POLARITY_LOW;
|
||||||
|
|
||||||
|
/* apply potential override in MADT */
|
||||||
|
ACPI_TABLE_MADT *madt = nullptr;
|
||||||
|
|
||||||
|
ACPI_STATUS status = AcpiGetTable(ACPI_STRING(ACPI_SIG_MADT), 0, (ACPI_TABLE_HEADER **)&madt);
|
||||||
|
if (status == AE_OK) {
|
||||||
|
using Genode::String;
|
||||||
|
|
||||||
|
for_each_element(madt, (ACPI_SUBTABLE_HEADER *) nullptr,
|
||||||
|
[&](ACPI_SUBTABLE_HEADER const * const s) {
|
||||||
|
|
||||||
|
if (s->Type != ACPI_MADT_TYPE_INTERRUPT_OVERRIDE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ACPI_MADT_INTERRUPT_OVERRIDE const * const irq =
|
||||||
|
reinterpret_cast<ACPI_MADT_INTERRUPT_OVERRIDE const * const>(s);
|
||||||
|
|
||||||
|
auto polarity_from_flags = [] (UINT16 flags) {
|
||||||
|
switch (flags & 0b11) {
|
||||||
|
case 0b01: return Irq_session::POLARITY_HIGH;
|
||||||
|
case 0b11: return Irq_session::POLARITY_LOW;
|
||||||
|
case 0b00:
|
||||||
|
default:
|
||||||
|
return Irq_session::POLARITY_UNCHANGED;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto trigger_from_flags = [] (UINT16 flags) {
|
||||||
|
switch ((flags & 0b1100) >> 2) {
|
||||||
|
case 0b01: return Irq_session::TRIGGER_EDGE;
|
||||||
|
case 0b11: return Irq_session::TRIGGER_LEVEL;
|
||||||
|
case 0b00:
|
||||||
|
default:
|
||||||
|
return Irq_session::TRIGGER_UNCHANGED;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (irq->SourceIrq == AcpiGbl_FADT.SciInterrupt) {
|
||||||
|
irq_handler.irq = irq->GlobalIrq;
|
||||||
|
irq_handler.trigger = trigger_from_flags(irq->IntiFlags);
|
||||||
|
irq_handler.polarity = polarity_from_flags(irq->IntiFlags);
|
||||||
|
|
||||||
|
AcpiGbl_FADT.SciInterrupt = irq->GlobalIrq;
|
||||||
|
}
|
||||||
|
}, [](ACPI_SUBTABLE_HEADER const * const s) { return s->Length; });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
status = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION);
|
status = AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION);
|
||||||
if (status != AE_OK) {
|
if (status != AE_OK) {
|
||||||
Genode::error("AcpiEnableSubsystem failed, status=", status);
|
Genode::error("AcpiEnableSubsystem failed, status=", status);
|
||||||
@ -398,7 +463,12 @@ struct Acpica::Main::Irq_handler Acpica::Main::irq_handler;
|
|||||||
ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 irq, ACPI_OSD_HANDLER handler,
|
ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 irq, ACPI_OSD_HANDLER handler,
|
||||||
void *context)
|
void *context)
|
||||||
{
|
{
|
||||||
Acpica::Main::irq_handler.irq = irq;
|
if (irq != Acpica::Main::irq_handler.irq) {
|
||||||
|
Genode::error("SCI interrupt is ", Acpica::Main::irq_handler.irq,
|
||||||
|
" but library requested ", irq);
|
||||||
|
return AE_BAD_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
Acpica::Main::irq_handler.handler = handler;
|
Acpica::Main::irq_handler.handler = handler;
|
||||||
Acpica::Main::irq_handler.context = context;
|
Acpica::Main::irq_handler.context = context;
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
|
@ -16,21 +16,12 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "bridge.h"
|
#include "bridge.h"
|
||||||
|
|
||||||
|
using namespace Acpica;
|
||||||
|
|
||||||
using Genode::Reporter;
|
using Genode::Reporter;
|
||||||
|
|
||||||
extern void AcpiGenodeFreeIOMem(ACPI_PHYSICAL_ADDRESS const phys, ACPI_SIZE const size);
|
extern void AcpiGenodeFreeIOMem(ACPI_PHYSICAL_ADDRESS const phys, ACPI_SIZE const size);
|
||||||
|
|
||||||
template <typename H, typename S, typename F, typename FSIZE>
|
|
||||||
void for_each_element(H const head, S *, F const &fn, FSIZE const &fn_size)
|
|
||||||
{
|
|
||||||
for(S const * e = reinterpret_cast<S const * const>(head + 1);
|
|
||||||
e < reinterpret_cast<S const *>(reinterpret_cast<char const *>(head) + head->Header.Length);
|
|
||||||
e = reinterpret_cast<S const *>(reinterpret_cast<char const *>(e) + fn_size(e)))
|
|
||||||
{
|
|
||||||
fn(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_madt(ACPI_TABLE_MADT const * const madt,
|
static void add_madt(ACPI_TABLE_MADT const * const madt,
|
||||||
Reporter::Xml_generator &xml)
|
Reporter::Xml_generator &xml)
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,9 @@
|
|||||||
* under the terms of the GNU Affero General Public License version 3.
|
* under the terms of the GNU Affero General Public License version 3.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef _ACPICA__UTIL_H_
|
||||||
|
#define _ACPICA__UTIL_H_
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "acpi.h"
|
#include "acpi.h"
|
||||||
}
|
}
|
||||||
@ -20,6 +23,9 @@ namespace Acpica {
|
|||||||
template<typename> class Buffer;
|
template<typename> class Buffer;
|
||||||
template<typename> class Callback;
|
template<typename> class Callback;
|
||||||
void generate_report(Genode::Env &, Bridge *);
|
void generate_report(Genode::Env &, Bridge *);
|
||||||
|
|
||||||
|
template <typename H, typename S, typename F, typename FSIZE>
|
||||||
|
void for_each_element(H const head, S *, F const &fn, FSIZE const &fn_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -48,3 +54,17 @@ class Acpica::Callback : public Genode::List<Acpica::Callback<T> >::Element
|
|||||||
reinterpret_cast<T *>(this)->generate(xml);
|
reinterpret_cast<T *>(this)->generate(xml);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename H, typename S, typename F, typename FSIZE>
|
||||||
|
void Acpica::for_each_element(H const head, S *, F const &fn, FSIZE const &fn_size)
|
||||||
|
{
|
||||||
|
for(S const * e = reinterpret_cast<S const * const>(head + 1);
|
||||||
|
e < reinterpret_cast<S const *>(reinterpret_cast<char const *>(head) + head->Header.Length);
|
||||||
|
e = reinterpret_cast<S const *>(reinterpret_cast<char const *>(e) + fn_size(e)))
|
||||||
|
{
|
||||||
|
fn(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _ACPICA__UTIL_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user