浏览代码

Split into two crates, bump to v0.2.0

Isaac Woods 6 年之前
父节点
当前提交
56bb7b38de
共有 18 个文件被更改,包括 75 次插入798 次删除
  1. 2 13
      Cargo.toml
  2. 14 0
      acpi/Cargo.toml
  3. 0 0
      acpi/src/fadt.rs
  4. 39 0
      acpi/src/handler.rs
  5. 0 0
      acpi/src/hpet.rs
  6. 0 0
      acpi/src/interrupt.rs
  7. 8 40
      acpi/src/lib.rs
  8. 0 0
      acpi/src/madt.rs
  9. 0 0
      acpi/src/rsdp.rs
  10. 0 0
      acpi/src/rsdp_search.rs
  11. 0 0
      acpi/src/sdt.rs
  12. 12 0
      aml_parser/Cargo.toml
  13. 0 0
      aml_parser/src/lib.rs
  14. 0 58
      src/aml/mod.rs
  15. 0 19
      src/aml/opcodes.rs
  16. 0 515
      src/aml/parser.rs
  17. 0 67
      src/aml/stream.rs
  18. 0 86
      src/aml/value.rs

+ 2 - 13
Cargo.toml

@@ -1,13 +1,2 @@
-[package]
-name = "acpi"
-version = "0.1.0"
-authors = ["Isaac Woods <isaacwoods.home@gmail.com>"]
-repository = "https://github.com/rust-osdev/acpi"
-description = "Library for parsing ACPI tables and AML"
-readme = "README.md"
-license = "MIT/Apache-2.0"
-edition = "2018"
-
-[dependencies]
-log = "0.*"
-bit_field = "0.9.0"
+[workspace]
+members = ["acpi", "aml_parser"]

+ 14 - 0
acpi/Cargo.toml

@@ -0,0 +1,14 @@
+[package]
+name = "acpi"
+version = "0.2.0"
+authors = ["Isaac Woods"]
+repository = "https://github.com/rust-osdev/acpi"
+description = "Library for parsing ACPI tables"
+categories = ["hardware-support", "no-std"]
+readme = "../README.md"
+license = "MIT/Apache-2.0"
+edition = "2018"
+
+[dependencies]
+log = "0.4"
+bit_field = "0.9"

+ 0 - 0
src/fadt.rs → acpi/src/fadt.rs


+ 39 - 0
acpi/src/handler.rs

@@ -0,0 +1,39 @@
+use core::{ops::Deref, ptr::NonNull};
+
+/// Describes a physical mapping created by `AcpiHandler::map_physical_region` and unmapped by
+/// `AcpiHandler::unmap_physical_region`. The region mapped must be at least `size_of::<T>()`
+/// bytes, but may be bigger.
+pub struct PhysicalMapping<T> {
+    pub physical_start: usize,
+    pub virtual_start: NonNull<T>,
+    pub region_length: usize, // Can be equal or larger than size_of::<T>()
+    pub mapped_length: usize, // Differs from `region_length` if padding is added for alignment
+}
+
+impl<T> Deref for PhysicalMapping<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        unsafe { self.virtual_start.as_ref() }
+    }
+}
+
+/// An implementation of this trait must be provided to allow `acpi` to access platform-specific
+/// functionality, such as mapping regions of physical memory. You are free to implement these
+/// however you please, as long as they conform to the documentation of each function.
+pub trait AcpiHandler {
+    /// Given a starting physical address and a size, map a region of physical memory that contains
+    /// a `T` (but may be bigger than `size_of::<T>()`). The address doesn't have to be
+    /// page-aligned, so the implementation may have to add padding to either end. The given
+    /// size must be greater or equal to the size of a `T`. The virtual address the memory is
+    /// mapped to does not matter, as long as it is accessible from `acpi`.
+    fn map_physical_region<T>(
+        &mut self,
+        physical_address: usize,
+        size: usize,
+    ) -> PhysicalMapping<T>;
+
+    /// Unmap the given physical mapping. Safe because we consume the mapping, and so it can't be
+    /// used after being passed to this function.
+    fn unmap_physical_region<T>(&mut self, region: PhysicalMapping<T>);
+}

+ 0 - 0
src/hpet.rs → acpi/src/hpet.rs


+ 0 - 0
src/interrupt.rs → acpi/src/interrupt.rs


+ 8 - 40
src/lib.rs → acpi/src/lib.rs

@@ -37,6 +37,7 @@ extern crate bit_field;
 
 mod aml;
 mod fadt;
+pub mod handler;
 mod hpet;
 pub mod interrupt;
 mod madt;
