Kernel: Add support for ACPI Embedded Controllers
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <BAN/Vector.h>
|
||||
#include <kernel/ACPI/AML/Namespace.h>
|
||||
#include <kernel/ACPI/EmbeddedController.h>
|
||||
#include <kernel/ACPI/Headers.h>
|
||||
#include <kernel/Memory/Types.h>
|
||||
#include <kernel/ThreadBlocker.h>
|
||||
@@ -35,8 +36,12 @@ namespace Kernel::ACPI
|
||||
BAN::ErrorOr<void> poweroff();
|
||||
BAN::ErrorOr<void> reset();
|
||||
|
||||
BAN::ErrorOr<void> register_gpe_handler(uint8_t gpe, void (*callback)(void*), void* argument);
|
||||
|
||||
void handle_irq() override;
|
||||
|
||||
BAN::Span<BAN::UniqPtr<EmbeddedController>> embedded_controllers() { return m_embedded_controllers.span(); }
|
||||
|
||||
private:
|
||||
ACPI() = default;
|
||||
BAN::ErrorOr<void> initialize_impl();
|
||||
@@ -50,6 +55,12 @@ namespace Kernel::ACPI
|
||||
|
||||
BAN::ErrorOr<void> route_interrupt_link_device(const AML::Scope& device, uint64_t& routed_irq_mask);
|
||||
|
||||
BAN::ErrorOr<void> initialize_embedded_controller(const AML::Scope& embedded_controller);
|
||||
BAN::ErrorOr<void> initialize_embedded_controllers();
|
||||
|
||||
BAN::Optional<GAS> find_gpe_block(size_t index);
|
||||
bool enable_gpe(uint8_t gpe);
|
||||
|
||||
private:
|
||||
paddr_t m_header_table_paddr = 0;
|
||||
vaddr_t m_header_table_vaddr = 0;
|
||||
@@ -68,8 +79,23 @@ namespace Kernel::ACPI
|
||||
|
||||
ThreadBlocker m_event_thread_blocker;
|
||||
|
||||
BAN::Vector<BAN::UniqPtr<EmbeddedController>> m_embedded_controllers;
|
||||
|
||||
struct GPEHandler
|
||||
{
|
||||
bool has_callback { false };
|
||||
union {
|
||||
AML::Reference* method;
|
||||
struct
|
||||
{
|
||||
void (*callback)(void*);
|
||||
void* argument;
|
||||
};
|
||||
};
|
||||
};
|
||||
bool m_has_any_gpes { false };
|
||||
AML::Scope m_gpe_scope;
|
||||
BAN::Array<AML::Reference*, 0xFF> m_gpe_methods { nullptr };
|
||||
BAN::Array<GPEHandler, 0xFF> m_gpe_methods;
|
||||
|
||||
bool m_hardware_reduced { false };
|
||||
AML::Namespace* m_namespace { nullptr };
|
||||
|
||||
69
kernel/include/kernel/ACPI/EmbeddedController.h
Normal file
69
kernel/include/kernel/ACPI/EmbeddedController.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include <BAN/Atomic.h>
|
||||
#include <BAN/UniqPtr.h>
|
||||
|
||||
#include <kernel/ACPI/AML/Scope.h>
|
||||
#include <kernel/Lock/Mutex.h>
|
||||
#include <kernel/Thread.h>
|
||||
|
||||
namespace Kernel::ACPI
|
||||
{
|
||||
|
||||
class EmbeddedController
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<BAN::UniqPtr<EmbeddedController>> create(AML::Scope&& scope, uint16_t command_port, uint16_t data_port, BAN::Optional<uint8_t> gpe);
|
||||
~EmbeddedController();
|
||||
|
||||
BAN::ErrorOr<uint8_t> read_byte(uint8_t offset);
|
||||
BAN::ErrorOr<void> write_byte(uint8_t offset, uint8_t value);
|
||||
|
||||
const AML::Scope& scope() const { return m_scope; }
|
||||
|
||||
private:
|
||||
EmbeddedController(AML::Scope&& scope, uint16_t command_port, uint16_t data_port, bool has_gpe)
|
||||
: m_scope(BAN::move(scope))
|
||||
, m_command_port(command_port)
|
||||
, m_data_port(data_port)
|
||||
, m_has_gpe(has_gpe)
|
||||
{ }
|
||||
|
||||
private:
|
||||
void wait_status_bit(uint8_t bit, uint8_t value);
|
||||
|
||||
uint8_t read_one(uint16_t port);
|
||||
void write_one(uint16_t port, uint8_t value);
|
||||
|
||||
static void handle_gpe_wrapper(void*);
|
||||
void handle_gpe();
|
||||
|
||||
BAN::ErrorOr<void> call_query_method(uint8_t notification);
|
||||
|
||||
void thread_task();
|
||||
|
||||
struct Command
|
||||
{
|
||||
uint8_t command;
|
||||
BAN::Optional<uint8_t> data1;
|
||||
BAN::Optional<uint8_t> data2;
|
||||
uint8_t* response;
|
||||
BAN::Atomic<bool> done;
|
||||
};
|
||||
BAN::ErrorOr<void> send_command(Command& command);
|
||||
|
||||
private:
|
||||
const AML::Scope m_scope;
|
||||
const uint16_t m_command_port;
|
||||
const uint16_t m_data_port;
|
||||
const bool m_has_gpe;
|
||||
|
||||
Mutex m_mutex;
|
||||
ThreadBlocker m_thread_blocker;
|
||||
|
||||
BAN::Optional<Command*> m_queued_command;
|
||||
|
||||
Thread* m_thread { nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user