Files
RedBear-OS/drivers/hwd/src/backend/acpi.rs
T
bjorn3 8506ae5581 init: Move daemon spawning from daemon to init
In preparation for concurrent daemon spawning.
2026-04-10 22:14:24 +02:00

112 lines
5.1 KiB
Rust

use amlserde::{AmlSerde, AmlSerdeValue};
use std::{error::Error, fs, process::Command};
use super::Backend;
pub struct AcpiBackend {
rxsdt: Vec<u8>,
}
impl Backend for AcpiBackend {
fn new() -> Result<Self, Box<dyn Error>> {
let rxsdt = fs::read("/scheme/kernel.acpi/rxsdt")?;
// Spawn acpid
//TODO: pass rxsdt data to acpid?
#[allow(deprecated, reason = "we can't yet move this to init")]
daemon::Daemon::spawn(Command::new("acpid"));
Ok(Self { rxsdt })
}
fn probe(&mut self) -> Result<(), Box<dyn Error>> {
// Read symbols from acpi scheme
let entries = fs::read_dir("/scheme/acpi/symbols")?;
// TODO: Reimplement with getdents?
let symbols_fd = libredox::Fd::open(
"/scheme/acpi/symbols",
libredox::flag::O_DIRECTORY | libredox::flag::O_RDONLY,
0,
)?;
for entry_res in entries {
let entry = entry_res?;
if let Some(file_name) = entry.file_name().to_str() {
if file_name.ends_with("_CID") || file_name.ends_with("_HID") {
let symbol_fd = symbols_fd.openat(file_name, libredox::flag::O_RDONLY, 0)?;
let stat = symbol_fd.stat()?;
let mut buf: Vec<u8> = vec![0u8; stat.st_size as usize];
let count = symbol_fd.read(&mut buf)?;
buf.truncate(count);
let ron = String::from_utf8(buf)?;
let AmlSerde { name, value } = ron::from_str(&ron)?;
let id = match value {
AmlSerdeValue::Integer(integer) => {
let vendor = integer & 0xFFFF;
let device = (integer >> 16) & 0xFFFF;
let vendor_rev = ((vendor & 0xFF) << 8) | vendor >> 8;
let vendor_1 = (((vendor_rev >> 10) & 0x1f) as u8 + 64) as char;
let vendor_2 = (((vendor_rev >> 5) & 0x1f) as u8 + 64) as char;
let vendor_3 = (((vendor_rev >> 0) & 0x1f) as u8 + 64) as char;
//TODO: simplify this nibble swap
let device_1 = (device >> 4) & 0xF;
let device_2 = (device >> 0) & 0xF;
let device_3 = (device >> 12) & 0xF;
let device_4 = (device >> 8) & 0xF;
format!(
"{}{}{}{:01X}{:01X}{:01X}{:01X}",
vendor_1,
vendor_2,
vendor_3,
device_1,
device_2,
device_3,
device_4
)
}
AmlSerdeValue::String(string) => string,
_ => {
log::warn!("{}: unsupported value {:x?}", name, value);
continue;
}
};
let what = match id.as_str() {
// https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html
"ACPI0003" => "Power source",
"ACPI0006" => "GPE block",
"ACPI0007" => "Processor",
"ACPI0010" => "Processor control",
// https://uefi.org/sites/default/files/resources/devids%20%285%29.txt
"PNP0000" => "AT interrupt controller",
"PNP0100" => "AT timer",
"PNP0103" => "HPET",
"PNP0200" => "AT DMA controller",
"PNP0303" => "IBM Enhanced (101/102-key, PS/2 mouse support)",
"PNP030B" => "PS/2 keyboard",
"PNP0400" => "Standard LPT printer port",
"PNP0501" => "16550A-compatible COM port",
"PNP0A03" | "PNP0A08" => "PCI bus",
"PNP0A05" => "Generic ACPI bus",
"PNP0A06" => "Generic ACPI Extended-IO bus (EIO bus)",
"PNP0B00" => "AT real-time clock",
"PNP0C01" => "System board",
"PNP0C02" => "Reserved resources",
"PNP0C04" => "Math coprocessor",
"PNP0C09" => "Embedded controller",
"PNP0C0A" => "Battery",
"PNP0C0B" => "Fan",
"PNP0C0C" => "Power button",
"PNP0C0D" => "Lid sensor",
"PNP0C0E" => "Sleep button",
"PNP0C0F" => "PCI interrupt link",
"PNP0C50" => "I2C HID",
"PNP0F13" => "PS/2 port for PS/2-style mouse",
_ => "?",
};
log::debug!("{}: {} ({})", name, id, what);
}
}
}
Ok(())
}
}