Skip to content

Commit fe31c72

Browse files
committed
Add Interpreter::new_from_tables helper method
1 parent 3e73ac4 commit fe31c72

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed

src/aml/mod.rs

+45-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub mod resource;
2323

2424
pub use pci_types::PciAddress;
2525

26+
use crate::{AcpiError, AcpiHandler, AcpiTables, AmlTable, sdt::SdtHeader};
2627
use alloc::{
2728
boxed::Box,
2829
collections::btree_map::BTreeMap,
@@ -32,7 +33,7 @@ use alloc::{
3233
vec::Vec,
3334
};
3435
use bit_field::BitField;
35-
use core::{mem, str::FromStr};
36+
use core::{mem, slice, str::FromStr};
3637
use log::{info, trace, warn};
3738
use namespace::{AmlName, Namespace, NamespaceLevelKind};
3839
use object::{
@@ -70,8 +71,8 @@ impl<H> Interpreter<H>
7071
where
7172
H: Handler,
7273
{
73-
// TODO: new_from_tables helper that does `new` and then loads the DSDT + any SSDTs
74-
74+
/// Construct a new `Interpreter`. This does not load any tables - if you have an `AcpiTables`
75+
/// already, use [`Interpreter::new_from_tables`] instead.
7576
pub fn new(handler: H, dsdt_revision: u8) -> Interpreter<H> {
7677
info!("Initializing AML interpreter v{}", env!("CARGO_PKG_VERSION"));
7778
Interpreter {
@@ -83,6 +84,46 @@ where
8384
}
8485
}
8586

87+
/// Construct a new `Interpreter` with the given set of ACPI tables. This will automatically
88+
/// load the DSDT and any SSDTs in the supplied [`AcpiTables`].
89+
// TODO: maybe merge handler types? Maybe make one a supertrait of the other?
90+
pub fn new_from_tables<AH: AcpiHandler>(
91+
acpi_handler: AH,
92+
aml_handler: H,
93+
tables: &AcpiTables<AH>,
94+
) -> Result<Interpreter<H>, AcpiError> {
95+
fn load_table<H: Handler, AH: AcpiHandler>(
96+
interpreter: &Interpreter<H>,
97+
acpi_handler: &AH,
98+
table: AmlTable,
99+
) -> Result<(), AcpiError> {
100+
let mapping = unsafe {
101+
acpi_handler.map_physical_region::<SdtHeader>(table.phys_address, table.length as usize)
102+
};
103+
let stream = unsafe {
104+
slice::from_raw_parts(
105+
mapping.virtual_start().as_ptr().byte_add(mem::size_of::<SdtHeader>()) as *const u8,
106+
table.length as usize - mem::size_of::<SdtHeader>(),
107+
)
108+
};
109+
interpreter.load_table(stream).map_err(|err| AcpiError::Aml(err))?;
110+
Ok(())
111+
}
112+
113+
let dsdt = tables.dsdt()?;
114+
let interpreter = Interpreter::new(aml_handler, dsdt.revision);
115+
load_table(&interpreter, &acpi_handler, dsdt)?;
116+
117+
for ssdt in tables.ssdts() {
118+
load_table(&interpreter, &acpi_handler, ssdt)?;
119+
}
120+
121+
Ok(interpreter)
122+
}
123+
124+
/// Load the supplied byte stream as an AML table. This should be only the encoded AML stream -
125+
/// not the header at the start of a table. If you've used [`Interpreter::new_from_tables`],
126+
/// you'll likely not need to load any tables manually.
86127
pub fn load_table(&self, stream: &[u8]) -> Result<(), AmlError> {
87128
let context = unsafe { MethodContext::new_from_table(stream) };
88129
self.do_execute_method(context)?;
@@ -93,7 +134,7 @@ where
93134
/// not a method, the object will instead be returned - this is useful for objects that can
94135
/// either be defined directly, or through a method (e.g. a `_CRS` object).
95136
pub fn invoke_method(&self, path: AmlName, args: Vec<Arc<Object>>) -> Result<Arc<Object>, AmlError> {
96-
info!("Invoking AML method: {}", path);
137+
trace!("Invoking AML method: {}", path);
97138

98139
let object = self.namespace.lock().get(path.clone())?.clone();
99140
match object.typ() {

src/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ pub unsafe trait AcpiTable {
234234
}
235235
}
236236

237-
#[derive(Clone, Copy, Debug)]
237+
#[derive(Clone, Debug)]
238238
pub enum AcpiError {
239239
NoValidRsdp,
240240
RsdpIncorrectSignature,
@@ -252,4 +252,7 @@ pub enum AcpiError {
252252
InvalidDsdtAddress,
253253
InvalidMadt(MadtError),
254254
InvalidGenericAddress,
255+
256+
#[cfg(feature = "alloc")]
257+
Aml(aml::AmlError),
255258
}

0 commit comments

Comments
 (0)