Skip to content

Commit ccde4c7

Browse files
committed
AML: support DefVarPackage
This necessitated also unwrapping more references for package and buffer lengths. This may need to be done elsewhere.
1 parent 4d66363 commit ccde4c7

File tree

3 files changed

+111
-8
lines changed

3 files changed

+111
-8
lines changed

src/aml/mod.rs

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ where
429429
else {
430430
panic!()
431431
};
432-
let buffer_size = buffer_size.as_integer()?;
432+
let buffer_size = buffer_size.clone().unwrap_reference().as_integer()?;
433433

434434
let buffer_len = pkg_length - (context.current_block.pc - start_pc);
435435
let mut buffer = vec![0; buffer_size as usize];
@@ -441,7 +441,7 @@ where
441441

442442
context.contribute_arg(Argument::Object(Arc::new(Object::Buffer(buffer))));
443443
}
444-
Opcode::Package => {
444+
Opcode::Package | Opcode::VarPackage => {
445445
let mut elements = Vec::with_capacity(op.expected_arguments);
446446
for arg in &op.arguments {
447447
let Argument::Object(object) = arg else { panic!() };
@@ -766,13 +766,28 @@ where
766766
*/
767767
assert!(context.block_stack.len() > 0);
768768

769-
// TODO: I think we can handle VarPackage here as well because by the
770-
// time the block finishes, the first arg should be resolvable (the var
771-
// length) and so can be updated here...
772769
if let Some(package_op) = context.in_flight.last_mut()
773-
&& package_op.op == Opcode::Package
770+
&& (package_op.op == Opcode::Package || package_op.op == Opcode::VarPackage)
774771
{
775-
let num_elements_left = package_op.expected_arguments - package_op.arguments.len();
772+
let num_elements_left = match package_op.op {
773+
Opcode::Package => package_op.expected_arguments - package_op.arguments.len(),
774+
Opcode::VarPackage => {
775+
let Argument::Object(total_elements) = &package_op.arguments[0] else {
776+
panic!()
777+
};
778+
let total_elements =
779+
total_elements.clone().unwrap_reference().as_integer()? as usize;
780+
781+
// Update the expected number of arguments to terminate the in-flight op
782+
package_op.expected_arguments = total_elements;
783+
784+
total_elements - package_op.arguments.len()
785+
}
786+
_ => panic!(
787+
"Current in-flight op is not a `Package` or `VarPackage` when finished parsing package block"
788+
),
789+
};
790+
776791
for _ in 0..num_elements_left {
777792
package_op.arguments.push(Argument::Object(Arc::new(Object::Uninitialized)));
778793
}
@@ -908,7 +923,20 @@ where
908923
context.start_in_flight_op(OpInFlight::new(Opcode::Package, num_elements as usize));
909924
context.start_new_block(BlockKind::Package, remaining_length);
910925
}
911-
Opcode::VarPackage => todo!(),
926+
Opcode::VarPackage => {
927+
let start_pc = context.current_block.pc;
928+
let pkg_length = context.pkglength()?;
929+
let remaining_length = pkg_length - (context.current_block.pc - start_pc);
930+
931+
/*
932+
* For variable packages, we're first going to parse a `TermArg` that encodes,
933+
* dynamically, how many elements the package will have. We then accept as many
934+
* elements as remain in the block, and we'll sort out how many are supposed to
935+
* be in the package later.
936+
*/
937+
context.start_in_flight_op(OpInFlight::new(Opcode::VarPackage, usize::MAX));
938+
context.start_new_block(BlockKind::Package, remaining_length);
939+
}
912940
Opcode::Method => {
913941
let start_pc = context.current_block.pc;
914942
let pkg_length = context.pkglength()?;

tests/complex_package.asl

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
DefinitionBlock ("", "DSDT", 2, "uTEST", "TESTTABL", 0xF0F0F0F0)
2+
{
3+
Method(GPKG) {
4+
Local1 = 10
5+
Local0 = Package (Local1) {
6+
0x123,
7+
0x321,
8+
Package {
9+
0x321,
10+
"123",
11+
Package {
12+
0x321,
13+
Package {
14+
0x321,
15+
"123",
16+
Package {
17+
0x321,
18+
"123",
19+
Package {
20+
0x321,
21+
Package {
22+
0x321,
23+
"123",
24+
Package (Local1) {
25+
0x321,
26+
"123",
27+
999,
28+
},
29+
999,
30+
},
31+
"123",
32+
999,
33+
},
34+
999,
35+
},
36+
999,
37+
},
38+
"123",
39+
999,
40+
},
41+
999,
42+
},
43+
"Hello world",
44+
Package {
45+
0x321,
46+
"Hello",
47+
},
48+
Package {
49+
0x321,
50+
"World",
51+
},
52+
Package {
53+
Buffer (Local1) { 0xFF },
54+
0xDEADBEEF,
55+
},
56+
Buffer { 1, 2, 3 }
57+
}
58+
59+
Return (Local0)
60+
}
61+
62+
Method (MAIN) {
63+
Local0 = GPKG()
64+
Debug = Local0
65+
Local0 = 1
66+
Return (Local0)
67+
}
68+
}

tests/package.asl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,11 @@ DefinitionBlock("package.aml", "DSDT", 1, "RSACPI", "PACKGE", 1) {
1919
Package { 0x0a, 0x0b, 0x0c },
2020
Package { 0x0d, 0x0e, 0x0f },
2121
})
22+
23+
Name(LEN, 10)
24+
Name(BAZ, Package (LEN) {
25+
4,
26+
11,
27+
16,
28+
})
2229
}

0 commit comments

Comments
 (0)