diff --git a/src/acpi/mod.rs b/src/acpi/mod.rs
index 96447ffdb26889f7a4e0824f5533350cd9b70d95..a1d5eccf042f657f8ae44aaa00d39981b37e3981 100644
--- a/src/acpi/mod.rs
+++ b/src/acpi/mod.rs
@@ -74,170 +74,6 @@ fn get_sdt(sdt_address: usize, active_table: &mut ActivePageTable) -> &'static S
     sdt
 }
 
-fn parse_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
-    print!("  ");
-    for &c in sdt.signature.iter() {
-        print!("{}", c as char);
-    }
-
-    if let Some(fadt) = Fadt::new(sdt) {
-        println!(": {:X}", fadt.dsdt);
-        
-        let dsdt = get_sdt(fadt.dsdt as usize, active_table);
-        parse_sdt(dsdt, active_table);
-        
-        let mut fadt_t = ACPI_TABLE.fadt.write();
-        *fadt_t = Some(fadt);
-    } else if let Some(madt) = Madt::new(sdt) {
-        println!(": {:>08X}: {}", madt.local_address, madt.flags);
-
-        let local_apic = unsafe { &mut LOCAL_APIC };
-
-        let me = local_apic.id() as u8;
-
-        if local_apic.x2 {
-            println!("    X2APIC {}", me);
-        } else {
-            println!("    XAPIC {}: {:>08X}", me, local_apic.address);
-        }
-
-        if cfg!(feature = "multi_core"){
-            let trampoline_frame = Frame::containing_address(PhysicalAddress::new(TRAMPOLINE));
-            let trampoline_page = Page::containing_address(VirtualAddress::new(TRAMPOLINE));
-
-            // Map trampoline
-            let result = active_table.map_to(trampoline_page, trampoline_frame, entry::PRESENT | entry::WRITABLE);
-            result.flush(active_table);
-
-            for madt_entry in madt.iter() {
-                println!("      {:?}", madt_entry);
-                match madt_entry {
-                    MadtEntry::LocalApic(ap_local_apic) => if ap_local_apic.id == me {
-                        println!("        This is my local APIC");
-                    } else {
-                        if ap_local_apic.flags & 1 == 1 {
-                            // Increase CPU ID
-                            CPU_COUNT.fetch_add(1, Ordering::SeqCst);
-
-                            // Allocate a stack
-                            let stack_start = allocate_frames(64).expect("no more frames in acpi stack_start").start_address().get() + ::KERNEL_OFFSET;
-                            let stack_end = stack_start + 64 * 4096;
-
-                            let ap_ready = TRAMPOLINE as *mut u64;
-                            let ap_cpu_id = unsafe { ap_ready.offset(1) };
-                            let ap_page_table = unsafe { ap_ready.offset(2) };
-                            let ap_stack_start = unsafe { ap_ready.offset(3) };
-                            let ap_stack_end = unsafe { ap_ready.offset(4) };
-                            let ap_code = unsafe { ap_ready.offset(5) };
-
-                            // Set the ap_ready to 0, volatile
-                            unsafe { atomic_store(ap_ready, 0) };
-                            unsafe { atomic_store(ap_cpu_id, ap_local_apic.id as u64) };
-                            unsafe { atomic_store(ap_page_table, active_table.address() as u64) };
-                            unsafe { atomic_store(ap_stack_start, stack_start as u64) };
-                            unsafe { atomic_store(ap_stack_end, stack_end as u64) };
-                            unsafe { atomic_store(ap_code, kstart_ap as u64) };
-                            AP_READY.store(false, Ordering::SeqCst);
-
-                            print!("        AP {}:", ap_local_apic.id);
-
-                            // Send INIT IPI
-                            {
-                                let mut icr = 0x4500;
-                                if local_apic.x2 {
-                                    icr |= (ap_local_apic.id as u64) << 32;
-                                } else {
-                                    icr |= (ap_local_apic.id as u64) << 56;
-                                }
-                                print!(" IPI...");
-                                local_apic.set_icr(icr);
-                            }
-
-                            // Send START IPI
-                            {
-                                //Start at 0x0800:0000 => 0x8000. Hopefully the bootloader code is still there
-                                let ap_segment = (AP_STARTUP >> 12) & 0xFF;
-                                let mut icr = 0x4600 | ap_segment as u64;
-
-                                if local_apic.x2 {
-                                    icr |= (ap_local_apic.id as u64) << 32;
-                                } else {
-                                    icr |= (ap_local_apic.id as u64) << 56;
-                                }
-
-                                print!(" SIPI...");
-                                local_apic.set_icr(icr);
-                            }
-
-                            // Wait for trampoline ready
-                            print!(" Wait...");
-                            while unsafe { atomic_load(ap_ready) } == 0 {
-                                interrupt::pause();
-                            }
-                            print!(" Trampoline...");
-                            while ! AP_READY.load(Ordering::SeqCst) {
-                                interrupt::pause();
-                            }
-                            println!(" Ready");
-
-                            active_table.flush_all();
-                        } else {
-                            println!("        CPU Disabled");
-                        }
-                    },
-                    _ => ()
-                }
-            }
-
-            // Unmap trampoline
-            let (result, _frame) = active_table.unmap_return(trampoline_page, false);
-            result.flush(active_table);
-        }
-    } else if let Some(dmar) = Dmar::new(sdt) {
-        println!(": {}: {}", dmar.addr_width, dmar.flags);
-
-        for dmar_entry in dmar.iter() {
-            println!("      {:?}", dmar_entry);
-            match dmar_entry {
-                DmarEntry::Drhd(dmar_drhd) => {
-                    let drhd = dmar_drhd.get(active_table);
-
-                    println!("VER: {:X}", drhd.version);
-                    println!("CAP: {:X}", drhd.cap);
-                    println!("EXT_CAP: {:X}", drhd.ext_cap);
-                    println!("GCMD: {:X}", drhd.gl_cmd);
-                    println!("GSTS: {:X}", drhd.gl_sts);
-                    println!("RT: {:X}", drhd.root_table);
-                },
-                _ => ()
-            }
-        }
-    } else if let Some(hpet) = Hpet::new(sdt, active_table) {
-        println!(": {}", hpet.hpet_number);
-        
-        let mut hpet_t = ACPI_TABLE.hpet.write();
-        *hpet_t = Some(hpet);
-    } else if is_aml_table(sdt) {
-        match parse_aml_table(sdt) {
-            Ok(_) => println!(": Parsed"),
-            Err(AmlError::AmlParseError(e)) => println!(": {}", e),
-            Err(AmlError::AmlInvalidOpCode) => println!(": Invalid opcode"),
-            Err(AmlError::AmlValueError) => println!(": Type constraints or value bounds not met"),
-            Err(AmlError::AmlDeferredLoad) => println!(": Deferred load reached top level"),
-            Err(AmlError::AmlFatalError(_, _, _)) => {
-                println!(": Fatal error occurred");
-                unsafe { kstop(); }
-            },
-            Err(AmlError::AmlHardFatal) => {
-                println!(": Fatal error occurred");
-                unsafe { kstop(); }
-            }
-        };
-    } else {
-        println!(": Unknown");
-    }
-}
-
 fn init_aml_table(sdt: &'static Sdt) {
     match parse_aml_table(sdt) {
         Ok(_) => println!(": Parsed"),
diff --git a/src/acpi/rsdp.rs b/src/acpi/rsdp.rs
new file mode 100644
index 0000000000000000000000000000000000000000..3e25ec05203cecd0f4e701a63797232b05eabcf8
--- /dev/null
+++ b/src/acpi/rsdp.rs
@@ -0,0 +1,57 @@
+use memory::{allocate_frames, Frame};
+use paging::{entry, ActivePageTable, Page, PhysicalAddress, VirtualAddress};
+
+/// RSDP
+#[derive(Copy, Clone, Debug)]
+#[repr(packed)]
+pub struct RSDP {
+    signature: [u8; 8],
+    checksum: u8,
+    oemid: [u8; 6],
+    revision: u8,
+    rsdt_address: u32,
+    length: u32,
+    xsdt_address: u64,
+    extended_checksum: u8,
+    reserved: [u8; 3]
+}
+
+impl RSDP {
+    /// Search for the RSDP
+    pub fn get_rsdp(active_table: &mut ActivePageTable) -> Option<RSDP> {    
+        let start_addr = 0xE0000;
+        let end_addr = 0xFFFFF;
+        
+        // Map all of the ACPI RSDP space
+        {
+            let start_frame = Frame::containing_address(PhysicalAddress::new(start_addr));
+            let end_frame = Frame::containing_address(PhysicalAddress::new(end_addr));
+            for frame in Frame::range_inclusive(start_frame, end_frame) {
+                let page = Page::containing_address(VirtualAddress::new(frame.start_address().get()));
+                let result = active_table.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE);
+                result.flush(active_table);
+            }
+        }
+
+        RSDP::search(start_addr, end_addr)
+    }
+    
+    fn search(start_addr: usize, end_addr: usize) -> Option<RSDP> {
+        for i in 0 .. (end_addr + 1 - start_addr)/16 {
+            let rsdp = unsafe { &*((start_addr + i * 16) as *const RSDP) };
+            if &rsdp.signature == b"RSD PTR " {
+                return Some(*rsdp);
+            }
+        }
+        None
+    }
+
+    /// Get the RSDT or XSDT address
+    pub fn sdt_address(&self) -> usize {
+        if self.revision >= 2 {
+            self.xsdt_address as usize
+        } else {
+            self.rsdt_address as usize
+        }
+    }
+}