mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
parent
924e1d741d
commit
c5bdc1ccbe
@ -72,8 +72,8 @@ set config {
|
||||
</start>}
|
||||
|
||||
append_if [expr !$use_acpica_as_acpi_drv] config {
|
||||
<start name="acpica" caps="150">
|
||||
<resource name="RAM" quantum="5M"/>
|
||||
<start name="acpica" caps="200">
|
||||
<resource name="RAM" quantum="8M"/>
|
||||
<config ld_verbose="yes" reset="no" poweroff="no" report="yes" acpi_ready="yes">
|
||||
</config>
|
||||
<route>
|
||||
@ -178,9 +178,9 @@ append config {
|
||||
<map acpi="ec" value="25" to_key="KEY_VENDOR"/>
|
||||
<map acpi="ec" value="20" to_key="KEY_BRIGHTNESSUP"/>
|
||||
<map acpi="ec" value="21" to_key="KEY_BRIGHTNESSDOWN"/>
|
||||
<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="OPEN" to_key="KEY_SLEEP" as="RELEASE"/>
|
||||
<map acpi="fixed" value="0" to_key="KEY_POWER" as="PRESS_RELEASE"/>
|
||||
<map acpi="lid" value="CLOSED" to_key="KEY_SLEEP" as="PRESS_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="OFFLINE" to_key="KEY_SLEEP"/>
|
||||
<map acpi="battery" value="0" to_key="KEY_BATTERY"/>
|
||||
@ -225,4 +225,30 @@ build_boot_image $boot_modules
|
||||
|
||||
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);
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
|
@ -116,6 +116,9 @@ struct Acpica::Main
|
||||
|
||||
static struct Irq_handler {
|
||||
UINT32 irq;
|
||||
Genode::Irq_session::Trigger trigger;
|
||||
Genode::Irq_session::Polarity polarity;
|
||||
|
||||
ACPI_OSD_HANDLER handler;
|
||||
void *context;
|
||||
} irq_handler;
|
||||
@ -152,9 +155,10 @@ struct Acpica::Main
|
||||
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->ack_irq();
|
||||
@ -276,6 +280,67 @@ void Acpica::Main::init_acpica(Wait_acpi_ready wait_acpi_ready,
|
||||
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);
|
||||
if (status != AE_OK) {
|
||||
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,
|
||||
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.context = context;
|
||||
return AE_OK;
|
||||
|
@ -16,21 +16,12 @@
|
||||
#include "util.h"
|
||||
#include "bridge.h"
|
||||
|
||||
using namespace Acpica;
|
||||
|
||||
using Genode::Reporter;
|
||||
|
||||
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,
|
||||
Reporter::Xml_generator &xml)
|
||||
{
|
||||
|
@ -10,6 +10,9 @@
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _ACPICA__UTIL_H_
|
||||
#define _ACPICA__UTIL_H_
|
||||
|
||||
extern "C" {
|
||||
#include "acpi.h"
|
||||
}
|
||||
@ -20,6 +23,9 @@ namespace Acpica {
|
||||
template<typename> class Buffer;
|
||||
template<typename> class Callback;
|
||||
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>
|
||||
@ -48,3 +54,17 @@ class Acpica::Callback : public Genode::List<Acpica::Callback<T> >::Element
|
||||
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