Files
RedBear-OS/src/acpi/aml/mod.rs
T

72 lines
1.9 KiB
Rust

//! # AML
//! Code to parse and execute AML tables
use alloc::boxed::Box;
use collections::string::String;
use collections::vec::Vec;
use collections::btree_map::BTreeMap;
use core::fmt::Debug;
use core::str::FromStr;
use super::sdt::Sdt;
#[macro_use]
mod parsermacros;
mod namespace;
mod termlist;
mod namespacemodifier;
mod pkglength;
mod namestring;
mod namedobj;
mod dataobj;
mod type1opcode;
mod type2opcode;
use self::termlist::{parse_term_list, TermObj};
pub use self::namespace::{get_namespace_string, AmlValue};
// TODO: This should be able to take parameters, and may also return multiple values
pub trait AmlExecutable {
fn execute(&self, namespace: &mut BTreeMap<String, AmlValue>, scope: String) -> Option<AmlValue>;
}
// TODO: make private
pub enum AmlInternalError {
AmlParseError(&'static str),
AmlInvalidOpCode,
AmlDeferredLoad
}
pub enum AmlError {
AmlParseError(&'static str)
}
pub fn parse_aml_table(sdt: &'static Sdt) -> Result<BTreeMap<String, AmlValue>, AmlError> {
let data = sdt.data();
let term_list = match parse_term_list(data) {
Ok(res) => res,
Err(AmlInternalError::AmlParseError(s)) => return Err(AmlError::AmlParseError(s)),
Err(AmlInternalError::AmlInvalidOpCode) => return Err(AmlError::AmlParseError("Unable to match opcode")),
Err(AmlInternalError::AmlDeferredLoad) => return Err(AmlError::AmlParseError("Deferred load reached top level"))
};
let global_namespace_specifier = String::from_str("\\").unwrap();
// Unwrap is fine here. I mean come on, if this goes wrong you've got bigger problems than AML
// not loading...
let mut global_namespace = BTreeMap::new();
term_list.execute(&mut global_namespace, global_namespace_specifier.clone());
Ok(global_namespace)
}
pub fn is_aml_table(sdt: &'static Sdt) -> bool {
if &sdt.signature == b"DSDT" || &sdt.signature == b"SSDT" {
true
} else {
false
}
}