Skip to content

Commit b82dcef

Browse files
committed
Remove some panics in AML interpreter
- Do not panic by default on fatal errors - Do not panic on encountering `DefLoad` or `DefLoadTable` - Do not panic on `DefNotify` - Add correct object type for `RawDataBuffer`s - Correctly handle `AccessField` and `ExtendedAccessField` - Partially handle stores to names
1 parent 2cae019 commit b82dcef

File tree

2 files changed

+84
-16
lines changed

2 files changed

+84
-16
lines changed

src/aml/mod.rs

Lines changed: 82 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,17 @@ where
561561
});
562562
}
563563
}
564+
Opcode::Notify => {
565+
// TODO: may need special handling on the node to get path?
566+
let [Argument::Namestring(name), Argument::Object(value)] = &op.arguments[..] else {
567+
panic!();
568+
};
569+
let value = value.as_integer()?;
570+
571+
info!("Notify {:?} with value {}", name, value);
572+
// TODO: support
573+
return Err(AmlError::LibUnimplemented);
574+
}
564575
Opcode::FromBCD => self.do_from_bcd(&mut context, op)?,
565576
Opcode::ToBCD => self.do_to_bcd(&mut context, op)?,
566577
Opcode::Name => {
@@ -581,6 +592,7 @@ where
581592
let arg = arg.as_integer()?;
582593
self.handler.handle_fatal_error(*typ, *code, arg);
583594
context.retire_op(op);
595+
return Err(AmlError::FatalErrorEncountered);
584596
}
585597
Opcode::OpRegion => {
586598
let [
@@ -822,6 +834,35 @@ where
822834
context.contribute_arg(Argument::Object(result));
823835
context.retire_op(op);
824836
}
837+
Opcode::Load => {
838+
let [Argument::Namestring(object), Argument::Object(result)] = &op.arguments[..] else {
839+
panic!();
840+
};
841+
// TODO: read the AML from the object and load it
842+
warn!("Ignoring unsupported DefLoad operation (object={}, result = {})", object, result);
843+
context.retire_op(op);
844+
return Err(AmlError::LibUnimplemented);
845+
}
846+
Opcode::LoadTable => {
847+
let [
848+
Argument::Object(signature),
849+
Argument::Object(oem_id),
850+
Argument::Object(oem_table_id),
851+
Argument::Object(root_path),
852+
Argument::Object(parameter_path),
853+
Argument::Object(parameter_data),
854+
] = &op.arguments[..]
855+
else {
856+
panic!();
857+
};
858+
// TODO: search for the table in the RSDT/XSDT and load the contained AML
859+
warn!(
860+
"Ignoring unsupported DefLoadTable operation (signature = {}, oem_id = {}, oem_table_id = {}, root_path = {}, parameter_path = {}, parameter_data = {})",
861+
signature, oem_id, oem_table_id, root_path, parameter_path, parameter_data
862+
);
863+
context.retire_op(op);
864+
return Err(AmlError::LibUnimplemented);
865+
}
825866
Opcode::Sleep => {
826867
let [Argument::Object(msec)] = &op.arguments[..] else { panic!() };
827868
self.handler.sleep(msec.as_integer()?);
@@ -936,7 +977,7 @@ where
936977
// XXX: 15 is reserved
937978
ObjectType::Debug => 16,
938979
ObjectType::Reference => panic!(),
939-
ObjectType::RawDataBuffer => todo!(),
980+
ObjectType::RawDataBuffer => 17,
940981
};
941982

942983
context.contribute_arg(Argument::Object(Object::Integer(typ).wrap()));
@@ -1266,8 +1307,17 @@ where
12661307
let name = name.resolve(&context.current_scope)?;
12671308
self.namespace.lock().insert(name, Object::Event(Arc::new(AtomicU64::new(0))).wrap())?;
12681309
}
1269-
Opcode::LoadTable => todo!(),
1270-
Opcode::Load => todo!(),
1310+
Opcode::LoadTable => {
1311+
context.start(OpInFlight::new(Opcode::LoadTable, &[ResolveBehaviour::TermArg; 6]));
1312+
}
1313+
Opcode::Load => {
1314+
let name = context.namestring()?;
1315+
context.start(OpInFlight::new_with(
1316+
Opcode::Load,
1317+
vec![Argument::Namestring(name)],
1318+
&[ResolveBehaviour::Target],
1319+
));
1320+
}
12711321
Opcode::Stall => context.start(OpInFlight::new(Opcode::Stall, &[ResolveBehaviour::TermArg])),
12721322
Opcode::Sleep => context.start(OpInFlight::new(Opcode::Sleep, &[ResolveBehaviour::TermArg])),
12731323
Opcode::Acquire => context.start(OpInFlight::new(opcode, &[ResolveBehaviour::SuperName])),
@@ -1710,7 +1760,7 @@ where
17101760
kind: FieldUnitKind,
17111761
start_pc: usize,
17121762
pkg_length: usize,
1713-
flags: u8,
1763+
mut flags: u8,
17141764
) -> Result<(), AmlError> {
17151765
const RESERVED_FIELD: u8 = 0x00;
17161766
const ACCESS_FIELD: u8 = 0x01;
@@ -1731,18 +1781,22 @@ where
17311781
* elements. They change the access type and attributes for remaining fields in
17321782
* the list.
17331783
*/
1734-
let _access_type = context.next()?;
1784+
let access_type = context.next()?;
17351785
let _access_attrib = context.next()?;
1736-
todo!()
1786+
flags.set_bits(0..4, access_type);
1787+
}
1788+
EXTENDED_ACCESS_FIELD => {
1789+
let access_type = context.next()?;
1790+
let _extended_access_attrib = context.next()?;
1791+
let _access_length = context.next()?;
1792+
flags.set_bits(0..4, access_type);
1793+
warn!("Ignoring extended attributes and length in ExtendedAccessField");
17371794
}
17381795
CONNECT_FIELD => {
17391796
// TODO: either consume a namestring or `BufferData` (it's not
17401797
// clear what a buffer data acc is lmao)
17411798
todo!("Connect field :(");
17421799
}
1743-
EXTENDED_ACCESS_FIELD => {
1744-
todo!("Extended access field :(");
1745-
}
17461800
_ => {
17471801
context.current_block.pc -= 1;
17481802
// TODO: this should only ever be a nameseg really...
@@ -2123,8 +2177,7 @@ where
21232177
Object::Package(_) => "[Package]".to_string(),
21242178
Object::PowerResource { .. } => "[Power Resource]".to_string(),
21252179
Object::Processor { .. } => "[Processor]".to_string(),
2126-
// TODO: what even is one of these??
2127-
Object::RawDataBuffer => todo!(),
2180+
Object::RawDataBuffer => "[Raw Data Buffer]".to_string(),
21282181
Object::String(value) => value.clone(),
21292182
Object::ThermalZone => "[Thermal Zone]".to_string(),
21302183
Object::Debug => "[Debug Object]".to_string(),
@@ -2339,10 +2392,21 @@ where
23392392
_ => panic!("Stores to objects like {:?} are not yet supported", target),
23402393
},
23412394

