From 157a3e5c0d7ecfa6e63a052b6dbcb098c190ce7a Mon Sep 17 00:00:00 2001
From: 4lDO2 <4lDO2@protonmail.com>
Date: Fri, 27 Mar 2020 16:21:15 +0100
Subject: [PATCH] Improve MSI.

---
 src/arch/x86_64/device/local_apic.rs | 205 +++++++++++++++++++++++++++
 src/arch/x86_64/interrupt/irq.rs     |  15 +-
 src/scheme/irq.rs                    |   2 +-
 3 files changed, 212 insertions(+), 10 deletions(-)

diff --git a/src/arch/x86_64/device/local_apic.rs b/src/arch/x86_64/device/local_apic.rs
index 03565cf2..895a55b3 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 637f55a0..4d8f86c0 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 18ee836f..b3784e61 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 {
-- 
GitLab