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