Update to latest acpi crate

This commit is contained in:
Jeremy Soller
2025-09-28 08:53:18 -06:00
parent 6b335d4f90
commit 62fab168e5
6 changed files with 255 additions and 222 deletions
Generated
+17 -56
View File
@@ -17,11 +17,24 @@ dependencies = [
"spin 0.9.8",
]
[[package]]
name = "acpi"
version = "6.0.1"
source = "git+https://github.com/jackpot51/acpi.git#1c404f42bae2c1c5e8e65f6f86a956c212e97311"
dependencies = [
"bit_field",
"bitflags 2.9.0",
"byteorder",
"log",
"pci_types",
"spinning_top",
]
[[package]]
name = "acpid"
version = "0.1.0"
dependencies = [
"aml",
"acpi",
"amlserde",
"arrayvec",
"common",
@@ -77,24 +90,11 @@ dependencies = [
"redox_syscall",
]
[[package]]
name = "aml"
version = "0.16.3"
source = "git+https://github.com/rw-vanc/acpi.git?branch=cumulative#e4eb93891367e73d3633804002aa050edfbacb6e"
dependencies = [
"bit_field",
"bitvec",
"byteorder",
"log",
"spinning_top",
]
[[package]]
name = "amlserde"
version = "0.0.1"
dependencies = [
"aml",
"rustc-hash",
"acpi",
"serde",
"toml 0.7.8",
]
@@ -221,18 +221,6 @@ dependencies = [
"serde",
]
[[package]]
name = "bitvec"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]]
name = "bumpalo"
version = "3.17.0"
@@ -495,12 +483,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "funty"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "futures"
version = "0.3.31"
@@ -1059,12 +1041,6 @@ version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "radium"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "rand"
version = "0.4.6"
@@ -1441,9 +1417,9 @@ dependencies = [
[[package]]
name = "spinning_top"
version = "0.2.5"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0"
checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300"
dependencies = [
"lock_api",
]
@@ -1488,12 +1464,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "termion"
version = "4.0.5"
@@ -2007,15 +1977,6 @@ dependencies = [
"bitflags 2.9.0",
]
[[package]]
name = "wyz"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
dependencies = [
"tap",
]
[[package]]
name = "xhcid"
version = "0.1.0"
+1 -1
View File
@@ -7,7 +7,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
aml = { git = "https://github.com/rw-vanc/acpi.git", branch = "cumulative" }
acpi = { git = "https://github.com/jackpot51/acpi.git" }
log = "0.4"
num-derive = "0.3"
num-traits = "0.2"
+29 -33
View File
@@ -1,6 +1,7 @@
use rustc_hash::FxHashMap;
use std::convert::{TryFrom, TryInto};
use std::ops::Deref;
use std::str::FromStr;
use std::sync::{Arc, Mutex};
use std::{fmt, mem};
use syscall::PAGE_SIZE;
@@ -11,9 +12,13 @@ use common::io::{Io, Pio};
use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use thiserror::Error;
use aml::{AmlContext, AmlError, AmlHandle, AmlName};
use acpi::{
aml::{namespace::AmlName, AmlError, Interpreter},
platform::AcpiPlatform,
AcpiTables,
};
use amlserde::aml_serde_name::aml_to_symbol;
use amlserde::{AmlHandleLookup, AmlSerde};
use amlserde::AmlSerde;
#[cfg(target_arch = "x86_64")]
pub mod dmar;
@@ -232,7 +237,7 @@ pub struct Ssdt(Sdt);
// must empty the cache so it is rebuilt.
// If you modify an SDT, you must discard the aml_context and rebuild it.
pub struct AmlSymbols {
aml_context: AmlContext,
aml_context: Interpreter<AmlPhysMemHandler>,
// k = name, v = description
symbol_cache: FxHashMap<String, String>,
page_cache: Arc<Mutex<AmlPageCache>>,
@@ -241,17 +246,19 @@ pub struct AmlSymbols {
impl AmlSymbols {
pub fn new() -> Self {
let page_cache = Arc::new(Mutex::new(AmlPageCache::default()));
let handler = AmlPhysMemHandler::new(Arc::clone(&page_cache));
//TODO: use these parsed tables for the rest of acpid and return errors instead of unwrap
let rsdp_address = usize::from_str_radix(&std::env::var("RSDP_ADDR").unwrap(), 16).unwrap();
let tables = unsafe { AcpiTables::from_rsdp(handler.clone(), rsdp_address).unwrap() };
let platform = AcpiPlatform::new(tables, handler).unwrap();
Self {
aml_context: AmlContext::new(
Box::new(AmlPhysMemHandler::new(Arc::clone(&page_cache))),
aml::DebugVerbosity::None,
),
aml_context: Interpreter::new_from_platform(&platform).unwrap(),
symbol_cache: FxHashMap::default(),
page_cache,
}
}
pub fn mut_aml_context(&mut self) -> &mut AmlContext {
pub fn mut_aml_context(&mut self) -> &mut Interpreter<AmlPhysMemHandler> {
&mut self.aml_context
}
@@ -260,7 +267,7 @@ impl AmlSymbols {
}
pub fn parse_table(&mut self, aml: &[u8]) -> Result<(), AmlError> {
self.aml_context.parse_table(aml)
self.aml_context.load_table(aml)
}
pub fn lookup(&self, symbol: &str) -> Option<String> {
@@ -272,18 +279,19 @@ impl AmlSymbols {
}
pub fn build_cache(&mut self) {
let mut symbol_list: Vec<(AmlName, String, AmlHandle)> = Vec::with_capacity(5000);
let mut symbol_list: Vec<(AmlName, String)> = Vec::with_capacity(5000);
if self
.aml_context
.namespace
.lock()
.traverse(|level_aml_name, level| {
for (child_seg, handle) in level.values.iter() {
if let Ok(aml_name) =
AmlName::from_name_seg(child_seg.to_owned()).resolve(level_aml_name)
{
let name = aml_to_symbol(&aml_name);
symbol_list.push((aml_name, name, handle.to_owned()));
symbol_list.push((aml_name, name));
} else {
log::error!(
"AmlName resolve failed, {:?}:{:?}",
@@ -300,24 +308,12 @@ impl AmlSymbols {
return;
}
let mut handle_lookup = AmlHandleLookup::new();
for (aml_name, name, handle) in &symbol_list {
handle_lookup.insert(handle.to_owned(), aml_name.to_owned());
}
let mut symbol_cache: FxHashMap<String, String> = FxHashMap::default();
for (aml_name, name, handle) in &symbol_list {
for (aml_name, name) in &symbol_list {
// create an empty entry, in case something goes wrong with serialization
symbol_cache.insert(name.to_owned(), "".to_owned());
if let Some(ser_value) = AmlSerde::from_aml(
&mut self.aml_context,
&handle_lookup,
&aml_to_symbol(aml_name),
aml_name,
handle,
) {
if let Some(ser_value) = AmlSerde::from_aml(&mut self.aml_context, aml_name) {
if let Ok(ser_string) = ron::ser::to_string_pretty(&ser_value, Default::default()) {
// replace the empty entry
symbol_cache.insert(name.to_owned(), ser_string);
@@ -536,7 +532,7 @@ impl AcpiContext {
let aml_symbols = self.aml_symbols.read();
let s5_aml_name = match aml::AmlName::from_str("\\_S5") {
let s5_aml_name = match acpi::aml::namespace::AmlName::from_str("\\_S5") {
Ok(aml_name) => aml_name,
Err(error) => {
log::error!("Could not build AmlName for \\_S5, {:?}", error);
@@ -544,7 +540,7 @@ impl AcpiContext {
}
};
let s5 = match aml_symbols.aml_context.namespace.get_by_path(&s5_aml_name) {
let s5 = match aml_symbols.aml_context.namespace.lock().get(s5_aml_name) {
Ok(s5) => s5,
Err(error) => {
log::error!("Cannot set S-state, missing \\_S5, {:?}", error);
@@ -552,23 +548,23 @@ impl AcpiContext {
}
};
let package = match s5 {
aml::AmlValue::Package(package) => package,
let package = match s5.deref() {
acpi::aml::object::Object::Package(package) => package,
_ => {
log::error!("Cannot set S-state, \\_S5 is not a package");
return;
}
};
let slp_typa = match package[0] {
aml::AmlValue::Integer(i) => i,
let slp_typa = match package[0].deref() {
acpi::aml::object::Object::Integer(i) => i.to_owned(),
_ => {
log::error!("typa is not an Integer");
return;
}
};
let slp_typb = match package[1] {
aml::AmlValue::Integer(i) => i,
let slp_typb = match package[1].deref() {
acpi::aml::object::Object::Integer(i) => i.to_owned(),
_ => {
log::error!("typb is not an Integer");
return;
+80 -18
View File
@@ -1,9 +1,11 @@
use acpi::{aml::AmlError, Handle, PciAddress, PhysicalMapping};
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use common::io::{Io, Pio};
use num_traits::PrimInt;
use rustc_hash::FxHashMap;
use std::fmt::LowerHex;
use std::mem::size_of;
use std::ptr::NonNull;
use std::sync::{Arc, Mutex};
use syscall::PAGE_SIZE;
@@ -21,7 +23,7 @@ impl MappedPage {
common::physmap(
phys_page,
PAGE_SIZE,
common::Prot::RO,
common::Prot::RW,
common::MemoryType::default(),
)
.map_err(|error| std::io::Error::from_raw_os_error(error.errno()))?
@@ -135,6 +137,7 @@ impl AmlPageCache {
}
}
#[derive(Clone)]
pub struct AmlPhysMemHandler {
page_cache: Arc<Mutex<AmlPageCache>>,
}
@@ -147,7 +150,35 @@ impl AmlPhysMemHandler {
}
}
impl aml::Handler for AmlPhysMemHandler {
impl acpi::Handler for AmlPhysMemHandler {
unsafe fn map_physical_region<T>(&self, phys: usize, size: usize) -> PhysicalMapping<Self, T> {
let phys_page = phys & PAGE_MASK;
let offset = phys & OFFSET_MASK;
let pages = (offset + size + PAGE_SIZE - 1) / PAGE_SIZE;
let map_size = pages * PAGE_SIZE;
let virt_page = common::physmap(
phys_page,
map_size,
common::Prot::RW,
common::MemoryType::default(),
)
.expect("failed to map physical region") as usize;
PhysicalMapping {
physical_start: phys,
virtual_start: NonNull::new((virt_page + offset) as *mut T).unwrap(),
region_length: size,
mapped_length: map_size,
handler: self.clone(),
}
}
fn unmap_physical_region<T>(region: &PhysicalMapping<Self, T>) {
let virt_page = region.virtual_start.addr().get() & PAGE_MASK;
unsafe {
libredox::call::munmap(virt_page as *mut (), region.mapped_length)
.expect("failed to unmap physical region")
}
}
fn read_u8(&self, address: usize) -> u8 {
log::trace!("read u8 {:X}", address);
if let Ok(mut page_cache) = self.page_cache.lock() {
@@ -189,7 +220,7 @@ impl aml::Handler for AmlPhysMemHandler {
0
}
fn write_u8(&mut self, address: usize, value: u8) {
fn write_u8(&self, address: usize, value: u8) {
log::trace!("write u8 {:X} = {:X}", address, value);
if let Ok(mut page_cache) = self.page_cache.lock() {
if page_cache.write_to_phys::<u8>(address, value).is_ok() {
@@ -198,7 +229,7 @@ impl aml::Handler for AmlPhysMemHandler {
}
log::error!("failed to write u8 {:#x}", address);
}
fn write_u16(&mut self, address: usize, value: u16) {
fn write_u16(&self, address: usize, value: u16) {
log::trace!("write u16 {:X} = {:X}", address, value);
if let Ok(mut page_cache) = self.page_cache.lock() {
if page_cache.write_to_phys::<u16>(address, value).is_ok() {
@@ -207,7 +238,7 @@ impl aml::Handler for AmlPhysMemHandler {
}
log::error!("failed to write u16 {:#x}", address);
}
fn write_u32(&mut self, address: usize, value: u32) {
fn write_u32(&self, address: usize, value: u32) {
log::trace!("write u32 {:X} = {:X}", address, value);
if let Ok(mut page_cache) = self.page_cache.lock() {
if page_cache.write_to_phys::<u32>(address, value).is_ok() {
@@ -216,7 +247,7 @@ impl aml::Handler for AmlPhysMemHandler {
}
log::error!("failed to write u32 {:#x}", address);
}
fn write_u64(&mut self, address: usize, value: u64) {
fn write_u64(&self, address: usize, value: u64) {
log::trace!("write u64 {:X} = {:X}", address, value);
if let Ok(mut page_cache) = self.page_cache.lock() {
if page_cache.write_to_phys::<u64>(address, value).is_ok() {
@@ -282,25 +313,56 @@ impl aml::Handler for AmlPhysMemHandler {
log::error!("cannot write 0x{value:08X} to port 0x{port:04X}");
}
fn read_pci_u8(&self, seg: u16, bus: u8, dev: u8, func: u8, off: u16) -> u8 {
log::error!("read pci u8 {seg:04X}:{bus:02X}:{dev:02X}.{func:01X}@{off:04X}");
fn read_pci_u8(&self, addr: PciAddress, off: u16) -> u8 {
log::error!("read pci u8 {addr}@{off:04X}");
0
}
fn read_pci_u16(&self, seg: u16, bus: u8, dev: u8, func: u8, off: u16) -> u16 {
log::error!("read pci u16 {seg:04X}:{bus:02X}:{dev:02X}.{func:01X}@{off:04X}");
fn read_pci_u16(&self, addr: PciAddress, off: u16) -> u16 {
log::error!("read pci u16 {addr}@{off:04X}");
0
}
fn read_pci_u32(&self, seg: u16, bus: u8, dev: u8, func: u8, off: u16) -> u32 {
log::error!("read pci u32 {seg:04X}:{bus:02X}:{dev:02X}.{func:01X}@{off:04X}");
fn read_pci_u32(&self, addr: PciAddress, off: u16) -> u32 {
log::error!("read pci u32 {addr}@{off:04X}");
0
}
fn write_pci_u8(&self, seg: u16, bus: u8, dev: u8, func: u8, off: u16, value: u8) {
log::error!("write pci u8 {seg:04X}:{bus:02X}:{dev:02X}.{func:01X}@{off:04X}={value:02X}");
fn write_pci_u8(&self, addr: PciAddress, off: u16, value: u8) {
log::error!("write pci u8 {addr}@{off:04X}={value:02X}");
}
fn write_pci_u16(&self, seg: u16, bus: u8, dev: u8, func: u8, off: u16, value: u16) {
log::error!("write pci u16 {seg:04X}:{bus:02X}:{dev:02X}.{func:01X}@{off:04X}={value:04X}");
fn write_pci_u16(&self, addr: PciAddress, off: u16, value: u16) {
log::error!("write pci u16 {addr}@{off:04X}={value:04X}");
}
fn write_pci_u32(&self, seg: u16, bus: u8, dev: u8, func: u8, off: u16, value: u32) {
log::error!("write pci u32 {seg:04X}:{bus:02X}:{dev:02X}.{func:01X}@{off:04X}={value:08X}");
fn write_pci_u32(&self, addr: PciAddress, off: u16, value: u32) {
log::error!("write pci u32 {addr}@{off:04X}={value:08X}");
}
fn nanos_since_boot(&self) -> u64 {
let ts = libredox::call::clock_gettime(libredox::flag::CLOCK_MONOTONIC)
.expect("failed to get time");
(ts.tv_sec as u64) * 1_000_000_000 + (ts.tv_nsec as u64)
}
fn stall(&self, microseconds: u64) {
let start = std::time::Instant::now();
while start.elapsed().as_micros() < microseconds.into() {
std::hint::spin_loop();
}
}
fn sleep(&self, milliseconds: u64) {
std::thread::sleep(std::time::Duration::from_millis(milliseconds));
}
fn create_mutex(&self) -> Handle {
log::warn!("TODO: Handler::create_mutex");
Handle(0)
}
fn acquire(&self, mutex: Handle, timeout: u16) -> Result<(), AmlError> {
log::warn!("TODO: Handler::aquire");
Ok(())
}
fn release(&self, mutex: Handle) {
log::warn!("TODO: Handler::release");
}
}
+1 -2
View File
@@ -9,7 +9,6 @@ license = "MIT/Apache-2.0"
edition = "2021"
[dependencies]
aml = { git = "https://github.com/rw-vanc/acpi.git", branch = "cumulative" }
rustc-hash = "1.1.0"
acpi = { git = "https://github.com/jackpot51/acpi.git" }
serde = { version = "1.0", features = ["derive"] }
toml = "0.7.3"
+127 -112
View File
@@ -1,7 +1,14 @@
use aml::value::{FieldAccessType, FieldUpdateRule, RegionSpace};
use aml::{AmlContext, AmlHandle, AmlName, AmlValue};
use rustc_hash::FxHashMap;
use acpi::{
aml::{
namespace::AmlName,
object::{FieldAccessType, FieldUnitKind, FieldUpdateRule, Object, ReferenceKind},
op_region::RegionSpace,
Interpreter,
},
Handler,
};
use serde::{Deserialize, Serialize};
use std::{ops::Deref, sync::atomic::Ordering};
#[derive(Debug, Serialize, Deserialize)]
pub struct AmlSerde {
@@ -11,7 +18,7 @@ pub struct AmlSerde {
#[derive(Debug, Serialize, Deserialize)]
pub enum AmlSerdeValue {
Boolean(bool),
Uninitialized,
Integer(u64),
String(String),
OpRegion {
@@ -21,14 +28,15 @@ pub enum AmlSerdeValue {
parent_device: Option<String>,
},
Field {
region: String,
kind: AmlSerdeFieldKind,
flags: AmlSerdeFieldFlags,
offset: u64,
length: u64,
},
Device,
Event(u64),
Method {
arg_count: u8,
arg_count: usize,
serialize: bool,
sync_level: u8,
},
@@ -36,7 +44,7 @@ pub enum AmlSerdeValue {
BufferField {
offset: u64,
length: u64,
data: Vec<u8>,
data: Option<Box<AmlSerdeValue>>,
},
Processor {
id: u8,
@@ -44,8 +52,13 @@ pub enum AmlSerdeValue {
pblk_len: u8,
},
Mutex {
mutex: u32,
sync_level: u8,
},
Reference {
kind: AmlSerdeReferenceKind,
inner: Option<Box<AmlSerdeValue>>,
},
Package {
contents: Vec<AmlSerdeValue>,
},
@@ -53,8 +66,9 @@ pub enum AmlSerdeValue {
system_level: u8,
resource_order: u16,
},
RawDataBuffer,
ThermalZone,
External,
Debug,
}
#[derive(Debug, Serialize, Deserialize)]
@@ -69,9 +83,26 @@ pub enum AmlSerdeRegionSpace {
IPMI,
GeneralPurposeIo,
GenericSerialBus,
Pcc,
OemDefined(u8),
}
#[derive(Debug, Serialize, Deserialize)]
pub enum AmlSerdeFieldKind {
Normal {
region: Option<Box<AmlSerdeValue>>,
},
Bank {
region: Option<Box<AmlSerdeValue>>,
bank: Option<Box<AmlSerdeValue>>,
bank_value: u64,
},
Index {
index: Option<Box<AmlSerdeValue>>,
data: Option<Box<AmlSerdeValue>>,
},
}
#[derive(Debug, Serialize, Deserialize)]
pub struct AmlSerdeFieldFlags {
pub access_type: AmlSerdeFieldAccessType,
@@ -96,6 +127,13 @@ pub enum AmlSerdeFieldUpdateRule {
WriteAsZeros,
}
#[derive(Debug, Serialize, Deserialize)]
pub enum AmlSerdeReferenceKind {
RefOf,
LocalOrArg,
Unresolved,
}
impl AmlSerde {
pub fn default() -> Self {
Self {
@@ -104,20 +142,15 @@ impl AmlSerde {
}
}
pub fn from_aml(
aml_context: &mut AmlContext,
aml_lookup: &AmlHandleLookup,
name: &String,
aml_name: &AmlName,
handle: &AmlHandle,
) -> Option<Self> {
let aml_value = if let Ok(aml_value) = aml_context.namespace.get(handle.clone()) {
pub fn from_aml<H: Handler>(aml_context: &Interpreter<H>, aml_name: &AmlName) -> Option<Self> {
//TODO: why does namespace.get not take a reference to aml_name
let aml_value = if let Ok(aml_value) = aml_context.namespace.lock().get(aml_name.clone()) {
aml_value
} else {
return None;
};
let value = if let Some(value) = AmlSerdeValue::from_aml_value(aml_value, aml_lookup) {
let value = if let Some(value) = AmlSerdeValue::from_aml_value(aml_value.deref()) {
value
} else {
return None;
@@ -135,55 +168,51 @@ impl AmlSerdeValue {
AmlSerdeValue::String("".to_owned())
}
fn from_aml_value(aml_value: &AmlValue, aml_lookup: &AmlHandleLookup) -> Option<Self> {
fn from_aml_value(aml_value: &Object) -> Option<Self> {
Some(match aml_value {
AmlValue::Boolean(b) => AmlSerdeValue::Boolean(b.to_owned()),
AmlValue::Integer(n) => AmlSerdeValue::Integer(n.to_owned()),
AmlValue::String(s) => AmlSerdeValue::String(s.to_owned()),
AmlValue::OpRegion {
region,
offset,
length,
parent_device,
} => AmlSerdeValue::OpRegion {
region: match region {
Object::Uninitialized => AmlSerdeValue::Uninitialized,
Object::Integer(n) => AmlSerdeValue::Integer(n.to_owned()),
Object::String(s) => AmlSerdeValue::String(s.to_owned()),
Object::OpRegion(region) => AmlSerdeValue::OpRegion {
region: match region.space {
RegionSpace::SystemMemory => AmlSerdeRegionSpace::SystemMemory,
RegionSpace::SystemIo => AmlSerdeRegionSpace::SystemIo,
RegionSpace::SystemIO => AmlSerdeRegionSpace::SystemIo,
RegionSpace::PciConfig => AmlSerdeRegionSpace::PciConfig,
RegionSpace::EmbeddedControl => AmlSerdeRegionSpace::EmbeddedControl,
RegionSpace::SMBus => AmlSerdeRegionSpace::SMBus,
RegionSpace::SmBus => AmlSerdeRegionSpace::SMBus,
RegionSpace::SystemCmos => AmlSerdeRegionSpace::SystemCmos,
RegionSpace::PciBarTarget => AmlSerdeRegionSpace::PciBarTarget,
RegionSpace::IPMI => AmlSerdeRegionSpace::IPMI,
RegionSpace::Ipmi => AmlSerdeRegionSpace::IPMI,
RegionSpace::GeneralPurposeIo => AmlSerdeRegionSpace::GeneralPurposeIo,
RegionSpace::GenericSerialBus => AmlSerdeRegionSpace::GenericSerialBus,
RegionSpace::OemDefined(n) => AmlSerdeRegionSpace::OemDefined(n.to_owned()),
},
offset: offset.to_owned(),
length: length.to_owned(),
parent_device: if let Some(parent) = parent_device {
Some(parent.to_string())
} else {
None
RegionSpace::Pcc => AmlSerdeRegionSpace::Pcc,
RegionSpace::Oem(n) => AmlSerdeRegionSpace::OemDefined(n.to_owned()),
},
offset: region.base,
length: region.length,
parent_device: Some(region.parent_device_path.to_string()),
},
AmlValue::Field {
region,
flags,
offset,
length,
} => AmlSerdeValue::Field {
region: if let Some((region, _handle)) = aml_lookup.get(region) {
region.to_string()
} else {
return None;
Object::FieldUnit(field) => AmlSerdeValue::Field {
kind: match &field.kind {
FieldUnitKind::Normal { region } => AmlSerdeFieldKind::Normal {
region: AmlSerdeValue::from_aml_value(region.deref()).map(Box::new),
},
FieldUnitKind::Bank {
region,
bank,
bank_value,
} => AmlSerdeFieldKind::Bank {
region: AmlSerdeValue::from_aml_value(region.deref()).map(Box::new),
bank: AmlSerdeValue::from_aml_value(bank.deref()).map(Box::new),
bank_value: bank_value.to_owned(),
},
FieldUnitKind::Index { index, data } => AmlSerdeFieldKind::Index {
index: AmlSerdeValue::from_aml_value(index.deref()).map(Box::new),
data: AmlSerdeValue::from_aml_value(data.deref()).map(Box::new),
},
},
flags: AmlSerdeFieldFlags {
access_type: match flags.access_type() {
access_type: match field.flags.access_type() {
Ok(FieldAccessType::Any) => AmlSerdeFieldAccessType::Any,
Ok(FieldAccessType::Byte) => AmlSerdeFieldAccessType::Byte,
Ok(FieldAccessType::Word) => AmlSerdeFieldAccessType::Word,
@@ -192,71 +221,82 @@ impl AmlSerdeValue {
Ok(FieldAccessType::Buffer) => AmlSerdeFieldAccessType::Buffer,
_ => return None,
},
lock_rule: flags.lock_rule(),
update_rule: match flags.field_update_rule() {
Ok(FieldUpdateRule::Preserve) => AmlSerdeFieldUpdateRule::Preserve,
Ok(FieldUpdateRule::WriteAsOnes) => AmlSerdeFieldUpdateRule::WriteAsOnes,
Ok(FieldUpdateRule::WriteAsZeros) => AmlSerdeFieldUpdateRule::WriteAsZeros,
_ => return None,
lock_rule: field.flags.lock_rule(),
update_rule: match field.flags.update_rule() {
FieldUpdateRule::Preserve => AmlSerdeFieldUpdateRule::Preserve,
FieldUpdateRule::WriteAsOnes => AmlSerdeFieldUpdateRule::WriteAsOnes,
FieldUpdateRule::WriteAsZeros => AmlSerdeFieldUpdateRule::WriteAsZeros,
},
},
offset: offset.to_owned(),
length: length.to_owned(),
offset: field.bit_index as u64,
length: field.bit_length as u64,
},
AmlValue::Device => AmlSerdeValue::Device,
AmlValue::Method { flags, code: _ } => AmlSerdeValue::Method {
Object::Device => AmlSerdeValue::Device,
Object::Event(event) => AmlSerdeValue::Event(event.load(Ordering::Relaxed)),
Object::Method { flags, code: _ } => AmlSerdeValue::Method {
arg_count: flags.arg_count(),
serialize: flags.serialize(),
sync_level: flags.sync_level(),
},
AmlValue::Buffer(buffer_data) => {
AmlSerdeValue::Buffer({ buffer_data.lock().to_owned() })
}
AmlValue::BufferField {
buffer_data,
//TODO: distinguish from Method?
Object::NativeMethod { f: _, flags } => AmlSerdeValue::Method {
arg_count: flags.arg_count(),
serialize: flags.serialize(),
sync_level: flags.sync_level(),
},
Object::Buffer(buffer_data) => AmlSerdeValue::Buffer(buffer_data.to_owned()),
Object::BufferField {
buffer,
offset,
length,
} => AmlSerdeValue::BufferField {
offset: offset.to_owned(),
length: length.to_owned(),
data: { buffer_data.lock().to_owned() },
offset: offset.to_owned() as u64,
length: length.to_owned() as u64,
data: AmlSerdeValue::from_aml_value(buffer.deref()).map(Box::new),
},
AmlValue::Processor {
id,
Object::Processor {
proc_id,
pblk_address,
pblk_len,
pblk_length,
} => AmlSerdeValue::Processor {
id: id.to_owned(),
id: proc_id.to_owned(),
pblk_address: pblk_address.to_owned(),
pblk_len: pblk_len.to_owned(),
pblk_len: pblk_length.to_owned(),
},
AmlValue::Mutex { sync_level } => AmlSerdeValue::Mutex {
Object::Mutex { mutex, sync_level } => AmlSerdeValue::Mutex {
mutex: mutex.0,
sync_level: sync_level.to_owned(),
},
AmlValue::Package(aml_contents) => AmlSerdeValue::Package {
Object::Reference { kind, inner } => AmlSerdeValue::Reference {
kind: match kind {
ReferenceKind::RefOf => AmlSerdeReferenceKind::RefOf,
ReferenceKind::LocalOrArg => AmlSerdeReferenceKind::LocalOrArg,
ReferenceKind::Unresolved => AmlSerdeReferenceKind::Unresolved,
},
inner: AmlSerdeValue::from_aml_value(inner.deref()).map(Box::new),
},
Object::Package(aml_contents) => AmlSerdeValue::Package {
contents: aml_contents
.iter()
.filter_map(|item| AmlSerdeValue::from_aml_value(item, aml_lookup))
.filter_map(|item| AmlSerdeValue::from_aml_value(item))
.collect(),
},
AmlValue::PowerResource {
Object::PowerResource {
system_level,
resource_order,
} => AmlSerdeValue::PowerResource {
system_level: system_level.to_owned(),
resource_order: resource_order.to_owned(),
},
AmlValue::ThermalZone => AmlSerdeValue::ThermalZone,
AmlValue::External => AmlSerdeValue::External,
Object::RawDataBuffer => AmlSerdeValue::RawDataBuffer,
Object::ThermalZone => AmlSerdeValue::ThermalZone,
Object::Debug => AmlSerdeValue::Debug,
})
}
}
pub mod aml_serde_name {
use aml::AmlName;
use acpi::aml::namespace::AmlName;
/// Add a leading backslash to make the name a valid
/// namespace reference
@@ -288,28 +328,3 @@ pub mod aml_serde_name {
to_symbol(&aml_name.as_string())
}
}
pub struct AmlHandleLookup {
map: FxHashMap<String, (AmlName, AmlHandle)>,
}
impl AmlHandleLookup {
pub fn new() -> Self {
Self {
map: FxHashMap::default(),
}
}
fn handle_to_key(&self, handle: &AmlHandle) -> String {
format!("{:?}", handle)
}
pub fn insert(&mut self, handle: AmlHandle, aml_name: AmlName) {
self.map
.insert(self.handle_to_key(&handle), (aml_name, handle));
}
pub fn get(&self, handle: &AmlHandle) -> Option<&(AmlName, AmlHandle)> {
self.map.get(&self.handle_to_key(handle))
}
}