diff --git a/Cargo.lock b/Cargo.lock index 0d927e43bf..607c1ad322 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/acpid/Cargo.toml b/acpid/Cargo.toml index b704be076c..516aa9a78d 100644 --- a/acpid/Cargo.toml +++ b/acpid/Cargo.toml @@ -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" diff --git a/acpid/src/acpi.rs b/acpid/src/acpi.rs index 48a1f559b8..464a8a1a2c 100644 --- a/acpid/src/acpi.rs +++ b/acpid/src/acpi.rs @@ -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, // k = name, v = description symbol_cache: FxHashMap, page_cache: Arc>, @@ -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 { &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 { @@ -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 = 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; diff --git a/acpid/src/aml_physmem.rs b/acpid/src/aml_physmem.rs index ce07ba4cfe..4145a5fe00 100644 --- a/acpid/src/aml_physmem.rs +++ b/acpid/src/aml_physmem.rs @@ -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>, } @@ -147,7 +150,35 @@ impl AmlPhysMemHandler { } } -impl aml::Handler for AmlPhysMemHandler { +impl acpi::Handler for AmlPhysMemHandler { + unsafe fn map_physical_region(&self, phys: usize, size: usize) -> PhysicalMapping { + 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(region: &PhysicalMapping) { + 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::(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::(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::(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::(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"); } } diff --git a/amlserde/Cargo.toml b/amlserde/Cargo.toml index 49adbe294e..28d1b56834 100644 --- a/amlserde/Cargo.toml +++ b/amlserde/Cargo.toml @@ -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" diff --git a/amlserde/src/lib.rs b/amlserde/src/lib.rs index a7ea76b9de..7fa2f7c50e 100644 --- a/amlserde/src/lib.rs +++ b/amlserde/src/lib.rs @@ -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, }, 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, + data: Option>, }, Processor { id: u8, @@ -44,8 +52,13 @@ pub enum AmlSerdeValue { pblk_len: u8, }, Mutex { + mutex: u32, sync_level: u8, }, + Reference { + kind: AmlSerdeReferenceKind, + inner: Option>, + }, Package { contents: Vec, }, @@ -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>, + }, + Bank { + region: Option>, + bank: Option>, + bank_value: u64, + }, + Index { + index: Option>, + data: Option>, + }, +} + #[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 { - let aml_value = if let Ok(aml_value) = aml_context.namespace.get(handle.clone()) { + pub fn from_aml(aml_context: &Interpreter, aml_name: &AmlName) -> Option { + //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 { + fn from_aml_value(aml_value: &Object) -> Option { 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, -} - -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)) - } -}