2342-
Argument::Namestring(_) => todo!(),
2343-
Argument::ByteData(_) | Argument::DWordData(_) | Argument::TrackedPc(_) | Argument::PkgLength(_) => {
2344-
panic!()
2395+
Argument::Namestring(name) => {
2396+
let existing = self.namespace.lock().get(name.clone());
2397+
match existing {
2398+
Ok(existing) => {
2399+
unsafe {
2400+
// TODO: this should likely be doing an implicit cast depending on object type?
2401+
*existing.gain_mut(&token) = (*object).clone();
2402+
}
2403+
}
2404+
Err(_) => {
2405+
self.namespace.lock().insert(name.clone(), object)?;
2406+
}
2407+
}
23452408
}
2409+
_ => panic!("Invalid argument type as DefStore target"),
23462410
}
23472411

23482412
Ok(to_return)
@@ -3330,6 +3394,10 @@ pub enum AmlError {
33303394
PrtInvalidSource,
33313395
PrtNoEntry,
33323396

3397+
/// An OEM-defined fatal error has occured. The specification states a host should log this
3398+
/// fatal error and then shutdown in a timely fashion.
3399+
FatalErrorEncountered,
3400+
33333401
/// This is emitted to signal that the library does not support the requested behaviour. This
33343402
/// should eventually never be emitted.
33353403
LibUnimplemented,

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ use core::{
7272
pin::Pin,
7373
ptr::NonNull,
7474
};
75-
use log::warn;
75+
use log::{error, warn};
7676
use rsdp::Rsdp;
7777

7878
/// `AcpiTables` should be constructed after finding the RSDP or RSDT/XSDT and allows enumeration
@@ -480,7 +480,7 @@ pub trait Handler: Clone {
480480

481481
#[cfg(feature = "aml")]
482482
fn handle_fatal_error(&self, fatal_type: u8, fatal_code: u32, fatal_arg: u64) {
483-
panic!(
483+
error!(
484484
"Fatal error while executing AML (encountered DefFatalOp). fatal_type = {}, fatal_code = {}, fatal_arg = {}",
485485
fatal_type, fatal_code, fatal_arg
486486
);

0 commit comments

Comments
 (0)