add bugged asynchronous read_block
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
b60ec92388
commit
df9d85a1a5
@ -1,8 +1,13 @@
|
||||
use crate::println;
|
||||
use crate::{println, serial_println};
|
||||
|
||||
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 serde::{Serialize, Deserialize};
|
||||
use spin::Mutex;
|
||||
use postcard::{to_vec};
|
||||
@ -37,6 +42,7 @@ const ATA_RDY: u8 = 1 << 6;
|
||||
const ATA_BSY: u8 = 1 << 7;
|
||||
|
||||
// DCR bits
|
||||
#[allow(dead_code)]
|
||||
const ATA_INTERRUPT_DISABLE: u8 = 1 << 1;
|
||||
const ATA_SRST: u8 = 1 << 2;
|
||||
|
||||
@ -57,8 +63,14 @@ 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");
|
||||
match DRIVE.lock().as_ref() {
|
||||
@ -76,6 +88,49 @@ pub fn init() {
|
||||
};
|
||||
println!("Detected {} drive on {} bus", drive_type, bus);
|
||||
}
|
||||
};
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,7 +260,7 @@ impl ATABus {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_block(&mut self, lba: u32) {
|
||||
pub fn sync_read_block(&mut self, lba: u32) {
|
||||
let mut packet = SCSIPacket::new();
|
||||
|
||||
packet.op_code = SCSI_READ_12;
|
||||
@ -241,6 +296,41 @@ impl ATABus {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn read_block(&mut self, lba: u32) {
|
||||
let mut packet = SCSIPacket::new();
|
||||
|
||||
packet.op_code = SCSI_READ_12;
|
||||
packet.set_lba(lba);
|
||||
packet.transfer_length_lo = 1;
|
||||
|
||||
self.send_packet(packet);
|
||||
|
||||
println!("Waiting packet send");
|
||||
|
||||
// Wait packet is transmitted
|
||||
(*INTERRUPT_FUTURE).await;
|
||||
|
||||
println!("Packet sent");
|
||||
|
||||
let mut _size: usize = 0;
|
||||
unsafe {
|
||||
_size = ((self.address3.read() as usize) << 8) | self.address2.read() as usize;
|
||||
}
|
||||
|
||||
for i in (0..CD_SECTOR_SIZE).step_by(2) {
|
||||
unsafe {
|
||||
let bytes: [u8; 2] = self.data.read().to_le_bytes();
|
||||
self.block[i] = bytes[0];
|
||||
self.block[i + 1] = bytes[1];
|
||||
}
|
||||
}
|
||||
|
||||
println!("Waiting command send");
|
||||
// Wait command end
|
||||
(*INTERRUPT_FUTURE).await;
|
||||
println!("Command sent");
|
||||
}
|
||||
|
||||
fn wait_busy(&mut self) {
|
||||
let mut status = ATA_BSY;
|
||||
while (status & ATA_BSY) != 0 {
|
||||
@ -312,3 +402,9 @@ impl SCSIPacket {
|
||||
self.transfer_length_hi = ((l >> 0x18) & 0xff) as u8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub async fn print_block() {
|
||||
DRIVE.lock().as_mut().unwrap().read_block(0).await;
|
||||
serial_println!("{:x?}", DRIVE.lock().as_mut().unwrap().block);
|
||||
}
|
@ -4,6 +4,7 @@ use super::{InterruptIndex, PICS};
|
||||
use x86_64::structures::idt::InterruptStackFrame;
|
||||
|
||||
fn disk_interrupt_handler(disk: u16) {
|
||||
crate::drivers::atapi::mark_interrupt();
|
||||
println!("Received disk {} interrupt", disk);
|
||||
}
|
||||
|
||||
|
@ -42,8 +42,6 @@ pub fn init(boot_info: &BootInformation) {
|
||||
memory::gdt::init_gdt();
|
||||
interrupts::init_idt();
|
||||
drivers::atapi::init();
|
||||
drivers::atapi::DRIVE.lock().as_mut().unwrap().read_block(0);
|
||||
serial_println!("{:x?}", drivers::atapi::DRIVE.lock().as_mut().unwrap().block);
|
||||
vga::change_color(ColorCode::new(Color::LightGreen, Color::Black));
|
||||
}
|
||||
|
||||
@ -56,6 +54,7 @@ pub extern "C" fn julios_main(multiboot_info_addr: usize) -> ! {
|
||||
serial_println!("Hello serial");
|
||||
|
||||
let mut executor = Executor::new();
|
||||
executor.spawn(Task::new(drivers::atapi::print_block()));
|
||||
executor.spawn(Task::new(keyboard::print_keypresses()));
|
||||
executor.run();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user