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::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 serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
use postcard::{to_vec};
|
use postcard::{to_vec};
|
||||||
@ -37,6 +42,7 @@ const ATA_RDY: u8 = 1 << 6;
|
|||||||
const ATA_BSY: u8 = 1 << 7;
|
const ATA_BSY: u8 = 1 << 7;
|
||||||
|
|
||||||
// DCR bits
|
// DCR bits
|
||||||
|
#[allow(dead_code)]
|
||||||
const ATA_INTERRUPT_DISABLE: u8 = 1 << 1;
|
const ATA_INTERRUPT_DISABLE: u8 = 1 << 1;
|
||||||
const ATA_SRST: u8 = 1 << 2;
|
const ATA_SRST: u8 = 1 << 2;
|
||||||
|
|
||||||
@ -57,8 +63,14 @@ 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");
|
||||||
match DRIVE.lock().as_ref() {
|
match DRIVE.lock().as_ref() {
|
||||||
@ -76,6 +88,49 @@ pub fn init() {
|
|||||||
};
|
};
|
||||||
println!("Detected {} drive on {} bus", drive_type, bus);
|
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();
|
let mut packet = SCSIPacket::new();
|
||||||
|
|
||||||
packet.op_code = SCSI_READ_12;
|
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) {
|
fn wait_busy(&mut self) {
|
||||||
let mut status = ATA_BSY;
|
let mut status = ATA_BSY;
|
||||||
while (status & ATA_BSY) != 0 {
|
while (status & ATA_BSY) != 0 {
|
||||||
@ -312,3 +402,9 @@ impl SCSIPacket {
|
|||||||
self.transfer_length_hi = ((l >> 0x18) & 0xff) as u8;
|
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;
|
use x86_64::structures::idt::InterruptStackFrame;
|
||||||
|
|
||||||
fn disk_interrupt_handler(disk: u16) {
|
fn disk_interrupt_handler(disk: u16) {
|
||||||
|
crate::drivers::atapi::mark_interrupt();
|
||||||
println!("Received disk {} interrupt", disk);
|
println!("Received disk {} interrupt", disk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,8 +42,6 @@ pub fn init(boot_info: &BootInformation) {
|
|||||||
memory::gdt::init_gdt();
|
memory::gdt::init_gdt();
|
||||||
interrupts::init_idt();
|
interrupts::init_idt();
|
||||||
drivers::atapi::init();
|
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));
|
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");
|
serial_println!("Hello serial");
|
||||||
|
|
||||||
let mut executor = Executor::new();
|
let mut executor = Executor::new();
|
||||||
|
executor.spawn(Task::new(drivers::atapi::print_block()));
|
||||||
executor.spawn(Task::new(keyboard::print_keypresses()));
|
executor.spawn(Task::new(keyboard::print_keypresses()));
|
||||||
executor.run();
|
executor.run();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user