refacto drive interrupt
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:
Julien CLEMENT 2022-12-16 20:50:08 +01:00
parent ff026bff7c
commit f44b808f67
3 changed files with 62 additions and 53 deletions

@ -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; mod scsi;
pub mod interrupt;
use crate::{println, serial_println}; use crate::{println, serial_println};
use scsi::{SCSIPacket}; use scsi::{SCSIPacket};
use interrupt::{INTERRUPT_FUTURE};
use core::convert::TryInto; 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 lazy_static::lazy_static;
use futures_util::task::AtomicWaker;
use spin::Mutex; use spin::Mutex;
use x86_64::instructions::port::Port; use x86_64::instructions::port::Port;
@ -64,13 +61,8 @@ lazy_static! {
pub static ref DRIVE: Mutex<Option<ATABus>> = { pub static ref DRIVE: Mutex<Option<ATABus>> = {
Mutex::new(ATABus::discover_atapi_drive()) 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() { pub fn init() {
println!("Detecting drives"); println!("Detecting drives");
@ -93,48 +85,6 @@ pub fn init() {
INTERRUPT_FUTURE.pop(); 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)] #[derive(Debug)]
pub struct ATABus { pub struct ATABus {
base_port: u16, base_port: u16,

@ -4,7 +4,7 @@ use super::{InterruptIndex, PICS};
use x86_64::structures::idt::InterruptStackFrame; use x86_64::structures::idt::InterruptStackFrame;
fn disk_interrupt_handler(disk: u16) { fn disk_interrupt_handler(disk: u16) {
crate::drivers::atapi::mark_interrupt(); crate::drivers::atapi::interrupt::mark_interrupt();
println!("Received disk {} interrupt", disk); println!("Received disk {} interrupt", disk);
} }