From a4ce596f7b109ee9ded6c80fb85e28e26dc21a90 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Wed, 16 Oct 2019 15:47:10 +0100 Subject: [PATCH] acpi_tables: aml: Add support for generating AML name paths Root ("\"), single, dual and multi-part names are supported. "^" is not supported (not widely used.) Signed-off-by: Rob Bradford --- acpi_tables/src/aml.rs | 88 ++++++++++++++++++++++++++++++++++++++++++ acpi_tables/src/lib.rs | 1 + 2 files changed, 89 insertions(+) create mode 100644 acpi_tables/src/aml.rs diff --git a/acpi_tables/src/aml.rs b/acpi_tables/src/aml.rs new file mode 100644 index 000000000..7ca8eb64b --- /dev/null +++ b/acpi_tables/src/aml.rs @@ -0,0 +1,88 @@ +// Copyright © 2019 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +pub trait Aml { + fn to_bytes(&self) -> Vec; +} + +pub struct Path { + root: bool, + name_parts: Vec<[u8; 4]>, +} + +impl Aml for Path { + fn to_bytes(&self) -> Vec { + let mut bytes = Vec::new(); + + if self.root { + bytes.push(b'\\'); + } + + match self.name_parts.len() { + 0 => panic!("Name cannot be empty"), + 1 => {} + 2 => { + bytes.push(0x2e); /* DualNamePrefix */ + } + n => { + bytes.push(0x2f); /* MultiNamePrefix */ + bytes.push(n as u8); + } + }; + + for part in self.name_parts.clone().iter_mut() { + bytes.append(&mut part.to_vec()); + } + + bytes + } +} + +impl Path { + pub fn new(name: &str) -> Self { + let root = name.starts_with('\\'); + let offset = root as usize; + let mut name_parts = Vec::new(); + for part in name[offset..].split('.') { + assert_eq!(part.len(), 4); + let mut name_part = [0u8; 4]; + name_part.copy_from_slice(part.as_bytes()); + name_parts.push(name_part); + } + + Path { root, name_parts } + } +} + +impl From<&str> for Path { + fn from(s: &str) -> Self { + Path::new(s) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_name_path() { + assert_eq!( + (&"_SB_".into() as &Path).to_bytes(), + [0x5Fu8, 0x53, 0x42, 0x5F] + ); + assert_eq!( + (&"\\_SB_".into() as &Path).to_bytes(), + [0x5C, 0x5F, 0x53, 0x42, 0x5F] + ); + assert_eq!( + (&"_SB_.COM1".into() as &Path).to_bytes(), + [0x2E, 0x5F, 0x53, 0x42, 0x5F, 0x43, 0x4F, 0x4D, 0x31] + ); + assert_eq!( + (&"_SB_.PCI0._HID".into() as &Path).to_bytes(), + [0x2F, 0x03, 0x5F, 0x53, 0x42, 0x5F, 0x50, 0x43, 0x49, 0x30, 0x5F, 0x48, 0x49, 0x44] + ); + } +} diff --git a/acpi_tables/src/lib.rs b/acpi_tables/src/lib.rs index 30297337f..1ca517c86 100644 --- a/acpi_tables/src/lib.rs +++ b/acpi_tables/src/lib.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 // +pub mod aml; pub mod rsdp; pub mod sdt;