refacto drive interrupt
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is passing
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	continuous-integration/drone/push Build is passing
				
			Signed-off-by: Julien CLEMENT <julien.clement@epita.fr>
This commit is contained in:
		
							parent
							
								
									ff026bff7c
								
							
						
					
					
						commit
						f44b808f67
					
				
							
								
								
									
										59
									
								
								src/drivers/atapi/interrupt.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										59
									
								
								src/drivers/atapi/interrupt.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,59 @@
 | 
			
		||||
 | 
			
		||||
use core::future::Future;
 | 
			
		||||
use core::pin::Pin;
 | 
			
		||||
use core::sync::atomic::{AtomicBool, Ordering};
 | 
			
		||||
use core::task::{Context, Poll};
 | 
			
		||||
 | 
			
		||||
use lazy_static::lazy_static;
 | 
			
		||||
use futures_util::task::AtomicWaker;
 | 
			
		||||
 | 
			
		||||
lazy_static! {
 | 
			
		||||
    pub static ref INTERRUPT_FUTURE: InterruptFuture = InterruptFuture::new();
 | 
			
		||||
 | 
			
		||||
    static ref INTERRUPT: AtomicBool = AtomicBool::new(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static WAKER: AtomicWaker = AtomicWaker::new();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pub(crate) fn mark_interrupt() {
 | 
			
		||||
    INTERRUPT.store(true, Ordering::Relaxed);
 | 
			
		||||
    WAKER.wake();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Copy,Clone)]
 | 
			
		||||
pub struct InterruptFuture {
 | 
			
		||||
    _private:(),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl InterruptFuture {
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
        InterruptFuture { _private: () }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn pop(&self) -> bool {
 | 
			
		||||
        let res = INTERRUPT.load(Ordering::Relaxed);
 | 
			
		||||
        INTERRUPT.store(false, Ordering::Relaxed);
 | 
			
		||||
        res
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Future for InterruptFuture {
 | 
			
		||||
    type Output = ();
 | 
			
		||||
 | 
			
		||||
    fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
 | 
			
		||||
        if self.pop() {
 | 
			
		||||
            return Poll::Ready(());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        WAKER.register(&cx.waker());
 | 
			
		||||
 | 
			
		||||
        match self.pop() {
 | 
			
		||||
            true => {
 | 
			
		||||
                WAKER.take();
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            },
 | 
			
		||||
            false => Poll::Pending,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,16 +1,13 @@
 | 
			
		||||
mod scsi;
 | 
			
		||||
pub mod interrupt;
 | 
			
		||||
 | 
			
		||||
use crate::{println, serial_println};
 | 
			
		||||
use scsi::{SCSIPacket};
 | 
			
		||||
use interrupt::{INTERRUPT_FUTURE};
 | 
			
		||||
 | 
			
		||||
use core::convert::TryInto;
 | 
			
		||||
use core::future::Future;
 | 
			
		||||
use core::pin::Pin;
 | 
			
		||||
use core::sync::atomic::{AtomicBool, Ordering};
 | 
			
		||||
use core::task::{Context, Poll};
 | 
			
		||||
 | 
			
		||||
use lazy_static::lazy_static;
 | 
			
		||||
use futures_util::task::AtomicWaker;
 | 
			
		||||
use spin::Mutex;
 | 
			
		||||
use x86_64::instructions::port::Port;
 | 
			
		||||
 | 
			
		||||
@ -64,13 +61,8 @@ lazy_static! {
 | 
			
		||||
    pub static ref DRIVE: Mutex<Option<ATABus>> = {
 | 
			
		||||
        Mutex::new(ATABus::discover_atapi_drive())
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static ref INTERRUPT_FUTURE: InterruptFuture = InterruptFuture::new();
 | 
			
		||||
 | 
			
		||||
    static ref INTERRUPT: AtomicBool = AtomicBool::new(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static WAKER: AtomicWaker = AtomicWaker::new();
 | 
			
		||||
 | 
			
		||||
pub fn init() {
 | 
			
		||||
    println!("Detecting drives");
 | 
			
		||||
@ -93,48 +85,6 @@ pub fn init() {
 | 
			
		||||
    INTERRUPT_FUTURE.pop();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(crate) fn mark_interrupt() {
 | 
			
		||||
    INTERRUPT.store(true, Ordering::Relaxed);
 | 
			
		||||
    WAKER.wake();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Copy,Clone)]
 | 
			
		||||
struct InterruptFuture {
 | 
			
		||||
    _private:(),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl InterruptFuture {
 | 
			
		||||
    pub fn new() -> Self {
 | 
			
		||||
        InterruptFuture { _private: () }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn pop(&self) -> bool {
 | 
			
		||||
        let res = INTERRUPT.load(Ordering::Relaxed);
 | 
			
		||||
        INTERRUPT.store(false, Ordering::Relaxed);
 | 
			
		||||
        res
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Future for InterruptFuture {
 | 
			
		||||
    type Output = ();
 | 
			
		||||
 | 
			
		||||
    fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
 | 
			
		||||
        if self.pop() {
 | 
			
		||||
            return Poll::Ready(());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        WAKER.register(&cx.waker());
 | 
			
		||||
 | 
			
		||||
        match self.pop() {
 | 
			
		||||
            true => {
 | 
			
		||||
                WAKER.take();
 | 
			
		||||
                Poll::Ready(())
 | 
			
		||||
            },
 | 
			
		||||
            false => Poll::Pending,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub struct ATABus {
 | 
			
		||||
    base_port: u16,
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ use super::{InterruptIndex, PICS};
 | 
			
		||||
use x86_64::structures::idt::InterruptStackFrame;
 | 
			
		||||
 | 
			
		||||
fn disk_interrupt_handler(disk: u16) {
 | 
			
		||||
    crate::drivers::atapi::mark_interrupt();
 | 
			
		||||
    crate::drivers::atapi::interrupt::mark_interrupt();
 | 
			
		||||
    println!("Received disk {} interrupt", disk);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user