Update to latest acpi crate
This commit is contained in:
+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