@@ -44,11 +45,16 @@ mod rsdp;
 mod rsdp_search;
 mod sdt;
 
-pub use crate::{aml::AmlError, madt::MadtError, rsdp_search::search_for_rsdp_bios};
+pub use crate::{
+    aml::AmlError,
+    handler::{AcpiHandler, PhysicalMapping},
+    madt::MadtError,
+    rsdp_search::search_for_rsdp_bios,
+};
 
 use crate::{aml::AmlValue, interrupt::InterruptModel, rsdp::Rsdp, sdt::SdtHeader};
 use alloc::{collections::BTreeMap, string::String, vec::Vec};
-use core::{mem, ops::Deref, ptr::NonNull};
+use core::mem;
 
 #[derive(Debug)]
 // TODO: manually implement Debug to print signatures correctly etc.
@@ -116,44 +122,6 @@ impl Processor {
     }
 }
 
-/// Describes a physical mapping created by `AcpiHandler::map_physical_region` and unmapped by
-/// `AcpiHandler::unmap_physical_region`. The region mapped must be at least `size_of::<T>()`
-/// bytes, but may be bigger.
-pub struct PhysicalMapping<T> {
-    pub physical_start: usize,
-    pub virtual_start: NonNull<T>,
-    pub region_length: usize, // Can be equal or larger than size_of::<T>()
-    pub mapped_length: usize, // Differs from `region_length` if padding is added for alignment
-}
-
-impl<T> Deref for PhysicalMapping<T> {
-    type Target = T;
-
-    fn deref(&self) -> &T {
-        unsafe { self.virtual_start.as_ref() }
-    }
-}
-
-/// An implementation of this trait must be provided to allow `acpi` to access platform-specific
-/// functionality, such as mapping regions of physical memory. You are free to implement these
-/// however you please, as long as they conform to the documentation of each function.
-pub trait AcpiHandler {
-    /// Given a starting physical address and a size, map a region of physical memory that contains
-    /// a `T` (but may be bigger than `size_of::<T>()`). The address doesn't have to be
-    /// page-aligned, so the implementation may have to add padding to either end. The given
-    /// size must be greater or equal to the size of a `T`. The virtual address the memory is
-    /// mapped to does not matter, as long as it is accessible from `acpi`.
-    fn map_physical_region<T>(
-        &mut self,
-        physical_address: usize,
-        size: usize,
-    ) -> PhysicalMapping<T>;
-
-    /// Unmap the given physical mapping. Safe because we consume the mapping, and so it can't be
-    /// used after being passed to this function.
-    fn unmap_physical_region<T>(&mut self, region: PhysicalMapping<T>);
-}
-
 #[derive(Debug)]
 pub struct Acpi {
     acpi_revision: u8,

+ 0 - 0
src/madt.rs → acpi/src/madt.rs


+ 0 - 0
src/rsdp.rs → acpi/src/rsdp.rs


+ 0 - 0
src/rsdp_search.rs → acpi/src/rsdp_search.rs


+ 0 - 0
src/sdt.rs → acpi/src/sdt.rs


+ 12 - 0
aml_parser/Cargo.toml

@@ -0,0 +1,12 @@
+[package]
+name = "aml_parser"
+version = "0.2.0"
+authors = ["Isaac Woods"]
+repository = "https://github.com/rust-osdev/acpi"
+description = "Library for parsing AML"
+categories = ["hardware-support", "no-std"]
+readme = "../README.md"
+license = "MIT/Apache-2.0"
+edition = "2018"
+
+[dependencies]

+ 0 - 0
aml_parser/src/lib.rs


+ 0 - 58
src/aml/mod.rs

@@ -1,58 +0,0 @@
-mod opcodes;
-mod parser;
-mod stream;
-mod value;
-
-pub use self::value::AmlValue;
-
-use self::{parser::AmlParser, stream::AmlStream};
-use crate::{sdt::SdtHeader, Acpi, AcpiError, AcpiHandler, PhysicalMapping};
-use alloc::string::String;
-use core::{mem, slice};
-
-/// Represents a table containing AML. For ACPI Version 2+, this is just the DSDT and SSDTs.
-/// Version 1.0 may also have a PSDT.
-#[repr(C, packed)]
-pub struct AmlTable {
-    header: SdtHeader,
-    // ...
-}
-
-#[derive(Debug)]
-pub enum AmlError {
-    EndOfStream,
-    UnexpectedByte(u8),
-    IncompatibleValueConversion,
-    InvalidPath(String),
-    InvalidFieldFlags,
-    InvalidNameSeg([u8; 4]),
-}
-
-impl AmlTable {
-    /// Get the AML stream encoded in this table so it can be safely accessed
-    pub fn stream<'a>(&'a self) -> AmlStream<'a> {
-        assert!(self.header.length() as usize > mem::size_of::<SdtHeader>());
-        let stream_length = self.header.length() as usize - mem::size_of::<SdtHeader>();
-        let stream_ptr =
-            ((self as *const AmlTable as usize) + mem::size_of::<SdtHeader>()) as *const u8;
-
-        unsafe { AmlStream::new(slice::from_raw_parts(stream_ptr, stream_length)) }
-    }
-}
-
-pub(crate) fn parse_aml_table<H>(
-    acpi: &mut Acpi,
-    handler: &mut H,
-    mapping: &PhysicalMapping<AmlTable>,
-    signature: &[u8; 4],
-) -> Result<(), AcpiError>
-where
-    H: AcpiHandler,
-{
-    (*mapping).header.validate(signature)?;
-
-    match AmlParser::parse(acpi, handler, "\\", (*mapping).stream()) {
-        Ok(_) => Ok(()),
-        Err(error) => Err(AcpiError::InvalidAmlTable(*signature, error)),
-    }
-}

