Update to latest acpi crate
This commit is contained in:
Generated
+17
-56
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user