diff --git a/ableos/src/arch/x86_64/interrupts.rs b/ableos/src/arch/x86_64/interrupts.rs index 9daaaca8..803af1a3 100644 --- a/ableos/src/arch/x86_64/interrupts.rs +++ b/ableos/src/arch/x86_64/interrupts.rs @@ -6,11 +6,7 @@ use core::panic::PanicInfo; -use crate::{ - arch::gdt, - println, - rhai_shell::KEYBUFF, -}; +use crate::{arch::gdt, println, rhai_shell::KEYBUFF}; use cpuio::outb; use pic8259::ChainedPics; use qrcode::QrCode; diff --git a/ableos/src/devices/pci/ide.rs b/ableos/src/devices/pci/ide.rs index ecac1cba..63e59c2a 100644 --- a/ableos/src/devices/pci/ide.rs +++ b/ableos/src/devices/pci/ide.rs @@ -7,9 +7,9 @@ use core::num::TryFromIntError; // FIXME: platform agnostic-ify these -use x86_64::instructions::{port::Port, interrupts}; -use x86_64::structures::paging::{FrameAllocator, FrameDeallocator}; +use x86_64::instructions::{interrupts, port::Port}; use x86_64::structures::paging::{mapper::MapToError, Mapper, Page, PhysFrame, Size4KiB}; +use x86_64::structures::paging::{FrameAllocator, FrameDeallocator}; use x86_64::VirtAddr; use crate::arch::memory::BootInfoFrameAllocator; @@ -21,6 +21,9 @@ use super::PciDeviceInfo; const PRDT_START: u64 = 0xffff_ffff_0000_0000; const BUFFER_START: u64 = 0xffff_ffff_0000_1000; +/// ATA logical sector size, in bytes +const SECTOR_SIZE: u16 = 512; + /// Bus Master IDE Command const BMIC_OFFSET: u16 = 0; /// Bus Master IDE Status @@ -251,7 +254,17 @@ impl PciIde { Ok(()) } - pub fn read(&mut self) -> Result<(), TryFromIntError> { + pub fn read( + &mut self, + channel: Channel, + drive: Drive, + lba: u64, + sector_count: u16, + ) -> Result, TryFromIntError> { + // FIXME: make this an error + assert!(lba < 0xFFFFFFFFFFFF); + let byte_count = sector_count * SECTOR_SIZE; + // prepare PRD table let prd = PRDT_START as *mut PhysRegionDescriptor; unsafe { @@ -259,8 +272,7 @@ impl PciIde { .start_address() .as_u64() .try_into()?; - // we want to read 512 bytes - (*prd).byte_count = 512; + (*prd).byte_count = byte_count; // this is the end of table (*prd).eot = 1 << 7; // this byte is reserved, we should probably set it to 0 @@ -268,40 +280,42 @@ impl PciIde { } unsafe { - self.load_prdt(Channel::Primary); - self.stop(Channel::Primary); - self.set_read(Channel::Primary); - self.clear_bmi_status(Channel::Primary); - select_drive(Drive::Master, Channel::Primary); - set_lba(Channel::Primary, 0, 1); - ata_send_command(CMD_READ_DMA_EXT, Channel::Primary); - self.start(Channel::Primary); + self.load_prdt(channel); + self.stop(channel); + self.set_read(channel); + self.clear_bmi_status(channel); + select_drive(drive, channel); + set_lba(channel, lba, sector_count); + ata_send_command(CMD_READ_DMA_EXT, channel); + self.start(channel); + } - loop { - let status = self.bmi_status(Channel::Primary); - trace!("read status: 0b{status:b}"); + loop { + let status = unsafe { self.bmi_status(channel) }; - // Bit 2 (INT) set? - if (status >> 2) & 1 == 1 { - break; - } - } - - // FIXME: error handling - - // Stop DMA - self.stop(Channel::Primary); - - // Clear the interrupt bit - self.clear_bmi_status(Channel::Primary); - - for i in 0..512 { - let addr = (BUFFER_START + i) as *mut u8; - trace!("byte {i}: {}", *addr); + // Bit 2 (INT) set? + if (status >> 2) & 1 == 1 { + break; } } - Ok(()) + // FIXME: error handling + + unsafe { + // Stop DMA + self.stop(channel); + + // Clear the interrupt bit + self.clear_bmi_status(channel); + } + + let mut buffer = Vec::with_capacity(byte_count as usize); + for i in 0..512 { + let addr = (BUFFER_START + i) as *mut u8; + buffer.push(unsafe { *addr }); + } + + Ok(buffer) } pub fn device_info(&self) -> PciDeviceInfo { @@ -512,7 +526,7 @@ struct IdeDevice { } #[derive(Copy, Clone, Debug)] -enum Channel { +pub enum Channel { Primary, Secondary, } @@ -524,7 +538,7 @@ impl Channel { } #[derive(Copy, Clone, Debug)] -enum Drive { +pub enum Drive { Master, Slave, } diff --git a/ableos/src/scratchpad.rs b/ableos/src/scratchpad.rs index 88886862..3d9f7394 100644 --- a/ableos/src/scratchpad.rs +++ b/ableos/src/scratchpad.rs @@ -6,6 +6,7 @@ use crate::arch::drivers::sysinfo::master; use crate::arch::interrupts::{reset_pit_for_cpu, set_pit_2}; +use crate::devices::pci::ide::{Channel, Drive}; use crate::devices::pci::{PciDevice, PCI_DEVICES}; use crate::filesystem; use crate::filesystem::vfs::VFS; @@ -113,7 +114,7 @@ pub fn scratchpad() { BANNER_WIDTH ); - let piix_ide_device = { + let pci_ide_device = { let pci_devices = PCI_DEVICES.lock(); pci_devices .iter() @@ -127,10 +128,15 @@ pub fn scratchpad() { }) .unwrap() }; - let mut piix_ide_device = piix_ide_device.lock(); - if let PciDevice::Ide(device) = &mut *piix_ide_device { - device.read().unwrap() + + { + let mut pci_ide_device = pci_ide_device.lock(); + if let PciDevice::Ide(device) = &mut *pci_ide_device { + let first_sector = device.read(Channel::Primary, Drive::Master, 0, 1).unwrap(); + trace!("IDE Primary/Master sector 0: {first_sector:?}"); + } } + real_shell(); }