diff --git a/src/arch/x86_64/device/local_apic.rs b/src/arch/x86_64/device/local_apic.rs
index 03565cf246f27d6b51c07e4032e1d6d236254bfa..895a55b32961ed5ed9a9e2277ad78aa6cd490d9c 100644
--- a/src/arch/x86_64/device/local_apic.rs
+++ b/src/arch/x86_64/device/local_apic.rs
@@ -251,6 +251,211 @@ impl LocalApic {
 
         Ok(())
     }
+    pub unsafe fn isr_bits_31_0(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_ISR0) as u32
+        } else {
+            self.read(0x100)
+        }
+    }
+    pub unsafe fn isr_bits_63_32(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_ISR1) as u32
+        } else {
+            self.read(0x110)
+        }
+    }
+    pub unsafe fn isr_bits_95_64(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_ISR2) as u32
+        } else {
+            self.read(0x120)
+        }
+    }
+    pub unsafe fn isr_bits_127_96(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_ISR3) as u32
+        } else {
+            self.read(0x130)
+        }
+    }
+    pub unsafe fn isr_bits_159_128(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_ISR4) as u32
+        } else {
+            self.read(0x140)
+        }
+    }
+    pub unsafe fn isr_bits_191_160(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_ISR5) as u32
+        } else {
+            self.read(0x150)
+        }
+    }
+    pub unsafe fn isr_bits_223_192(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_ISR6) as u32
+        } else {
+            self.read(0x160)
+        }
+    }
+    pub unsafe fn isr_bits_255_224(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_ISR7) as u32
+        } else {
+            self.read(0x170)
+        }
+    }
+    pub unsafe fn entire_isr(&mut self) -> [u32; 8] {
+        [
+            self.isr_bits_31_0(),
+            self.isr_bits_63_32(),
+            self.isr_bits_95_64(),
+            self.isr_bits_127_96(),
+            self.isr_bits_159_128(),
+            self.isr_bits_191_160(),
+            self.isr_bits_223_192(),
+            self.isr_bits_255_224(),
+        ]
+    }
+    pub unsafe fn tmr_bits_31_0(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_TMR0) as u32
+        } else {
+            self.read(0x180)
+        }
+    }
+    pub unsafe fn tmr_bits_63_32(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_TMR1) as u32
+        } else {
+            self.read(0x190)
+        }
+    }
+    pub unsafe fn tmr_bits_95_64(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_TMR2) as u32
+        } else {
+            self.read(0x1A0)
+        }
+    }
+    pub unsafe fn tmr_bits_127_96(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_TMR3) as u32
+        } else {
+            self.read(0x1B0)
+        }
+    }
+    pub unsafe fn tmr_bits_159_128(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_TMR4) as u32
+        } else {
+            self.read(0x1C0)
+        }
+    }
+    pub unsafe fn tmr_bits_191_160(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_TMR5) as u32
+        } else {
+            self.read(0x1D0)
+        }
+    }
+    pub unsafe fn tmr_bits_223_192(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_TMR6) as u32
+        } else {
+            self.read(0x1E0)
+        }
+    }
+    pub unsafe fn tmr_bits_255_224(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_TMR7) as u32
+        } else {
+            self.read(0x1F0)
+        }
+    }
+    pub unsafe fn entire_tmr(&mut self) -> [u32; 8] {
+        [
+            self.tmr_bits_31_0(),
+            self.tmr_bits_63_32(),
+            self.tmr_bits_95_64(),
+            self.tmr_bits_127_96(),
+            self.tmr_bits_159_128(),
+            self.tmr_bits_191_160(),
+            self.tmr_bits_223_192(),
+            self.tmr_bits_255_224(),
+        ]
+    }
+    pub unsafe fn irr_bits_31_0(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_IRR0) as u32
+        } else {
+            self.read(0x200)
+        }
+    }
+    pub unsafe fn irr_bits_63_32(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_IRR1) as u32
+        } else {
+            self.read(0x210)
+        }
+    }
+    pub unsafe fn irr_bits_95_64(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_IRR2) as u32
+        } else {
+            self.read(0x220)
+        }
+    }
+    pub unsafe fn irr_bits_127_96(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_IRR3) as u32
+        } else {
+            self.read(0x230)
+        }
+    }
+    pub unsafe fn irr_bits_159_128(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_IRR4) as u32
+        } else {
+            self.read(0x240)
+        }
+    }
+    pub unsafe fn irr_bits_191_160(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_IRR5) as u32
+        } else {
+            self.read(0x250)
+        }
+    }
+    pub unsafe fn irr_bits_223_192(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_IRR6) as u32
+        } else {
+            self.read(0x260)
+        }
+    }
+    pub unsafe fn irr_bits_255_224(&mut self) -> u32 {
+        if self.x2 {
+            rdmsr(IA32_X2APIC_IRR7) as u32
+        } else {
+            self.read(0x270)
+        }
+    }
+    pub unsafe fn entire_irr(&mut self) -> [u32; 8] {
+        [
+            self.irr_bits_31_0(),
+            self.irr_bits_63_32(),
+            self.irr_bits_95_64(),
+            self.irr_bits_127_96(),
+            self.irr_bits_159_128(),
+            self.irr_bits_191_160(),
+            self.irr_bits_223_192(),
+            self.irr_bits_255_224(),
+        ]
+    }
+
     /// Determine the APIC timer frequency, if the info wasn't already retrieved directly from the
     /// CPU.
     unsafe fn determine_freq(&mut self) -> (u128, u128) {
diff --git a/src/arch/x86_64/interrupt/irq.rs b/src/arch/x86_64/interrupt/irq.rs
index 637f55a076c67a5bf8372edde6731a4a548f1c34..4d8f86c0cd11486e0c8dd2558b0640ead42c0a65 100644
--- a/src/arch/x86_64/interrupt/irq.rs
+++ b/src/arch/x86_64/interrupt/irq.rs
@@ -11,10 +11,11 @@ use crate::{context, ptrace, time};
 #[thread_local]
 pub static PIT_TICKS: AtomicUsize = AtomicUsize::new(0);
 
+extern {
+    fn irq_trigger(irq: u8);
+}
+
 unsafe fn trigger(irq: u8) {
-    extern {
-        fn irq_trigger(irq: u8);
-    }
 
     if irq < 16 {
         if irq >= 8 {
@@ -143,10 +144,6 @@ interrupt!(lapic_error, {
     println!("Local apic internal error: ESR={:#0x}", local_apic::LOCAL_APIC.esr());
     lapic_eoi();
 });
-interrupt!(msi_vector, {
-    println!("MSI interrupt");
-    lapic_eoi();
-});
 interrupt!(calib_pit, {
     const PIT_RATE: u64 = 2_250_286;
 
@@ -171,8 +168,8 @@ macro_rules! allocatable_irq(
 
 pub unsafe fn allocatable_irq_generic(number: u8) {
     println!("generic irq: {}", number);
-    trigger(number - 32);
-    lapic_eoi(); // not sure if needed
+    irq_trigger(number - 32);
+    lapic_eoi();
 }
 
 define_default_irqs!();
diff --git a/src/scheme/irq.rs b/src/scheme/irq.rs
index 18ee836fce0904a096460c77b935f354ff2350fa..b3784e610d2aca2f9969076361901719f529117f 100644
--- a/src/scheme/irq.rs
+++ b/src/scheme/irq.rs
@@ -43,7 +43,7 @@ pub extern fn irq_trigger(irq: u8) {
 
     let guard = HANDLES.read();
     if let Some(handles) = guard.as_ref() {
-        for (fd, _) in handles.iter().filter_map(|(fd, handle)| Some((fd, handle.as_irq_handle()?))).filter(|&(_, (_, handle_irq))| handle_irq == irq) {
+        for (fd, (_, handle_irq)) in handles.iter().filter_map(|(fd, handle)| Some((fd, handle.as_irq_handle()?))).filter(|&(_, (_, handle_irq))| handle_irq == irq) {
             event::trigger(IRQ_SCHEME_ID.load(Ordering::SeqCst), *fd, EVENT_READ);
         }
     } else {