+ 0 - 19
src/aml/opcodes.rs

@@ -1,19 +0,0 @@
-pub const NULL_NAME: u8 = 0x00;
-pub const DUAL_NAME_PREFIX: u8 = 0x2E;
-pub const MULTI_NAME_PREFIX: u8 = 0x2F;
-
-pub const ZERO_OP: u8 = 0x00;
-pub const ONE_OP: u8 = 0x01;
-pub const ONES_OP: u8 = 0xff;
-pub const BYTE_CONST: u8 = 0x0a;
-pub const WORD_CONST: u8 = 0x0b;
-pub const DWORD_CONST: u8 = 0x0c;
-pub const STRING_PREFIX: u8 = 0x0d;
-pub const QWORD_CONST: u8 = 0x0e;
-
-pub const SCOPE_OP: u8 = 0x10;
-pub const EXT_OP_REGION_OP: u8 = 0x80;
-pub const EXT_REVISION_OP: u8 = 0x30;
-pub const EXT_FIELD_OP: u8 = 0x81;
-
-pub const EXT_OPCODE_PREFIX: u8 = 0x5b;

+ 0 - 515
src/aml/parser.rs

@@ -1,515 +0,0 @@
-use super::{
-    opcodes,
-    stream::AmlStream,
-    value::{AmlValue, FieldFlags, RegionSpace},
-    AmlError,
-};
-use crate::{Acpi, AcpiHandler};
-use alloc::string::String;
-use bit_field::BitField;
-use core::str;
-
-/// This is used internally by the parser to keep track of what we know about a field before we can
-/// add it to the namespace.
-struct FieldInfo {
-    pub name: String,
-    pub length: u64,
-}
-
-/// This is used internally by the parser. Often, we're only interested in offset of the end of the
-/// current explicit-length structure, so we know when to stop parsing it. However, various
-/// constants (e.g. the size of fields) are also encoded as PkgLengths, and so sometimes we want to
-/// access the raw data as well.
-struct PkgLength {
-    pub raw_length: u32,
-    pub end_offset: u32,
-}
-
-pub(crate) struct AmlParser<'s, 'a, 'h, H>
-where
-    H: AcpiHandler + 'h,
-{
-    acpi: &'a mut Acpi,
-    handler: &'h mut H,
-    scope: String,
-    stream: AmlStream<'s>,
-}
-
-/// This macro takes a parser and one or more parsing functions and tries to parse the next part of
-/// the stream with each one. If a parsing function fails, it rolls back the stream and tries the
-/// next one. If none of the functions can parse the next part of the stream, we error on the
-/// unexpected byte.
-macro_rules! try_parse {
-    ($parser: expr, $($function: path),+) => {{
-        $(if let Some(value) = $parser.try_parse($function)? {
-            Ok(value)
-        } else)+ {
-            Err(AmlError::UnexpectedByte($parser.stream.peek()?))
-        }
-    }}
-}
-
-impl<'s, 'a, 'h, H> AmlParser<'s, 'a, 'h, H>
-where
-    H: AcpiHandler,
-{
-    pub(crate) fn parse(
-        acpi: &'a mut Acpi,
-        handler: &'h mut H,
-        scope: &str,
-        stream: AmlStream<'s>,
-    ) -> Result<(), AmlError> {
-        let mut parser = AmlParser { acpi, handler, scope: String::from(scope), stream };
-
-        let end_offset = parser.stream.len() as u32;
-        parser.parse_term_list(end_offset)
-    }
-
-    /// Consume the next byte in the stream and check if it fulfils the given predicate. If it
-    /// does, returns `Ok(the consumed char)`. If it doesn't, returns
-    /// `Err(AmlError::UnexpectedByte(the consumed char)`. If there's an error consuming the char,
-    /// it will forward the error on from that.
-    fn consume_byte<F>(&mut self, predicate: F) -> Result<u8, AmlError>
-    where
-        F: Fn(u8) -> bool,
-    {
-        let byte = self.stream.next()?;
-
-        match predicate(byte) {
-            true => Ok(byte),
-            false => Err(AmlError::UnexpectedByte(byte)),
-        }
-    }
-
-    fn consume_opcode(&mut self, opcode: u8) -> Result<(), AmlError> {
-        self.consume_byte(matches_byte(opcode))?;
-        Ok(())
-    }
-
-    fn consume_ext_opcode(&mut self, ext_opcode: u8) -> Result<(), AmlError> {
-        self.consume_byte(matches_byte(opcodes::EXT_OPCODE_PREFIX))?;
-        self.consume_byte(matches_byte(ext_opcode))?;
-        Ok(())
-    }
-
-    /// Try to parse the next part of the stream with the given parsing function. This returns any
-    /// `AmlError` as an `Err`, except `AmlError::UnexpectedByte`, to which it will return
-    /// `Ok(None)`. A successful parse gives `Ok(Some(...))`. On failure, this also reverts any
-    /// changes made to the stream, so it's as if the parsing function never run.
-    fn try_parse<T, F>(&mut self, parsing_function: F) -> Result<Option<T>, AmlError>
-    where
-        F: Fn(&mut Self) -> Result<T, AmlError>,
-    {
-        let stream = self.stream.clone();
-
-        match parsing_function(self) {
-            Ok(result) => Ok(Some(result)),
-
-            Err(AmlError::UnexpectedByte(_)) => {
-                self.stream = stream;
-                Ok(None)
-            }
-
-            Err(error) => Err(error),
-        }
-    }
-
-    fn parse_term_list(&mut self, end_offset: u32) -> Result<(), AmlError> {
-        /*
-         * TermList := Nothing | <TermObj TermList>
-         *
-         * Because TermLists don't have PkgLengths, we pass the offset to stop at from whatever
-         * explicit-length object we were parsing before.
-         */
-        while self.stream.offset() <= end_offset {
-            self.parse_term_object()?;
-        }
-
-        Ok(())
-    }
-
-    fn parse_term_object(&mut self) -> Result<(), AmlError> {
-        /*
-         * TermObj := NameSpaceModifierObj | NamedObj | Type1Opcode | Type2Opcode
-         * NameSpaceModifierObj := DefAlias | DefName | DefScope
-         * NamedObj := DefBankField | DefCreateBitField | DefCreateByteField |
-         * DefCreateDWordField |             DefCreateField | DefCreateQWordField |
-         * DefCreateWordField | DefDataRegion |             DefExternal | DefOpRegion |
-         * DefPowerRes | DefProcessor | DefThermalZone
-         */
-        try_parse!(
-            self,
-            AmlParser::parse_def_scope,
-            AmlParser::parse_def_op_region,
-            AmlParser::parse_def_field //,
-                                       // AmlParser::parse_type1_opcode    TODO: reenable when we can parse them
-        )
-    }
-
-    fn parse_def_scope(&mut self) -> Result<(), AmlError> {
-        /*
-         * DefScope := 0x10 PkgLength NameString TermList
-         */
-        self.consume_opcode(opcodes::SCOPE_OP)?;
-        trace!("Parsing scope op");
-        let scope_end_offset = self.parse_pkg_length()?.end_offset;
-
-        let name_string = self.parse_name_string()?;
-        let containing_scope = self.scope.clone();
-
-        self.scope = name_string;
-        let _term_list = self.parse_term_list(scope_end_offset)?;
-        self.scope = containing_scope;
-
-        Ok(())
-    }
-
-    fn parse_def_op_region(&mut self) -> Result<(), AmlError> {
-        /*
-         * DefOpRegion := ExtOpPrefix 0x80 NameString RegionSpace RegionOffset RegionLen
-         * RegionSpace := ByteData (where 0x00      = SystemMemory
-         *                                0x01      = SystemIO
-         *                                0x02      = PciConfig
-         *                                0x03      = EmbeddedControl
-         *                                0x04      = SMBus
-         *                                0x05      = SystemCMOS
-         *                                0x06      = PciBarTarget
-         *                                0x07      = IPMI
-         *                                0x08      = GeneralPurposeIO
-         *                                0x09      = GenericSerialBus
-         *                                0x80-0xff = OEM Defined)
-         * ByteData := 0x00 - 0xff
-         * RegionOffset := TermArg => Integer
-         * RegionLen := TermArg => Integer
-         */
-        self.consume_ext_opcode(opcodes::EXT_OP_REGION_OP)?;
-        info!("Parsing op region");
-
-        let name = self.parse_name_string()?;
-        info!("name: {}", name);
-        let region_space = match self.stream.next()? {
-            0x00 => RegionSpace::SystemMemory,
-            0x01 => RegionSpace::SystemIo,
-            0x02 => RegionSpace::PciConfig,
-            0x03 => RegionSpace::EmbeddedControl,
-            0x04 => RegionSpace::SMBus,
-            0x05 => RegionSpace::SystemCmos,
-            0x06 => RegionSpace::PciBarTarget,
-            0x07 => RegionSpace::IPMI,
-            0x08 => RegionSpace::GeneralPurposeIo,
-            0x09 => RegionSpace::GenericSerialBus,
-            space @ 0x80..0xff => RegionSpace::OemDefined(space),
-            byte => return Err(AmlError::UnexpectedByte(byte)),
-        };
-        info!("region space: {:?}", region_space);
-        let offset = self.parse_term_arg()?.as_integer()?;
-        info!("region offset: {}", offset);
-        let length = self.parse_term_arg()?.as_integer()?;
-        info!("region len: {}", length);
-
-        // Insert it into the namespace
-        let namespace_path = self.resolve_path(&name)?;
-        self.acpi.namespace.insert(
-            // self.resolve_path(name)?, TODO: I thought this would work with nll?
-            namespace_path,
-            AmlValue::OpRegion { region: region_space, offset, length },
-        );
-
-        Ok(())
-    }
-
-    fn parse_def_field(&mut self) -> Result<(), AmlError> {
-        /*
-         * DefField = ExtOpPrefix 0x81 PkgLength NameString FieldFlags FieldList
-         * FieldList := Nothing | <FieldElement FieldList>
-         * FieldElement := NamedField | ReservedField | AccessField | ExtendedAccessField |
-         *                 ConnectField
-         * ReservedField := 0x00 PkgLength
-         * AccessField := 0x01 AccessType AccessAttrib
-         * AccessType := ByteData
-         * AccessAttrib := ByteData
-         * ConnectField := <0x02 NameString> | <0x02 BufferData>
-         */
-        self.consume_ext_opcode(opcodes::EXT_FIELD_OP)?;
-        trace!("Parsing DefField");
-        let end_offset = self.parse_pkg_length()?.end_offset;
-        trace!("end offset: {}", end_offset);
-        let name = self.parse_name_string()?;
-        trace!("name: {}", name);
-        let flags = FieldFlags::new(self.stream.next()?);
-        trace!("Field flags: {:?}", flags);
-
-        while self.stream.offset() < end_offset {
-            // TODO: parse other field types
-            let info = try_parse!(self, AmlParser::parse_named_field)?;
-
-            // TODO: add field name to this (info.name)?
-            let namespace_path = self.resolve_path(&name)?;
-            self.acpi.namespace.insert(
-                namespace_path,
-                AmlValue::Field {
-                    flags,
-                    offset: 0, // TODO: calculate offset
-                    length: info.length,
-                },
-            );
-        }
-
-        Ok(())
-    }
-
-    fn parse_named_field(&mut self) -> Result<FieldInfo, AmlError> {
-        /*
-         * NamedField := NameSeg PkgLength
-         *
-         * This encodes the size of the field using a PkgLength - it doesn't mark the length of
-         * an explicit-length structure!
-         */
-        let name = String::from(name_seg_to_string(&self.parse_name_seg()?)?);
-        let length = self.parse_pkg_length()?.raw_length as u64;
-        info!("Adding named field called {:?} with size {}", name, length);
-
-        Ok(FieldInfo { name, length })
-    }
-
-    fn parse_def_buffer(&mut self) -> Result<AmlValue, AmlError> {
-        unimplemented!(); // TODO
-    }
-
-    fn parse_term_arg(&mut self) -> Result<AmlValue, AmlError> {
-        /*
-         * TermArg := Type2Opcode | DataObject | ArgObj | LocalObj
-         * DataObject := ComputationalData | DefPackage | DefVarPackage
-         */
-        if let Some(result) = self.try_parse(AmlParser::parse_computational_data)? {
-            Ok(result)
-        } else {
-            Err(AmlError::UnexpectedByte(self.stream.next()?))
-        }
-    }
-
-    fn parse_computational_data(&mut self) -> Result<AmlValue, AmlError> {
-        /*
-         * ComputationalData := ByteConst | WordConst | DWordConst | QWordConst | String |
-         *                      ConstObj | RevisionOp | DefBuffer
-         * ByteConst := 0x0a ByteData
-         * WordConst := 0x0b WordData
-         * DWordConst := 0x0c DWordData
-         * QWordConst := 0x0e QWordData
-         * String := 0x0d AsciiCharList NullChar
-         * ConstObj := ZeroOp(0x00) | OneOp(0x01) | OnesOp(0xff)
-         * RevisionOp := ExtOpPrefix(0x5B) 0x30
-         */
-        match self.stream.peek()? {
-            opcodes::BYTE_CONST => {
-                self.consume_opcode(opcodes::BYTE_CONST)?;
-                Ok(AmlValue::Integer(self.stream.next()? as u64))
-            }
-
-            opcodes::WORD_CONST => {
-                self.consume_opcode(opcodes::WORD_CONST)?;
-                Ok(AmlValue::Integer(self.stream.next_u16()? as u64))
-            }
-
-            opcodes::DWORD_CONST => {
-                self.consume_opcode(opcodes::DWORD_CONST)?;
-                Ok(AmlValue::Integer(self.stream.next_u16()? as u64))
-            }
-
-            opcodes::QWORD_CONST => {
-                self.consume_opcode(opcodes::QWORD_CONST)?;
-                Ok(AmlValue::Integer(self.stream.next_u16()? as u64))
-            }
-
-            opcodes::STRING_PREFIX => {
-                self.consume_opcode(opcodes::STRING_PREFIX)?;
-                unimplemented!(); // TODO
-            }
-
-            opcodes::ZERO_OP => {
-                self.consume_opcode(opcodes::ZERO_OP)?;
-                Ok(AmlValue::Integer(0))
-            }
-
-            opcodes::ONE_OP => {
-                self.consume_opcode(opcodes::ONE_OP)?;
-                Ok(AmlValue::Integer(1))
-            }
-
-            opcodes::ONES_OP => {
-                self.consume_opcode(opcodes::ONES_OP)?;
-                Ok(AmlValue::Integer(u64::max_value()))
-            }
-
-            opcodes::EXT_OPCODE_PREFIX if self.stream.lookahead(1)? == opcodes::EXT_REVISION_OP => {
-                unimplemented!(); // TODO
-            }
-
-            _ => self.parse_def_buffer(),
-        }
-    }
-
-    fn parse_type1_opcode(&mut self) -> Result<(), AmlError> {
-        /*
-         * Type1Opcode := DefBreak | DefBreakPoint | DefContinue | DefFatal | DefIfElse | DefLoad
-         * |                DefNoop | DefNotify | DefRelease | DefReset | DefReturn |
-         * DefSignal |                DefSleep | DefStall | DefUnload | DefWhile
-         */
-        unimplemented!(); // TODO
-    }
-
-    /// Parse a PkgLength. Returns the offset into the stream to stop parsing whatever object the
-    /// PkgLength describes at.
-    // TODO: think hard about whether we actually need to minus the length now because we use
-    // `next()`? Isn't this already handled?
-    fn parse_pkg_length(&mut self) -> Result<PkgLength, AmlError> {
-        /*
-         * PkgLength := PkgLeadByte |
-         *              <PkgLeadByte ByteData> |
-         *              <PkgLeadByte ByteData ByteData> |
-         *              <PkgLeadByte ByteData ByteData ByteData>
-         */
-        let lead_byte = self.stream.next()?;
-        let byte_data_count = lead_byte.get_bits(6..8);
-
-        if byte_data_count == 0 {
-            let length = u32::from(lead_byte.get_bits(0..6));
-            let end_offset = self.stream.offset() + length - 1; // Minus 1 to remove the PkgLength byte
-            trace!(
-                "Parsed 1-byte PkgLength with length {}, so ends at {}(current offset={}",
-                length,
-                end_offset,
-                self.stream.offset()
-            );
-            return Ok(PkgLength { raw_length: length, end_offset });
-        }
-
-        let mut length = u32::from(lead_byte.get_bits(0..4));
-        for i in 0..byte_data_count {
-            length += u32::from(self.stream.next()?) << (4 + i * 8);
-        }
-
-        // Minus `byte_data_count + 1` to not include the PkgLength in the remaining bytes
-        let end_offset = self.stream.offset() + length - byte_data_count as u32 - 1;
-        trace!(
-            "Parsed PkgLength with length {}, so ends at {}(current offset={})",
-            length,
-            end_offset,
-            self.stream.offset()
-        );
-        Ok(PkgLength { raw_length: length, end_offset })
-    }
-
-    fn parse_name_string(&mut self) -> Result<String, AmlError> {
-        /*
-         * NameString := <RootChar('\') NamePath> | <PrefixPath NamePath>
-         * PrefixPath := Nothing | <'^' PrefixPath>
-         */
-        match self.stream.peek()? {
-            b'\\' => {
-                /*
-                 * NameString := RootChar NamePath
-                 */
-                self.stream.next()?;
-                Ok(String::from("\\") + &self.parse_name_path()?)
-            }
-
-            b'^' => {
-                unimplemented!();
-            }
-
-            _ => self.parse_name_path(),
-        }
-    }
-
-    fn parse_name_path(&mut self) -> Result<String, AmlError> {
-        /*
-         * NamePath := NameSeg | DualNamePath | MultiNamePath | NullPath
-         * DualNamePath := DualNamePrefix NameSeg NameSeg
-         * MultiNamePath := MultiNamePrefix SegCount{ByteData} NameSeg(..SegCount)
-         */
-        match self.stream.peek()? {
-            opcodes::NULL_NAME => {
-                self.stream.next()?;
-                Ok(String::from(""))
-            }
-
-            opcodes::DUAL_NAME_PREFIX => {
-                self.stream.next()?;
-                let first = self.parse_name_seg()?;
-                let second = self.parse_name_seg()?;
-
-                Ok(String::from(str::from_utf8(&first).unwrap()) + str::from_utf8(&second).unwrap())
-            }
-
-            opcodes::MULTI_NAME_PREFIX => {
-                // TODO
-                unimplemented!();
-            }
-
-            _ => Ok(String::from(str::from_utf8(&self.parse_name_seg()?).unwrap())),
-        }
-    }
-
-    fn parse_name_seg(&mut self) -> Result<[u8; 4], AmlError> {
-        /*
-         * NameSeg := <LeadNameChar NameChar NameChar NameChar>
-         */
-        Ok([
-            self.consume_byte(is_lead_name_char)?,
-            self.consume_byte(is_name_char)?,
-            self.consume_byte(is_name_char)?,
-            self.consume_byte(is_name_char)?,
-        ])
-    }
-
-    /// Resolve a given path and the current scope to an absolute path in the namespace.
-    fn resolve_path(&mut self, mut path: &str) -> Result<String, AmlError> {
-        /*
-         * TODO: how should we handle '.' as they appear in paths?
-         */
-        let original_path = path.clone();
-
-        // If the scope to resolve is from the root of the namespace, or the current scope is
-        // nothing, just return the given scope
-        if self.scope == "" || path.starts_with("\\") {
-            return Ok(String::from(path));
-        }
-
-        // "^"s at the start of a path specify to go up one level from the current scope, to its
-        // parent object
-        let mut namespace_object = self.scope.clone();
-        while path.starts_with("^") {
-            path = &path[1..];
-
-            if namespace_object.pop() == None {
-                return Err(AmlError::InvalidPath(String::from(original_path)));
-            }
-        }
-
-        Ok(namespace_object + &path)
-    }
-}
-
-fn matches_byte(byte: u8) -> impl Fn(u8) -> bool {
-    move |x| x == byte
-}
-
-fn is_lead_name_char(byte: u8) -> bool {
-    (byte >= b'A' && byte <= b'Z') || byte == b'_'
-}
-
-fn is_digit_char(byte: u8) -> bool {
-    byte >= b'0' && byte <= b'9'
-}
-
-fn is_name_char(byte: u8) -> bool {
-    is_lead_name_char(byte) || is_digit_char(byte)
-}
-
-fn name_seg_to_string<'a>(seg: &'a [u8; 4]) -> Result<&'a str, AmlError> {
-    match str::from_utf8(seg) {
-        Ok(seg_str) => Ok(seg_str),
-        Err(_) => Err(AmlError::InvalidNameSeg(*seg)),
-    }
-}

