/* * EmbeddedController.hpp * ACPI Embedded Controller (PNP0C09) transport * Copyright (c) 2026 Daniel Hammer */ #pragma once #include namespace Hal { namespace EmbeddedController { // ============================================================================ // Bring-up // ============================================================================ // Locate the EC in the ACPI namespace and latch its command/data ports. // Prefers the ECDT table when present (it is valid before the namespace // is loaded); otherwise walks the namespace for PNP0C09 and reads _CRS. // Safe to call more than once; only the first call does work. void Initialize(void* xsdt); // True once a usable command/data port pair has been found. bool IsAvailable(); // Run the namespace's _REG(EmbeddedControl, 1) methods, telling firmware // that EC region access is live. ACPI requires this once a handler for // an address space is installed, and firmware leans on it hard: EC // methods are typically guarded by a flag that _REG sets, and until it // is set they return safe do-nothing answers (a battery reports itself // absent, a thermal zone reports no temperature). Called by Initialize. void RunRegMethods(); // Log `bytes` bytes of EC address space starting at `base_`. Purely a // diagnostic: it is the only way to tell a broken handshake from a // register that genuinely reads zero. void DumpSpace(uint8_t base_, int bytes); // ============================================================================ // Transport // ============================================================================ // Read/write one byte of the EC's 256-byte address space. Both return // false on timeout or when no EC is present, leaving *value untouched. bool Read(uint8_t address, uint8_t& value); bool Write(uint8_t address, uint8_t value); }; };