Implemented notification API
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
use alloc::boxed::Box;
|
||||
use collections::string::String;
|
||||
use collections::btree_map::BTreeMap;
|
||||
|
||||
use super::AmlError;
|
||||
use super::parser::{ AmlParseType, ParseResult, AmlParseTypeGeneric, AmlExecutionContext, ExecutionState };
|
||||
use super::namespace::{AmlValue, ObjectReference, FieldSelector, Method, get_namespace_string,
|
||||
Accessor, BufferField, FieldUnit, Processor, PowerResource, OperationRegion};
|
||||
Accessor, BufferField, FieldUnit, Processor, PowerResource, OperationRegion,
|
||||
Device, ThermalZone};
|
||||
use super::namestring::{parse_name_string, parse_name_seg};
|
||||
use super::termlist::{parse_term_arg, parse_object_list};
|
||||
use super::pkglength::parse_pkg_length;
|
||||
@@ -428,7 +430,10 @@ fn parse_def_device(data: &[u8],
|
||||
|
||||
parse_object_list(&data[2 + pkg_length_len + name.len .. 2 + pkg_length], &mut local_ctx)?;
|
||||
|
||||
ctx.add_to_namespace(local_scope_string, AmlValue::Device(local_ctx.namespace_delta.clone()))?;
|
||||
ctx.add_to_namespace(local_scope_string, AmlValue::Device(Device {
|
||||
obj_list: local_ctx.namespace_delta.clone(),
|
||||
notify_methods: BTreeMap::new()
|
||||
}))?;
|
||||
|
||||
Ok(AmlParseType {
|
||||
val: AmlValue::None,
|
||||
@@ -893,7 +898,8 @@ fn parse_def_processor(data: &[u8],
|
||||
ctx.add_to_namespace(local_scope_string, AmlValue::Processor(Processor {
|
||||
proc_id: proc_id,
|
||||
p_blk: if p_blk_len > 0 { Some(p_blk_addr) } else { None },
|
||||
obj_list: local_ctx.namespace_delta.clone()
|
||||
obj_list: local_ctx.namespace_delta.clone(),
|
||||
notify_methods: BTreeMap::new()
|
||||
}))?;
|
||||
|
||||
Ok(AmlParseType {
|
||||
@@ -922,7 +928,10 @@ fn parse_def_thermal_zone(data: &[u8],
|
||||
let mut local_ctx = AmlExecutionContext::new(local_scope_string.clone());
|
||||
parse_object_list(&data[2 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?;
|
||||
|
||||
ctx.add_to_namespace(local_scope_string, AmlValue::ThermalZone(local_ctx.namespace_delta.clone()))?;
|
||||
ctx.add_to_namespace(local_scope_string, AmlValue::ThermalZone(ThermalZone {
|
||||
obj_list: local_ctx.namespace_delta.clone(),
|
||||
notify_methods: BTreeMap::new()
|
||||
}))?;
|
||||
|
||||
Ok(AmlParseType {
|
||||
val: AmlValue::None,
|
||||
|
||||
@@ -2,6 +2,7 @@ use alloc::boxed::Box;
|
||||
use collections::string::String;
|
||||
use collections::string::ToString;
|
||||
use collections::vec::Vec;
|
||||
use collections::btree_map::BTreeMap;
|
||||
|
||||
use core::fmt::{Debug, Formatter, Error};
|
||||
use core::str::FromStr;
|
||||
@@ -57,11 +58,24 @@ pub struct FieldUnit {
|
||||
pub length: usize
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Device {
|
||||
pub obj_list: Vec<String>,
|
||||
pub notify_methods: BTreeMap<u8, Vec<fn()>>
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ThermalZone {
|
||||
pub obj_list: Vec<String>,
|
||||
pub notify_methods: BTreeMap<u8, Vec<fn()>>
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Processor {
|
||||
pub proc_id: u8,
|
||||
pub p_blk: Option<u32>,
|
||||
pub obj_list: Vec<String>
|
||||
pub obj_list: Vec<String>,
|
||||
pub notify_methods: BTreeMap<u8, Vec<fn()>>
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -103,7 +117,7 @@ pub enum AmlValue {
|
||||
BufferField(BufferField),
|
||||
DDBHandle(Vec<String>),
|
||||
DebugObject,
|
||||
Device(Vec<String>),
|
||||
Device(Device),
|
||||
Event(u64),
|
||||
FieldUnit(FieldUnit),
|
||||
Integer(u64),
|
||||
@@ -117,7 +131,7 @@ pub enum AmlValue {
|
||||
PowerResource(PowerResource),
|
||||
Processor(Processor),
|
||||
RawDataBuffer(Vec<u8>),
|
||||
ThermalZone(Vec<String>)
|
||||
ThermalZone(ThermalZone)
|
||||
}
|
||||
|
||||
impl Debug for AmlValue {
|
||||
@@ -246,7 +260,7 @@ impl AmlValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_as_device(&self) -> Result<Vec<String>, AmlError> {
|
||||
pub fn get_as_device(&self) -> Result<Device, AmlError> {
|
||||
match *self {
|
||||
AmlValue::Device(ref s) => Ok(s.clone()),
|
||||
_ => Err(AmlError::AmlValueError)
|
||||
@@ -397,7 +411,7 @@ impl AmlValue {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_as_thermal_zone(&self) -> Result<Vec<String>, AmlError> {
|
||||
pub fn get_as_thermal_zone(&self) -> Result<ThermalZone, AmlError> {
|
||||
match *self {
|
||||
AmlValue::ThermalZone(ref p) => Ok(p.clone()),
|
||||
_ => Err(AmlError::AmlValueError)
|
||||
|
||||
@@ -177,12 +177,38 @@ fn parse_def_notify(data: &[u8],
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: This requires significantly more infrastructure from the OS itself, see 5.6.6
|
||||
parser_opcode!(data, 0x86);
|
||||
|
||||
let object = parse_super_name(&data[1..], ctx)?;
|
||||
let value = parse_term_arg(&data[1 + object.len..], ctx)?;
|
||||
|
||||
let number = value.val.get_as_integer()? as u8;
|
||||
|
||||
match ctx.get(object.val)? {
|
||||
AmlValue::Device(d) => {
|
||||
if let Some(methods) = d.notify_methods.get(&number) {
|
||||
for method in methods {
|
||||
method();
|
||||
}
|
||||
}
|
||||
},
|
||||
AmlValue::Processor(d) => {
|
||||
if let Some(methods) = d.notify_methods.get(&number) {
|
||||
for method in methods {
|
||||
method();
|
||||
}
|
||||
}
|
||||
},
|
||||
AmlValue::ThermalZone(d) => {
|
||||
if let Some(methods) = d.notify_methods.get(&number) {
|
||||
for method in methods {
|
||||
method();
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => return Err(AmlError::AmlValueError)
|
||||
}
|
||||
|
||||
Ok(AmlParseType {
|
||||
val: AmlValue::None,
|
||||
len: 1 + object.len + value.len
|
||||
|
||||
Reference in New Issue
Block a user