Skip to content

Commit 9795a38

Browse files
committed
aml: support aliases
1 parent 8378db4 commit 9795a38

File tree

3 files changed

+85
-8
lines changed

3 files changed

+85
-8
lines changed

aml/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,15 @@ where
504504
Opcode::One => {
505505
context.last_op()?.arguments.push(Argument::Object(Arc::new(Object::Integer(1))));
506506
}
507-
Opcode::Alias => todo!(),
507+
Opcode::Alias => {
508+
let source = context.namestring()?;
509+
let alias = context.namestring()?;
510+
511+
let mut namespace = self.namespace.lock();
512+
let object = namespace.get(source.resolve(&context.current_scope)?)?.clone();
513+
let alias = alias.resolve(&context.current_scope)?;
514+
namespace.create_alias(alias, object)?;
515+
}
508516
Opcode::Name => {
509517
let name = context.namestring()?;
510518
context.start_in_flight_op(OpInFlight::new_with(

aml/src/namespace.rs

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use alloc::{
66
vec,
77
vec::Vec,
88
};
9+
use bit_field::BitField;
910
use core::{fmt, str, str::FromStr};
1011

1112
pub struct Namespace {
@@ -63,7 +64,18 @@ impl Namespace {
6364
let path = path.normalize()?;
6465

6566
let (level, last_seg) = self.get_level_for_path_mut(&path)?;
66-
match level.values.insert(last_seg, object) {
67+
match level.values.insert(last_seg, (ObjectFlags::new(false), object)) {
68+
None => Ok(()),
69+
Some(_) => Err(AmlError::NameCollision(path)),
70+
}
71+
}
72+
73+
pub fn create_alias(&mut self, path: AmlName, object: Arc<Object>) -> Result<(), AmlError> {
74+
assert!(path.is_absolute());
75+
let path = path.normalize()?;
76+
77+
let (level, last_seg) = self.get_level_for_path_mut(&path)?;
78+
match level.values.insert(last_seg, (ObjectFlags::new(true), object)) {
6779
None => Ok(()),
6880
Some(_) => Err(AmlError::NameCollision(path)),
6981
}
@@ -75,7 +87,7 @@ impl Namespace {
7587

7688
let (level, last_seg) = self.get_level_for_path_mut(&path)?;
7789
match level.values.get(&last_seg) {
78-
Some(object) => Ok(object.clone()),
90+
Some((_, object)) => Ok(object.clone()),
7991
None => Err(AmlError::ObjectDoesNotExist(path.clone())),
8092
}
8193
}
@@ -97,7 +109,7 @@ impl Namespace {
97109
let name = path.resolve(&scope)?;
98110
match self.get_level_for_path(&name) {
99111
Ok((level, last_seg)) => {
100-
if let Some(object) = level.values.get(&last_seg) {
112+
if let Some((_, object)) = level.values.get(&last_seg) {
101113
return Ok((name, object.clone()));
102114
}
103115
}
@@ -117,7 +129,7 @@ impl Namespace {
117129
let name = path.resolve(starting_scope)?;
118130
let (level, last_seg) = self.get_level_for_path(&path.resolve(starting_scope)?)?;
119131

120-
if let Some(object) = level.values.get(&last_seg) {
132+
if let Some((_, object)) = level.values.get(&last_seg) {
121133
Ok((name, object.clone()))
122134
} else {
123135
Err(AmlError::ObjectDoesNotExist(path.clone()))
@@ -207,6 +219,35 @@ impl Namespace {
207219

208220
Ok((current_level, *last_seg))
209221
}
222+
223+
/// Traverse the namespace, calling `f` on each namespace level. `f` returns a `Result<bool, AmlError>` -
224+
/// errors terminate the traversal and are propagated, and the `bool` on the successful path marks whether the
225+
/// children of the level should also be traversed.
226+
pub fn traverse<F>(&mut self, mut f: F) -> Result<(), AmlError>
227+
where
228+
F: FnMut(&AmlName, &NamespaceLevel) -> Result<bool, AmlError>,
229+
{
230+
fn traverse_level<F>(level: &NamespaceLevel, scope: &AmlName, f: &mut F) -> Result<(), AmlError>
231+
where
232+
F: FnMut(&AmlName, &NamespaceLevel) -> Result<bool, AmlError>,
233+
{
234+
for (name, child) in level.children.iter() {
235+
let name = AmlName::from_name_seg(*name).resolve(scope)?;
236+
237+
if f(&name, child)? {
238+
traverse_level(child, &name, f)?;
239+
}
240+
}
241+
242+
Ok(())
243+
}
244+
245+
if f(&AmlName::root(), &self.root)? {
246+
traverse_level(&self.root, &AmlName::root(), &mut f)?;
247+
}
248+
249+
Ok(())
250+
}
210251
}
211252

212253
impl fmt::Display for Namespace {
@@ -221,10 +262,18 @@ impl fmt::Display for Namespace {
221262
level: &NamespaceLevel,
222263
indent_stack: String,
223264
) -> fmt::Result {
224-
for (i, (name, object)) in level.values.iter().enumerate() {
265+
for (i, (name, (flags, object))) in level.values.iter().enumerate() {
225266
let end = (i == level.values.len() - 1)
226267
&& level.children.iter().filter(|(_, l)| l.kind == NamespaceLevelKind::Scope).count() == 0;
227-
writeln!(f, "{}{}{}: {:?}", &indent_stack, if end { END } else { BRANCH }, name.as_str(), object)?;
268+
writeln!(
269+
f,
270+
"{}{}{}: {}{:?}",
271+
&indent_stack,
272+
if end { END } else { BRANCH },
273+
name.as_str(),
274+
if flags.is_alias() { "[A] " } else { "" },
275+
object
276+
)?;
228277

229278
// If the object has a corresponding scope, print it here
230279
if let Some(child_level) = level.children.get(&name) {
@@ -265,10 +314,25 @@ pub enum NamespaceLevelKind {
265314

266315
pub struct NamespaceLevel {
267316
pub kind: NamespaceLevelKind,
268-
pub values: BTreeMap<NameSeg, Arc<Object>>,
317+
pub values: BTreeMap<NameSeg, (ObjectFlags, Arc<Object>)>,
269318
pub children: BTreeMap<NameSeg, NamespaceLevel>,
270319
}
271320

321+
#[derive(Clone, Copy, Debug)]
322+
pub struct ObjectFlags(u8);
323+
324+
impl ObjectFlags {
325+
pub fn new(is_alias: bool) -> ObjectFlags {
326+
let mut flags = 0;
327+
flags.set_bit(0, is_alias);
328+
ObjectFlags(flags)
329+
}
330+
331+
pub fn is_alias(&self) -> bool {
332+
self.0.get_bit(0)
333+
}
334+
}
335+
272336
impl NamespaceLevel {
273337
pub fn new(kind: NamespaceLevelKind) -> NamespaceLevel {
274338
NamespaceLevel { kind, values: BTreeMap::new(), children: BTreeMap::new() }

tests/scopes.asl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,10 @@ DefinitionBlock("scopes.aml", "DSDT", 1, "RSACPI", "SCOPES", 1) {
1010
Name(Z, 413)
1111
}
1212
}
13+
14+
Device(FOO) {
15+
Name (_HID, EisaId ("PNP0A03"))
16+
Alias (\_SB.PCI0.Y, MY_Y)
17+
}
1318
}
1419
}

0 commit comments

Comments
 (0)