@@ -23,6 +23,7 @@ pub mod resource;
2323
2424pub use pci_types:: PciAddress ;
2525
26+ use crate :: { AcpiError , AcpiHandler , AcpiTables , AmlTable , sdt:: SdtHeader } ;
2627use alloc:: {
2728 boxed:: Box ,
2829 collections:: btree_map:: BTreeMap ,
@@ -32,7 +33,7 @@ use alloc::{
3233 vec:: Vec ,
3334} ;
3435use bit_field:: BitField ;
35- use core:: { mem, str:: FromStr } ;
36+ use core:: { mem, slice , str:: FromStr } ;
3637use log:: { info, trace, warn} ;
3738use namespace:: { AmlName , Namespace , NamespaceLevelKind } ;
3839use object:: {
@@ -70,8 +71,8 @@ impl<H> Interpreter<H>
7071where
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 {
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) ?;
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 ( ) {
0 commit comments