+ 0 - 67
src/aml/stream.rs

@@ -1,67 +0,0 @@
-use super::AmlError;
-
-#[derive(Clone)]
-pub struct AmlStream<'a> {
-    data: &'a [u8],
-    offset: u32, // TODO: PkgLength can't be longer than u32, but can a whole AML stream?
-}
-
-impl<'a> AmlStream<'a> {
-    pub unsafe fn new(data: &'a [u8]) -> AmlStream<'a> {
-        AmlStream { data, offset: 0 }
-    }
-
-    pub fn peek(&self) -> Result<u8, AmlError> {
-        if (self.offset + 1) >= self.len() {
-            Err(AmlError::EndOfStream)
-        } else {
-            Ok(self.data[self.offset as usize])
-        }
-    }
-
-    pub fn next(&mut self) -> Result<u8, AmlError> {
-        let byte = self.peek()?;
-        self.offset += 1;
-        Ok(byte)
-    }
-
-    pub fn next_u16(&mut self) -> Result<u16, AmlError> {
-        let first_byte = self.next()?;
-        let second_byte = self.next()?;
-        Ok(first_byte as u16 + ((second_byte as u16) << 8))
-    }
-
-    pub fn next_u32(&mut self) -> Result<u32, AmlError> {
-        let first_byte = self.next()?;
-        let second_byte = self.next()?;
-        let third_byte = self.next()?;
-        Ok(first_byte as u32 + ((second_byte as u32) << 8) + ((third_byte as u32) << 16))
-    }
-
-    pub fn next_u64(&mut self) -> Result<u64, AmlError> {
-        let first_byte = self.next()?;
-        let second_byte = self.next()?;
-        let third_byte = self.next()?;
-        let forth_byte = self.next()?;
-        Ok(first_byte as u64
-            + ((second_byte as u64) << 8)
-            + ((third_byte as u64) << 16)
-            + ((forth_byte as u64) << 24))
-    }
-
-    pub fn lookahead(&self, amount: u32) -> Result<u8, AmlError> {
-        match self.offset.checked_add(amount) {
-            Some(offset) => Ok(self.data[offset as usize]),
-            None => Err(AmlError::EndOfStream),
-        }
-    }
-
-    pub fn len(&self) -> u32 {
-        self.data.len() as u32
-    }
-
-    /// This gets the current offset into the stream
-    pub fn offset(&self) -> u32 {
-        self.offset
-    }
-}

+ 0 - 86
src/aml/value.rs

@@ -1,86 +0,0 @@
-use super::AmlError;
-use bit_field::BitField;
-
-#[derive(Debug)]
-pub enum RegionSpace {
-    SystemMemory,
-    SystemIo,
-    PciConfig,
-    EmbeddedControl,
-    SMBus,
-    SystemCmos,
-    PciBarTarget,
-    IPMI,
-    GeneralPurposeIo,
-    GenericSerialBus,
-    OemDefined(u8),
-}
-
-pub enum FieldAccessType {
-    Any,
-    Byte,
-    Word,
-    DWord,
-    QWord,
-    Buffer,
-    Reserved,
-}
-
-pub enum FieldUpdateRule {
-    Preserve,
-    WriteAsOnes,
-    WriteAsZeros,
-}
-
-#[derive(Clone, Copy, Debug)] // TODO: custom debug / get rid of completely
-pub struct FieldFlags(u8);
-
-impl FieldFlags {
-    pub fn new(value: u8) -> FieldFlags {
-        FieldFlags(value)
-    }
-
-    pub fn access_type(&self) -> Result<FieldAccessType, AmlError> {
-        match self.0.get_bits(0..4) {
-            0 => Ok(FieldAccessType::Any),
-            1 => Ok(FieldAccessType::Byte),
-            2 => Ok(FieldAccessType::Word),
-            3 => Ok(FieldAccessType::DWord),
-            4 => Ok(FieldAccessType::QWord),
-            5 => Ok(FieldAccessType::Buffer),
-            _ => Err(AmlError::InvalidFieldFlags),
-        }
-    }
-
-    pub fn lock_rule(&self) -> bool {
-        self.0.get_bit(4)
-    }
-
-    pub fn field_update_rule(&self) -> Result<FieldUpdateRule, AmlError> {
-        match self.0.get_bits(5..7) {
-            0 => Ok(FieldUpdateRule::Preserve),
-            1 => Ok(FieldUpdateRule::WriteAsOnes),
-            2 => Ok(FieldUpdateRule::WriteAsZeros),
-            _ => Err(AmlError::InvalidFieldFlags),
-        }
-    }
-}
-
-#[derive(Debug)]
-pub enum AmlValue {
-    Integer(u64),
-
-    OpRegion { region: RegionSpace, offset: u64, length: u64 },
-
-    Field { flags: FieldFlags, offset: u64, length: u64 },
-}
-
-impl AmlValue {
-    pub fn as_integer(&self) -> Result<u64, AmlError> {
-        match self {
-            AmlValue::Integer(value) => Ok(*value),
-
-            _ => Err(AmlError::IncompatibleValueConversion),
-        }
-    }
-}