44//! As always, feel free to offer PRs for improvements.
55
66pub mod handlers;
7+ pub mod tables;
78
9+ use crate :: tables:: { TestAcpiTable , bytes_to_tables} ;
810use acpi:: {
911 Handler ,
1012 PhysicalMapping ,
1113 address:: MappedGas ,
1214 aml:: { AmlError , Interpreter , namespace:: AmlName , object:: Object } ,
15+ sdt:: Signature ,
1316} ;
1417use log:: { error, trace} ;
1518use std:: {
@@ -99,6 +102,8 @@ pub enum TestFailureReason {
99102 CompileFail ,
100103 /// Some error occurred attempting to read or write the test file.
101104 FilesystemErr ,
105+ /// There was a problem interpreting the basic structure of the tables in the AML file.
106+ TablesErr ,
102107 /// Our interpreter failed to parse or execute the resulting AML.
103108 ParseFail ( AmlError ) ,
104109}
@@ -278,10 +283,11 @@ where
278283 let mut contents = Vec :: new ( ) ;
279284 file. read_to_end ( & mut contents) . unwrap ( ) ;
280285
281- const AML_TABLE_HEADER_LENGTH : usize = 36 ;
282- let stream = & contents[ AML_TABLE_HEADER_LENGTH ..] ;
286+ let Ok ( tables) = bytes_to_tables ( & contents) else {
287+ return RunTestResult :: Failed ( interpreter, TestFailureReason :: TablesErr ) ;
288+ } ;
283289
284- run_test ( stream , interpreter)
290+ run_test ( tables , interpreter)
285291}
286292
287293/// Internal function to create a temporary script file from an ASL string, plus to calculate the
@@ -307,19 +313,32 @@ fn create_script_file(asl: &'static str) -> TempScriptFile {
307313///
308314/// Arguments:
309315///
310- /// * `stream`: A slice containing the AML bytecode to test.
316+ /// * `tables`: A Vec of tables to test. The DSDT will be loaded first, if found. Other tables will
317+ /// be loaded in the order they appear in the Vec.
311318/// * `interpreter`: The interpreter to test with. The interpreter is consumed to maintain unwind
312319/// safety - if the interpreter panics, the caller should not be able to see the interpreter in
313320/// an inconsistent state.
314- pub fn run_test < T > ( stream : & [ u8 ] , interpreter : Interpreter < T > ) -> RunTestResult < T >
321+ pub fn run_test < T > ( tables : Vec < TestAcpiTable > , interpreter : Interpreter < T > ) -> RunTestResult < T >
315322where
316323 T : Handler ,
317324{
318325 // Without `AssertUnwindSafe`, the following code will not build as the Interpreter is not
319326 // unwind safe. To avoid the caller being able to see an inconsistent Interpreter, if a panic
320327 // occurs we drop the Interpreter, forcing the caller to create a new one.
321328 let result = catch_unwind ( AssertUnwindSafe ( || -> Result < ( ) , AmlError > {
322- interpreter. load_table ( stream) ?;
329+ // Load the DSDT table first, if there is one.
330+ if let Some ( dsdt) = tables. iter ( ) . find ( |t| t. header ( ) . signature == Signature :: DSDT ) {
331+ trace ! ( "Loading table: DSDT" ) ;
332+ interpreter. load_table ( dsdt. content ( ) ) ?;
333+ }
334+ let others = tables. iter ( ) . filter ( |t| t. header ( ) . signature != Signature :: DSDT ) ;
335+
336+ for t in others {
337+ trace ! ( "Loading table: {:?}" , t. header( ) . signature) ;
338+ interpreter. load_table ( t. content ( ) ) ?;
339+ }
340+
341+ trace ! ( "All tables loaded" ) ;
323342
324343 if let Some ( result) = interpreter. evaluate_if_present ( AmlName :: from_str ( "\\ MAIN" ) . unwrap ( ) , vec ! [ ] ) ? {
325344 match * result {
0 commit comments