feat: add kernel ACPI support for querying battery percentage, add battery indicator to desktop, move log state to 0:/state directory

This commit is contained in:
daniel committed 2026-09-11 07:11:48 +02:00
1 parent 0a18b2cf2d
commit e641500b40
34 files changed
+2461 -100

No files matched your search

+67 -22
View File
@@ -319,6 +319,58 @@ namespace Hal {
// EnumerateAll
// ============================================================================
// Fill one DeviceInfo from a namespace node.
static void DescribeDevice(AML::Namespace& ns, int32_t idx, DeviceInfo& dev) {
dev.NodeIndex = idx;
ns.GetNodePath(idx, dev.Path, 128);
dev.Status = EvaluateSta(idx);
dev.IsPresent = (dev.Status & STA_PRESENT) && (dev.Status & STA_FUNCTIONAL);
if (!EvaluateHid(idx, dev.HardwareId, 16))
dev.HardwareId[0] = '\0';
if (!EvaluateUid(idx, dev.UniqueId, 16))
dev.UniqueId[0] = '\0';
dev.Address = EvaluateAdr(idx);
}
// ============================================================================
// FindDeviceByHid
// ============================================================================
bool FindDeviceByHid(const char* hid, DeviceInfo& out) {
auto& interp = AML::GetInterpreter();
if (!interp.IsInitialized()) return false;
auto& ns = interp.GetNamespace();
int32_t found = -1;
// Only _HID is evaluated per candidate; the full description is
// built once, for the match. WalkDescendants has no early exit, so
// the first match wins and later ones are ignored.
ns.WalkDescendants(ns.RootIndex(), AML::ObjectType::Device,
[&](int32_t idx, [[maybe_unused]] const AML::NamespaceNode* node) {
if (found >= 0) return;
char candidate[16];
if (!EvaluateHid(idx, candidate, 16)) return;
if (StrEqual(candidate, hid)) found = idx;
});
if (found < 0) return false;
out = DeviceInfo{};
DescribeDevice(ns, found, out);
return true;
}
// ============================================================================
// EnumerateAll
// ============================================================================
void EnumerateAll(DeviceList& result) {
auto& interp = AML::GetInterpreter();
@@ -326,39 +378,32 @@ namespace Hal {
auto& ns = interp.GetNamespace();
result.Count = 0;
result.Truncated = false;
// Walk all namespace nodes looking for Device objects
ns.WalkDescendants(ns.RootIndex(), AML::ObjectType::Device,
[&](int32_t idx, [[maybe_unused]] const AML::NamespaceNode* node) {
if (result.Count >= MaxDevices) return;
auto& dev = result.Devices[result.Count];
dev.NodeIndex = idx;
// Get the path
ns.GetNodePath(idx, dev.Path, 128);
// Evaluate _STA
dev.Status = EvaluateSta(idx);
dev.IsPresent = (dev.Status & STA_PRESENT) && (dev.Status & STA_FUNCTIONAL);
// Evaluate _HID
if (!EvaluateHid(idx, dev.HardwareId, 16))
dev.HardwareId[0] = '\0';
// Evaluate _UID
if (!EvaluateUid(idx, dev.UniqueId, 16))
dev.UniqueId[0] = '\0';
// Evaluate _ADR
dev.Address = EvaluateAdr(idx);
if (result.Count >= MaxDevices) {
result.Truncated = true;
return;
}
DescribeDevice(ns, idx, result.Devices[result.Count]);
result.Count++;
});
KernelLogStream(OK, "ACPI") << "Enumerated " << base::dec
<< (uint64_t)result.Count << " ACPI devices";
// The list is a fixed-size stack object, so a large namespace runs
// past it. Say so: a device missing from the log below may simply
// be one that did not fit, and looking it up by HID still works.
if (result.Truncated) {
KernelLogStream(WARNING, "ACPI") << "Device list truncated at "
<< base::dec << (uint64_t)MaxDevices
<< "; use FindDeviceByHid to reach the rest";
}
// Log discovered devices
for (int i = 0; i < result.Count; i++) {
auto& dev = result.Devices[i];