Expose AML evaluation through acpi scheme
This commit is contained in:
Generated
+1
@@ -50,6 +50,7 @@ dependencies = [
|
||||
"redox_syscall",
|
||||
"ron",
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
|
||||
+2
-1
@@ -24,4 +24,5 @@ amlserde = { path = "../amlserde" }
|
||||
common = { path = "../common" }
|
||||
libredox = "0.1.3"
|
||||
redox-scheme = "0.6.2"
|
||||
arrayvec = "0.7.6"
|
||||
arrayvec = "0.7.6"
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
|
||||
+49
-1
@@ -1,3 +1,4 @@
|
||||
use acpi::aml::object::{Object, WrappedObject};
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::ops::Deref;
|
||||
@@ -18,7 +19,7 @@ use acpi::{
|
||||
AcpiTables,
|
||||
};
|
||||
use amlserde::aml_serde_name::aml_to_symbol;
|
||||
use amlserde::AmlSerde;
|
||||
use amlserde::{AmlSerde, AmlSerdeValue};
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub mod dmar;
|
||||
@@ -328,6 +329,21 @@ impl AmlSymbols {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum AmlEvalError {
|
||||
#[error("AML error")]
|
||||
AmlError(AmlError),
|
||||
#[error("Failed to serialize argument")]
|
||||
SerializationError,
|
||||
#[error("Failed to deserialize")]
|
||||
DeserializationError,
|
||||
}
|
||||
impl From<AmlError> for AmlEvalError {
|
||||
fn from(value: AmlError) -> Self {
|
||||
AmlEvalError::AmlError(value)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AcpiContext {
|
||||
tables: Vec<Sdt>,
|
||||
dsdt: Option<Dsdt>,
|
||||
@@ -344,6 +360,38 @@ pub struct AcpiContext {
|
||||
}
|
||||
|
||||
impl AcpiContext {
|
||||
pub fn aml_eval(
|
||||
&self,
|
||||
symbol: AmlName,
|
||||
args: Vec<AmlSerdeValue>,
|
||||
) -> Result<AmlSerdeValue, AmlEvalError> {
|
||||
let interpreter = &mut self.aml_symbols.write().aml_context;
|
||||
interpreter.acquire_global_lock(16)?;
|
||||
|
||||
let args = args
|
||||
.into_iter()
|
||||
.map(|aml_serde_value| {
|
||||
aml_serde_value
|
||||
.to_aml_object()
|
||||
.map(Object::wrap)
|
||||
.ok_or(AmlEvalError::DeserializationError)
|
||||
})
|
||||
.collect::<Result<Vec<WrappedObject>, AmlEvalError>>()?;
|
||||
|
||||
let result = interpreter.evaluate(symbol, args);
|
||||
interpreter
|
||||
.release_global_lock()
|
||||
.expect("Failed to release GIL!"); //TODO: check if this should panic
|
||||
|
||||
result
|
||||
.map_err(AmlEvalError::from)
|
||||
.map(|object| {
|
||||
AmlSerdeValue::from_aml_value(object.deref())
|
||||
.ok_or(AmlEvalError::SerializationError)
|
||||
})
|
||||
.flatten()
|
||||
}
|
||||
|
||||
pub fn init(rxsdt_physaddrs: impl Iterator<Item = u64>) -> Self {
|
||||
let tables = rxsdt_physaddrs
|
||||
.map(|physaddr| {
|
||||
|
||||
@@ -358,7 +358,7 @@ impl acpi::Handler for AmlPhysMemHandler {
|
||||
}
|
||||
|
||||
fn acquire(&self, mutex: Handle, timeout: u16) -> Result<(), AmlError> {
|
||||
log::warn!("TODO: Handler::aquire");
|
||||
log::warn!("TODO: Handler::acquire");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ use syscall::{EAGAIN, EWOULDBLOCK};
|
||||
|
||||
mod acpi;
|
||||
mod aml_physmem;
|
||||
|
||||
mod scheme;
|
||||
|
||||
fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
|
||||
+64
-9
@@ -1,9 +1,14 @@
|
||||
use acpi::aml::namespace::AmlName;
|
||||
use amlserde::aml_serde_name::to_aml_format;
|
||||
use amlserde::AmlSerdeValue;
|
||||
use core::str;
|
||||
use parking_lot::RwLockReadGuard;
|
||||
use redox_scheme::scheme::SchemeSync;
|
||||
use redox_scheme::{CallerCtx, OpenResult};
|
||||
use ron::de::SpannedError;
|
||||
use std::collections::BTreeMap;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::str::FromStr;
|
||||
use syscall::dirent::{DirEntry, DirentBuf, DirentKind};
|
||||
use syscall::schemev2::NewFdFlags;
|
||||
|
||||
@@ -12,7 +17,7 @@ use syscall::error::{Error, Result};
|
||||
use syscall::error::{EBADF, EBADFD, EINVAL, EIO, EISDIR, ENOENT, ENOTDIR};
|
||||
use syscall::flag::{MODE_DIR, MODE_FILE};
|
||||
use syscall::flag::{O_ACCMODE, O_DIRECTORY, O_RDONLY, O_STAT, O_SYMLINK};
|
||||
use syscall::EOPNOTSUPP;
|
||||
use syscall::{EOPNOTSUPP, EOVERFLOW, EPERM};
|
||||
|
||||
use crate::acpi::{AcpiContext, AmlSymbols, SdtSignature};
|
||||
|
||||
@@ -25,13 +30,14 @@ pub struct AcpiScheme<'acpi> {
|
||||
struct Handle<'a> {
|
||||
kind: HandleKind<'a>,
|
||||
stat: bool,
|
||||
allowed_to_eval: bool,
|
||||
}
|
||||
enum HandleKind<'a> {
|
||||
TopLevel,
|
||||
Tables,
|
||||
Table(SdtSignature),
|
||||
Symbols(RwLockReadGuard<'a, AmlSymbols>),
|
||||
Symbol(String),
|
||||
Symbol { name: String, description: String },
|
||||
}
|
||||
|
||||
impl HandleKind<'_> {
|
||||
@@ -41,7 +47,7 @@ impl HandleKind<'_> {
|
||||
Self::Tables => true,
|
||||
Self::Table(_) => false,
|
||||
Self::Symbols(_) => true,
|
||||
Self::Symbol(_) => false,
|
||||
Self::Symbol { .. } => false,
|
||||
}
|
||||
}
|
||||
fn len(&self, acpi_ctx: &AcpiContext) -> Result<usize> {
|
||||
@@ -51,7 +57,7 @@ impl HandleKind<'_> {
|
||||
.sdt_from_signature(signature)
|
||||
.ok_or(Error::new(EBADFD))?
|
||||
.length(),
|
||||
Self::Symbol(description) => description.len(),
|
||||
Self::Symbol { description, .. } => description.len(),
|
||||
// Directories
|
||||
Self::TopLevel | Self::Symbols(_) | Self::Tables => 0,
|
||||
})
|
||||
@@ -143,7 +149,7 @@ fn parse_table(table: &[u8]) -> Option<SdtSignature> {
|
||||
}
|
||||
|
||||
impl SchemeSync for AcpiScheme<'_> {
|
||||
fn open(&mut self, path: &str, flags: usize, _ctx: &CallerCtx) -> Result<OpenResult> {
|
||||
fn open(&mut self, path: &str, flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
|
||||
let path = path.trim_start_matches('/');
|
||||
|
||||
let flag_stat = flags & O_STAT == O_STAT;
|
||||
@@ -179,7 +185,10 @@ impl SchemeSync for AcpiScheme<'_> {
|
||||
|
||||
["symbols", symbol] => {
|
||||
if let Some(description) = self.ctx.aml_lookup(symbol) {
|
||||
HandleKind::Symbol(description)
|
||||
HandleKind::Symbol {
|
||||
name: (*symbol).to_owned(),
|
||||
description,
|
||||
}
|
||||
} else {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
@@ -194,9 +203,13 @@ impl SchemeSync for AcpiScheme<'_> {
|
||||
return Err(Error::new(ENOTDIR));
|
||||
}
|
||||
|
||||
if flags & O_ACCMODE != O_RDONLY && !flag_stat {
|
||||
let allowed_to_eval = if flags & O_ACCMODE == O_RDONLY || flag_stat {
|
||||
false
|
||||
} else if ctx.uid != 0 {
|
||||
true
|
||||
} else {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
};
|
||||
|
||||
if flags & O_SYMLINK == O_SYMLINK && !flag_stat {
|
||||
return Err(Error::new(EINVAL));
|
||||
@@ -210,6 +223,7 @@ impl SchemeSync for AcpiScheme<'_> {
|
||||
Handle {
|
||||
stat: flag_stat,
|
||||
kind,
|
||||
allowed_to_eval,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -259,7 +273,7 @@ impl SchemeSync for AcpiScheme<'_> {
|
||||
.sdt_from_signature(signature)
|
||||
.ok_or(Error::new(EBADFD))?
|
||||
.as_slice(),
|
||||
HandleKind::Symbol(description) => description.as_bytes(),
|
||||
HandleKind::Symbol { description, .. } => description.as_bytes(),
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
};
|
||||
|
||||
@@ -358,6 +372,47 @@ impl SchemeSync for AcpiScheme<'_> {
|
||||
) -> Result<usize> {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
|
||||
fn call(&mut self, id: usize, payload: &mut [u8], _metadata: &[u64]) -> Result<usize> {
|
||||
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||
if !handle.allowed_to_eval {
|
||||
return Err(Error::new(EPERM));
|
||||
}
|
||||
|
||||
let Ok(args): Result<Vec<AmlSerdeValue>, SpannedError> = ron::de::from_bytes(payload)
|
||||
else {
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
|
||||
let HandleKind::Symbol { name, .. } = &handle.kind else {
|
||||
return Err(Error::new(EBADF));
|
||||
};
|
||||
|
||||
let Ok(aml_name) = AmlName::from_str(&to_aml_format(name)) else {
|
||||
log::error!("Failed to convert symbol name: \"{name}\" to aml name!");
|
||||
return Err(Error::new(EBADF));
|
||||
};
|
||||
|
||||
let Ok(result) = self.ctx.aml_eval(aml_name, args) else {
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
|
||||
let Ok(serialized_result) = ron::ser::to_string(&result) else {
|
||||
log::error!("Failed to serialize aml result!");
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
|
||||
let byte_result = serialized_result.as_bytes();
|
||||
let result_len = byte_result.len();
|
||||
|
||||
if result_len > payload.len() {
|
||||
return Err(Error::new(EOVERFLOW));
|
||||
}
|
||||
|
||||
payload[..result_len].copy_from_slice(byte_result);
|
||||
|
||||
Ok(result_len)
|
||||
}
|
||||
}
|
||||
|
||||
impl AcpiScheme<'_> {
|
||||
|
||||
+179
-34
@@ -1,14 +1,24 @@
|
||||
use acpi::{
|
||||
aml::{
|
||||
namespace::AmlName,
|
||||
object::{FieldAccessType, FieldUnitKind, FieldUpdateRule, Object, ReferenceKind},
|
||||
op_region::RegionSpace,
|
||||
object::{
|
||||
FieldAccessType, FieldFlags, FieldUnit, FieldUnitKind, FieldUpdateRule, MethodFlags,
|
||||
Object, ReferenceKind, WrappedObject,
|
||||
},
|
||||
op_region::{OpRegion, RegionSpace},
|
||||
Interpreter,
|
||||
},
|
||||
Handler,
|
||||
Handle, Handler,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{ops::Deref, sync::atomic::Ordering};
|
||||
use std::{
|
||||
ops::{Deref, Shl},
|
||||
str::FromStr,
|
||||
sync::{
|
||||
atomic::{AtomicU64, Ordering},
|
||||
Arc,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct AmlSerde {
|
||||
@@ -25,7 +35,7 @@ pub enum AmlSerdeValue {
|
||||
region: AmlSerdeRegionSpace,
|
||||
offset: u64,
|
||||
length: u64,
|
||||
parent_device: Option<String>,
|
||||
parent_device: String,
|
||||
},
|
||||
Field {
|
||||
kind: AmlSerdeFieldKind,
|
||||
@@ -44,7 +54,7 @@ pub enum AmlSerdeValue {
|
||||
BufferField {
|
||||
offset: u64,
|
||||
length: u64,
|
||||
data: Option<Box<AmlSerdeValue>>,
|
||||
data: Box<AmlSerdeValue>,
|
||||
},
|
||||
Processor {
|
||||
id: u8,
|
||||
@@ -57,7 +67,7 @@ pub enum AmlSerdeValue {
|
||||
},
|
||||
Reference {
|
||||
kind: AmlSerdeReferenceKind,
|
||||
inner: Option<Box<AmlSerdeValue>>,
|
||||
inner: Box<AmlSerdeValue>,
|
||||
},
|
||||
Package {
|
||||
contents: Vec<AmlSerdeValue>,
|
||||
@@ -90,41 +100,53 @@ pub enum AmlSerdeRegionSpace {
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum AmlSerdeFieldKind {
|
||||
Normal {
|
||||
region: Option<Box<AmlSerdeValue>>,
|
||||
region: Box<AmlSerdeValue>,
|
||||
},
|
||||
Bank {
|
||||
region: Option<Box<AmlSerdeValue>>,
|
||||
bank: Option<Box<AmlSerdeValue>>,
|
||||
region: Box<AmlSerdeValue>,
|
||||
bank: Box<AmlSerdeValue>,
|
||||
bank_value: u64,
|
||||
},
|
||||
Index {
|
||||
index: Option<Box<AmlSerdeValue>>,
|
||||
data: Option<Box<AmlSerdeValue>>,
|
||||
index: Box<AmlSerdeValue>,
|
||||
data: Box<AmlSerdeValue>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct AmlSerdeFieldFlags {
|
||||
pub access_type: AmlSerdeFieldAccessType,
|
||||
pub lock_rule: bool,
|
||||
pub lock_rule: bool, // bit 4
|
||||
pub update_rule: AmlSerdeFieldUpdateRule,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum AmlSerdeFieldAccessType {
|
||||
Any,
|
||||
Byte,
|
||||
Word,
|
||||
DWord,
|
||||
QWord,
|
||||
Buffer,
|
||||
impl Into<u8> for AmlSerdeFieldFlags {
|
||||
fn into(self) -> u8 {
|
||||
// bits 0..4
|
||||
(self.access_type as u8) +
|
||||
// bit 4
|
||||
(self.lock_rule as u8).shl(4) +
|
||||
// bits 5..7
|
||||
(self.update_rule as u8).shl(5)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[repr(u8)]
|
||||
pub enum AmlSerdeFieldAccessType {
|
||||
Any = 0,
|
||||
Byte = 1,
|
||||
Word = 2,
|
||||
DWord = 3,
|
||||
QWord = 4,
|
||||
Buffer = 5,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[repr(u8)]
|
||||
pub enum AmlSerdeFieldUpdateRule {
|
||||
Preserve,
|
||||
WriteAsOnes,
|
||||
WriteAsZeros,
|
||||
Preserve = 0,
|
||||
WriteAsOnes = 1,
|
||||
WriteAsZeros = 2,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
@@ -168,7 +190,7 @@ impl AmlSerdeValue {
|
||||
AmlSerdeValue::String("".to_owned())
|
||||
}
|
||||
|
||||
fn from_aml_value(aml_value: &Object) -> Option<Self> {
|
||||
pub fn from_aml_value(aml_value: &Object) -> Option<Self> {
|
||||
Some(match aml_value {
|
||||
Object::Uninitialized => AmlSerdeValue::Uninitialized,
|
||||
Object::Integer(n) => AmlSerdeValue::Integer(n.to_owned()),
|
||||
@@ -190,25 +212,25 @@ impl AmlSerdeValue {
|
||||
},
|
||||
offset: region.base,
|
||||
length: region.length,
|
||||
parent_device: Some(region.parent_device_path.to_string()),
|
||||
parent_device: region.parent_device_path.to_string(),
|
||||
},
|
||||
Object::FieldUnit(field) => AmlSerdeValue::Field {
|
||||
kind: match &field.kind {
|
||||
FieldUnitKind::Normal { region } => AmlSerdeFieldKind::Normal {
|
||||
region: AmlSerdeValue::from_aml_value(region.deref()).map(Box::new),
|
||||
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),
|
||||
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),
|
||||
index: AmlSerdeValue::from_aml_value(index.deref()).map(Box::new)?,
|
||||
data: AmlSerdeValue::from_aml_value(data.deref()).map(Box::new)?,
|
||||
},
|
||||
},
|
||||
flags: AmlSerdeFieldFlags {
|
||||
@@ -252,7 +274,7 @@ impl AmlSerdeValue {
|
||||
} => AmlSerdeValue::BufferField {
|
||||
offset: offset.to_owned() as u64,
|
||||
length: length.to_owned() as u64,
|
||||
data: AmlSerdeValue::from_aml_value(buffer.deref()).map(Box::new),
|
||||
data: AmlSerdeValue::from_aml_value(buffer.deref()).map(Box::new)?,
|
||||
},
|
||||
Object::Processor {
|
||||
proc_id,
|
||||
@@ -273,7 +295,7 @@ impl AmlSerdeValue {
|
||||
ReferenceKind::LocalOrArg => AmlSerdeReferenceKind::LocalOrArg,
|
||||
ReferenceKind::Unresolved => AmlSerdeReferenceKind::Unresolved,
|
||||
},
|
||||
inner: AmlSerdeValue::from_aml_value(inner.deref()).map(Box::new),
|
||||
inner: AmlSerdeValue::from_aml_value(inner.deref()).map(Box::new)?,
|
||||
},
|
||||
Object::Package(aml_contents) => AmlSerdeValue::Package {
|
||||
contents: aml_contents
|
||||
@@ -293,6 +315,129 @@ impl AmlSerdeValue {
|
||||
Object::Debug => AmlSerdeValue::Debug,
|
||||
})
|
||||
}
|
||||
pub fn to_aml_object(self) -> Option<Object> {
|
||||
Some(match self {
|
||||
AmlSerdeValue::Uninitialized => Object::Uninitialized,
|
||||
AmlSerdeValue::Integer(n) => Object::Integer(n),
|
||||
AmlSerdeValue::String(s) => Object::String(s),
|
||||
AmlSerdeValue::OpRegion {
|
||||
region,
|
||||
offset,
|
||||
length,
|
||||
parent_device,
|
||||
} => Object::OpRegion(OpRegion {
|
||||
space: match region {
|
||||
AmlSerdeRegionSpace::PciConfig => RegionSpace::PciConfig,
|
||||
AmlSerdeRegionSpace::EmbeddedControl => RegionSpace::EmbeddedControl,
|
||||
AmlSerdeRegionSpace::SMBus => RegionSpace::SmBus,
|
||||
AmlSerdeRegionSpace::SystemCmos => RegionSpace::SystemCmos,
|
||||
AmlSerdeRegionSpace::PciBarTarget => RegionSpace::PciBarTarget,
|
||||
AmlSerdeRegionSpace::IPMI => RegionSpace::Ipmi,
|
||||
AmlSerdeRegionSpace::GeneralPurposeIo => RegionSpace::GeneralPurposeIo,
|
||||
AmlSerdeRegionSpace::GenericSerialBus => RegionSpace::GenericSerialBus,
|
||||
AmlSerdeRegionSpace::SystemMemory => RegionSpace::SystemMemory,
|
||||
AmlSerdeRegionSpace::SystemIo => RegionSpace::SystemIO,
|
||||
AmlSerdeRegionSpace::Pcc => RegionSpace::Pcc,
|
||||
AmlSerdeRegionSpace::OemDefined(n) => RegionSpace::Oem(n),
|
||||
},
|
||||
base: offset,
|
||||
length,
|
||||
//
|
||||
parent_device_path: AmlName::from_str(&parent_device).ok()?, // TODO: Error value hidden
|
||||
}),
|
||||
AmlSerdeValue::Field {
|
||||
kind,
|
||||
flags,
|
||||
offset,
|
||||
length,
|
||||
} => Object::FieldUnit(FieldUnit {
|
||||
kind: match kind {
|
||||
AmlSerdeFieldKind::Normal { region } => FieldUnitKind::Normal {
|
||||
region: region.to_aml_object()?.wrap(),
|
||||
},
|
||||
AmlSerdeFieldKind::Bank {
|
||||
region,
|
||||
bank,
|
||||
bank_value,
|
||||
} => FieldUnitKind::Bank {
|
||||
region: region.to_aml_object()?.wrap(),
|
||||
bank: bank.to_aml_object()?.wrap(),
|
||||
bank_value: bank_value.to_owned(),
|
||||
},
|
||||
AmlSerdeFieldKind::Index { index, data } => FieldUnitKind::Index {
|
||||
index: index.to_aml_object()?.wrap(),
|
||||
data: data.to_aml_object()?.wrap(),
|
||||
},
|
||||
},
|
||||
flags: FieldFlags(flags.into()),
|
||||
bit_index: offset as usize,
|
||||
bit_length: length as usize,
|
||||
}),
|
||||
AmlSerdeValue::Device => Object::Device,
|
||||
AmlSerdeValue::Event(event) => Object::Event(Arc::new(AtomicU64::new(event))),
|
||||
AmlSerdeValue::Method {
|
||||
arg_count,
|
||||
serialize,
|
||||
sync_level,
|
||||
} => Object::Method {
|
||||
code: (return None), //TODO figure out what to do here
|
||||
//TODO check specs to see if all bit patterns are allowed
|
||||
flags: MethodFlags(
|
||||
(arg_count as u8).clamp(0, 7)
|
||||
+ (serialize as u8).shl(3)
|
||||
+ sync_level.clamp(0, 15).shl(4),
|
||||
),
|
||||
},
|
||||
//TODO: handle native method?
|
||||
AmlSerdeValue::Buffer(buffer_data) => Object::Buffer(buffer_data),
|
||||
AmlSerdeValue::BufferField {
|
||||
data,
|
||||
offset,
|
||||
length,
|
||||
} => Object::BufferField {
|
||||
offset: offset as usize,
|
||||
length: length as usize,
|
||||
buffer: data.to_aml_object()?.wrap(),
|
||||
},
|
||||
AmlSerdeValue::Processor {
|
||||
id,
|
||||
pblk_address,
|
||||
pblk_len,
|
||||
} => Object::Processor {
|
||||
proc_id: id,
|
||||
pblk_address,
|
||||
pblk_length: pblk_len,
|
||||
},
|
||||
AmlSerdeValue::Mutex { mutex, sync_level } => Object::Mutex {
|
||||
mutex: Handle(mutex),
|
||||
sync_level: sync_level,
|
||||
},
|
||||
AmlSerdeValue::Reference { kind, inner } => Object::Reference {
|
||||
kind: match kind {
|
||||
AmlSerdeReferenceKind::RefOf => ReferenceKind::RefOf,
|
||||
AmlSerdeReferenceKind::LocalOrArg => ReferenceKind::LocalOrArg,
|
||||
AmlSerdeReferenceKind::Unresolved => ReferenceKind::Unresolved,
|
||||
},
|
||||
inner: inner.to_aml_object()?.wrap(),
|
||||
},
|
||||
AmlSerdeValue::Package { contents } => Object::Package(
|
||||
contents
|
||||
.into_iter()
|
||||
.map(|item| item.to_aml_object().map(Object::wrap)) // TODO: see if errors should be ignored here
|
||||
.collect::<Option<Vec<WrappedObject>>>()?,
|
||||
),
|
||||
AmlSerdeValue::PowerResource {
|
||||
system_level,
|
||||
resource_order,
|
||||
} => Object::PowerResource {
|
||||
system_level: system_level.to_owned(),
|
||||
resource_order: resource_order.to_owned(),
|
||||
},
|
||||
AmlSerdeValue::RawDataBuffer => Object::RawDataBuffer,
|
||||
AmlSerdeValue::ThermalZone => Object::ThermalZone,
|
||||
AmlSerdeValue::Debug => Object::Debug,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub mod aml_serde_name {
|
||||
|
||||
Reference in New Issue
Block a user