From f44b808f67189497baf90acb55fb8237a8d7b70f Mon Sep 17 00:00:00 2001 From: Julien CLEMENT Date: Fri, 16 Dec 2022 20:50:08 +0100 Subject: [PATCH] refacto drive interrupt Signed-off-by: Julien CLEMENT --- src/drivers/atapi/interrupt.rs | 59 ++++++++++++++++++++++++++++++++++ src/drivers/atapi/mod.rs | 54 ++----------------------------- src/interrupts/pic/disk.rs | 2 +- 3 files changed, 62 insertions(+), 53 deletions(-) create mode 100644 src/drivers/atapi/interrupt.rs diff --git a/src/drivers/atapi/interrupt.rs b/src/drivers/atapi/interrupt.rs new file mode 100644 index 0000000..d2ab98d --- /dev/null +++ b/src/drivers/atapi/interrupt.rs @@ -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 { + if self.pop() { + return Poll::Ready(()); + } + + WAKER.register(&cx.waker()); + + match self.pop() { + true => { + WAKER.take(); + Poll::Ready(()) + }, + false => Poll::Pending, + } + } +} \ No newline at end of file diff --git a/src/drivers/atapi/mod.rs b/src/drivers/atapi/mod.rs index 590c24e..7708c3c 100644 --- a/src/drivers/atapi/mod.rs +++ b/src/drivers/atapi/mod.rs @@ -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> = { 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 { - 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, diff --git a/src/interrupts/pic/disk.rs b/src/interrupts/pic/disk.rs index 03dcc5d..405a5cf 100644 --- a/src/interrupts/pic/disk.rs +++ b/src/interrupts/pic/disk.rs @@ -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); }