diff --git a/src/acpi/aml/dataobj.rs b/src/acpi/aml/dataobj.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4400c8d87c12c712529d9c5d89c7adbe51d180f2
--- /dev/null
+++ b/src/acpi/aml/dataobj.rs
@@ -0,0 +1,168 @@
+use collections::vec::Vec;
+use collections::string::String;
+
+use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace, get_namespace_string};
+
+use super::type2opcode::{parse_def_buffer, parse_def_package, parse_def_var_package,
+                         DefBuffer, DefPackage, DefVarPackage};
+use super::termlist::{parse_term_arg, TermArg};
+use super::namestring::{parse_super_name, SuperName};
+
+#[derive(Debug, Clone)]
+pub enum DataObj {
+    ComputationalData(ComputationalData),
+    DefPackage(DefPackage),
+    DefVarPackage(DefVarPackage)
+}
+
+#[derive(Debug, Clone)]
+pub enum DataRefObj {
+    DataObj(DataObj),
+    ObjectReference(TermArg),
+    DDBHandle(SuperName)
+}
+
+#[derive(Debug, Clone)]
+pub struct ArgObj(u8);
+#[derive(Debug, Clone)]
+pub struct LocalObj(u8);
+// Not actually doing anything to contain data, but does give us type guarantees, which is useful
+
+#[derive(Debug, Clone)]
+pub enum ComputationalData {
+    Byte(u8),
+    Word(u16),
+    DWord(u32),
+    QWord(u64),
+    String(String),
+    Zero,
+    One,
+    Ones,
+    DefBuffer(DefBuffer),
+    RevisionOp
+}
+
+impl AmlExecutable for DataRefObj {
+    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
+        match *self {
+            DataRefObj::DataObj(ref cd) => cd.execute(namespace, scope),
+            _ => Some(AmlValue::Integer)
+        }
+    }
+}
+
+impl AmlExecutable for DataObj {
+    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
+        match *self {
+            DataObj::ComputationalData(ref cd) => cd.execute(namespace, scope),
+            DataObj::DefPackage(ref pkg) => pkg.execute(namespace, scope),
+            _ => Some(AmlValue::Integer)
+        }
+    }
+}
+
+impl AmlExecutable for ComputationalData {
+    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
+        match *self {
+            ComputationalData::Byte(b) => Some(AmlValue::IntegerConstant(b as u64)),
+            ComputationalData::Word(w) => Some(AmlValue::IntegerConstant(w as u64)),
+            ComputationalData::DWord(d) => Some(AmlValue::IntegerConstant(d as u64)),
+            ComputationalData::QWord(q) => Some(AmlValue::IntegerConstant(q as u64)),
+            ComputationalData::Zero => Some(AmlValue::IntegerConstant(0)),
+            ComputationalData::One => Some(AmlValue::IntegerConstant(1)),
+            ComputationalData::Ones => Some(AmlValue::IntegerConstant(0xFFFFFFFFFFFFFFFF)),
+            _ => Some(AmlValue::Integer)
+        }
+    }
+}
+
+pub fn parse_data_obj(data: &[u8]) -> Result<(DataObj, usize), AmlInternalError> {
+    parser_selector! {
+        data,
+        parser_wrap!(DataObj::ComputationalData, parse_computational_data),
+        parser_wrap!(DataObj::DefPackage, parse_def_package),
+        parser_wrap!(DataObj::DefVarPackage, parse_def_var_package)
+    };
+    
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
+
+pub fn parse_data_ref_obj(data: &[u8]) -> Result<(DataRefObj, usize), AmlInternalError> {
+    parser_selector! {
+        data,
+        parser_wrap!(DataRefObj::DataObj, parse_data_obj),
+        parser_wrap!(DataRefObj::ObjectReference, parse_term_arg),
+        parser_wrap!(DataRefObj::DDBHandle, parse_super_name)
+    };
+    
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
+
+pub fn parse_arg_obj(data: &[u8]) -> Result<(ArgObj, usize), AmlInternalError> {
+    match data[0] {
+        0x68 ... 0x6E => Ok((ArgObj(data[0] - 0x68), 1 as usize)),
+        _ => Err(AmlInternalError::AmlInvalidOpCode)
+    }
+}
+
+pub fn parse_local_obj(data: &[u8]) -> Result<(LocalObj, usize), AmlInternalError> {
+    match data[0] {
+        0x60 ... 0x67 => Ok((LocalObj(data[0] - 0x60), 1 as usize)),
+        _ => Err(AmlInternalError::AmlInvalidOpCode)
+    }
+}
+
+fn parse_computational_data(data: &[u8]) -> Result<(ComputationalData, usize), AmlInternalError> {
+    match data[0] {
+        0x0A => Ok((ComputationalData::Byte(data[1]), 2 as usize)),
+        0x0B => {
+            let res = (data[1] as u16) +
+                ((data[2] as u16) << 8);
+            Ok((ComputationalData::Word(res), 3 as usize))
+        },
+        0x0C => {
+            let res = (data[1] as u32) +
+                ((data[2] as u32) << 8) +
+                ((data[3] as u32) << 16) +
+                ((data[4] as u32) << 24);
+            Ok((ComputationalData::DWord(res), 5 as usize))
+        },
+        0x0D => {
+            let mut cur_ptr: usize = 1;
+            let mut cur_string: Vec<u8> = vec!();
+
+            while data[cur_ptr] != 0x00 {
+                cur_string.push(data[cur_ptr]);
+                cur_ptr += 1;
+            }
+
+            match String::from_utf8(cur_string) {
+                Ok(s) => Ok((ComputationalData::String(s.clone()), s.clone().len() + 2)),
+                Err(_) => Err(AmlInternalError::AmlParseError("String data - invalid string"))
+            }
+        },
+        0x0E => {
+            let res = (data[1] as u64) +
+                ((data[2] as u64) << 8) +
+                ((data[3] as u64) << 16) +
+                ((data[4] as u64) << 24) +
+                ((data[5] as u64) << 32) +
+                ((data[6] as u64) << 40) +
+                ((data[7] as u64) << 48) +
+                ((data[8] as u64) << 56);
+            Ok((ComputationalData::QWord(res), 9 as usize))
+        },
+        0x00 => Ok((ComputationalData::Zero, 1 as usize)),
+        0x01 => Ok((ComputationalData::One, 1 as usize)),
+        0x5B => if data[1] == 0x30 {
+            Ok((ComputationalData::RevisionOp, 2 as usize))
+        } else {
+            Err(AmlInternalError::AmlInvalidOpCode)
+        },
+        0xFF => Ok((ComputationalData::Ones, 1 as usize)),
+        _ => match parse_def_buffer(data) {
+            Ok((res, size)) => Ok((ComputationalData::DefBuffer(res), size)),
+            Err(e) => Err(e)
+        }
+    }
+}
diff --git a/src/acpi/aml/mod.rs b/src/acpi/aml/mod.rs
new file mode 100644
index 0000000000000000000000000000000000000000..3d35395d7adc2f1f4a3d75bc430351241eccbcd6
--- /dev/null
+++ b/src/acpi/aml/mod.rs
@@ -0,0 +1,85 @@
+//! # AML
+//! Code to parse and execute AML tables
+
+use collections::vec::Vec;
+use collections::string::String;
+use collections::boxed::Box;
+use core::fmt::Debug;
+use core::str::FromStr;
+
+use super::sdt::Sdt;
+
+#[macro_use]
+mod parsermacros;
+
+mod namespace;
+mod termlist;
+mod namespacemodifier;
+mod pkglength;
+mod namestring;
+mod namedobj;
+mod dataobj;
+mod type1opcode;
+mod type2opcode;
+
+use self::termlist::{parse_term_list, TermObj};
+pub use self::namespace::{AmlNamespace, AmlValue};
+use self::namespace::AmlNamespaceContents;
+
+// TODO: This should be able to take parameters, and may also return multiple values
+pub trait AmlExecutable {
+    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue>;
+}
+
+// TODO: make private
+pub enum AmlInternalError {
+    AmlParseError(&'static str),
+    AmlInvalidOpCode,
+    AmlDeferredLoad
+}
+
+pub enum AmlError {
+    AmlParseError(&'static str)
+}
+
+pub fn get_namespace_string(current: String, modifier: String) -> String {
+    if modifier.starts_with("\\") {
+        return modifier;
+    }
+
+    if modifier.starts_with("^") {
+        // TODO
+    }
+
+    let mut namespace = current.clone();
+    namespace.push('.');
+    namespace + &modifier
+}
+
+pub fn parse_aml_table(sdt: &'static Sdt) -> Result<AmlNamespace, AmlError> {
+    let data = sdt.data();
+    
+    let term_list = match parse_term_list(data) {
+        Ok(res) => res,
+        Err(AmlInternalError::AmlParseError(s)) => return Err(AmlError::AmlParseError(s)),
+        Err(AmlInternalError::AmlInvalidOpCode) => return Err(AmlError::AmlParseError("Unable to match opcode")),
+        Err(AmlInternalError::AmlDeferredLoad) => return Err(AmlError::AmlParseError("Deferred load reached top level"))
+    };
+
+    let global_namespace_specifier = String::from_str("\\").unwrap();
+    // Unwrap is fine here. I mean come on, if this goes wrong you've got bigger problems than AML
+    // not loading...
+
+    let mut global_namespace = AmlNamespace::new_namespace(&global_namespace_specifier);
+    term_list.execute(&mut global_namespace, global_namespace_specifier.clone());
+
+    Ok(global_namespace)
+}
+
+pub fn is_aml_table(sdt: &'static Sdt) -> bool {
+    if &sdt.signature == b"DSDT" {//|| &sdt.signature == b"SSDT" {
+        true
+    } else {
+        false
+    }
+}
diff --git a/src/acpi/aml/namedobj.rs b/src/acpi/aml/namedobj.rs
new file mode 100644
index 0000000000000000000000000000000000000000..67c2e32f6bbe86e2356c0d4b33a8799d0b633281
--- /dev/null
+++ b/src/acpi/aml/namedobj.rs
@@ -0,0 +1,783 @@
+use collections::vec::Vec;
+use collections::string::String;
+use collections::boxed::Box;
+
+use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace, AmlNamespaceContents, get_namespace_string};
+use super::namestring::{parse_name_string, parse_name_seg};
+use super::termlist::{parse_term_arg, parse_term_list, parse_object_list, TermArg, TermObj, Object};
+use super::pkglength::parse_pkg_length;
+use super::type2opcode::{parse_def_buffer, DefBuffer};
+
+#[derive(Debug, Clone)]
+pub enum NamedObj {
+    DefBankField {
+        region_name: String,
+        bank_name: String,
+        bank_value: TermArg,
+        flags: FieldFlags,
+        field_list: Vec<FieldElement>
+    },
+    DefCreateBitField {
+        name: String,
+        source_buf: TermArg,
+        bit_index: TermArg
+    },
+    DefCreateByteField {
+        name: String,
+        source_buf: TermArg,
+        byte_index: TermArg
+    },
+    DefCreateWordField {
+        name: String,
+        source_buf: TermArg,
+        byte_index: TermArg
+    },
+    DefCreateDWordField {
+        name: String,
+        source_buf: TermArg,
+        byte_index: TermArg
+    },
+    DefCreateQWordField {
+        name: String,
+        source_buf: TermArg,
+        byte_index: TermArg
+    },
+    DefCreateField {
+        name: String,
+        source_buf: TermArg,
+        bit_index: TermArg,
+        num_bits: TermArg
+    },
+    DefDataRegion {
+        name: String,
+        signature: TermArg,
+        oem_id: TermArg,
+        oem_table_id: TermArg
+    },
+    DefDevice {
+        name: String,
+        obj_list: Vec<Object>
+    },
+    DefEvent {
+        name: String
+    },
+    DefOpRegion {
+        name: String,
+        region: RegionSpace,
+        offset: TermArg,
+        len: TermArg
+    },
+    DefField {
+        name: String,
+        flags: FieldFlags,
+        field_list: Vec<FieldElement>
+    },
+    DefIndexField {
+        idx_name: String,
+        data_name: String,
+        flags: FieldFlags,
+        field_list: Vec<FieldElement>
+    },
+    DefMethod {
+        name: String,
+        method: Method
+    },
+    DefMutex {
+        name: String,
+        sync_level: u8
+    },
+    DefPowerRes {
+        name: String,
+        system_level: u8,
+        resource_order: u16,
+        obj_list: Vec<Object>
+    },
+    DefProcessor {
+        name: String,
+        proc_id: u8,
+        p_blk_addr: u32,
+        p_blk_len: u8,
+        obj_list: Vec<Object>
+    },
+    DefThermalZone {
+        name: String,
+        obj_list: Vec<Object>
+    },
+    DeferredLoad(Vec<u8>)
+}
+
+#[derive(Debug, Clone)]
+pub struct Method {
+    arg_count: u8,
+    serialized: bool,
+    sync_level: u8,
+    term_list: Vec<TermObj>
+}
+
+impl AmlExecutable for NamedObj {
+    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
+        match *self {
+            NamedObj::DefOpRegion { ref name, ref region, ref offset, ref len } => {
+                let local_scope_string = get_namespace_string(scope.clone(), name.clone());
+
+                let resolved_offset = match offset.execute(namespace, scope.clone()) {
+                    Some(r) => r,
+                    _ => return None
+                };
+
+                let resolved_len = match len.execute(namespace, scope.clone()) {
+                    Some(r) => r,
+                    _ => return None
+                };
+                
+                namespace.push_to(local_scope_string, AmlNamespaceContents::OpRegion {
+                    region: *region,
+                    offset: resolved_offset,
+                    len: resolved_len
+                });
+            },
+            NamedObj::DefField { ref name, ref flags, ref field_list } => {
+                let mut offset: usize = 0;
+                
+                for f in field_list {
+                    match *f {
+                        FieldElement::ReservedField { length } => offset += length,
+                        FieldElement::NamedField { name: ref field_name, length } => {
+                            let local_scope_string = get_namespace_string(scope.clone(),
+                                                                          field_name.clone());
+                            namespace.push_to(local_scope_string, AmlNamespaceContents::Field {
+                                op_region: name.clone(),
+                                flags: flags.clone(),
+                                offset: offset.clone(),
+                                length: length.clone()
+                            });
+
+                            offset += length;
+                        },
+                        _ => ()
+                    }
+                }
+            },
+            NamedObj::DefMethod { ref name, ref method } => {
+                let local_scope_string = get_namespace_string(scope.clone(), name.clone());
+                namespace.push_to(local_scope_string, AmlNamespaceContents::Value(
+                                  AmlValue::Method(method.clone())));
+            },
+            _ => ()
+        }
+        
+        None
+    }
+}
+
+#[derive(Debug, Copy, Clone)]
+pub enum RegionSpace {
+    SystemMemory,
+    SystemIO,
+    PCIConfig,
+    EmbeddedControl,
+    SMBus,
+    SystemCMOS,
+    PciBarTarget,
+    IPMI,
+    GeneralPurposeIO,
+    GenericSerialBus,
+    UserDefined(u8)
+}
+
+#[derive(Debug, Clone)]
+pub struct FieldFlags {
+    access_type: AccessType,
+    lock_rule: bool,
+    update_rule: UpdateRule
+}
+
+#[derive(Debug, Clone)]
+pub enum AccessType {
+    AnyAcc,
+    ByteAcc,
+    WordAcc,
+    DWordAcc,
+    QWordAcc,
+    BufferAcc
+}
+
+#[derive(Debug, Clone)]
+pub enum UpdateRule {
+    Preserve,
+    WriteAsOnes,
+    WriteAsZeros
+}
+
+#[derive(Debug, Clone)]
+pub enum FieldElement {
+    NamedField {
+        name: String,
+        length: usize
+    },
+    ReservedField {
+        length: usize
+    },
+    AccessField {
+        access_type: AccessType,
+        access_attrib: AccessAttrib
+    },
+    ConnectFieldNameString(String),
+    ConnectFieldBufferData(DefBuffer),
+}
+
+#[derive(Debug, Clone)]
+pub enum AccessAttrib {
+    AttribBytes(u8),
+    AttribRawBytes(u8),
+    AttribRawProcessBytes(u8),
+    AttribQuick,
+    AttribSendReceive,
+    AttribByte,
+    AttribWord,
+    AttribBlock,
+    AttribProcessCall,
+    AttribBlockProcessCall
+}
+
+pub fn parse_named_obj(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_selector! {
+        data,
+        parse_def_bank_field,
+        parse_def_create_bit_field,
+        parse_def_create_byte_field,
+        parse_def_create_word_field,
+        parse_def_create_dword_field,
+        parse_def_create_qword_field,
+        parse_def_create_field,
+        parse_def_data_region,
+        parse_def_event,
+        parse_def_device,
+        parse_def_op_region,
+        parse_def_field,
+        parse_def_index_field,
+        parse_def_method,
+        parse_def_mutex,
+        parse_def_power_res,
+        parse_def_processor,
+        parse_def_thermal_zone
+    };
+
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
+
+fn parse_def_bank_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x87);
+
+    let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?;
+    let (region_name, region_name_len) = match parse_name_string(
+            &data[2 + pkg_length_len .. 2 + pkg_length]) {
+        Ok(res) => res,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+
+    let (bank_name, bank_name_len) = match parse_name_string(
+            &data[2 + pkg_length_len + region_name_len .. 2 + pkg_length]) {
+        Ok(res) => res,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+
+    let (bank_value, bank_value_len) = match parse_term_arg(
+            &data[2 + pkg_length_len + region_name_len .. 2 + pkg_length]) {
+        Ok(res) => res,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+
+    let flags_raw = data[2 + pkg_length_len + region_name_len + bank_name_len + bank_value_len];
+    let flags = FieldFlags {
+        access_type: match flags_raw & 0x0F {
+            0 => AccessType::AnyAcc,
+            1 => AccessType::ByteAcc,
+            2 => AccessType::WordAcc,
+            3 => AccessType::DWordAcc,
+            4 => AccessType::QWordAcc,
+            5 => AccessType::BufferAcc,
+            _ => return Err(AmlInternalError::AmlParseError("BankField - invalid access type"))
+        },
+        lock_rule: (flags_raw & 0x10) == 0x10,
+        update_rule: match (flags_raw & 0x60) >> 5 {
+            0 => UpdateRule::Preserve,
+            1 => UpdateRule::WriteAsOnes,
+            2 => UpdateRule::WriteAsZeros,
+            _ => return Err(AmlInternalError::AmlParseError("BankField - invalid update rule"))
+        }
+    };
+    
+    let field_list = match parse_field_list(
+        &data[3 + pkg_length_len + region_name_len + bank_name_len + bank_value_len ..
+              2 + pkg_length]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+    
+    Ok((NamedObj::DefBankField {region_name, bank_name, bank_value, flags, field_list},
+        2 + pkg_length))
+}
+
+fn parse_def_create_bit_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode!(data, 0x8D);
+
+    let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?;
+    let (bit_index, bit_index_len) = parse_term_arg(&data[1 + source_buf_len..])?;
+    let (name, name_len) = parse_name_string(&data[1 + source_buf_len + bit_index_len..])?;
+
+    Ok((NamedObj::DefCreateBitField {name, source_buf, bit_index},
+        1 + source_buf_len + bit_index_len + name_len))
+}
+
+fn parse_def_create_byte_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode!(data, 0x8C);
+
+    let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?;
+    let (byte_index, byte_index_len) = parse_term_arg(&data[1 + source_buf_len..])?;
+    let (name, name_len) = parse_name_string(&data[1 + source_buf_len + byte_index_len..])?;
+
+    Ok((NamedObj::DefCreateByteField {name, source_buf, byte_index},
+        1 + source_buf_len + byte_index_len + name_len))
+}
+
+fn parse_def_create_word_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode!(data, 0x8B);
+
+    let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?;
+    let (byte_index, byte_index_len) = parse_term_arg(&data[1 + source_buf_len..])?;
+    let (name, name_len) = parse_name_string(&data[1 + source_buf_len + byte_index_len..])?;
+
+    Ok((NamedObj::DefCreateWordField {name, source_buf, byte_index},
+        1 + source_buf_len + byte_index_len + name_len))
+}
+
+fn parse_def_create_dword_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode!(data, 0x8A);
+
+    let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?;
+    let (byte_index, byte_index_len) = parse_term_arg(&data[1 + source_buf_len..])?;
+    let (name, name_len) = parse_name_string(&data[1 + source_buf_len + byte_index_len..])?;
+
+    Ok((NamedObj::DefCreateDWordField {name, source_buf, byte_index},
+        1 + source_buf_len + byte_index_len + name_len))
+}
+
+fn parse_def_create_qword_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode!(data, 0x8F);
+
+    let (source_buf, source_buf_len) = parse_term_arg(&data[1..])?;
+    let (byte_index, byte_index_len) = parse_term_arg(&data[1 + source_buf_len..])?;
+    let (name, name_len) = parse_name_string(&data[1 + source_buf_len + byte_index_len..])?;
+
+    Ok((NamedObj::DefCreateQWordField {name, source_buf, byte_index},
+        1 + source_buf_len + byte_index_len + name_len))
+}
+
+fn parse_def_create_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x13);
+
+    let (source_buf, source_buf_len) = parse_term_arg(&data[2..])?;
+    let (bit_index, bit_index_len) = parse_term_arg(&data[2 + source_buf_len..])?;
+    let (num_bits, num_bits_len) = parse_term_arg(&data[2 + source_buf_len + bit_index_len..])?;
+    let (name, name_len) = parse_name_string(
+        &data[2 + source_buf_len + bit_index_len + num_bits_len..])?;
+
+    Ok((NamedObj::DefCreateField {name, source_buf, bit_index, num_bits},
+        2 + source_buf_len + bit_index_len + num_bits_len + name_len))
+}
+
+fn parse_def_data_region(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x88);
+
+    let (name, name_len) = parse_name_string(&data[2..])?;
+    let (signature, signature_len) = parse_term_arg(&data[2 + name_len..])?;
+    let (oem_id, oem_id_len) = parse_term_arg(&data[2 + name_len + signature_len..])?;
+    let (oem_table_id, oem_table_id_len) = parse_term_arg(
+        &data[2 + name_len + signature_len + oem_id_len..])?;
+
+    Ok((NamedObj::DefDataRegion {name, signature, oem_id, oem_table_id},
+        2 + name_len + signature_len + oem_id_len + oem_table_id_len))
+}
+
+fn parse_def_event(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x02);
+
+    let (name, name_len) = parse_name_string(&data[2..])?;
+
+    Ok((NamedObj::DefEvent {name}, 2 + name_len))
+}
+
+fn parse_def_device(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x82);
+
+    let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?;
+    let (name, name_len) = match parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+
+    let obj_list = match parse_object_list(&data[2 + pkg_length_len + name_len .. 2 + pkg_length]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+
+    Ok((NamedObj::DefDevice {name, obj_list}, 2 + pkg_length_len))
+}
+
+fn parse_def_op_region(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x80);
+    
+    let (name, name_len) = parse_name_string(&data[2..])?;
+    let region = match data[2 + name_len] {
+        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,
+        0x80 ... 0xFF => RegionSpace::UserDefined(data[2 + name_len]),
+        _ => return Err(AmlInternalError::AmlParseError("OpRegion - invalid region"))
+    };
+    
+    let (offset, offset_len) = parse_term_arg(&data[3 + name_len..])?;
+    let (len, len_len) = parse_term_arg(&data[3 + name_len + offset_len..])?;
+
+    Ok((NamedObj::DefOpRegion {name, region, offset, len}, 3 + name_len + offset_len + len_len))
+}
+
+fn parse_def_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x81);
+    
+    let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?;
+    let (name, name_len) = match parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length])  {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+
+    let flags_raw = data[2 + pkg_length_len + name_len];
+    let flags = FieldFlags {
+        access_type: match flags_raw & 0x0F {
+            0 => AccessType::AnyAcc,
+            1 => AccessType::ByteAcc,
+            2 => AccessType::WordAcc,
+            3 => AccessType::DWordAcc,
+            4 => AccessType::QWordAcc,
+            5 => AccessType::BufferAcc,
+            _ => return Err(AmlInternalError::AmlParseError("Field - Invalid access type"))
+        },
+        lock_rule: (flags_raw & 0x10) == 0x10,
+        update_rule: match (flags_raw & 0x60) >> 5 {
+            0 => UpdateRule::Preserve,
+            1 => UpdateRule::WriteAsOnes,
+            2 => UpdateRule::WriteAsZeros,
+            _ => return Err(AmlInternalError::AmlParseError("Field - Invalid update rule"))
+        }
+    };
+    
+    let field_list = match parse_field_list(&data[3 + pkg_length_len + name_len .. 2 + pkg_length]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+
+    Ok((NamedObj::DefField {name, flags, field_list}, 2 + pkg_length))
+}
+
+fn parse_def_index_field(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x86);
+
+    let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?;
+    let (idx_name, idx_name_len) = match parse_name_string(
+        &data[2 + pkg_length_len .. 2 + pkg_length])  {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+
+    let (data_name, data_name_len) = match parse_name_string(
+        &data[2 + pkg_length_len + idx_name_len .. 2 + pkg_length])  {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+    
+    let flags_raw = data[2 + pkg_length_len + idx_name_len + data_name_len];
+    let flags = FieldFlags {
+        access_type: match flags_raw & 0x0F {
+            0 => AccessType::AnyAcc,
+            1 => AccessType::ByteAcc,
+            2 => AccessType::WordAcc,
+            3 => AccessType::DWordAcc,
+            4 => AccessType::QWordAcc,
+            5 => AccessType::BufferAcc,
+            _ => return Err(AmlInternalError::AmlParseError("IndexField - Invalid access type"))
+        },
+        lock_rule: (flags_raw & 0x10) == 0x10,
+        update_rule: match (flags_raw & 0x60) >> 5 {
+            0 => UpdateRule::Preserve,
+            1 => UpdateRule::WriteAsOnes,
+            2 => UpdateRule::WriteAsZeros,
+            _ => return Err(AmlInternalError::AmlParseError("IndexField - Invalid update rule"))
+        }
+    };
+    
+    let field_list = match parse_field_list(
+        &data[3 + pkg_length_len + idx_name_len + data_name_len .. 2 + pkg_length]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_length].to_vec()), 2 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+
+    Ok((NamedObj::DefIndexField {idx_name, data_name, flags, field_list}, 2 + pkg_length))
+}
+
+fn parse_field_list(data: &[u8]) -> Result<Vec<FieldElement>, AmlInternalError> {
+    let mut terms: Vec<FieldElement> = vec!();
+    let mut current_offset: usize = 0;
+
+    while current_offset < data.len() {
+        let (res, len) = match parse_field_element(&data[current_offset..]) {
+            Ok(r) => r,
+            Err(AmlInternalError::AmlInvalidOpCode) =>
+                return Err(AmlInternalError::AmlParseError("FieldList - no valid field")),
+            Err(e) => return Err(e)
+        };
+        
+        terms.push(res);
+        current_offset += len;
+    }
+
+    Ok(terms)
+}
+
+fn parse_field_element(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> {
+    parser_selector! {
+        data,
+        parse_named_field,
+        parse_reserved_field,
+        parse_access_field,
+        parse_connect_field
+    };
+
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
+
+fn parse_named_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> {
+    let (name_seg, name_seg_len) = parse_name_seg(&data[0..4])?;
+    let name = match String::from_utf8(name_seg) {
+        Ok(s) => s,
+        Err(_) => return Err(AmlInternalError::AmlParseError("NamedField - invalid name"))
+    };
+    let (length, length_len) = parse_pkg_length(&data[4..])?;
+
+    Ok((FieldElement::NamedField {name, length}, 4 + length_len))
+}
+
+fn parse_reserved_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> {
+    parser_opcode!(data, 0x00);
+    
+    let (length, length_len) = parse_pkg_length(&data[1..])?;
+    Ok((FieldElement::ReservedField {length}, 1 + length_len))
+}
+
+fn parse_access_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> {
+    parser_opcode!(data, 0x01, 0x03);
+    
+    let flags_raw = data[1];
+    let access_type = match flags_raw & 0x0F {
+        0 => AccessType::AnyAcc,
+        1 => AccessType::ByteAcc,
+        2 => AccessType::WordAcc,
+        3 => AccessType::DWordAcc,
+        4 => AccessType::QWordAcc,
+        5 => AccessType::BufferAcc,
+        _ => return Err(AmlInternalError::AmlParseError("AccessField - Invalid access type"))
+    };
+
+    let access_attrib = match (flags_raw & 0xC0) >> 6 {
+        0 => match data[2] {
+            0x02 => AccessAttrib::AttribQuick,
+            0x04 => AccessAttrib::AttribSendReceive,
+            0x06 => AccessAttrib::AttribByte,
+            0x08 => AccessAttrib::AttribWord,
+            0x0A => AccessAttrib::AttribBlock,
+            0x0B => AccessAttrib::AttribBytes(data[3]),
+            0x0C => AccessAttrib::AttribProcessCall,
+            0x0D => AccessAttrib::AttribBlockProcessCall,
+            0x0E => AccessAttrib::AttribRawBytes(data[3]),
+            0x0F => AccessAttrib::AttribRawProcessBytes(data[3]),
+            _ => return Err(AmlInternalError::AmlParseError("AccessField - Invalid access attrib"))
+        },
+        1 => AccessAttrib::AttribBytes(data[2]),
+        2 => AccessAttrib::AttribRawBytes(data[2]),
+        3 => AccessAttrib::AttribRawProcessBytes(data[2]),
+        _ => return Err(AmlInternalError::AmlParseError("AccessField - Invalid access attrib"))
+            // This should never happen but the compiler bitches if I don't cover this
+    };
+
+    return Ok((FieldElement::AccessField {access_type, access_attrib}, if data[0] == 0x01 {
+        3 as usize
+    } else {
+        4 as usize
+    }))
+}
+
+fn parse_connect_field(data: &[u8]) -> Result<(FieldElement, usize), AmlInternalError> {
+    parser_opcode!(data, 0x02);
+    
+    match parse_def_buffer(&data[1..]) {
+        Ok((buf, buf_len)) => return Ok((FieldElement::ConnectFieldBufferData(buf), buf_len + 1)),
+        Err(AmlInternalError::AmlInvalidOpCode) => (),
+        Err(e) => return Err(e)
+    }
+
+    match parse_name_string(&data[1..]) {
+        Ok((name, name_len)) => Ok((FieldElement::ConnectFieldNameString(name), name_len + 1)),
+        Err(AmlInternalError::AmlInvalidOpCode) => Err(AmlInternalError::AmlParseError("ConnectField - unable to match field")),
+        Err(e) => Err(e)
+    }
+}
+
+fn parse_def_method(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode!(data, 0x14);
+
+    let (pkg_len, pkg_len_len) = parse_pkg_length(&data[1..])?;
+    let (name, name_len) = match parse_name_string(&data[1 + pkg_len_len..]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 1 + pkg_len].to_vec()), 1 + pkg_len)),
+        Err(e) => return Err(e)
+    };
+    let flags = data[1 + pkg_len_len + name_len];
+
+    let arg_count = flags & 0x07;
+    let serialized = (flags & 0x08) == 0x08;
+    let sync_level = flags & 0xF0 >> 4;
+
+    let term_list = match parse_term_list(&data[2 + pkg_len_len + name_len .. 1 + pkg_len]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 1 + pkg_len].to_vec()), 1 + pkg_len)),
+        Err(e) => return Err(e)
+    };
+
+    Ok((NamedObj::DefMethod {
+        name: name,
+        method: Method {
+            arg_count,
+            serialized,
+            sync_level,
+            term_list
+        }
+    }, pkg_len + 1))
+}
+
+fn parse_def_mutex(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x01);
+
+    let (name, name_len) = match parse_name_string(&data[2 ..]) {
+        Ok(p) => p,
+        Err(e) => return Err(e),
+    };
+    let flags = data[2 + name_len];
+    let sync_level = flags & 0x0F;
+
+    Ok((NamedObj::DefMutex {name, sync_level}, name_len + 3))
+}
+
+fn parse_def_power_res(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x84);
+
+    let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?;
+    let (name, name_len) = match parse_name_string(&data[2 + pkg_len_len..]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)),
+        Err(e) => return Err(e)
+    };
+    
+    let system_level = data[2 + pkg_len_len + name_len];
+    let resource_order: u16 = (data[3 + pkg_len_len + name_len] as u16) +
+        ((data[4 + pkg_len_len + name_len] as u16) << 8);
+
+    let obj_list = match parse_object_list(&data[5 + pkg_len_len + name_len .. 2 + pkg_len]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)),
+        Err(e) => return Err(e)
+    };
+
+    Ok((NamedObj::DefPowerRes {name, system_level, resource_order, obj_list}, 2 + pkg_len))
+}
+
+fn parse_def_processor(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x83);
+
+    let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?;
+    let (name, name_len) = match parse_name_string(&data[2 + pkg_len_len..]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)),
+        Err(e) => return Err(e)
+    };
+    
+    let proc_id = data[2 + pkg_len_len + name_len];
+    let p_blk_addr: u32 = (data[3 + pkg_len_len + name_len] as u32) +
+        ((data[4 + pkg_len_len + name_len] as u32) << 8) +
+        ((data[5 + pkg_len_len + name_len] as u32) << 16) +
+        ((data[6 + pkg_len_len + name_len] as u32) << 24);
+    let p_blk_len = data[7 + pkg_len_len + name_len];
+
+    let obj_list = match parse_object_list(&data[8 + pkg_len_len + name_len .. 2 + pkg_len]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)),
+        Err(e) => return Err(e)
+    };
+
+    Ok((NamedObj::DefProcessor {name, proc_id, p_blk_addr, p_blk_len, obj_list}, 2 + pkg_len))
+}
+
+fn parse_def_thermal_zone(data: &[u8]) -> Result<(NamedObj, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x85);
+
+    let (pkg_len, pkg_len_len) = parse_pkg_length(&data[2..])?;
+    let (name, name_len) = match parse_name_string(&data[2 + pkg_len_len..]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)),
+        Err(e) => return Err(e)
+    };
+    
+    let obj_list = match parse_object_list(&data[2 + pkg_len_len + name_len .. 2 + pkg_len]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamedObj::DeferredLoad(data[0 .. 2 + pkg_len].to_vec()), 2 + pkg_len)),
+        Err(e) => return Err(e)
+    };
+
+    Ok((NamedObj::DefThermalZone {name, obj_list}, 2 + pkg_len))
+}
diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8a0c6f966fbb241c7e75b0cdb6619fcfc17807b9
--- /dev/null
+++ b/src/acpi/aml/namespace.rs
@@ -0,0 +1,225 @@
+use collections::string::String;
+use collections::vec::Vec;
+use collections::boxed::Box;
+
+use core::str::FromStr;
+
+use super::namedobj::{ RegionSpace, FieldFlags, Method };
+
+#[derive(Debug, Clone)]
+pub struct AmlNamespace {
+    name: String,
+    contents: AmlNamespaceContents
+}
+
+#[derive(Debug, Clone)]
+pub enum AmlNamespaceContents {
+    Value(AmlValue),
+    SubNamespace(Box<AmlNamespace>),
+    Namespace(Vec<AmlNamespaceContents>),
+    OpRegion {
+        region: RegionSpace,
+        offset: AmlValue,
+        len: AmlValue
+    },
+    Field {
+        op_region: String,
+        flags: FieldFlags,
+        offset: usize,
+        length: usize
+    }
+}
+
+#[derive(Debug, Clone)]
+pub enum AmlValue {
+    Uninitialized,
+    Buffer,
+    BufferField,
+    DDBHandle,
+    DebugObject,
+    Device,
+    Event,
+    FieldUnit,
+    Integer,
+    IntegerConstant(u64),
+    Method(Method),
+    Mutex,
+    ObjectReference,
+    OperationRegion,
+    Package(Vec<AmlValue>),
+    String,
+    PowerResource,
+    Processor,
+    RawDataBuffer,
+    ThermalZone
+}
+
+impl AmlValue {
+    pub fn get_as_package(&self) -> Option<Vec<AmlValue>> {
+        match *self {
+            AmlValue::Package(ref p) => Some(p.clone()),
+            _ => None
+        }
+    }
+
+    pub fn get_as_integer(&self) -> Option<u64> {
+        match *self {
+            AmlValue::IntegerConstant(ref i) => Some(i.clone()),
+            _ => None
+        }
+    }
+}
+
+impl AmlNamespace {
+    pub fn new_namespace(name: &String) -> AmlNamespace {
+        AmlNamespace {
+            name: name.clone(),
+            contents: AmlNamespaceContents::Namespace(vec!())
+        }
+    }
+
+    pub fn find_str(&self, scope_str: &str) -> Option<AmlValue> {
+        let scope_string = String::from_str(scope_str).unwrap();
+        self.find(scope_string)
+    }
+    
+    pub fn find(&self, scope_string: String) -> Option<AmlValue> {
+        if scope_string.len() == 0 {
+            match self.contents {
+                AmlNamespaceContents::Value(ref v) => return Some(v.clone()),
+                _ => return None
+            }
+        }
+        
+        let mut scope_string = scope_string.clone();
+        
+        if scope_string.starts_with("\\") {
+            if self.name != "\\" {
+                return None;
+            }
+
+            scope_string.remove(0);
+        }
+
+        if scope_string.starts_with(".") {
+            scope_string.remove(0);
+        }
+        
+        if scope_string.len() == 0 {
+            match self.contents {
+                AmlNamespaceContents::Value(ref v) => return Some(v.clone()),
+                _ => return None
+            }
+        }
+
+        let (current, nextset) = match scope_string.find(".") {
+            Some(s) => {
+                let (x, mut y) = scope_string.split_at(s);
+                y = &y[1..];
+
+                (String::from_str(x).unwrap(), String::from_str(y).unwrap())
+            },
+            None => if scope_string.len() <= 4 {
+                (scope_string, String::from_str("").unwrap())
+            } else {
+                return None;
+            }
+        };
+
+        match self.contents {
+            AmlNamespaceContents::Namespace(ref namespace) => {
+                // TODO: Remove this while loop here, there has to be a more elegant way
+                let mut current_index = 0;
+                while current_index < namespace.len() {
+                    match namespace[current_index] {
+                        AmlNamespaceContents::SubNamespace(ref ns) => if ns.name == current {
+                            return ns.find(nextset);
+                        },
+                        _ => ()
+                    }
+
+                    current_index += 1;
+                }
+            },
+            _ => ()
+        }
+
+        None
+    }
+    
+    pub fn push(&mut self, val: AmlNamespaceContents) {
+        match self.contents {
+            AmlNamespaceContents::Namespace(ref mut v) => v.push(val),
+            _ => () // TODO: Error this
+        }
+    }
+
+    pub fn push_to(&mut self, scope_string: String, contents: AmlNamespaceContents) {
+        if scope_string.len() == 0 {
+            return;
+        }
+        
+        let mut scope_string = scope_string.clone();
+        
+        if scope_string.starts_with("\\") {
+            if self.name != "\\" {
+                return;
+                // TODO: Error this
+            }
+
+            scope_string.remove(0);
+        }
+
+        if scope_string.starts_with(".") {
+            scope_string.remove(0);
+        }
+        
+        if scope_string.len() == 0 {
+            return;
+        }
+
+        let (current, nextset) = match scope_string.find(".") {
+            Some(s) => {
+                let (x, mut y) = scope_string.split_at(s);
+                y = &y[1..];
+
+                (String::from_str(x).unwrap(), String::from_str(y).unwrap())
+            },
+            None => if scope_string.len() <= 4 {
+                (scope_string, String::from_str("").unwrap())
+            } else {
+                return;
+            }
+        };
+
+        match self.contents {
+            AmlNamespaceContents::Namespace(ref mut namespace) => {
+                // TODO: Remove this while loop here, there has to be a more elegant way
+                let mut current_index = 0;
+                while current_index < namespace.len() {
+                    match namespace[current_index] {
+                        AmlNamespaceContents::SubNamespace(ref mut ns) => if ns.name == current {
+                            ns.push_to(nextset, contents);
+                            return;
+                        },
+                        _ => ()
+                    }
+
+                    current_index += 1;
+                }
+                
+                let mut next = AmlNamespace {
+                    name: current,
+                    contents: contents
+                };
+                
+                namespace.push(AmlNamespaceContents::SubNamespace(Box::new(next)));
+            }
+            _ => () // TODO: Error this
+        }
+    }
+
+    pub fn push_subordinate_namespace(&mut self, scope_string: String) {
+        self.push_to(scope_string, AmlNamespaceContents::Namespace(vec!()));
+    }
+}
diff --git a/src/acpi/aml/namespacemodifier.rs b/src/acpi/aml/namespacemodifier.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a49e2bb0b677978b6abb37a185c7e8bdc62b3d0a
--- /dev/null
+++ b/src/acpi/aml/namespacemodifier.rs
@@ -0,0 +1,102 @@
+use collections::vec::Vec;
+use collections::string::String;
+use collections::boxed::Box;
+
+use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace, AmlNamespaceContents, get_namespace_string};
+use super::pkglength::parse_pkg_length;
+use super::namestring::parse_name_string;
+use super::termlist::{parse_term_list, TermObj};
+use super::dataobj::{parse_data_ref_obj, DataRefObj};
+
+#[derive(Debug, Clone)]
+pub enum NamespaceModifier {
+    Name {
+        name: String,
+        data_ref_obj: DataRefObj
+    },
+    Scope {
+        name: String,
+        terms: Vec<TermObj>
+    },
+    Alias {
+        source_name: String,
+        alias_name: String
+    },
+    DeferredLoad(Vec<u8>)
+}
+
+impl AmlExecutable for NamespaceModifier {
+    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
+        match *self {
+            NamespaceModifier::Scope { name: ref name, terms: ref terms } => {
+                let local_scope_string = get_namespace_string(scope, name.clone());
+                namespace.push_subordinate_namespace(local_scope_string.clone());
+
+                terms.execute(namespace, local_scope_string);
+            },
+            NamespaceModifier::Name { ref name, ref data_ref_obj } => {
+                let local_scope_string = get_namespace_string(scope.clone(), name.clone());
+                let dro = match data_ref_obj.execute(namespace, scope) {
+                    Some(s) => s,
+                    None => return None
+                };
+
+                namespace.push_to(local_scope_string, AmlNamespaceContents::Value(dro));
+            },
+            _ => ()
+        }
+
+        None
+    }
+}
+
+pub fn parse_namespace_modifier(data: &[u8]) -> Result<(NamespaceModifier, usize), AmlInternalError> {
+    parser_selector! {
+        data,
+        parse_alias_op,
+        parse_scope_op,
+        parse_name_op
+    };
+
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
+
+fn parse_alias_op(data: &[u8]) -> Result<(NamespaceModifier, usize), AmlInternalError> {
+    parser_opcode!(data, 0x06);
+    
+    let (source_name, source_name_len) = parse_name_string(&data[1..])?;
+    let (alias_name, alias_name_len) = parse_name_string(&data[1 + source_name_len..])?;
+    
+    Ok((NamespaceModifier::Alias {source_name, alias_name}, 1 + source_name_len + alias_name_len))
+}
+
+fn parse_name_op(data: &[u8]) -> Result<(NamespaceModifier, usize), AmlInternalError> {
+    parser_opcode!(data, 0x08);
+
+    let (name, name_len) = parse_name_string(&data[1..])?;
+    let (data_ref_obj, data_ref_obj_len) = parse_data_ref_obj(&data[1 + name_len..])?;
+    
+    Ok((NamespaceModifier::Name {name, data_ref_obj}, 1 + name_len + data_ref_obj_len))
+}
+
+fn parse_scope_op(data: &[u8]) -> Result<(NamespaceModifier, usize), AmlInternalError> {
+    parser_opcode!(data, 0x10);
+    
+    let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
+    let (name, name_len) = match parse_name_string(&data[1 + pkg_length_len..]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamespaceModifier::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()),
+                       1 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+    let terms = match parse_term_list(&data[1 + pkg_length_len + name_len..]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((NamespaceModifier::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()),
+                       1 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+
+    Ok((NamespaceModifier::Scope {name, terms}, pkg_length + 1))
+}
diff --git a/src/acpi/aml/namestring.rs b/src/acpi/aml/namestring.rs
new file mode 100644
index 0000000000000000000000000000000000000000..8015a8ca8559a53421e5a38a72544f3476d706a2
--- /dev/null
+++ b/src/acpi/aml/namestring.rs
@@ -0,0 +1,188 @@
+use collections::vec::Vec;
+use collections::string::String;
+
+use super::AmlInternalError;
+
+use super::dataobj::{parse_arg_obj, parse_local_obj, ArgObj, LocalObj};
+use super::type2opcode::{parse_type6_opcode, Type6OpCode};
+
+#[derive(Debug, Clone)]
+pub enum SuperName {
+    NameString(String),
+    ArgObj(ArgObj),
+    LocalObj(LocalObj),
+    DebugObj,
+    Type6OpCode(Type6OpCode)
+}
+
+#[derive(Debug, Clone)]
+pub enum Target {
+    SuperName(SuperName),
+    Null
+}
+
+pub fn parse_name_string(data: &[u8]) -> Result<(String, usize), AmlInternalError> {
+    let mut characters: Vec<u8> = vec!();
+    let mut starting_index: usize = 0;
+
+    if data[0] == 0x5C {
+        characters.push(data[0]);
+        starting_index = 1;
+    } else if data[0] == 0x5E {
+        while data[starting_index] == 0x5E {
+            characters.push(data[starting_index]);
+            starting_index += 1;
+        }
+    }
+
+    let sel = |data| {
+        parser_selector! {
+            data,
+            parse_dual_name_path,
+            parse_multi_name_path,
+            parse_null_name,
+            parse_name_seg
+        };
+
+        Err(AmlInternalError::AmlInvalidOpCode)
+    };
+    let (mut chr, len) = sel(&data[starting_index..])?;
+    characters.append(&mut chr);
+
+    let name_string = String::from_utf8(characters);
+
+    match name_string {
+        Ok(s) => Ok((s.clone(), len + starting_index)),
+        Err(_) => Err(AmlInternalError::AmlParseError("Namestring - Name is invalid"))
+    }
+}
+
+fn parse_null_name(data: &[u8]) -> Result<(Vec<u8>, usize), AmlInternalError> {
+    parser_opcode!(data, 0x00);
+    Ok((vec!(), 1 as usize))
+}
+
+pub fn parse_name_seg(data: &[u8]) -> Result<(Vec<u8>, usize), AmlInternalError> {
+    match data[0] {
+        0x41 ... 0x5A | 0x5F => (),
+        _ => return Err(AmlInternalError::AmlInvalidOpCode)
+    }
+
+    match data[1] {
+        0x30 ... 0x39 | 0x41 ... 0x5A | 0x5F => (),
+        _ => return Err(AmlInternalError::AmlInvalidOpCode)
+    }
+
+    match data[2] {
+        0x30 ... 0x39 | 0x41 ... 0x5A | 0x5F => (),
+        _ => return Err(AmlInternalError::AmlInvalidOpCode)
+    }
+
+    match data[3] {
+        0x30 ... 0x39 | 0x41 ... 0x5A | 0x5F => (),
+        _ => return Err(AmlInternalError::AmlInvalidOpCode)
+    }
+
+    let mut name_seg = vec!(data[0], data[1], data[2], data[3]);
+    while *(name_seg.last().unwrap()) == 0x5F {
+        name_seg.pop();
+    }
+
+    Ok((name_seg, 4 as usize))
+}
+
+fn parse_dual_name_path(data: &[u8]) -> Result<(Vec<u8>, usize), AmlInternalError> {
+    parser_opcode!(data, 0x2E);
+
+    let mut characters: Vec<u8> = vec!();
+    let mut dual_len: usize = 1;
+
+    match parse_name_seg(&data[1..5]) {
+        Ok((mut v, len)) => {
+            characters.append(&mut v);
+            dual_len += len;
+        },
+        Err(e) => return Err(e)
+    }
+
+    characters.push(0x2E);
+
+    match parse_name_seg(&data[5..9]) {
+        Ok((mut v, len)) => {
+            characters.append(&mut v);
+            dual_len += len;
+        },
+        Err(e) => return Err(e)
+    }
+
+    Ok((characters, dual_len))
+}
+
+fn parse_multi_name_path(data: &[u8]) -> Result<(Vec<u8>, usize), AmlInternalError> {
+    parser_opcode!(data, 0x2F);
+
+    let seg_count = data[1];
+    if seg_count == 0x00 {
+        return Err(AmlInternalError::AmlParseError("MultiName Path - can't have zero name segments"));
+    }
+
+    let mut current_seg = 0;
+    let mut characters: Vec<u8> = vec!();
+    let mut multi_len: usize = 2;
+    
+    while current_seg < seg_count {
+        match parse_name_seg(&data[(current_seg as usize * 4) + 2 ..]) {
+            Ok((mut v, len)) => {
+                characters.append(&mut v);
+                multi_len += len;
+            },
+            Err(e) => return Err(e)
+        }
+
+        characters.push(0x2E);
+
+        current_seg += 1;
+    }
+
+    characters.pop();
+
+    Ok((characters, multi_len))
+}
+
+pub fn parse_super_name(data: &[u8]) -> Result<(SuperName, usize), AmlInternalError> {
+    parser_selector! {
+        data,
+        parse_simple_name,
+        parser_wrap!(SuperName::Type6OpCode, parse_type6_opcode),
+        parse_debug_obj
+    };
+
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
+
+fn parse_debug_obj(data: &[u8]) -> Result<(SuperName, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x31);
+    Ok((SuperName::DebugObj, 2 as usize))
+}
+
+pub fn parse_simple_name(data: &[u8]) -> Result<(SuperName, usize), AmlInternalError> {
+    parser_selector! {
+        data,
+        parser_wrap!(SuperName::NameString, parse_name_string),
+        parser_wrap!(SuperName::ArgObj, parse_arg_obj),
+        parser_wrap!(SuperName::LocalObj, parse_local_obj)
+    };
+
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
+
+pub fn parse_target(data: &[u8]) -> Result<(Target, usize), AmlInternalError> {
+    if data[0] == 0x00 {
+        Ok((Target::Null, 1 as usize))
+    } else {
+        match parse_super_name(data) {
+            Ok((name, name_len)) => Ok((Target::SuperName(name), name_len)),
+            Err(e) => Err(e)
+        }
+    }
+}
diff --git a/src/acpi/aml/parsermacros.rs b/src/acpi/aml/parsermacros.rs
new file mode 100644
index 0000000000000000000000000000000000000000..50e3aed575cc59feb62baca60c2e5db7636c92b3
--- /dev/null
+++ b/src/acpi/aml/parsermacros.rs
@@ -0,0 +1,49 @@
+#[macro_export]
+macro_rules! parser_selector {
+    {$data:expr, $func:expr} => {
+        match $func($data) {
+            Ok(res) => return Ok(res),
+            Err(AmlInternalError::AmlInvalidOpCode) => (),
+            Err(e) => return Err(e)
+        }
+    };
+    {$data:expr, $func:expr, $($funcs:expr),+} => {
+        parser_selector! {$data, $func};
+        parser_selector! {$data, $($funcs),*};
+    };
+}
+
+#[macro_export]
+macro_rules! parser_wrap {
+    ($wrap:expr, $func:expr) => {
+        |data| { 
+            match $func(data) {
+                Ok((res, size)) => Ok(($wrap(res), size)),
+                Err(e) => Err(e)
+            }
+        }
+    };
+}
+
+#[macro_export]
+macro_rules! parser_opcode {
+    ($data:expr, $opcode:expr) => {
+        if $data[0] != $opcode {
+            return Err(AmlInternalError::AmlInvalidOpCode);
+        }
+    };
+    ($data:expr, $opcode:expr, $alternate_opcode:expr) => {
+        if $data[0] != $opcode && $data[0] != $alternate_opcode {
+            return Err(AmlInternalError::AmlInvalidOpCode);
+        }
+    };
+}
+
+#[macro_export]
+macro_rules! parser_opcode_extended {
+    ($data:expr, $opcode:expr) => {
+        if $data[0] != 0x5B || $data[1] != $opcode {
+            return Err(AmlInternalError::AmlInvalidOpCode);
+        }
+    };
+}
diff --git a/src/acpi/aml/pkglength.rs b/src/acpi/aml/pkglength.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7c4ace8d124aea4f64ac9bc7c8740d38449451a4
--- /dev/null
+++ b/src/acpi/aml/pkglength.rs
@@ -0,0 +1,25 @@
+use super::AmlInternalError;
+
+pub fn parse_pkg_length(data: &[u8]) -> Result<(usize, usize), AmlInternalError> {
+    let lead_byte = data[0];
+    let count_bytes: usize = (lead_byte >> 6) as usize;
+
+    if count_bytes == 0 {
+        return Ok(((lead_byte & 0x3F) as usize, 1 as usize));
+    }
+
+    let upper_two = (lead_byte >> 4) & 0x03;
+    if upper_two != 0 {
+        return Err(AmlInternalError::AmlParseError("Invalid package length"));
+    }
+
+    let mut current_byte = 0;
+    let mut pkg_len: usize = (lead_byte & 0x0F) as usize;
+
+    while current_byte < count_bytes {
+        pkg_len += (data[1 + current_byte] as u32 * 16 * (256 as u32).pow(current_byte as u32)) as usize;
+        current_byte += 1;
+    }
+    
+    return Ok((pkg_len, count_bytes + 1));
+}
diff --git a/src/acpi/aml/termlist.rs b/src/acpi/aml/termlist.rs
new file mode 100644
index 0000000000000000000000000000000000000000..014bddb97f49f0ff48e706da87b280422c59303c
--- /dev/null
+++ b/src/acpi/aml/termlist.rs
@@ -0,0 +1,135 @@
+use collections::vec::Vec;
+use collections::boxed::Box;
+use collections::string::String;
+
+use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace, get_namespace_string};
+use super::namespacemodifier::{parse_namespace_modifier, NamespaceModifier};
+use super::namedobj::{parse_named_obj, NamedObj};
+use super::dataobj::{parse_data_obj, parse_arg_obj, parse_local_obj, DataObj, ArgObj, LocalObj};
+use super::type1opcode::{parse_type1_opcode, Type1OpCode};
+use super::type2opcode::{parse_type2_opcode, Type2OpCode};
+use super::namestring::parse_name_string;
+
+#[derive(Debug, Clone)]
+pub enum TermArg {
+    LocalObj(Box<LocalObj>),
+    DataObj(Box<DataObj>),
+    ArgObj(Box<ArgObj>),
+    Type2Opcode(Box<Type2OpCode>)
+}
+
+#[derive(Debug, Clone)]
+pub enum TermObj {
+    NamespaceModifier(Box<NamespaceModifier>),
+    NamedObj(Box<NamedObj>),
+    Type1Opcode(Box<Type1OpCode>),
+    Type2Opcode(Box<Type2OpCode>)
+}
+
+#[derive(Debug, Clone)]
+pub enum Object {
+    NamespaceModifier(Box<NamespaceModifier>),
+    NamedObj(Box<NamedObj>)
+}
+
+#[derive(Debug, Clone)]
+pub struct MethodInvocation {
+
+}
+
+impl AmlExecutable for Vec<TermObj> {
+    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
+        for term in self {
+            term.execute(namespace, scope.clone());
+        }
+
+        None
+    }
+}
+
+impl AmlExecutable for TermArg {
+    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
+        match *self {
+            TermArg::LocalObj(ref l) => Some(AmlValue::Integer),
+            TermArg::DataObj(ref d) => d.execute(namespace, scope),
+            TermArg::ArgObj(ref a) => Some(AmlValue::Integer),
+            TermArg::Type2Opcode(ref o) => Some(AmlValue::Integer)
+        }
+    }
+}
+
+impl AmlExecutable for TermObj {
+    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
+        match *self {
+            TermObj::NamespaceModifier(ref res) => res.execute(namespace, scope.clone()),
+            TermObj::NamedObj(ref res) => res.execute(namespace, scope.clone()),
+            TermObj::Type1Opcode(ref res) => res.execute(namespace, scope.clone()),
+            TermObj::Type2Opcode(ref res) => res.execute(namespace, scope.clone())
+        }
+    }
+}
+
+pub fn parse_term_list(data: &[u8]) -> Result<Vec<TermObj>, AmlInternalError> {
+    let mut terms: Vec<TermObj> = vec!();
+    let mut current_offset: usize = 0;
+
+    while current_offset < data.len() {
+        let (res, len) = parse_term_obj(&data[current_offset..])?;
+        terms.push(res);
+        current_offset += len;
+    }
+
+    Ok(terms)
+}
+
+pub fn parse_term_arg(data: &[u8]) -> Result<(TermArg, usize), AmlInternalError> {
+    parser_selector! {
+        data,
+        parser_wrap!(TermArg::LocalObj, parser_wrap!(Box::new, parse_local_obj)),
+        parser_wrap!(TermArg::DataObj, parser_wrap!(Box::new, parse_data_obj)),
+        parser_wrap!(TermArg::ArgObj, parser_wrap!(Box::new, parse_arg_obj)),
+        parser_wrap!(TermArg::Type2Opcode, parser_wrap!(Box::new, parse_type2_opcode))
+    };
+
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
+
+pub fn parse_object_list(data: &[u8]) -> Result<Vec<Object>, AmlInternalError> {
+    let mut terms: Vec<Object> = vec!();
+    let mut current_offset: usize = 0;
+
+    while current_offset < data.len() {
+        let (res, len) = parse_object(&data[current_offset..])?;
+        terms.push(res);
+        current_offset += len;
+    }
+    
+    Ok(terms)
+}
+
+fn parse_object(data: &[u8]) -> Result<(Object, usize), AmlInternalError> {
+    parser_selector! {
+        data,
+        parser_wrap!(Object::NamespaceModifier, parser_wrap!(Box::new, parse_namespace_modifier)),
+        parser_wrap!(Object::NamedObj, parser_wrap!(Box::new, parse_named_obj))
+    };
+
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
+
+pub fn parse_method_invocation(data: &[u8]) -> Result<(MethodInvocation, usize), AmlInternalError> {
+    let (name, name_len) = parse_name_string(data)?;
+    Err(AmlInternalError::AmlDeferredLoad)
+}
+
+fn parse_term_obj(data: &[u8]) -> Result<(TermObj, usize), AmlInternalError> {
+    parser_selector! {
+        data,
+        parser_wrap!(TermObj::NamespaceModifier, parser_wrap!(Box::new, parse_namespace_modifier)),
+        parser_wrap!(TermObj::NamedObj, parser_wrap!(Box::new, parse_named_obj)),
+        parser_wrap!(TermObj::Type1Opcode, parser_wrap!(Box::new, parse_type1_opcode)),
+        parser_wrap!(TermObj::Type2Opcode, parser_wrap!(Box::new, parse_type2_opcode))
+    };
+
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
diff --git a/src/acpi/aml/type1opcode.rs b/src/acpi/aml/type1opcode.rs
new file mode 100644
index 0000000000000000000000000000000000000000..c6cc5cab5e207962e9282ca09809cbae9974114b
--- /dev/null
+++ b/src/acpi/aml/type1opcode.rs
@@ -0,0 +1,259 @@
+use collections::vec::Vec;
+use collections::string::String;
+use collections::boxed::Box;
+
+use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace};
+use super::pkglength::parse_pkg_length;
+use super::termlist::{parse_term_arg, parse_term_list, TermObj, TermArg};
+use super::namestring::{parse_name_string, parse_super_name, SuperName};
+
+#[derive(Debug, Clone)]
+pub enum Type1OpCode {
+    DefBreak,
+    DefBreakPoint,
+    DefContinue,
+    DefFatal {
+        fatal_type: u8,
+        fatal_code: u16,
+        fatal_arg: TermArg
+    },
+    DefNoop,
+    DefIfElse {
+        if_block: IfBlock,
+        else_block: IfBlock
+    },
+    DefLoad {
+        name: String,
+        ddb_handle_object: SuperName
+    },
+    DefNotify {
+        object: SuperName,
+        value: TermArg
+    },
+    DefRelease(SuperName),
+    DefReset(SuperName),
+    DefSignal(SuperName),
+    DefSleep(TermArg),
+    DefStall(TermArg),
+    DefUnload(SuperName),
+    DefWhile {
+        predicate: TermArg,
+        block: Vec<TermObj>
+    },
+    DefReturn(TermArg),
+    DeferredLoad(Vec<u8>)
+}
+
+impl AmlExecutable for Type1OpCode {
+    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
+        None
+    }
+}
+
+#[derive(Debug, Clone)]
+pub enum IfBlock {
+    If {
+        predicate: TermArg,
+        if_block: Vec<TermObj>
+    },
+    Else(Vec<TermObj>),
+    NoBlock,
+    DeferredLoad(Vec<u8>)
+}
+
+pub fn parse_type1_opcode(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
+    match data[0] {
+        0xA5 => return Ok((Type1OpCode::DefBreak, 1 as usize)),
+        0xCC => return Ok((Type1OpCode::DefBreakPoint, 1 as usize)),
+        0x9F => return Ok((Type1OpCode::DefContinue, 1 as usize)),
+        0xA3 => return Ok((Type1OpCode::DefNoop, 1 as usize)),
+        _ => ()
+    }
+
+    parser_selector! {
+        data,
+        parse_def_fatal,
+        parse_def_if_else,
+        parse_def_load,
+        parse_def_notify,
+        parse_def_release,
+        parse_def_reset,
+        parse_def_signal,
+        parse_def_sleep,
+        parse_def_stall,
+        parse_def_return,
+        parse_def_unload,
+        parse_def_while
+    };
+
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
+
+fn parse_def_fatal(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
+    if data[0] != 0x5B || data[1] != 0x32 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let fatal_type = data[2];
+    let fatal_code: u16 = (data[3] as u16) +
+        ((data[4] as u16) << 8);
+    let (fatal_arg, fatal_arg_len) = parse_term_arg(&data[5..])?;
+
+    Ok((Type1OpCode::DefFatal {fatal_type, fatal_code, fatal_arg}, fatal_arg_len + 5))
+}
+
+fn parse_def_load(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
+    if data[0] != 0x5B || data[1] != 0x20 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (name, name_len) = parse_name_string(&data[2..])?;
+    let (ddb_handle_object, ddb_handle_object_len) = parse_super_name(&data[2 + name_len..])?;
+
+    Ok((Type1OpCode::DefLoad {name, ddb_handle_object}, 2 + name_len + ddb_handle_object_len))
+}
+
+fn parse_def_notify(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
+    if data[0] != 0x86 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (object, object_len) = parse_super_name(&data[1..])?;
+    let (value, value_len) = parse_term_arg(&data[1 + object_len..])?;
+
+    Ok((Type1OpCode::DefNotify {object, value}, 1 + object_len + value_len))
+}
+
+fn parse_def_release(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
+    if data[0] != 0x5B || data[1] != 0x27 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (object, object_len) = parse_super_name(&data[2..])?;
+
+    Ok((Type1OpCode::DefRelease(object), 2 + object_len))
+}
+
+fn parse_def_reset(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
+    if data[0] != 0x5B || data[1] != 0x26 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (object, object_len) = parse_super_name(&data[2..])?;
+
+    Ok((Type1OpCode::DefReset(object), 2 + object_len))
+}
+
+fn parse_def_signal(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
+    if data[0] != 0x5B || data[1] != 0x24 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (object, object_len) = parse_super_name(&data[2..])?;
+
+    Ok((Type1OpCode::DefSignal(object), 2 + object_len))
+}
+
+fn parse_def_sleep(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
+    if data[0] != 0x5B || data[1] != 0x22 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (time, time_len) = parse_term_arg(&data[2..])?;
+
+    Ok((Type1OpCode::DefSleep(time), 2 + time_len))
+}
+
+fn parse_def_stall(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
+    if data[0] != 0x5B || data[1] != 0x21 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (time, time_len) = parse_term_arg(&data[2..])?;
+
+    Ok((Type1OpCode::DefStall(time), 2 + time_len))
+}
+
+fn parse_def_unload(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
+    if data[0] != 0x5B || data[1] != 0x2A {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (object, object_len) = parse_super_name(&data[2..])?;
+
+    Ok((Type1OpCode::DefUnload(object), 2 + object_len))
+}
+
+fn parse_def_if_else(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
+    if data[0] != 0xA0 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
+
+    let if_block = match parse_term_arg(&data[1 + pkg_length_len..]) {
+        Ok((predicate, predicate_len)) => {
+            match parse_term_list(&data[1 + pkg_length_len + predicate_len .. 1 + pkg_length]) {
+                Ok(if_block) => IfBlock::If {predicate, if_block},
+                Err(AmlInternalError::AmlDeferredLoad) => 
+                    IfBlock::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()),
+                Err(e) => return Err(e)
+            }
+        },
+        Err(AmlInternalError::AmlDeferredLoad) => 
+            IfBlock::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()),
+        Err(e) => return Err(e)
+    };
+    
+    let (else_block, else_block_len) = parse_def_else(&data[1 + pkg_length..])?;
+    
+    return Ok((Type1OpCode::DefIfElse {if_block, else_block},
+               pkg_length + else_block_len + 1));
+}
+
+fn parse_def_else(data: &[u8]) -> Result<(IfBlock, usize), AmlInternalError> {
+    if data.len() == 0 || data[0] != 0xA1 {
+        // We might be at the very end of a buffer, in which case there isn't an else
+        return Ok((IfBlock::NoBlock, 0));
+    }
+
+    let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
+    match parse_term_list(&data[1 + pkg_length_len .. 1 + pkg_length]) {
+        Ok(term_list) => Ok((IfBlock::Else(term_list), 1 + pkg_length)),
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            Ok((IfBlock::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), 1 + pkg_length)),
+        Err(e) => return Err(e)
+    }
+}
+
+fn parse_def_while(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
+    if data[0] != 0xA2 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
+    let (predicate, predicate_len) = match parse_term_arg(&data[1 + pkg_length_len..]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((Type1OpCode::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), 1 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+    let block = match parse_term_list(&data[1 + pkg_length_len + predicate_len .. 1 + pkg_length]) {
+        Ok(p) => p,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((Type1OpCode::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), 1 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+
+    Ok((Type1OpCode::DefWhile {predicate, block}, pkg_length + 1))
+}
+
+fn parse_def_return(data: &[u8]) -> Result<(Type1OpCode, usize), AmlInternalError> {
+    if data[0] != 0xA4 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (arg_object, arg_object_len) = parse_term_arg(&data[1..])?;
+
+    Ok((Type1OpCode::DefReturn(arg_object), 1 + arg_object_len))
+}
diff --git a/src/acpi/aml/type2opcode.rs b/src/acpi/aml/type2opcode.rs
new file mode 100644
index 0000000000000000000000000000000000000000..50d1ff2ea228ddd22b12428eaa21ccaf2b9579d1
--- /dev/null
+++ b/src/acpi/aml/type2opcode.rs
@@ -0,0 +1,932 @@
+use collections::vec::Vec;
+use collections::string::String;
+use collections::boxed::Box;
+
+use super::{AmlInternalError, AmlExecutable, AmlValue, AmlNamespace};
+use super::pkglength::parse_pkg_length;
+use super::termlist::{parse_term_arg, parse_method_invocation, TermArg, MethodInvocation};
+use super::namestring::{parse_super_name, parse_target, parse_name_string, parse_simple_name,
+                        SuperName, Target};
+use super::dataobj::{parse_data_ref_obj, DataRefObj};
+
+#[derive(Debug, Clone)]
+pub enum Type2OpCode {
+    DefAcquire {
+        object: SuperName,
+        timeout: u16
+    },
+    DefBuffer(DefBuffer),
+    DefPackage(DefPackage),
+    DefVarPackage(DefVarPackage),
+    DefDerefOf(TermArg),
+    DefRefOf(SuperName),
+    DefIncrement(SuperName),
+    DefIndex(DefIndex),
+    DefDecrement(SuperName),
+    DefFindSetLeftBit {
+        operand: TermArg,
+        target: Target
+    },
+    DefFindSetRightBit {
+        operand: TermArg,
+        target: Target
+    },
+    DefFromBCD {
+        operand: TermArg,
+        target: Target
+    },
+    DefDivide {
+        dividend: TermArg,
+        divisor: TermArg,
+        remainder: Target,
+        quotient: Target
+    },
+    DefCondRefOf {
+        operand: SuperName,
+        target: Target
+    },
+    DefCopyObject {
+        source: TermArg,
+        destination: SuperName
+    },
+    DefLAnd {
+        lhs: TermArg,
+        rhs: TermArg
+    },
+    DefLEqual {
+        lhs: TermArg,
+        rhs: TermArg
+    },
+    DefLGreater {
+        lhs: TermArg,
+        rhs: TermArg
+    },
+    DefLLess {
+        lhs: TermArg,
+        rhs: TermArg
+    },
+    DefLNot(TermArg),
+    DefLOr {
+        lhs: TermArg,
+        rhs: TermArg
+    },
+    DefSizeOf(SuperName),
+    DefStore {
+        operand: TermArg,
+        target: SuperName
+    },
+    DefSubtract {
+        minuend: TermArg,
+        subtrahend: TermArg,
+        target: Target
+    },
+    DefToBuffer {
+        operand: TermArg,
+        target: Target
+    },
+    DefToHexString {
+        operand: TermArg,
+        target: Target
+    },
+    DefToBCD {
+        operand: TermArg,
+        target: Target
+    },
+    DefToDecimalString {
+        operand: TermArg,
+        target: Target
+    },
+    DefToInteger {
+        operand: TermArg,
+        target: Target
+    },
+    DefToString {
+        operand: TermArg,
+        length: TermArg,
+        target: Target
+    },
+    DefConcat {
+        lhs: TermArg,
+        rhs: TermArg,
+        target: Target
+    },
+    DefConcatRes {
+        lhs: TermArg,
+        rhs: TermArg,
+        target: Target
+    },
+    DefShiftLeft {
+        lhs: TermArg,
+        rhs: TermArg,
+        target: Target
+    },
+    DefShiftRight {
+        lhs: TermArg,
+        rhs: TermArg,
+        target: Target
+    },
+    DefAdd {
+        lhs: TermArg,
+        rhs: TermArg,
+        target: Target
+    },
+    DefMultiply {
+        lhs: TermArg,
+        rhs: TermArg,
+        target: Target
+    },
+    DefMod {
+        dividend: TermArg,
+        divisor: TermArg,
+        target: Target
+    },
+    DefAnd {
+        lhs: TermArg,
+        rhs: TermArg,
+        target: Target
+    },
+    DefNAnd {
+        lhs: TermArg,
+        rhs: TermArg,
+        target: Target
+    },
+    DefOr {
+        lhs: TermArg,
+        rhs: TermArg,
+        target: Target
+    },
+    DefXor {
+        lhs: TermArg,
+        rhs: TermArg,
+        target: Target
+    },
+    DefNOr {
+        lhs: TermArg,
+        rhs: TermArg,
+        target: Target
+    },
+    DefNot {
+        operand: TermArg,
+        target: Target
+    },
+    DefLoadTable {
+        signature: TermArg,
+        oem_id: TermArg,
+        oem_table_id: TermArg,
+        root_path: TermArg,
+        parameter_path: TermArg,
+        parameter_data: TermArg
+    },
+    DefMatch {
+        search_pkg: TermArg,
+        first_operation: MatchOpcode,
+        first_operand: TermArg,
+        second_operation: MatchOpcode,
+        second_operand: TermArg,
+        start_index: TermArg
+    },
+    DefMid {
+        source: TermArg,
+        index: TermArg,
+        length: TermArg,
+        target: Target
+    },
+    DefWait {
+        event_object: SuperName,
+        operand: TermArg
+    },
+    DefObjectType(DefObjectType),
+    DefTimer,
+    MethodInvocation(MethodInvocation)
+}
+
+impl AmlExecutable for Type2OpCode {
+    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
+        None
+    }
+}
+
+#[derive(Debug, Clone)]
+pub enum DefObjectType {
+    SuperName(SuperName),
+    DefIndex(DefIndex),
+    DefRefOf(SuperName),
+    DefDerefOf(TermArg)
+}
+
+#[derive(Debug, Clone)]
+pub enum MatchOpcode {
+    MTR,
+    MEQ,
+    MLE,
+    MLT,
+    MGE,
+    MGT
+}
+
+#[derive(Debug, Clone)]
+pub enum Type6OpCode {
+    DefDerefOf(TermArg),
+    DefRefOf(Box<SuperName>),
+    DefIndex(DefIndex),
+    MethodInvocation(MethodInvocation)
+}
+
+#[derive(Debug, Clone)]
+pub struct DefIndex {
+    obj: TermArg,
+    idx: TermArg,
+    target: Box<Target>
+}
+
+#[derive(Debug, Clone)]
+pub enum DefBuffer {
+    Buffer {
+        buffer_size: TermArg,
+        byte_list: Vec<u8>
+    },
+    DeferredLoad(Vec<u8>)
+}
+
+#[derive(Debug, Clone)]
+pub enum DefPackage {
+    Package {
+        num_elements: u8,
+        elements: Vec<PackageElement>
+    },
+    DeferredLoad(Vec<u8>)
+}
+
+#[derive(Debug, Clone)]
+pub enum DefVarPackage {
+    Package {
+        num_elements: TermArg,
+        elements: Vec<PackageElement>
+    },
+    DeferredLoad(Vec<u8>)
+}
+
+#[derive(Debug, Clone)]
+pub enum PackageElement {
+    DataRefObj(DataRefObj),
+    NameString(String)
+}
+
+impl AmlExecutable for DefPackage {
+    fn execute(&self, namespace: &mut AmlNamespace, scope: String) -> Option<AmlValue> {
+        match *self {
+            DefPackage::Package { ref num_elements, ref elements } => {
+                let mut values: Vec<AmlValue> = vec!();
+                
+                for element in elements {
+                    match *element {
+                        PackageElement::DataRefObj(ref d) => {
+                            let elem = match d.execute(namespace, scope.clone()) {
+                                Some(e) => e,
+                                None => continue
+                            };
+
+                            values.push(elem);
+                        },
+                        _ => return None
+                    }
+                }
+
+                Some(AmlValue::Package(values))
+            },
+            _ => None
+        }
+    }
+}
+
+pub fn parse_type2_opcode(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_selector! {
+        data,
+        parse_def_increment,
+        parse_def_acquire,
+        parse_def_wait,
+        parse_def_land,
+        parse_def_lequal,
+        parse_def_lgreater,
+        parse_def_lless,
+        parse_def_lnot,
+        parse_def_lor,
+        parse_def_size_of,
+        parse_def_store,
+        parse_def_subtract,
+        parse_def_to_buffer,
+        parse_def_to_hex_string,
+        parse_def_to_bcd,
+        parse_def_to_decimal_string,
+        parse_def_to_integer,
+        parse_def_to_string,
+        parse_def_add,
+        parse_def_xor,
+        parse_def_shift_left,
+        parse_def_shift_right,
+        parse_def_mod,
+        parse_def_and,
+        parse_def_or,
+        parse_def_concat_res,
+        parse_def_concat,
+        parse_def_cond_ref_of,
+        parse_def_copy_object,
+        parse_def_decrement,
+        parse_def_divide,
+        parse_def_find_set_left_bit,
+        parse_def_find_set_right_bit,
+        parse_def_from_bcd,
+        parse_def_load_table,
+        parse_def_match,
+        parse_def_mid,
+        parse_def_multiply,
+        parse_def_nand,
+        parse_def_nor,
+        parse_def_not,
+        parse_def_timer,
+        parser_wrap!(Type2OpCode::DefBuffer, parse_def_buffer),
+        parser_wrap!(Type2OpCode::DefPackage, parse_def_package),
+        parser_wrap!(Type2OpCode::DefVarPackage, parse_def_var_package),
+        parser_wrap!(Type2OpCode::DefObjectType, parse_def_object_type),
+        parser_wrap!(Type2OpCode::DefDerefOf, parse_def_deref_of),
+        parser_wrap!(Type2OpCode::DefRefOf, parse_def_ref_of),
+        parser_wrap!(Type2OpCode::DefIndex, parse_def_index),
+        parser_wrap!(Type2OpCode::MethodInvocation, parse_method_invocation)
+    };
+    
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
+
+pub fn parse_type6_opcode(data: &[u8]) -> Result<(Type6OpCode, usize), AmlInternalError> {
+    parser_selector! {
+        data,
+        parser_wrap!(Type6OpCode::DefDerefOf, parse_def_deref_of),
+        parser_wrap!(Type6OpCode::DefRefOf, parser_wrap!(Box::new, parse_def_ref_of)),
+        parser_wrap!(Type6OpCode::DefIndex, parse_def_index),
+        parser_wrap!(Type6OpCode::MethodInvocation, parse_method_invocation)
+    };
+    
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
+
+pub fn parse_def_object_type(data: &[u8]) -> Result<(DefObjectType, usize), AmlInternalError> {
+    parser_opcode!(data, 0x8E);
+    parser_selector! {
+        data,
+        parser_wrap!(DefObjectType::SuperName, parse_super_name),
+        parser_wrap!(DefObjectType::DefRefOf, parse_def_ref_of),
+        parser_wrap!(DefObjectType::DefDerefOf, parse_def_deref_of),
+        parser_wrap!(DefObjectType::DefIndex, parse_def_index)
+    }
+
+    Err(AmlInternalError::AmlInvalidOpCode)
+}
+
+pub fn parse_def_package(data: &[u8]) -> Result<(DefPackage, usize), AmlInternalError> {
+    parser_opcode!(data, 0x12);
+
+    let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
+    let num_elements = data[1 + pkg_length_len];
+    
+    let elements = match parse_package_elements_list(&data[2 + pkg_length_len .. 1 + pkg_length]) {
+        Ok(e) => e,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((DefPackage::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()), 1 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+
+    Ok((DefPackage::Package {num_elements, elements}, 1 + pkg_length))
+}
+
+pub fn parse_def_var_package(data: &[u8]) -> Result<(DefVarPackage, usize), AmlInternalError> {
+    parser_opcode!(data, 0x13);
+
+    let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
+    let (num_elements, num_elements_len) = parse_term_arg(&data[1 + pkg_length_len ..])?;
+
+    let elements = match parse_package_elements_list(&data[1 + pkg_length_len + num_elements_len ..
+                                                           1 + pkg_length]) {
+        Ok(e) => e,
+        Err(AmlInternalError::AmlDeferredLoad) =>
+            return Ok((DefVarPackage::DeferredLoad(data[0 .. 1 + pkg_length].to_vec()),
+                       1 + pkg_length)),
+        Err(e) => return Err(e)
+    };
+
+    Ok((DefVarPackage::Package {num_elements, elements}, 1 + pkg_length))
+}
+                                                
+fn parse_package_elements_list(data: &[u8]) -> Result<Vec<PackageElement>, AmlInternalError> {
+    let mut current_offset: usize = 0;
+    let mut elements: Vec<PackageElement> = vec!();
+    
+    while current_offset < data.len() {
+        match parse_data_ref_obj(&data[current_offset ..]) {
+            Ok((data_ref_obj, data_ref_obj_len)) => {
+                elements.push(PackageElement::DataRefObj(data_ref_obj));
+                current_offset += data_ref_obj_len;
+            },
+            Err(AmlInternalError::AmlInvalidOpCode) => 
+                match parse_name_string(&data[current_offset ..]) {
+                    Ok((name_string, name_string_len)) => {
+                        elements.push(PackageElement::NameString(name_string));
+                        current_offset += name_string_len;
+                    },
+                    Err(e) => return Err(e)
+                },
+            Err(e) => return Err(e)
+        }
+    }
+
+    Ok(elements)
+}
+                                                
+pub fn parse_def_buffer(data: &[u8]) -> Result<(DefBuffer, usize), AmlInternalError> {
+    parser_opcode!(data, 0x11);
+    
+    let (pkg_length, pkg_length_len) = parse_pkg_length(&data[1..])?;
+    let (buffer_size, buffer_size_len) = match parse_term_arg(&data[1 + pkg_length_len..]) {
+        Ok(s) => s,
+        Err(AmlInternalError::AmlDeferredLoad) => return Ok((DefBuffer::DeferredLoad(
+            data[0 .. 1 + pkg_length].to_vec()
+        ), 1 + pkg_length)),
+        Err(e) => return Err(e),
+    };
+    let byte_list = data[1 + pkg_length_len + buffer_size_len .. 1 + pkg_length].to_vec();
+    
+    Ok((DefBuffer::Buffer {buffer_size, byte_list}, pkg_length + 1))
+}
+
+fn parse_def_ref_of(data: &[u8]) -> Result<(SuperName, usize), AmlInternalError> {
+    parser_opcode!(data, 0x71);
+    let (obj_reference, obj_reference_len) = parse_super_name(&data[1..])?;
+
+    Ok((obj_reference, obj_reference_len + 1))
+}
+
+fn parse_def_deref_of(data: &[u8]) -> Result<(TermArg, usize), AmlInternalError> {
+    parser_opcode!(data, 0x83);
+    let (obj_reference, obj_reference_len) = parse_term_arg(&data[1..])?;
+
+    Ok((obj_reference, obj_reference_len + 1))
+}
+
+fn parse_def_acquire(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x23);
+    
+    let (object, object_len) = parse_super_name(&data[2..])?;
+    let timeout = (data[2 + object_len] as u16) +
+        ((data[3 + object_len] as u16) << 8);
+    
+    Ok((Type2OpCode::DefAcquire {object, timeout}, object_len + 4))
+}
+
+fn parse_def_increment(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x75);
+    
+    let (obj, obj_len) = parse_super_name(&data[1..])?;
+    Ok((Type2OpCode::DefIncrement(obj), obj_len + 1))
+}
+
+fn parse_def_index(data: &[u8]) -> Result<(DefIndex, usize), AmlInternalError> {
+    parser_opcode!(data, 0x88);
+    
+    let (obj, obj_len) = parse_term_arg(&data[1..])?;
+    let (idx, idx_len) = parse_term_arg(&data[1 + obj_len..])?;
+    let (target, target_len) = parse_target(&data[1 + obj_len + idx_len..])?;
+
+    Ok((DefIndex {obj, idx, target: Box::new(target)}, 1 + obj_len + idx_len + target_len))
+}
+
+fn parse_def_land(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x90);
+    
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+
+    Ok((Type2OpCode::DefLAnd {lhs, rhs}, 1 + lhs_len + rhs_len))
+}
+
+fn parse_def_lequal(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x93);
+    
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+
+    Ok((Type2OpCode::DefLEqual {lhs, rhs}, 1 + lhs_len + rhs_len))
+}
+
+fn parse_def_lgreater(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x94);
+    
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+
+    Ok((Type2OpCode::DefLGreater {lhs, rhs}, 1 + lhs_len + rhs_len))
+}
+
+fn parse_def_lless(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x95);
+
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+
+    Ok((Type2OpCode::DefLLess {lhs, rhs}, 1 + lhs_len + rhs_len))
+}
+
+fn parse_def_lnot(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x92);
+
+    let (operand, operand_len) = parse_term_arg(&data[1..])?;
+
+    Ok((Type2OpCode::DefLNot(operand), 1 + operand_len))
+}
+
+fn parse_def_lor(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x91);
+
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+
+    Ok((Type2OpCode::DefLOr {lhs, rhs}, 1 + lhs_len + rhs_len))
+}
+
+fn parse_def_to_hex_string(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x98);
+
+    let (operand, operand_len) = parse_term_arg(&data[1..])?;
+    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
+
+    Ok((Type2OpCode::DefToHexString {operand, target}, 1 + operand_len + target_len))
+}
+
+fn parse_def_to_buffer(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x96);
+
+    let (operand, operand_len) = parse_term_arg(&data[1..])?;
+    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
+
+    Ok((Type2OpCode::DefToBuffer {operand, target}, 1 + operand_len + target_len))
+}
+
+fn parse_def_to_bcd(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x29);
+
+    let (operand, operand_len) = parse_term_arg(&data[2..])?;
+    let (target, target_len) = parse_target(&data[2 + operand_len..])?;
+
+    Ok((Type2OpCode::DefToBCD {operand, target}, 2 + operand_len + target_len))
+}
+
+fn parse_def_to_decimal_string(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x97);
+
+    let (operand, operand_len) = parse_term_arg(&data[1..])?;
+    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
+
+    Ok((Type2OpCode::DefToDecimalString {operand, target}, 1 + operand_len + target_len))
+}
+
+fn parse_def_to_integer(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x99);
+
+    let (operand, operand_len) = parse_term_arg(&data[1..])?;
+    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
+
+    Ok((Type2OpCode::DefToInteger {operand, target}, 1 + operand_len + target_len))
+}
+
+fn parse_def_to_string(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x9C);
+
+    let (operand, operand_len) = parse_term_arg(&data[1..])?;
+    let (length, length_len) = parse_term_arg(&data[1 + operand_len..])?;
+    let (target, target_len) = parse_target(&data[1 + operand_len + length_len..])?;
+
+    Ok((Type2OpCode::DefToString {operand, length, target}, 1 + operand_len + length_len + target_len))
+}
+
+fn parse_def_subtract(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x74);
+
+    let (minuend, minuend_len) = parse_term_arg(&data[1..])?;
+    let (subtrahend, subtrahend_len) = parse_term_arg(&data[1 + minuend_len..])?;
+    let (target, target_len) = parse_target(&data[1 + minuend_len + subtrahend_len..])?;
+
+    Ok((Type2OpCode::DefSubtract {minuend, subtrahend, target}, 1 + minuend_len + subtrahend_len + target_len))
+}
+
+fn parse_def_size_of(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x87);
+
+    let (name, name_len) = parse_super_name(&data[1..])?;
+    Ok((Type2OpCode::DefSizeOf(name), name_len + 1))
+}
+
+fn parse_def_store(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x70);
+
+    let (operand, operand_len) = parse_term_arg(&data[1..])?;
+    let (target, target_len) = parse_super_name(&data[1 + operand_len..])?;
+
+    Ok((Type2OpCode::DefStore {operand, target}, operand_len + target_len + 1))
+}
+
+fn parse_def_or(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x7D);
+
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+
+    Ok((Type2OpCode::DefOr {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+}
+
+fn parse_def_shift_left(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x79);
+
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+
+    Ok((Type2OpCode::DefShiftLeft {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+}
+
+fn parse_def_shift_right(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x7A);
+
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+
+    Ok((Type2OpCode::DefShiftRight {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+}
+
+fn parse_def_add(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x72);
+    
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+
+    Ok((Type2OpCode::DefAdd {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+}
+
+fn parse_def_and(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x7B);
+
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+
+    Ok((Type2OpCode::DefAnd {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+}
+
+fn parse_def_xor(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x7F);
+
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+
+    Ok((Type2OpCode::DefXor {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+}
+
+fn parse_def_concat_res(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x84);
+
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+
+    Ok((Type2OpCode::DefConcatRes {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+}
+
+fn parse_def_wait(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x25);
+
+    let (event_object, event_object_len) = parse_super_name(&data[2..])?;
+    let (operand, operand_len) = parse_term_arg(&data[2 + event_object_len..])?;
+
+
+    Ok((Type2OpCode::DefWait {event_object, operand}, 2 + event_object_len + operand_len))
+}
+
+fn parse_def_cond_ref_of(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode_extended!(data, 0x12);
+
+    let (operand, operand_len) = parse_super_name(&data[2..])?;
+    let (target, target_len) = parse_target(&data[2 + operand_len..])?;
+
+    Ok((Type2OpCode::DefCondRefOf {operand, target}, 2 + operand_len + target_len))
+}
+
+fn parse_def_copy_object(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x9D);
+
+    let (source, source_len) = parse_term_arg(&data[1..])?;
+    let (destination, destination_len) = parse_simple_name(&data[1 + source_len..])?;
+
+    Ok((Type2OpCode::DefCopyObject {source, destination}, 1 + source_len + destination_len))
+}
+
+fn parse_def_concat(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x73);
+
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+
+    Ok((Type2OpCode::DefConcat {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+}
+
+fn parse_def_decrement(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x76);
+
+    let (target, target_len) = parse_super_name(&data[1..])?;
+
+    Ok((Type2OpCode::DefDecrement(target), 1 + target_len))
+}
+
+fn parse_def_divide(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x78);
+
+    let (dividend, dividend_len) = parse_term_arg(&data[1..])?;
+    let (divisor, divisor_len) = parse_term_arg(&data[1 + dividend_len..])?;
+    let (remainder, remainder_len) = parse_target(&data[1 + dividend_len + divisor_len..])?;
+    let (quotient, quotient_len) = parse_target(&data[1 + dividend_len + divisor_len + remainder_len..])?;
+
+    Ok((Type2OpCode::DefDivide {dividend, divisor, remainder, quotient},
+        1 + dividend_len + divisor_len + remainder_len + quotient_len))
+}
+
+fn parse_def_find_set_left_bit(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    parser_opcode!(data, 0x81);
+
+    let (operand, operand_len) = parse_term_arg(&data[1..])?;
+    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
+
+    Ok((Type2OpCode::DefFindSetLeftBit {operand, target}, 1 + operand_len + target_len))
+}
+
+fn parse_def_find_set_right_bit(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    if data[0] != 0x82 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (operand, operand_len) = parse_term_arg(&data[1..])?;
+    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
+
+    Ok((Type2OpCode::DefFindSetRightBit {operand, target}, 1 + operand_len + target_len))
+}
+
+fn parse_def_load_table(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    if data[0] != 0x5B || data[1] != 0x1F {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (signature, signature_len) = parse_term_arg(&data[2..])?;
+    let (oem_id, oem_id_len) = parse_term_arg(&data[2 + signature_len..])?;
+    let (oem_table_id, oem_table_id_len) = parse_term_arg(&data[2 + signature_len + oem_id_len..])?;
+    let (root_path, root_path_len) =
+        parse_term_arg(&data[2 + signature_len + oem_id_len + oem_table_id_len..])?;
+    let (parameter_path, parameter_path_len) =
+        parse_term_arg(&data[2 + signature_len + oem_id_len + oem_table_id_len + root_path_len..])?;
+    let (parameter_data, parameter_data_len) =
+        parse_term_arg(&data[2 + signature_len + oem_id_len + oem_table_id_len + root_path_len +
+                             parameter_path_len..])?;
+
+    Ok((Type2OpCode::DefLoadTable {signature, oem_id, oem_table_id, root_path,
+                                   parameter_path, parameter_data},
+        2 + signature_len + oem_id_len + oem_table_id_len + root_path_len +
+        parameter_path_len + parameter_data_len))
+}
+
+fn parse_def_match(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    if data[0] != 0x89 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (search_pkg, search_pkg_len) = parse_term_arg(&data[1..])?;
+    let first_operation = match data[1 + search_pkg_len] {
+        0 => MatchOpcode::MTR,
+        1 => MatchOpcode::MEQ,
+        2 => MatchOpcode::MLE,
+        3 => MatchOpcode::MLT,
+        4 => MatchOpcode::MGE,
+        5 => MatchOpcode::MGT,
+        _ => return Err(AmlInternalError::AmlParseError("DefMatch - Invalid Opcode"))
+    };
+    let (first_operand, first_operand_len) = parse_term_arg(&data[2 + search_pkg_len..])?;
+
+    let second_operation = match data[2 + search_pkg_len + first_operand_len] {
+        0 => MatchOpcode::MTR,
+        1 => MatchOpcode::MEQ,
+        2 => MatchOpcode::MLE,
+        3 => MatchOpcode::MLT,
+        4 => MatchOpcode::MGE,
+        5 => MatchOpcode::MGT,
+        _ => return Err(AmlInternalError::AmlParseError("DefMatch - Invalid Opcode"))
+    };
+    let (second_operand, second_operand_len) =
+        parse_term_arg(&data[3 + search_pkg_len + first_operand_len..])?;
+
+    let (start_index, start_index_len) =
+        parse_term_arg(&data[3 + search_pkg_len + first_operand_len + second_operand_len..])?;
+
+    Ok((Type2OpCode::DefMatch {search_pkg, first_operation, first_operand,
+                               second_operation, second_operand, start_index},
+        3 + search_pkg_len + first_operand_len + second_operand_len + start_index_len))
+}
+
+fn parse_def_from_bcd(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    if data[0] != 0x5B || data[1] != 0x28 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (operand, operand_len) = parse_term_arg(&data[2..])?;
+    let (target, target_len) = parse_target(&data[2 + operand_len..])?;
+
+    Ok((Type2OpCode::DefFromBCD {operand, target}, 2 + operand_len + target_len))
+}
+
+fn parse_def_mid(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    if data[0] != 0x9E {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (source, source_len) = parse_term_arg(&data[1..])?;
+    let (index, index_len) = parse_term_arg(&data[1 + source_len..])?;
+    let (length, length_len) = parse_term_arg(&data[1 + source_len + index_len..])?;
+    let (target, target_len) = parse_target(&data[1 + source_len + index_len + length_len..])?;
+
+    Ok((Type2OpCode::DefMid {source, index, length, target},
+        1 + source_len + index_len + length_len + target_len))
+}
+
+fn parse_def_mod(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    if data[0] != 0x85 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (dividend, dividend_len) = parse_term_arg(&data[1..])?;
+    let (divisor, divisor_len) = parse_term_arg(&data[1 + dividend_len..])?;
+    let (target, target_len) = parse_target(&data[1 + dividend_len + divisor_len..])?;
+
+    Ok((Type2OpCode::DefMod {dividend, divisor, target}, 1 + dividend_len + divisor_len + target_len))
+}
+
+fn parse_def_multiply(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    if data[0] != 0x77 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+
+    Ok((Type2OpCode::DefMultiply {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+}
+
+fn parse_def_nand(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    if data[0] != 0x7C {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+
+    Ok((Type2OpCode::DefNAnd {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+}
+
+fn parse_def_nor(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    if data[0] != 0x7E {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (lhs, lhs_len) = parse_term_arg(&data[1..])?;
+    let (rhs, rhs_len) = parse_term_arg(&data[1 + lhs_len..])?;
+    let (target, target_len) = parse_target(&data[1 + lhs_len + rhs_len..])?;
+
+    Ok((Type2OpCode::DefNOr {lhs, rhs, target}, 1 + lhs_len + rhs_len + target_len))
+}
+
+fn parse_def_not(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    if data[0] != 0x80 {
+        return Err(AmlInternalError::AmlInvalidOpCode);
+    }
+
+    let (operand, operand_len) = parse_term_arg(&data[1..])?;
+    let (target, target_len) = parse_target(&data[1 + operand_len..])?;
+
+    Ok((Type2OpCode::DefNot {operand, target}, 1 + operand_len + target_len))
+}
+
+fn parse_def_timer(data: &[u8]) -> Result<(Type2OpCode, usize), AmlInternalError> {
+    if data[0] != 0x5B || data[1] != 0x33 {
+        return Err(AmlInternalError::AmlInvalidOpCode)
+    }
+
+    Ok((Type2OpCode::DefTimer, 2 as usize))
+}
diff --git a/src/acpi/dsdt.rs b/src/acpi/dsdt.rs
deleted file mode 100644
index 67bcb7f96812b08992eee144b6bd08ec227d1b17..0000000000000000000000000000000000000000
--- a/src/acpi/dsdt.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-use core::slice;
-
-use super::sdt::Sdt;
-
-#[derive(Debug)]
-pub struct Dsdt(&'static Sdt);
-
-impl Dsdt {
-    pub fn new(sdt: &'static Sdt) -> Option<Dsdt> {
-        if &sdt.signature == b"DSDT" {
-            Some(Dsdt(sdt))
-        } else {
-            None
-        }
-    }
-
-    pub fn data(&self) -> &[u8] {
-        unsafe { slice::from_raw_parts(self.0.data_address() as *const u8, self.0.data_len()) }
-    }
-
-    pub fn slp_typ(&self) -> Option<(u16, u16)> {
-        // Code from http://forum.osdev.org/viewtopic.php?t=16990, should be adapted
-
-        let mut i = 0;
-        let data = self.data();
-
-        // search the \_S5 package in the DSDT
-        let s5_a = b"\x08_S5_\x12";
-        let s5_b = b"\x08\\_S5_\x12";
-        while i < data.len() {
-            if data[i..].starts_with(s5_a) {
-                i += s5_a.len();
-                break;
-            } else if data[i..].starts_with(s5_b) {
-                i += s5_b.len();
-                break;
-            } else {
-                i += 1;
-            }
-        }
-
-        if i >= data.len() {
-            return None;
-        }
-
-        // check if \_S5 was found
-        let pkglen = ((data[i] & 0xC0) >> 6) + 2;
-        i += pkglen as usize;
-        if i >= data.len() {
-            return None;
-        }
-
-        if data[i] == 0x0A {
-            i += 1;   // skip byteprefix
-            if i >= data.len() {
-                return None;
-            }
-        }
-
-        let a = (data[i] as u16) << 10;
-        i += 1;
-        if i >= data.len() {
-            return None;
-        }
-
-        if data[i] == 0x0A {
-            i += 1;   // skip byteprefix
-            if i >= data.len() {
-                return None;
-            }
-        }
-
-        let b = (data[i] as u16) << 10;
-
-        Some((a, b))
-    }
-
-}
diff --git a/src/acpi/mod.rs b/src/acpi/mod.rs
index 751044a8bbdcca8225f9a51002b74ea319313395..54a55e5a16fc5d0f66471abf1b315c1e817f9ec6 100644
--- a/src/acpi/mod.rs
+++ b/src/acpi/mod.rs
@@ -13,20 +13,21 @@ use paging::{entry, ActivePageTable, Page, PhysicalAddress, VirtualAddress};
 use start::{kstart_ap, CPU_COUNT, AP_READY};
 
 use self::dmar::{Dmar, DmarEntry};
-use self::dsdt::Dsdt;
 use self::fadt::Fadt;
 use self::madt::{Madt, MadtEntry};
 use self::rsdt::Rsdt;
 use self::sdt::Sdt;
 use self::xsdt::Xsdt;
 
+use self::aml::{is_aml_table, parse_aml_table, AmlNamespace, AmlError};
+
 mod dmar;
-mod dsdt;
 mod fadt;
 mod madt;
 mod rsdt;
 mod sdt;
 mod xsdt;
+mod aml;
 
 const TRAMPOLINE: usize = 0x7E00;
 const AP_STARTUP: usize = TRAMPOLINE + 512;
@@ -70,9 +71,6 @@ fn parse_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
         let dsdt = get_sdt(fadt.dsdt as usize, active_table);
         parse_sdt(dsdt, active_table);
         ACPI_TABLE.lock().fadt = Some(fadt);
-    } else if let Some(dsdt) = Dsdt::new(sdt) {
-        println!(": {}", dsdt.data().len());
-        ACPI_TABLE.lock().dsdt = Some(dsdt);
     } else if let Some(madt) = Madt::new(sdt) {
         println!(": {:>08X}: {}", madt.local_address, madt.flags);
 
@@ -197,6 +195,17 @@ fn parse_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
                 _ => ()
             }
         }
+    } else if is_aml_table(sdt) {
+        ACPI_TABLE.lock().namespace = match parse_aml_table(sdt) {
+            Ok(res) => {
+                println!(": Parsed");
+                Some(res)
+            },
+            Err(AmlError::AmlParseError(e)) => {
+                println!(": {}", e);
+                None
+            }
+        };
     } else {
         println!(": Unknown");
     }
@@ -259,10 +268,10 @@ pub unsafe fn init(active_table: &mut ActivePageTable) {
 
 pub struct Acpi {
     pub fadt: Option<Fadt>,
-    pub dsdt: Option<Dsdt>,
+    pub namespace: Option<AmlNamespace>,
 }
 
-pub static ACPI_TABLE: Mutex<Acpi> = Mutex::new(Acpi { fadt: None, dsdt: None });
+pub static ACPI_TABLE: Mutex<Acpi> = Mutex::new(Acpi { fadt: None, namespace: None });
 
 /// RSDP
 #[derive(Copy, Clone, Debug)]
diff --git a/src/acpi/sdt.rs b/src/acpi/sdt.rs
index 0d8cedd6bed1a3848d22c2f749950d0a3dc24792..62d55cf472bb0e97ce31e68dc6f6d23be494a5a0 100644
--- a/src/acpi/sdt.rs
+++ b/src/acpi/sdt.rs
@@ -1,4 +1,5 @@
 use core::mem;
+use core::slice;
 
 #[derive(Copy, Clone, Debug)]
 #[repr(packed)]
@@ -30,4 +31,8 @@ impl Sdt {
             0
         }
     }
+
+    pub fn data(&'static self) -> &[u8] {
+        unsafe { slice::from_raw_parts(self.data_address() as *const u8, self.data_len()) }
+    }
 }
diff --git a/src/stop.rs b/src/stop.rs
index db2dfd6e6f63dfb0f7943b9be0a6e656cc796e80..7a9ac751d98907c1ca83fe75894b3a3ee3335e08 100644
--- a/src/stop.rs
+++ b/src/stop.rs
@@ -11,12 +11,18 @@ pub unsafe extern fn kstop() -> ! {
         if let Some(ref fadt) = acpi.fadt {
             let port = fadt.pm1a_control_block as u16;
             let mut val = 1 << 13;
-            if let Some(ref dsdt) = acpi.dsdt {
-                if let Some((a, b)) = dsdt.slp_typ() {
-                    println!("Shutdown SLP_TYPa {:X}, SLP_TYPb {:X}", a, b);
-                    val |= a;
+            if let Some(ref namespace) = acpi.namespace {
+                if let Some(s) = namespace.find_str("\\_S5") {
+                    if let Some(p) = s.get_as_package() {
+                        let slp_typa = p[0].get_as_integer().expect("SLP_TYPa is not an integer");
+                        let slp_typb = p[1].get_as_integer().expect("SLP_TYPb is not an integer");
+
+                        println!("Shutdown SLP_TYPa {:X}, SLP_TYPb {:X}", slp_typa, slp_typb);
+                        val |= slp_typa as u16;
+                    }
                 }
             }
+            
             println!("Shutdown with ACPI outw(0x{:X}, 0x{:X})", port, val);
             Pio::<u16>::new(port).write(val);
         }