From 867d9ceb8b68b25fc5afea4cb7eca30d3ec8213a Mon Sep 17 00:00:00 2001 From: Harthann Date: Tue, 14 Nov 2023 09:29:23 +0100 Subject: [PATCH 01/10] Some pci/ide code cleaning, still wip and changes may occur with the need for higher level currently. IDEDevices is now seperated from IDEChannel, and read/write operation are now in lower level (IDEChannel instead of IDEController) --- srcs/pci/ide/ata.rs | 45 +++--- srcs/pci/ide/atapi.rs | 68 ++++----- srcs/pci/ide/channel.rs | 119 +++++++++++++++ srcs/pci/ide/device.rs | 213 +++++++++++++++++++++++++++ srcs/pci/ide/mod.rs | 319 ++++++---------------------------------- 5 files changed, 421 insertions(+), 343 deletions(-) create mode 100644 srcs/pci/ide/channel.rs create mode 100644 srcs/pci/ide/device.rs diff --git a/srcs/pci/ide/ata.rs b/srcs/pci/ide/ata.rs index b8893e63..9eaec505 100644 --- a/srcs/pci/ide/ata.rs +++ b/srcs/pci/ide/ata.rs @@ -1,4 +1,4 @@ -use super::{IDEChannelRegisters, IDEController, IDEDevice, IDE_IRQ_INVOKED}; +use super::{IDEChannelRegisters, IDEDevice, IDE_IRQ_INVOKED}; use crate::io; @@ -124,7 +124,7 @@ impl ATA { // Disable IRQ *IDE_IRQ_INVOKED.lock() = 0x0; channel.n_ien = 0x02; - IDEController::write(channel, ATAReg::CONTROL, channel.n_ien); + channel.write(ATAReg::CONTROL, channel.n_ien); // (I) Select one from LBA28, LBA48 or CHS // Sure Drive should support LBA in this case or you @@ -168,38 +168,30 @@ impl ATA { dma = 0; // We don't support DMA // (III) Wait if the drive is busy - while (IDEController::read(channel, ATAReg::STATUS) & ATAStatus::BSY) + while (channel.read(ATAReg::STATUS) & ATAStatus::BSY) != 0 {} // (IV) Select Drive from the controller if lba_mode == 0 { // Drive & CHS - IDEController::write( - channel, - ATAReg::HDDEVSEL, - 0xa0 | ((slavebit as u8) << 4) | head - ); + channel.write(ATAReg::HDDEVSEL, 0xa0 | ((slavebit as u8) << 4) | head); } else { // Drive & LBA - IDEController::write( - channel, - ATAReg::HDDEVSEL, - 0xe0 | ((slavebit as u8) << 4) | head - ); + channel.write(ATAReg::HDDEVSEL, 0xe0 | ((slavebit as u8) << 4) | head); } // (V) Write Parameters if lba_mode == 2 { - IDEController::write(channel, ATAReg::SECCOUNT1, 0); - IDEController::write(channel, ATAReg::LBA3, lba_io[3]); - IDEController::write(channel, ATAReg::LBA4, lba_io[4]); - IDEController::write(channel, ATAReg::LBA5, lba_io[5]); + channel.write(ATAReg::SECCOUNT1, 0); + channel.write(ATAReg::LBA3, lba_io[3]); + channel.write(ATAReg::LBA4, lba_io[4]); + channel.write(ATAReg::LBA5, lba_io[5]); } - IDEController::write(channel, ATAReg::SECCOUNT0, numsects); - IDEController::write(channel, ATAReg::LBA0, lba_io[0]); - IDEController::write(channel, ATAReg::LBA1, lba_io[1]); - IDEController::write(channel, ATAReg::LBA2, lba_io[2]); + channel.write(ATAReg::SECCOUNT0, numsects); + channel.write(ATAReg::LBA0, lba_io[0]); + channel.write(ATAReg::LBA1, lba_io[1]); + channel.write(ATAReg::LBA2, lba_io[2]); // (VI) Select the command and send it // Routine that is followed: @@ -226,7 +218,7 @@ impl ATA { _ => todo!() }; // Send the command - IDEController::write(channel, ATAReg::COMMAND, cmd as u8); + channel.write(ATAReg::COMMAND, cmd as u8); if dma != 0 { if direction == 0 { @@ -239,7 +231,7 @@ impl ATA { // PIO Read for _ in 0..numsects { // Polling, set error and exit if there is - IDEController::polling(channel, 1)?; + channel.polling(1)?; io::insw(bus as u16, edi as *mut _, words); edi += words * 2; } @@ -247,12 +239,11 @@ impl ATA { // PIO Write for _ in 0..numsects { // Polling - IDEController::polling(channel, 0)?; + channel.polling(0)?; io::outsw(bus as u16, edi as *mut _, words); edi += words * 2; } - IDEController::write( - channel, + channel.write( ATAReg::COMMAND, [ ATACommand::CacheFlush, @@ -261,7 +252,7 @@ impl ATA { ][lba_mode as usize] as u8 ); // Polling - IDEController::polling(channel, 0)?; + channel.polling(0)?; } } Ok(()) diff --git a/srcs/pci/ide/atapi.rs b/srcs/pci/ide/atapi.rs index 7fd5a25c..64906bf3 100644 --- a/srcs/pci/ide/atapi.rs +++ b/srcs/pci/ide/atapi.rs @@ -30,7 +30,7 @@ impl ATAPI { // Enable IRQs *IDE_IRQ_INVOKED.lock() = 0; channel.n_ien = 0; - IDEController::write(channel, ATAReg::CONTROL, channel.n_ien); + channel.write(ATAReg::CONTROL, channel.n_ien); // (I) Setup SCSI Packet let packet: [u8; 12] = [ @@ -49,44 +49,40 @@ impl ATAPI { ]; // (II) Select the drive - IDEController::write(channel, ATAReg::HDDEVSEL, (slavebit << 4) as u8); + channel.write(ATAReg::HDDEVSEL, (slavebit << 4) as u8); // (III) Delay 400 nanoseconds for select to complete for _ in 0..4 { // Reading the Alternate Status port wastes 100ns - IDEController::read(channel, ATAReg::ALTSTATUS); + channel.read(ATAReg::ALTSTATUS); } // (IV) Inform the Controller that we use PIO mode - IDEController::write(channel, ATAReg::FEATURES, 0); + channel.write(ATAReg::FEATURES, 0); // (V) Tell the Controller the size of buffer (16 bytes will be returned) let size: usize = 0x0008; // Lower Byte of Sector size - IDEController::write(channel, ATAReg::LBA1, (size & 0xff) as u8); + channel.write(ATAReg::LBA1, (size & 0xff) as u8); // Upper Byte of Sector size - IDEController::write(channel, ATAReg::LBA2, (size >> 8) as u8); + channel.write(ATAReg::LBA2, (size >> 8) as u8); // (VI) Send the Packet Command - IDEController::write( - channel, - ATAReg::COMMAND, - ATACommand::Packet as u8 - ); + channel.write(ATAReg::COMMAND, ATACommand::Packet as u8); // (VII) Waiting for the driver to finish or return an error code - IDEController::polling(channel, 1)?; + channel.polling(1)?; // (VIII) Sending the packet data io::outsw(bus as u16, packet.as_ptr() as *const _, 6); // (IX) Receiving Data - IDEController::polling(channel, 1)?; + channel.polling(1)?; io::insw(bus as u16, buffer.as_mut_ptr() as *mut _, 4); // (X) Waiting for BSY & DRQ to clear loop { - if (IDEController::read(channel, ATAReg::STATUS) + if (channel.read(ATAReg::STATUS) & (ATAStatus::BSY | ATAStatus::DRQ)) == 0 { @@ -116,7 +112,7 @@ impl ATAPI { // Enable IRQs *IDE_IRQ_INVOKED.lock() = 0; channel.n_ien = 0; - IDEController::write(channel, ATAReg::CONTROL, channel.n_ien); + channel.write(ATAReg::CONTROL, channel.n_ien); // (I) Setup SCSI Packet let packet: [u8; 12] = [ @@ -135,32 +131,28 @@ impl ATAPI { ]; // (II) Select the drive - IDEController::write(channel, ATAReg::HDDEVSEL, (slavebit << 4) as u8); + channel.write(ATAReg::HDDEVSEL, (slavebit << 4) as u8); // (III) Delay 400 nanoseconds for select to complete for _ in 0..4 { // Reading the Alternate Status port wastes 100ns - IDEController::read(channel, ATAReg::ALTSTATUS); + channel.read(ATAReg::ALTSTATUS); } // (IV) Inform the Controller that we use PIO mode - IDEController::write(channel, ATAReg::FEATURES, 0); + channel.write(ATAReg::FEATURES, 0); // (V) Tell the Controller the size of buffer // Lower Byte of Sector size - IDEController::write(channel, ATAReg::LBA1, ((words * 2) & 0xff) as u8); + channel.write(ATAReg::LBA1, ((words * 2) & 0xff) as u8); // Upper Byte of Sector size - IDEController::write(channel, ATAReg::LBA2, ((words * 2) >> 8) as u8); + channel.write(ATAReg::LBA2, ((words * 2) >> 8) as u8); // (VI) Send the Packet Command - IDEController::write( - channel, - ATAReg::COMMAND, - ATACommand::Packet as u8 - ); + channel.write(ATAReg::COMMAND, ATACommand::Packet as u8); // (VII) Waiting for the driver to finish or return an error code - IDEController::polling(channel, 1)?; + channel.polling(1)?; // (VIII) Sending the packet data io::outsw(bus as u16, packet.as_ptr() as *const _, 6); @@ -168,7 +160,7 @@ impl ATAPI { // (IX) Receiving Data for _ in 0..numsects { IDEController::wait_irq(); - IDEController::polling(channel, 1)?; + channel.polling(1)?; io::insw(bus as u16, edi as *mut _, words); edi += words * 2; } @@ -178,7 +170,7 @@ impl ATAPI { // (XI) Waiting for BSY & DRQ to clear loop { - if (IDEController::read(channel, ATAReg::STATUS) + if (channel.read(ATAReg::STATUS) & (ATAStatus::BSY | ATAStatus::DRQ)) == 0 { @@ -206,7 +198,7 @@ impl ATAPI { // Enable IRQs *IDE_IRQ_INVOKED.lock() = 0x0; channel.n_ien = 0x0; - IDEController::write(channel, ATAReg::CONTROL, channel.n_ien); + channel.write(ATAReg::CONTROL, channel.n_ien); // (I) Setup SCSI Packet let packet: [u8; 12] = [ @@ -225,35 +217,27 @@ impl ATAPI { ]; // (II) Select the Drive - IDEController::write( - channel, - ATAReg::HDDEVSEL, - (slavebit << 4) as u8 - ); + channel.write(ATAReg::HDDEVSEL, (slavebit << 4) as u8); // (III) Delay 400 nanosecond for select to complete for _ in 0..4 { // Reading Alternate Status Port Wastes 100ns - IDEController::read(channel, ATAReg::ALTSTATUS); + channel.read(ATAReg::ALTSTATUS); } // (IV) Send the Packet Command - IDEController::write( - channel, - ATAReg::COMMAND, - ATACommand::Packet as u8 - ); + channel.write(ATAReg::COMMAND, ATACommand::Packet as u8); // (V) Waiting for the driver to finish or invoke an error // Polling and stop if error - IDEController::polling(channel, 1)?; + channel.polling(1)?; // (VI) Sending the packet data io::outsw(bus as u16, packet.as_ptr() as *const _, 6); IDEController::wait_irq(); // Polling and get error code - match IDEController::polling(channel, 1) { + match channel.polling(1) { Err(err) if err != 3 => return Err(err), _ => {} } diff --git a/srcs/pci/ide/channel.rs b/srcs/pci/ide/channel.rs new file mode 100644 index 00000000..59b0533c --- /dev/null +++ b/srcs/pci/ide/channel.rs @@ -0,0 +1,119 @@ +use crate::io::{inb, insl, outb}; +use super::ata::ATAChannel; +use super::ATAStatus; +use super::ATAReg; + +#[derive(Clone, Copy)] +pub struct IDEChannelRegisters { + pub r#type: ATAChannel, // 0 - Primary Channel, 1 - Secondary Channel + pub base: u16, // I/O Base + ctrl: u16, // ControlBase + bmide: u16, // Bus Master IDE + pub n_ien: u8 // nIEN (No Interrupt) +} + +impl IDEChannelRegisters { + pub const fn new(channel: ATAChannel, base: u16, ctrl: u16, bmide: u16, n_ien: u8) -> Self { + Self { r#type: channel, base, ctrl, bmide, n_ien} + } + + pub fn read(&mut self, reg: u8) -> u8 { + let mut result: u8 = 0; + if reg > 0x07 && reg < 0x0c { + self.write(ATAReg::CONTROL, 0x80 | self.n_ien); + } + if reg < 0x08 { + result = inb(self.base + reg as u16 - 0x00); + } else if reg < 0x0c { + result = inb(self.base + reg as u16 - 0x06); + } else if reg < 0x0e { + result = inb(self.ctrl + reg as u16 - 0x0a); + } else if reg < 0x16 { + result = inb(self.bmide + reg as u16 - 0x0e); + } + if reg > 0x07 && reg < 0x0c { + self.write(ATAReg::CONTROL, self.n_ien); + } + return result; + } + + pub fn read_buffer( + &mut self, + reg: u8, + buffer: &mut [u32], + quads: u32 + ) { + if reg > 0x07 && reg < 0x0c { + self.write( + ATAReg::CONTROL, + 0x80 | self.n_ien + ); + } + if reg < 0x08 { + insl(self.base + reg as u16 - 0x00, buffer.as_mut_ptr(), quads); + } else if reg < 0x0c { + insl(self.base + reg as u16 - 0x06, buffer.as_mut_ptr(), quads); + } else if reg < 0x0e { + insl(self.ctrl + reg as u16 - 0x0a, buffer.as_mut_ptr(), quads); + } else if reg < 0x16 { + insl(self.bmide + reg as u16 - 0x0e, buffer.as_mut_ptr(), quads); + } + if reg > 0x07 && reg < 0x0c { + self.write(ATAReg::CONTROL, self.n_ien); + } + } + + + pub fn write(&mut self, reg: u8, data: u8) { + if reg > 0x07 && reg < 0x0c { + self.write(ATAReg::CONTROL, 0x80 | self.n_ien); + } + if reg < 0x08 { + outb(self.base + reg as u16 - 0x00, data); + } else if reg < 0x0c { + outb(self.base + reg as u16 - 0x06, data); + } else if reg < 0x0e { + outb(self.ctrl + reg as u16 - 0x0a, data); + } else if reg < 0x16 { + outb(self.bmide + reg as u16 - 0x0e, data); + } + if reg > 0x07 && reg < 0x0c { + self.write(ATAReg::CONTROL, self.n_ien); + } + } + + + pub fn polling(&mut self, advanced_check: u32) -> Result<(), u8> { + for _ in 0..4 { + self.read(ATAReg::ALTSTATUS); + } + + // (II) Wait for BSY to be cleared + while (self.read(ATAReg::STATUS) & ATAStatus::BSY as u8) != 0 + { /* Wait for BSY to be zero */ } + + if advanced_check != 0 { + // Read Status Register + let state: u8 = self.read(ATAReg::STATUS); + + // (III) Check for errors + if (state & ATAStatus::ERR) != 0 { + return Err(2); + } + + // (IV) Check if device fault + if (state & ATAStatus::DF) != 0 { + return Err(1); + } + + // (V) Check DRQ + // BSY = 0; DF = 0; Err = 0; So we should check for DRQ now + if (state & ATAStatus::DRQ) == 0 { + return Err(3); + } + } + // No Error + Ok(()) + } + +} diff --git a/srcs/pci/ide/device.rs b/srcs/pci/ide/device.rs new file mode 100644 index 00000000..386ca769 --- /dev/null +++ b/srcs/pci/ide/device.rs @@ -0,0 +1,213 @@ +use crate::utils::arcm::Arcm; +pub use super::channel::IDEChannelRegisters; +use crate::kprintln; +use core::ffi::CStr; +use super::ata::{ + ATAError, + ATADirection, + ATAReg, + ATA +}; +use super::atapi::{self, ATAPI}; +use super::IDEType; + + +pub struct IDEDevice { + pub reserved: u8, // 0 (Empty) or 1 (This Drive really exists) + pub channel: Option>, + pub drive: u8, // 0 (Master Drive) or 1 (Slave Drive) + pub r#type: u16, // 0: ATA, 1:ATAPI + pub signature: u16, // Drive Signature + pub capabilities: u16, // Features + pub command_sets: u32, // Command Sets Supported + pub size: u32, // Size in Sectors + pub model: [u8; 41] // Model in string +} + +impl IDEDevice { + pub const fn new() -> Self { + Self { + reserved: 0, + channel: None, + drive: 0, + r#type: 0, + signature: 0, + capabilities: 0, + command_sets: 0, + size: 0, + model: [0; 41] + } + } + + pub fn print_error(&mut self, mut err: u8) -> u8 { + + if err == 0 { + return err; + } + kprintln!("IDE:"); + let binding = match &self.channel { + Some(x) => x, + None => { + kprintln!("- Channel non-initialized"); + return 23; + } + }; + let channel: &mut IDEChannelRegisters = &mut binding.lock(); + match err { + 1 => { + kprintln!("- Device Fault"); + err = 19; + }, + 2 => { + let st: u8 = channel.read(ATAReg::ERROR); + if (st & ATAError::AMNF) != 0 { + kprintln!("- No Address Mark Found"); + err = 7; + } + if (st & ATAError::ABRT) != 0 { + kprintln!("- Command Aborted"); + err = 20; + } + if ((st & ATAError::TK0NF) != 0) + | ((st & ATAError::MCR) != 0) + | ((st & ATAError::MC) != 0) + { + kprintln!("- No Media or Media Error"); + err = 3; + } + if (st & ATAError::IDNF) != 0 { + kprintln!("- ID mark not Found"); + err = 21; + } + if (st & ATAError::UNC) != 0 { + kprintln!("- Uncorrectable Data Error"); + err = 22; + } + if (st & ATAError::BBK) != 0 { + kprintln!("- Bad Sectors"); + err = 13; + } + }, + 3 => { + kprintln!("- Reads Nothing"); + err = 23; + }, + 4 => { + kprintln!("- Write Protected"); + err = 8; + }, + _ => {} + } + kprintln!( + " - [{} {}] {}", + ["Primary", "Secondary"][channel.r#type as usize], + ["Master", "Slave"][self.drive as usize], + CStr::from_bytes_until_nul(&self.model) + .unwrap() + .to_str() + .unwrap() + ); + err + } + + /// Read sector from a device + /// + /// Parameters: + /// + numsects: number of sectors to be read. If 0, the ATA controller will now we want 256 sectors + /// + lba: LBA address --> index of the sector, which allows us to acces disks up to 2TB + /// + edi: adress of the buffer we want to fill + pub fn read_sectors( + &mut self, + numsects: u8, + lba: u32, + edi: u32 + ) -> Result<(), u8> { + + // 1- Check if the drive presents + if self.reserved == 0 { + // Drive not found + return Err(0x1); + // 2- Check if inputs are valid + } else if (lba + numsects as u32 > self.size) + && (self.r#type == IDEType::ATA as u16) + { + // Seeking to invalid position + return Err(0x2); + // 3- Read in PIO Mode through Polling & IRQs + } else { + if self.r#type == IDEType::ATA as u16 { + match ATA::access( + ATADirection::Read as u8, + self, + lba, + numsects, + edi + ) { + Ok(_) => {}, + Err(err) => return Err(self.print_error(err)) + } + } else if self.r#type == IDEType::ATAPI as u16 { + for i in 0..numsects { + match ATAPI::read( + self, + lba + i as u32, + 1, + edi + i as u32 * atapi::SECTOR_SIZE + ) { + Ok(_) => {}, + Err(err) => return Err(self.print_error(err)) + } + } + } + } + Ok(()) + } + + /// Write sector from a device + /// + /// Parameters: + /// + numsects: number of sectors to write. If 0, the ATA controller will now we want 256 sectors + /// + lba: LBA address --> index of the sector, which allows us to access disks up to 2TB + /// + edi: adress of the buffer we want to fill + pub fn write_sectors( + &mut self, + numsects: u8, + lba: u32, + edi: u32 + ) -> Result<(), u8> { + + // 1- Check if the drive presents + if self.reserved == 0 { + // Drive not found + return Err(0x1); + // 2- Check if inputs are valid + } else if (lba + numsects as u32 > self.size) + && (self.r#type == IDEType::ATA as u16) + { + return Err(0x2); + // 3- Read in PIO Mode through Polling & IRQs + } else { + if self.r#type == IDEType::ATA as u16 { + match ATA::access( + ATADirection::Write as u8, + self, + lba, + numsects, + edi + ) { + Ok(_) => {}, + Err(err) => return Err(self.print_error(err)) + } + } else if self.r#type == IDEType::ATAPI as u16 { + // Write-Protected + return Err(0x4); + } + } + Ok(()) + } + + + +} + + diff --git a/srcs/pci/ide/mod.rs b/srcs/pci/ide/mod.rs index a05e18b7..189327e5 100644 --- a/srcs/pci/ide/mod.rs +++ b/srcs/pci/ide/mod.rs @@ -1,7 +1,6 @@ use core::ffi::CStr; use core::mem::size_of; -use crate::io::{inb, insl, outb}; use crate::kprintln; use crate::spin::{KMutex, Mutex}; use crate::time::sleep; @@ -9,18 +8,21 @@ use crate::utils::arcm::Arcm; pub mod ata; pub mod atapi; +pub mod device; +pub mod channel; use ata::{ ATAChannel, ATACommand, ATADirection, - ATAError, ATAIdentify, ATAReg, ATAStatus, ATA }; use atapi::ATAPI; +pub use device::IDEDevice; +use channel::IDEChannelRegisters; static IDE_IRQ_INVOKED: KMutex = KMutex::::new(0); pub static IDE: Mutex = @@ -31,49 +33,6 @@ pub enum IDEType { ATAPI = 0x01 } -#[derive(Clone, Copy)] -struct IDEChannelRegisters { - r#type: ATAChannel, // 0 - Primary Channel, 1 - Secondary Channel - base: u16, // I/O Base - ctrl: u16, // ControlBase - bmide: u16, // Bus Master IDE - n_ien: u8 // nIEN (No Interrupt) -} - -impl IDEChannelRegisters { - const fn new(channel: ATAChannel) -> Self { - Self { r#type: channel, base: 0, ctrl: 0, bmide: 0, n_ien: 0 } - } -} - -pub struct IDEDevice { - reserved: u8, // 0 (Empty) or 1 (This Drive really exists) - channel: Option>, - drive: u8, // 0 (Master Drive) or 1 (Slave Drive) - pub r#type: u16, // 0: ATA, 1:ATAPI - signature: u16, // Drive Signature - capabilities: u16, // Features - command_sets: u32, // Command Sets Supported - size: u32, // Size in Sectors - model: [u8; 41] // Model in string -} - -impl IDEDevice { - const fn new() -> Self { - Self { - reserved: 0, - channel: None, - drive: 0, - r#type: 0, - signature: 0, - capabilities: 0, - command_sets: 0, - size: 0, - model: [0; 41] - } - } -} - pub struct IDEController { devices: [IDEDevice; 4] } @@ -107,32 +66,29 @@ impl IDEController { ) -> Result<(), u8> { let mut ide_buf: [u8; 2048] = [0; 2048]; + let primary = IDEChannelRegisters::new( + ATAChannel::Primary, + (bar0 & 0xfffffffc) as u16, + (bar1 & 0xfffffffc) as u16, + ((bar4 & 0xfffffffc) + 0) as u16, + 0 + ); + let secondary = IDEChannelRegisters::new( + ATAChannel::Secondary, + (bar2 & 0xfffffffc) as u16, + (bar3 & 0xfffffffc) as u16, + ((bar4 & 0xfffffffc) + 8) as u16, + 0 + ); let channels: [Arcm; 2] = [ - Arcm::new(IDEChannelRegisters::new(ATAChannel::Primary)), - Arcm::new(IDEChannelRegisters::new(ATAChannel::Secondary)) + Arcm::new(primary), + Arcm::new(secondary) ]; - // 1- Detect I/O Ports which interface IDE Controller - channels[ATAChannel::Primary as usize].lock().base = - (bar0 & 0xfffffffc) as u16; - channels[ATAChannel::Primary as usize].lock().ctrl = - (bar1 & 0xfffffffc) as u16; - channels[ATAChannel::Secondary as usize].lock().base = - (bar2 & 0xfffffffc) as u16; - channels[ATAChannel::Secondary as usize].lock().ctrl = - (bar3 & 0xfffffffc) as u16; - channels[ATAChannel::Primary as usize].lock().bmide = - ((bar4 & 0xfffffffc) + 0) as u16; - channels[ATAChannel::Secondary as usize].lock().bmide = - ((bar4 & 0xfffffffc) + 8) as u16; - // 2- Disable IRQs - IDEController::write( - &channels[ATAChannel::Primary as usize].lock(), + channels[ATAChannel::Primary as usize].lock().write( ATAReg::CONTROL, - 2 - ); - IDEController::write( - &channels[ATAChannel::Secondary as usize].lock(), + 2); + channels[ATAChannel::Secondary as usize].lock().write( ATAReg::CONTROL, 2 ); @@ -143,39 +99,25 @@ impl IDEController { for j in 0..2 { let mut err: u8 = 0; let mut r#type: u8 = IDEType::ATA as u8; - - // Assuming that no drive here - self.devices[count].reserved = 0; - // (I) Select Drive - IDEController::write( - &mut channels[i].lock(), - ATAReg::HDDEVSEL, - 0xa0 | (j << 4) - ); + channels[i].lock().write(ATAReg::HDDEVSEL, 0xa0 | (j << 4)); sleep(1); // (II) Send ATA Identify Command - IDEController::write( - &mut channels[i].lock(), - ATAReg::COMMAND, + channels[i].lock().write( + ATAReg::COMMAND, ATACommand::Identify as u8 ); sleep(1); // (III) Polling // If Status = 0, No Device - if IDEController::read(&mut channels[i].lock(), ATAReg::STATUS) - == 0 - { + if channels[i].lock().read(ATAReg::STATUS) == 0 { continue; } loop { - let status: u8 = IDEController::read( - &mut channels[i].lock(), - ATAReg::STATUS - ); + let status: u8 = channels[i].lock().read(ATAReg::STATUS); if (status & ATAStatus::ERR) != 0 { err = 1; break; @@ -189,14 +131,8 @@ impl IDEController { // (IV) Probe for ATAPI Devices if err != 0 { - let cl: u8 = IDEController::read( - &mut channels[i].lock(), - ATAReg::LBA1 - ); - let ch: u8 = IDEController::read( - &mut channels[i].lock(), - ATAReg::LBA2 - ); + let cl: u8 = channels[i].lock().read(ATAReg::LBA1); + let ch: u8 = channels[i].lock().read(ATAReg::LBA2); if cl == 0x14 && ch == 0xeb { r#type = IDEType::ATAPI as u8; @@ -207,8 +143,7 @@ impl IDEController { continue; } - IDEController::write( - &mut channels[i].lock(), + channels[i].lock().write( ATAReg::COMMAND, ATACommand::IdentifyPacket as u8 ); @@ -216,8 +151,7 @@ impl IDEController { } // (V) Read Identification Space of the Device - IDEController::read_buffer( - &mut channels[i].lock(), + channels[i].lock().read_buffer( ATAReg::DATA, unsafe { ide_buf.align_to_mut::().1 }, 128 @@ -315,191 +249,28 @@ impl IDEController { *IDE_IRQ_INVOKED.lock() = 1; } - fn read(channel: &IDEChannelRegisters, reg: u8) -> u8 { - let mut result: u8 = 0; - if reg > 0x07 && reg < 0x0c { - IDEController::write( - channel, - ATAReg::CONTROL, - 0x80 | channel.n_ien - ); - } - if reg < 0x08 { - result = inb(channel.base + reg as u16 - 0x00); - } else if reg < 0x0c { - result = inb(channel.base + reg as u16 - 0x06); - } else if reg < 0x0e { - result = inb(channel.ctrl + reg as u16 - 0x0a); - } else if reg < 0x16 { - result = inb(channel.bmide + reg as u16 - 0x0e); - } - if reg > 0x07 && reg < 0x0c { - IDEController::write(channel, ATAReg::CONTROL, channel.n_ien); - } - return result; - } + fn read(channel: &mut IDEChannelRegisters, reg: u8) -> u8 { + channel.read(reg) + } - fn write(channel: &IDEChannelRegisters, reg: u8, data: u8) { - if reg > 0x07 && reg < 0x0c { - IDEController::write( - channel, - ATAReg::CONTROL, - 0x80 | channel.n_ien - ); - } - if reg < 0x08 { - outb(channel.base + reg as u16 - 0x00, data); - } else if reg < 0x0c { - outb(channel.base + reg as u16 - 0x06, data); - } else if reg < 0x0e { - outb(channel.ctrl + reg as u16 - 0x0a, data); - } else if reg < 0x16 { - outb(channel.bmide + reg as u16 - 0x0e, data); - } - if reg > 0x07 && reg < 0x0c { - IDEController::write(channel, ATAReg::CONTROL, channel.n_ien); - } - } + fn write(channel: &mut IDEChannelRegisters, reg: u8, data: u8) { + channel.write(reg, data); + } fn read_buffer( - channel: &IDEChannelRegisters, + channel: &mut IDEChannelRegisters, reg: u8, buffer: &mut [u32], quads: u32 ) { - if reg > 0x07 && reg < 0x0c { - IDEController::write( - channel, - ATAReg::CONTROL, - 0x80 | channel.n_ien - ); - } - if reg < 0x08 { - insl(channel.base + reg as u16 - 0x00, buffer.as_mut_ptr(), quads); - } else if reg < 0x0c { - insl(channel.base + reg as u16 - 0x06, buffer.as_mut_ptr(), quads); - } else if reg < 0x0e { - insl(channel.ctrl + reg as u16 - 0x0a, buffer.as_mut_ptr(), quads); - } else if reg < 0x16 { - insl(channel.bmide + reg as u16 - 0x0e, buffer.as_mut_ptr(), quads); - } - if reg > 0x07 && reg < 0x0c { - IDEController::write(channel, ATAReg::CONTROL, channel.n_ien); - } + channel.read_buffer(reg, buffer, quads); } fn polling( - channel: &IDEChannelRegisters, + channel: &mut IDEChannelRegisters, advanced_check: u32 ) -> Result<(), u8> { - // (I) Delay 400 nanosecond for BSY to be set - // Reading port wastes 100ns - for _ in 0..4 { - IDEController::read(channel, ATAReg::ALTSTATUS); - } - - // (II) Wait for BSY to be cleared - while (IDEController::read(channel, ATAReg::STATUS) - & ATAStatus::BSY as u8) - != 0 - { - // Wait for BSY to be zero - } - - if advanced_check != 0 { - // Read Status Register - let state: u8 = IDEController::read(channel, ATAReg::STATUS); - - // (III) Check for errors - if (state & ATAStatus::ERR) != 0 { - return Err(2); - } - - // (IV) Check if device fault - if (state & ATAStatus::DF) != 0 { - return Err(1); - } - - // (V) Check DRQ - // BSY = 0; DF = 0; Err = 0; So we should check for DRQ now - if (state & ATAStatus::DRQ) == 0 { - return Err(3); - } - } - // No Error - Ok(()) - } - - fn print_error(&mut self, drive: u8, mut err: u8) -> u8 { - let device: &IDEDevice = &self.devices[drive as usize]; - - if err == 0 { - return err; - } - kprintln!("IDE:"); - let binding = match &device.channel { - Some(x) => x, - None => { - kprintln!("- Channel non-initialized"); - return 23; - } - }; - let channel: &IDEChannelRegisters = &binding.lock(); - match err { - 1 => { - kprintln!("- Device Fault"); - err = 19; - }, - 2 => { - let st: u8 = IDEController::read(channel, ATAReg::ERROR); - if (st & ATAError::AMNF) != 0 { - kprintln!("- No Address Mark Found"); - err = 7; - } - if (st & ATAError::ABRT) != 0 { - kprintln!("- Command Aborted"); - err = 20; - } - if ((st & ATAError::TK0NF) != 0) - | ((st & ATAError::MCR) != 0) - | ((st & ATAError::MC) != 0) - { - kprintln!("- No Media or Media Error"); - err = 3; - } - if (st & ATAError::IDNF) != 0 { - kprintln!("- ID mark not Found"); - err = 21; - } - if (st & ATAError::UNC) != 0 { - kprintln!("- Uncorrectable Data Error"); - err = 22; - } - if (st & ATAError::BBK) != 0 { - kprintln!("- Bad Sectors"); - err = 13; - } - }, - 3 => { - kprintln!("- Reads Nothing"); - err = 23; - }, - 4 => { - kprintln!("- Write Protected"); - err = 8; - }, - _ => {} - } - kprintln!( - " - [{} {}] {}", - ["Primary", "Secondary"][channel.r#type as usize], - ["Master", "Slave"][device.drive as usize], - CStr::from_bytes_until_nul(&device.model) - .unwrap() - .to_str() - .unwrap() - ); - err + channel.polling(advanced_check) } /// Read sector from a drive @@ -539,7 +310,7 @@ impl IDEController { edi ) { Ok(_) => {}, - Err(err) => return Err(self.print_error(drive, err)) + Err(err) => return Err(device.print_error(err)) } } else if device.r#type == IDEType::ATAPI as u16 { for i in 0..numsects { @@ -550,7 +321,7 @@ impl IDEController { edi + i as u32 * atapi::SECTOR_SIZE ) { Ok(_) => {}, - Err(err) => return Err(self.print_error(drive, err)) + Err(err) => return Err(device.print_error(err)) } } } @@ -594,7 +365,7 @@ impl IDEController { edi ) { Ok(_) => {}, - Err(err) => return Err(self.print_error(drive, err)) + Err(err) => return Err(device.print_error(err)) } } else if device.r#type == IDEType::ATAPI as u16 { // Write-Protected From cf714dc922255bd084690eeb9594e2f991e0b5c8 Mon Sep 17 00:00:00 2001 From: Harthann Date: Tue, 14 Nov 2023 09:30:03 +0100 Subject: [PATCH 02/10] Adding starting point of the DiskIO trait and implementation for the IDEDevice --- srcs/disk/ide.rs | 32 ++++++++++++++++++++++++++++++++ srcs/disk/mod.rs | 21 +++++++++++++++++++++ srcs/kinit.rs | 1 + 3 files changed, 54 insertions(+) create mode 100644 srcs/disk/ide.rs create mode 100644 srcs/disk/mod.rs diff --git a/srcs/disk/ide.rs b/srcs/disk/ide.rs new file mode 100644 index 00000000..1fcfa4d9 --- /dev/null +++ b/srcs/disk/ide.rs @@ -0,0 +1,32 @@ +use crate::pci::ide::IDEDevice; +use super::DiskIO; + +pub struct IDEDisk { + diskno: u8, + device: IDEDevice +} + +impl DiskIO for IDEDisk { + + fn read_sectors( + &mut self, + numsects: u8, + lba: u32, + edi: u32 + ) -> Result<(), u8> { + self.device.read_sectors(numsects, lba, edi) + } + + fn write_sectors( + &mut self, + numsects: u8, + lba: u32, + edi: u32 + ) -> Result<(), u8> { + self.device.write_sectors(numsects, lba, edi) + } + + fn sector_size(&self) -> usize { + self.device.size as usize + } +} diff --git a/srcs/disk/mod.rs b/srcs/disk/mod.rs new file mode 100644 index 00000000..e8db12e0 --- /dev/null +++ b/srcs/disk/mod.rs @@ -0,0 +1,21 @@ +pub mod ide; + +pub trait DiskIO { + fn read_sectors( + &mut self, + numsects: u8, + lba: u32, + edi: u32 + ) -> Result<(), u8>; + + fn write_sectors( + &mut self, + numsects: u8, + lba: u32, + edi: u32 + ) -> Result<(), u8>; + + fn sector_size(&self) -> usize; +} + + diff --git a/srcs/kinit.rs b/srcs/kinit.rs index dc5b41d8..ac9eb0dd 100644 --- a/srcs/kinit.rs +++ b/srcs/kinit.rs @@ -77,6 +77,7 @@ mod multiboot; mod syscalls; mod io; mod pci; +mod disk; mod pic; mod proc; mod time; From 966efdd926e960dc369e0c78ec8fe07955673fc9 Mon Sep 17 00:00:00 2001 From: Harthann Date: Thu, 16 Nov 2023 10:31:21 +0100 Subject: [PATCH 03/10] Updating pci interface and calls to match new function location (ex: read_sector/write_sector) --- srcs/pci/ide/ata.rs | 13 +++++++---- srcs/pci/ide/atapi.rs | 36 ++++++++++++++++++++--------- srcs/pci/ide/device.rs | 11 +++++---- srcs/pci/ide/mod.rs | 51 +++++++++++++++++++++--------------------- 4 files changed, 68 insertions(+), 43 deletions(-) diff --git a/srcs/pci/ide/ata.rs b/srcs/pci/ide/ata.rs index 9eaec505..a9f22023 100644 --- a/srcs/pci/ide/ata.rs +++ b/srcs/pci/ide/ata.rs @@ -103,13 +103,18 @@ pub struct ATA {} impl ATA { pub fn access( direction: u8, - device: &mut IDEDevice, + device: &IDEDevice, lba: u32, numsects: u8, mut edi: u32 ) -> Result<(), u8> { - let binding = device.channel.as_mut().ok_or(1)?; - let channel: &mut IDEChannelRegisters = &mut binding.lock(); + let binding = match &device.channel { + Some(x) => x, + None => return Err(0x1) + + }; + let bind = binding.lock(); + let mut channel = bind.borrow_mut(); let lba_mode: u8; // 0: CHS, 1: LBA28, 2: LBA48 let dma: u8; // 0: No DMA, 1: DMA let mut lba_io: [u8; 6] = [0; 6]; @@ -124,7 +129,7 @@ impl ATA { // Disable IRQ *IDE_IRQ_INVOKED.lock() = 0x0; channel.n_ien = 0x02; - channel.write(ATAReg::CONTROL, channel.n_ien); + channel.write(ATAReg::CONTROL, 0x02); // (I) Select one from LBA28, LBA48 or CHS // Sure Drive should support LBA in this case or you diff --git a/srcs/pci/ide/atapi.rs b/srcs/pci/ide/atapi.rs index 64906bf3..0292b7c8 100644 --- a/srcs/pci/ide/atapi.rs +++ b/srcs/pci/ide/atapi.rs @@ -21,8 +21,13 @@ pub struct ATAPI {} impl ATAPI { pub fn capacity(device: &mut IDEDevice, lba: u32) -> Result { - let binding = device.channel.as_mut().ok_or(1)?; - let channel: &mut IDEChannelRegisters = &mut binding.lock(); + let binding = match &device.channel { + Some(x) => x, + None => return Err(0x1) + + }; + let bind = binding.lock(); + let mut channel = bind.borrow_mut(); let slavebit: u32 = device.drive as u32; let bus: u32 = channel.base as u32; let mut buffer: [u32; 2] = [0; 2]; @@ -30,7 +35,8 @@ impl ATAPI { // Enable IRQs *IDE_IRQ_INVOKED.lock() = 0; channel.n_ien = 0; - channel.write(ATAReg::CONTROL, channel.n_ien); + let n_ien = channel.n_ien; + channel.write(ATAReg::CONTROL, n_ien); // (I) Setup SCSI Packet let packet: [u8; 12] = [ @@ -96,13 +102,18 @@ impl ATAPI { } pub fn read( - device: &mut IDEDevice, + device: &IDEDevice, lba: u32, numsects: u8, mut edi: u32 ) -> Result<(), u8> { - let binding = device.channel.as_mut().ok_or(1)?; - let channel: &mut IDEChannelRegisters = &mut binding.lock(); + let binding = match &device.channel { + Some(x) => x, + None => return Err(0x1) + + }; + let bind = binding.lock(); + let mut channel = bind.borrow_mut(); let slavebit: u32 = device.drive as u32; let bus: u32 = channel.base as u32; // Sector Size @@ -112,7 +123,7 @@ impl ATAPI { // Enable IRQs *IDE_IRQ_INVOKED.lock() = 0; channel.n_ien = 0; - channel.write(ATAReg::CONTROL, channel.n_ien); + channel.write(ATAReg::CONTROL, 0); // (I) Setup SCSI Packet let packet: [u8; 12] = [ @@ -182,8 +193,13 @@ impl ATAPI { } pub fn eject(device: &mut IDEDevice) -> Result<(), u8> { - let binding = device.channel.as_mut().ok_or(1)?; - let channel: &mut IDEChannelRegisters = &mut binding.lock(); + let binding = match &device.channel { + Some(x) => x, + None => return Err(0x1) + + }; + let bind = binding.lock(); + let mut channel = bind.borrow_mut(); let slavebit: u32 = device.drive as u32; let bus: u32 = channel.base as u32; @@ -198,7 +214,7 @@ impl ATAPI { // Enable IRQs *IDE_IRQ_INVOKED.lock() = 0x0; channel.n_ien = 0x0; - channel.write(ATAReg::CONTROL, channel.n_ien); + channel.write(ATAReg::CONTROL, 0x0); // (I) Setup SCSI Packet let packet: [u8; 12] = [ diff --git a/srcs/pci/ide/device.rs b/srcs/pci/ide/device.rs index 386ca769..9e06fefb 100644 --- a/srcs/pci/ide/device.rs +++ b/srcs/pci/ide/device.rs @@ -10,11 +10,13 @@ use super::ata::{ }; use super::atapi::{self, ATAPI}; use super::IDEType; +use core::cell::RefCell; +#[derive(Clone)] pub struct IDEDevice { pub reserved: u8, // 0 (Empty) or 1 (This Drive really exists) - pub channel: Option>, + pub channel: Option>>, pub drive: u8, // 0 (Master Drive) or 1 (Slave Drive) pub r#type: u16, // 0: ATA, 1:ATAPI pub signature: u16, // Drive Signature @@ -39,7 +41,7 @@ impl IDEDevice { } } - pub fn print_error(&mut self, mut err: u8) -> u8 { + pub fn print_error(&self, mut err: u8) -> u8 { if err == 0 { return err; @@ -52,7 +54,8 @@ impl IDEDevice { return 23; } }; - let channel: &mut IDEChannelRegisters = &mut binding.lock(); + let bind = binding.lock(); + let channel: &mut IDEChannelRegisters = &mut bind.borrow_mut(); match err { 1 => { kprintln!("- Device Fault"); @@ -117,7 +120,7 @@ impl IDEDevice { /// + lba: LBA address --> index of the sector, which allows us to acces disks up to 2TB /// + edi: adress of the buffer we want to fill pub fn read_sectors( - &mut self, + &self, numsects: u8, lba: u32, edi: u32 diff --git a/srcs/pci/ide/mod.rs b/srcs/pci/ide/mod.rs index 189327e5..85547b80 100644 --- a/srcs/pci/ide/mod.rs +++ b/srcs/pci/ide/mod.rs @@ -1,6 +1,7 @@ use core::ffi::CStr; use core::mem::size_of; +use core::cell::RefCell; use crate::kprintln; use crate::spin::{KMutex, Mutex}; use crate::time::sleep; @@ -38,6 +39,7 @@ pub struct IDEController { } impl IDEController { + /// Create a controller with default devices pub const fn new() -> Self { Self { devices: [ @@ -49,6 +51,11 @@ impl IDEController { } } + /// Obtain reference to an existing device. + /// + /// Actually return a reference to the device and should be clone afterward + /// However if the reference is never needed this function will probably + /// be change to return a clone of the device instead pub fn get_device(&self, num: u8) -> Option<&IDEDevice> { if num > 3 || self.devices[num as usize].reserved == 0 { return None; @@ -80,15 +87,15 @@ impl IDEController { ((bar4 & 0xfffffffc) + 8) as u16, 0 ); - let channels: [Arcm; 2] = [ - Arcm::new(primary), - Arcm::new(secondary) + let mut channels: [Arcm>; 2] = [ + Arcm::new(RefCell::new(primary)), + Arcm::new(RefCell::new(secondary)) ]; // 2- Disable IRQs - channels[ATAChannel::Primary as usize].lock().write( + channels[ATAChannel::Primary as usize].lock().borrow_mut().write( ATAReg::CONTROL, 2); - channels[ATAChannel::Secondary as usize].lock().write( + channels[ATAChannel::Secondary as usize].lock().borrow_mut().write( ATAReg::CONTROL, 2 ); @@ -100,11 +107,11 @@ impl IDEController { let mut err: u8 = 0; let mut r#type: u8 = IDEType::ATA as u8; // (I) Select Drive - channels[i].lock().write(ATAReg::HDDEVSEL, 0xa0 | (j << 4)); + channels[i].lock().borrow_mut().write(ATAReg::HDDEVSEL, 0xa0 | (j << 4)); sleep(1); // (II) Send ATA Identify Command - channels[i].lock().write( + channels[i].lock().borrow_mut().write( ATAReg::COMMAND, ATACommand::Identify as u8 ); @@ -112,12 +119,12 @@ impl IDEController { // (III) Polling // If Status = 0, No Device - if channels[i].lock().read(ATAReg::STATUS) == 0 { + if channels[i].lock().borrow_mut().read(ATAReg::STATUS) == 0 { continue; } loop { - let status: u8 = channels[i].lock().read(ATAReg::STATUS); + let status: u8 = channels[i].lock().borrow_mut().read(ATAReg::STATUS); if (status & ATAStatus::ERR) != 0 { err = 1; break; @@ -131,8 +138,8 @@ impl IDEController { // (IV) Probe for ATAPI Devices if err != 0 { - let cl: u8 = channels[i].lock().read(ATAReg::LBA1); - let ch: u8 = channels[i].lock().read(ATAReg::LBA2); + let cl: u8 = channels[i].lock().borrow_mut().read(ATAReg::LBA1); + let ch: u8 = channels[i].lock().borrow_mut().read(ATAReg::LBA2); if cl == 0x14 && ch == 0xeb { r#type = IDEType::ATAPI as u8; @@ -143,7 +150,7 @@ impl IDEController { continue; } - channels[i].lock().write( + channels[i].lock().borrow_mut().write( ATAReg::COMMAND, ATACommand::IdentifyPacket as u8 ); @@ -151,7 +158,7 @@ impl IDEController { } // (V) Read Identification Space of the Device - channels[i].lock().read_buffer( + channels[i].lock().borrow_mut().read_buffer( ATAReg::DATA, unsafe { ide_buf.align_to_mut::().1 }, 128 @@ -387,12 +394,9 @@ mod test { let to_write = vec!['B' as u8; 512]; let read_from = vec![0x0 as u8; 512]; - let _ = IDE - .lock() - .write_sectors(1, 1, 0x0, to_write.as_ptr() as u32); - let _ = IDE - .lock() - .read_sectors(1, 1, 0x0, read_from.as_ptr() as u32); + let mut device = IDE.lock().get_device(1).unwrap().clone(); + let _ = device.write_sectors(1, 0x0, to_write.as_ptr() as u32); + let _ = device.read_sectors(1, 0x0, read_from.as_ptr() as u32); assert_eq!(to_write, read_from); } @@ -402,12 +406,9 @@ mod test { let to_write = vec!['A' as u8; 1024]; let read_from = vec![0x0 as u8; 1024]; - let _ = IDE - .lock() - .write_sectors(1, 2, 0x0, to_write.as_ptr() as u32); - let _ = IDE - .lock() - .read_sectors(1, 2, 0x0, read_from.as_ptr() as u32); + let mut device = IDE.lock().get_device(1).unwrap().clone(); + let _ = device.write_sectors(2, 0x0, to_write.as_ptr() as u32); + let _ = device.read_sectors(2, 0x0, read_from.as_ptr() as u32); assert_eq!(to_write, read_from); } From d1d8b5b8c849cc4223ce9ba28141d898fa6a4d1b Mon Sep 17 00:00:00 2001 From: Harthann Date: Thu, 16 Nov 2023 10:32:50 +0100 Subject: [PATCH 04/10] Adding some test, removing mutable self form read_sector as we now use interior mutabity. Creating a function to scan different disk and returning a traiti interface on them --- srcs/disk/ide.rs | 24 ++++++++++++++++--- srcs/disk/mod.rs | 62 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/srcs/disk/ide.rs b/srcs/disk/ide.rs index 1fcfa4d9..3c02219a 100644 --- a/srcs/disk/ide.rs +++ b/srcs/disk/ide.rs @@ -1,4 +1,7 @@ -use crate::pci::ide::IDEDevice; +use crate::pci::ide::{ + self, + IDEDevice +}; use super::DiskIO; pub struct IDEDisk { @@ -6,10 +9,18 @@ pub struct IDEDisk { device: IDEDevice } +unsafe impl Send for IDEDisk {} + +impl IDEDisk { + pub const fn new(diskno: u8, device: IDEDevice) -> Self { + Self {diskno, device} + } +} + impl DiskIO for IDEDisk { fn read_sectors( - &mut self, + &self, numsects: u8, lba: u32, edi: u32 @@ -27,6 +38,13 @@ impl DiskIO for IDEDisk { } fn sector_size(&self) -> usize { - self.device.size as usize + match self.device.r#type { + x if x == ide::IDEType::ATA as u16 => ide::ata::SECTOR_SIZE as usize, + x if x == ide::IDEType::ATAPI as u16 => ide::atapi::SECTOR_SIZE as usize, + _ => { + panic!("Unrecognized disk.") + } + } } } + diff --git a/srcs/disk/mod.rs b/srcs/disk/mod.rs index e8db12e0..e4afc69c 100644 --- a/srcs/disk/mod.rs +++ b/srcs/disk/mod.rs @@ -1,8 +1,13 @@ +use crate::alloc::boxed::Box; +use crate::alloc::vec::Vec; +use crate::pci::ide::IDE; + pub mod ide; +use ide::IDEDisk; pub trait DiskIO { fn read_sectors( - &mut self, + &self, numsects: u8, lba: u32, edi: u32 @@ -18,4 +23,59 @@ pub trait DiskIO { fn sector_size(&self) -> usize; } +pub fn discover() -> Vec> { + let mut found_disks = Vec::>::new(); + + // Discover IDE disks + let binding = IDE.lock(); + for i in 0..4 { + let disk = binding.get_device(i); + match disk { + Some(x) => { + let idedisk = IDEDisk::new(i as u8, x.clone()); + let diskio = Box::new(idedisk); + found_disks.push(diskio); + }, + None => {} + } + + } + + found_disks +} + +#[cfg(test)] +mod test { + + use crate::alloc::vec; + use crate::{sys_macros, IDE}; + use super::ide::IDEDisk; + use super::DiskIO; + + #[sys_macros::test_case] + fn idedisk_read_write_sector() { + let to_write = vec!['C' as u8; 512]; + let read_from = vec![0x0 as u8; 512]; + + let device = IDE.lock().get_device(1).unwrap().clone(); + let mut idedisk = IDEDisk::new(1, device); + let _ = idedisk.write_sectors(1, 0x0, to_write.as_ptr() as u32); + let _ = idedisk.read_sectors(1, 0x0, read_from.as_ptr() as u32); + + assert_eq!(to_write, read_from); + } + + #[sys_macros::test_case] + fn idedisk_read_write_multiple_sectors() { + let to_write = vec!['D' as u8; 1024]; + let read_from = vec![0x0 as u8; 1024]; + + let device = IDE.lock().get_device(1).unwrap().clone(); + let mut idedisk = IDEDisk::new(1, device); + let _ = idedisk.write_sectors(2, 0x0, to_write.as_ptr() as u32); + let _ = idedisk.read_sectors(2, 0x0, read_from.as_ptr() as u32); + + assert_eq!(to_write, read_from); + } +} From 0b9f0b9fcbf7f9975c8a7192e6e0cf0c4bd7e773 Mon Sep 17 00:00:00 2001 From: Harthann Date: Thu, 16 Nov 2023 10:33:45 +0100 Subject: [PATCH 05/10] Updating ext2 to be built with a DiskioIO dyn trait and use it to communicate with disk --- srcs/fs/ext2/mod.rs | 80 ++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 44 deletions(-) diff --git a/srcs/fs/ext2/mod.rs b/srcs/fs/ext2/mod.rs index a5fc87af..ed1cc738 100644 --- a/srcs/fs/ext2/mod.rs +++ b/srcs/fs/ext2/mod.rs @@ -3,6 +3,8 @@ use crate::pci::ide::IDE; use crate::string::ToString; use crate::utils::math::roundup; use crate::utils::path::Path; +use crate::disk::DiskIO; +use alloc::boxed::Box; mod bitmap; pub mod block; @@ -13,32 +15,25 @@ pub mod inode; /// In the filesystem created to test it this means we read/write 16 sectors for each operations /// This is pretty ineffective and will probably need optimisation in later version pub struct Ext2 { - diskno: u8, sector_size: usize, + diskio: Box, pub sblock: block::BaseSuperblock } impl Ext2 { - pub fn new(diskno: u8) -> Result { - let sector_size = { - let binding = IDE.lock(); - let device = binding.get_device(diskno); - if device.is_none() { - return Err(1); - } - match device.unwrap().r#type { - x if x == ide::IDEType::ATA as u16 => ide::ata::SECTOR_SIZE, - x if x == ide::IDEType::ATAPI as u16 => ide::atapi::SECTOR_SIZE, - _ => { - panic!("Unrecognized disk.") - } - } + pub fn new(mut diskio: Box) -> Result { + let sector_size = diskio.sector_size() as usize; + let sblock = read_superblock(&mut diskio)?; + let fs = Self { + sector_size, + diskio, + sblock }; - Ok(Self { - diskno: diskno, - sector_size: sector_size as usize, - sblock: read_superblock(diskno, sector_size as usize)? - }) + if fs.is_valid() { + Ok(fs) + } else { + Err(0x01) + } } pub fn is_valid(&self) -> bool { @@ -114,12 +109,11 @@ impl Ext2 { let first_sector = (bsize * block_no as usize) / self.sector_size; let mut block: crate::vec::Vec = crate::vec::Vec::new(); for i in first_sector..first_sector + nb_sector { - IDE.lock().read_sectors( - self.diskno, + self.diskio.read_sectors( 1, i as u32, buffer.as_ptr() as u32 - ); + ).expect("Something went wrong in read_block"); let mut start = 0; if sector_per_block < 1.0 { start = (block_no as usize % (1.0 / sector_per_block) as usize) @@ -137,12 +131,11 @@ impl Ext2 { let sector_per_block = bsize / self.sector_size as usize; let sector_no = bsize / self.sector_size as usize; - IDE.lock().write_sectors( - self.diskno, + self.diskio.write_sectors( sector_no as u8, block_no * sector_per_block as u32, block.as_ptr() as u32 - ); + ).expect("Something went wrong in write block"); } fn write_slice(&mut self, block_no: u32, offset: usize, slice: &[u8]) { @@ -512,10 +505,8 @@ impl Ext2 { use crate::pci::ide; -pub fn read_superblock( - diskno: u8, - sector_size: usize -) -> Result { +pub fn read_superblock(diskio: &mut Box) -> Result { + let sector_size = diskio.sector_size(); // superblock is at index 1024 and 1024 bytes long let mut nb_sector = roundup(2048 / sector_size, 1) as usize; // sector_size > 2048 @@ -524,8 +515,7 @@ pub fn read_superblock( } let buffer: Vec = vec![0; nb_sector * sector_size]; - IDE.lock().read_sectors( - diskno, + diskio.read_sectors( nb_sector as u8, 0, buffer.as_ptr() as u32 @@ -539,9 +529,11 @@ pub fn read_superblock( Ok(sblock) } +/* pub fn is_ext2(diskno: u8) -> bool { Ext2::new(diskno as u8).is_ok_and(|fs| fs.is_valid()) } +*/ use crate::vec::Vec; @@ -553,8 +545,8 @@ fn get_block_content(block: Vec, size: usize) -> Vec { /// Helper function to get content of a file. /// Does not yet check if found entry is really a file. /// Does not yet take into account file bigger than 4096 -pub fn get_file_content(diskno: u8, path: &str, inode: usize) -> Vec { - let ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); +pub fn get_file_content(ext2: &Ext2, path: &str, inode: usize) -> Vec { + //let ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); let opt = ext2.recurs_find(path, inode); match opt { None => Vec::new(), @@ -653,11 +645,11 @@ pub fn get_file_content(diskno: u8, path: &str, inode: usize) -> Vec { /// Helper function to list all entries in a directory /// Does not yet check if found entry is a directory or not pub fn list_dir( - diskno: u8, + ext2: &Ext2, path: &str, inode: usize ) -> crate::vec::Vec { - let ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); + //let ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); let inode = ext2.recurs_find(path, inode); return match inode { None => crate::vec::Vec::new(), @@ -680,8 +672,8 @@ pub fn list_dir( }; } -pub fn create_file(diskno: u8, path: &str, inode_no: usize) { - let mut ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); +pub fn create_file(ext2: &mut Ext2, path: &str, inode_no: usize) { + //let mut ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); let path = Path::new(path); let filename = path.file_name().unwrap(); let binding = path.parent().unwrap(); @@ -725,8 +717,8 @@ pub fn create_file(diskno: u8, path: &str, inode_no: usize) { } } -pub fn remove_file(diskno: u8, path: &str, inode_no: usize) { - let mut ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); +pub fn remove_file(ext2: &mut Ext2, path: &str, inode_no: usize) { + //let mut ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); let path = Path::new(path); let filename = path.file_name().unwrap(); let binding = path.parent().unwrap(); @@ -753,8 +745,8 @@ pub fn remove_file(diskno: u8, path: &str, inode_no: usize) { } /// Helper function to create a folder at a given path -pub fn create_dir(diskno: u8, path: &str, inode_no: usize) { - let mut ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); +pub fn create_dir(ext2: &mut Ext2, path: &str, inode_no: usize) { + //let mut ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); let path = Path::new(path); let new_dir = path.file_name().unwrap(); let binding = path.parent().unwrap(); @@ -826,8 +818,8 @@ pub fn create_dir(diskno: u8, path: &str, inode_no: usize) { } } -pub fn show_inode_info(diskno: u8, path: &str, inode_no: usize) { - let ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); +pub fn show_inode_info(ext2: &Ext2, path: &str, inode_no: usize) { + //let ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); let inode = ext2.recurs_find(&path, inode_no); match inode { None => { From 0ca0f033f013fa4cfbba45ff5cd52803e4eebc29 Mon Sep 17 00:00:00 2001 From: Harthann Date: Thu, 16 Nov 2023 10:34:23 +0100 Subject: [PATCH 06/10] Replacing old disk discovery and DISKNO initialisation with a call to the new discovery function --- srcs/kmain.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/srcs/kmain.rs b/srcs/kmain.rs index cb4fd78b..585d1753 100644 --- a/srcs/kmain.rs +++ b/srcs/kmain.rs @@ -34,20 +34,19 @@ mod poc { use crate::cli::DISKNO; use crate::fs::ext2; +use crate::disk; #[no_mangle] pub extern "C" fn kmain() -> ! { - for i in 0..4 { - if ext2::is_ext2(i) { - *DISKNO.lock() = i as i8; - crate::kprintln!("Found ext2 filesystem on disk {}.", i); - break; - } - } - if *DISKNO.lock() == -1 { - todo!("No ext2 disk found."); - } - // poc::insertion_poc(); + // Mounting first ext2 disk found to DISKNO + let disks = disk::discover(); + for i in disks { + if let Ok(ext) = ext2::Ext2::new(i) { + kprintln!("Found an ext2 fs"); + *DISKNO.lock() = Some(ext); + } + } + kprintln!("Hello World of {}!", 42); change_color!(Color::Red, Color::White); let workspace_msg = string::String::from( From d15b989210a1207e7d2f03619c056024625b591f Mon Sep 17 00:00:00 2001 From: Harthann Date: Thu, 16 Nov 2023 10:35:20 +0100 Subject: [PATCH 07/10] Changing DISKNO type and updating debugfs commands to match the new interface --- srcs/cli/commands/debugfs.rs | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/srcs/cli/commands/debugfs.rs b/srcs/cli/commands/debugfs.rs index dff9b998..f956f8ce 100644 --- a/srcs/cli/commands/debugfs.rs +++ b/srcs/cli/commands/debugfs.rs @@ -8,7 +8,7 @@ use crate::utils::path::Path; pub static ROOT_INODE: usize = 2; pub static CURRENTDIR_INODE: Mutex = Mutex::new(ROOT_INODE); pub static PWD: Mutex> = Mutex::new(None); -pub static DISKNO: Mutex = Mutex::new(-1); +pub static DISKNO: Mutex> = Mutex::new(None); fn help() { crate::kprintln!( @@ -55,7 +55,7 @@ fn rm(command: Vec) { return; } ext2::remove_file( - *DISKNO.lock() as u8, + DISKNO.lock().as_mut().unwrap(), command[1].as_str(), *CURRENTDIR_INODE.lock() ); @@ -67,7 +67,7 @@ fn stat(command: Vec) { return; } ext2::show_inode_info( - *DISKNO.lock() as u8, + DISKNO.lock().as_ref().unwrap(), command[1].as_str(), *CURRENTDIR_INODE.lock() ); @@ -79,7 +79,7 @@ fn mkdir(command: Vec) { return; } ext2::create_dir( - *DISKNO.lock() as u8, + DISKNO.lock().as_mut().unwrap(), command[1].as_str(), *CURRENTDIR_INODE.lock() ); @@ -91,7 +91,7 @@ fn touch(command: Vec) { return; } ext2::create_file( - *DISKNO.lock() as u8, + DISKNO.lock().as_mut().unwrap(), command[1].as_str(), *CURRENTDIR_INODE.lock() ); @@ -103,7 +103,7 @@ fn cat(command: Vec) { return; } let file_content = ext2::get_file_content( - *DISKNO.lock() as u8, + DISKNO.lock().as_ref().unwrap(), command[1].as_str(), *CURRENTDIR_INODE.lock() ); @@ -113,13 +113,15 @@ fn cat(command: Vec) { } fn test() { - let mut ext2 = ext2::Ext2::new(*DISKNO.lock() as u8) - .expect("Disk is not a ext2 filesystem."); + /* + let binding = DISKNO.lock(); + let ext2 = binding.as_ref().unwrap(); // let mut dentry = crate::fs::ext2::inode::Dentry::default(); let _node = ext2.alloc_node(0); let _block = ext2.alloc_block(0); crate::dprintln!("Node {}", _node); + */ } fn ls(command: Vec) { @@ -129,7 +131,7 @@ fn ls(command: Vec) { }; crate::dprintln!("Ls: {}", path); let dentries = - ext2::list_dir(*DISKNO.lock() as u8, path, *CURRENTDIR_INODE.lock()); + ext2::list_dir(DISKNO.lock().as_ref().unwrap(), path, *CURRENTDIR_INODE.lock()); for i in dentries { crate::kprint!("{} ", i.name); @@ -143,8 +145,8 @@ fn cd(command: Vec) { _ => command[1].as_str() }; let path = Path::new(path); - let ext2 = ext2::Ext2::new(*DISKNO.lock() as u8) - .expect("Disk is not a ext2 filesystem."); + let binding = DISKNO.lock(); + let ext2 = binding.as_ref().unwrap(); let lookup = ext2.recurs_find(path.as_str(), *CURRENTDIR_INODE.lock()); match lookup { None => crate::kprintln!("Dir not found"), @@ -174,8 +176,8 @@ fn imap(command: Vec) { 1 => "/", _ => command[1].as_str() }; - let ext2 = ext2::Ext2::new(*DISKNO.lock() as u8) - .expect("Disk is not a ext2 filesystem."); + let binding = DISKNO.lock(); + let ext2 = binding.as_ref().unwrap(); let lookup = ext2.get_inode_of(path); match lookup { None => crate::kprintln!("File not found"), From 142c7d44468b48a1213fe4bd608d9f7ae22533cd Mon Sep 17 00:00:00 2001 From: Harthann Date: Thu, 16 Nov 2023 11:12:47 +0100 Subject: [PATCH 08/10] Formatting --- srcs/cli/commands/debugfs.rs | 25 ++++----- srcs/disk/ide.rs | 46 ++++++++--------- srcs/disk/mod.rs | 55 +++++++++----------- srcs/fs/ext2/mod.rs | 76 +++++++++++++-------------- srcs/kinit.rs | 2 +- srcs/kmain.rs | 18 +++---- srcs/pci/ide/ata.rs | 23 ++++----- srcs/pci/ide/atapi.rs | 41 +++++++-------- srcs/pci/ide/channel.rs | 50 ++++++++---------- srcs/pci/ide/device.rs | 38 +++++--------- srcs/pci/ide/mod.rs | 99 +++++++++++++++++++----------------- 11 files changed, 218 insertions(+), 255 deletions(-) diff --git a/srcs/cli/commands/debugfs.rs b/srcs/cli/commands/debugfs.rs index f956f8ce..2df9ce4f 100644 --- a/srcs/cli/commands/debugfs.rs +++ b/srcs/cli/commands/debugfs.rs @@ -113,15 +113,13 @@ fn cat(command: Vec) { } fn test() { - /* - let binding = DISKNO.lock(); - let ext2 = binding.as_ref().unwrap(); + // let binding = DISKNO.lock(); + // let ext2 = binding.as_ref().unwrap(); // let mut dentry = crate::fs::ext2::inode::Dentry::default(); - - let _node = ext2.alloc_node(0); - let _block = ext2.alloc_block(0); - crate::dprintln!("Node {}", _node); - */ + // + // let _node = ext2.alloc_node(0); + // let _block = ext2.alloc_block(0); + // crate::dprintln!("Node {}", _node); } fn ls(command: Vec) { @@ -130,8 +128,11 @@ fn ls(command: Vec) { _ => command[1].as_str() }; crate::dprintln!("Ls: {}", path); - let dentries = - ext2::list_dir(DISKNO.lock().as_ref().unwrap(), path, *CURRENTDIR_INODE.lock()); + let dentries = ext2::list_dir( + DISKNO.lock().as_ref().unwrap(), + path, + *CURRENTDIR_INODE.lock() + ); for i in dentries { crate::kprint!("{} ", i.name); @@ -145,7 +146,7 @@ fn cd(command: Vec) { _ => command[1].as_str() }; let path = Path::new(path); - let binding = DISKNO.lock(); + let binding = DISKNO.lock(); let ext2 = binding.as_ref().unwrap(); let lookup = ext2.recurs_find(path.as_str(), *CURRENTDIR_INODE.lock()); match lookup { @@ -176,7 +177,7 @@ fn imap(command: Vec) { 1 => "/", _ => command[1].as_str() }; - let binding = DISKNO.lock(); + let binding = DISKNO.lock(); let ext2 = binding.as_ref().unwrap(); let lookup = ext2.get_inode_of(path); match lookup { diff --git a/srcs/disk/ide.rs b/srcs/disk/ide.rs index 3c02219a..c43c6aa5 100644 --- a/srcs/disk/ide.rs +++ b/srcs/disk/ide.rs @@ -1,50 +1,44 @@ -use crate::pci::ide::{ - self, - IDEDevice -}; use super::DiskIO; +use crate::pci::ide::{self, IDEDevice}; pub struct IDEDisk { - diskno: u8, - device: IDEDevice + diskno: u8, + device: IDEDevice } unsafe impl Send for IDEDisk {} impl IDEDisk { - pub const fn new(diskno: u8, device: IDEDevice) -> Self { - Self {diskno, device} - } + pub const fn new(diskno: u8, device: IDEDevice) -> Self { + Self { diskno, device } + } } impl DiskIO for IDEDisk { - - fn read_sectors( - &self, - numsects: u8, - lba: u32, - edi: u32 - ) -> Result<(), u8> { - self.device.read_sectors(numsects, lba, edi) + fn read_sectors(&self, numsects: u8, lba: u32, edi: u32) -> Result<(), u8> { + self.device.read_sectors(numsects, lba, edi) } - fn write_sectors( + fn write_sectors( &mut self, numsects: u8, lba: u32, edi: u32 ) -> Result<(), u8> { - self.device.write_sectors(numsects, lba, edi) - } + self.device.write_sectors(numsects, lba, edi) + } - fn sector_size(&self) -> usize { + fn sector_size(&self) -> usize { match self.device.r#type { - x if x == ide::IDEType::ATA as u16 => ide::ata::SECTOR_SIZE as usize, - x if x == ide::IDEType::ATAPI as u16 => ide::atapi::SECTOR_SIZE as usize, + x if x == ide::IDEType::ATA as u16 => { + ide::ata::SECTOR_SIZE as usize + }, + x if x == ide::IDEType::ATAPI as u16 => { + ide::atapi::SECTOR_SIZE as usize + }, _ => { panic!("Unrecognized disk.") } - } - } + } + } } - diff --git a/srcs/disk/mod.rs b/srcs/disk/mod.rs index e4afc69c..b805b722 100644 --- a/srcs/disk/mod.rs +++ b/srcs/disk/mod.rs @@ -6,12 +6,7 @@ pub mod ide; use ide::IDEDisk; pub trait DiskIO { - fn read_sectors( - &self, - numsects: u8, - lba: u32, - edi: u32 - ) -> Result<(), u8>; + fn read_sectors(&self, numsects: u8, lba: u32, edi: u32) -> Result<(), u8>; fn write_sectors( &mut self, @@ -20,45 +15,44 @@ pub trait DiskIO { edi: u32 ) -> Result<(), u8>; - fn sector_size(&self) -> usize; + fn sector_size(&self) -> usize; } pub fn discover() -> Vec> { - let mut found_disks = Vec::>::new(); - - // Discover IDE disks - let binding = IDE.lock(); - for i in 0..4 { - let disk = binding.get_device(i); - match disk { - Some(x) => { - let idedisk = IDEDisk::new(i as u8, x.clone()); - let diskio = Box::new(idedisk); - found_disks.push(diskio); - }, - None => {} - } - - } + let mut found_disks = Vec::>::new(); + + // Discover IDE disks + let binding = IDE.lock(); + for i in 0..4 { + let disk = binding.get_device(i); + match disk { + Some(x) => { + let idedisk = IDEDisk::new(i as u8, x.clone()); + let diskio = Box::new(idedisk); + found_disks.push(diskio); + }, + None => {} + } + } - found_disks + found_disks } #[cfg(test)] mod test { + use super::ide::IDEDisk; + use super::DiskIO; use crate::alloc::vec; use crate::{sys_macros, IDE}; - use super::ide::IDEDisk; - use super::DiskIO; #[sys_macros::test_case] fn idedisk_read_write_sector() { let to_write = vec!['C' as u8; 512]; let read_from = vec![0x0 as u8; 512]; - let device = IDE.lock().get_device(1).unwrap().clone(); - let mut idedisk = IDEDisk::new(1, device); + let device = IDE.lock().get_device(1).unwrap().clone(); + let mut idedisk = IDEDisk::new(1, device); let _ = idedisk.write_sectors(1, 0x0, to_write.as_ptr() as u32); let _ = idedisk.read_sectors(1, 0x0, read_from.as_ptr() as u32); @@ -70,12 +64,11 @@ mod test { let to_write = vec!['D' as u8; 1024]; let read_from = vec![0x0 as u8; 1024]; - let device = IDE.lock().get_device(1).unwrap().clone(); - let mut idedisk = IDEDisk::new(1, device); + let device = IDE.lock().get_device(1).unwrap().clone(); + let mut idedisk = IDEDisk::new(1, device); let _ = idedisk.write_sectors(2, 0x0, to_write.as_ptr() as u32); let _ = idedisk.read_sectors(2, 0x0, read_from.as_ptr() as u32); assert_eq!(to_write, read_from); } } - diff --git a/srcs/fs/ext2/mod.rs b/srcs/fs/ext2/mod.rs index ed1cc738..1b3bc55d 100644 --- a/srcs/fs/ext2/mod.rs +++ b/srcs/fs/ext2/mod.rs @@ -1,9 +1,9 @@ use crate::alloc::vec; +use crate::disk::DiskIO; use crate::pci::ide::IDE; use crate::string::ToString; use crate::utils::math::roundup; use crate::utils::path::Path; -use crate::disk::DiskIO; use alloc::boxed::Box; mod bitmap; @@ -16,24 +16,20 @@ pub mod inode; /// This is pretty ineffective and will probably need optimisation in later version pub struct Ext2 { sector_size: usize, - diskio: Box, + diskio: Box, pub sblock: block::BaseSuperblock } impl Ext2 { pub fn new(mut diskio: Box) -> Result { - let sector_size = diskio.sector_size() as usize; - let sblock = read_superblock(&mut diskio)?; - let fs = Self { - sector_size, - diskio, - sblock - }; - if fs.is_valid() { - Ok(fs) - } else { - Err(0x01) - } + let sector_size = diskio.sector_size() as usize; + let sblock = read_superblock(&mut diskio)?; + let fs = Self { sector_size, diskio, sblock }; + if fs.is_valid() { + Ok(fs) + } else { + Err(0x01) + } } pub fn is_valid(&self) -> bool { @@ -109,11 +105,9 @@ impl Ext2 { let first_sector = (bsize * block_no as usize) / self.sector_size; let mut block: crate::vec::Vec = crate::vec::Vec::new(); for i in first_sector..first_sector + nb_sector { - self.diskio.read_sectors( - 1, - i as u32, - buffer.as_ptr() as u32 - ).expect("Something went wrong in read_block"); + self.diskio + .read_sectors(1, i as u32, buffer.as_ptr() as u32) + .expect("Something went wrong in read_block"); let mut start = 0; if sector_per_block < 1.0 { start = (block_no as usize % (1.0 / sector_per_block) as usize) @@ -131,11 +125,13 @@ impl Ext2 { let sector_per_block = bsize / self.sector_size as usize; let sector_no = bsize / self.sector_size as usize; - self.diskio.write_sectors( - sector_no as u8, - block_no * sector_per_block as u32, - block.as_ptr() as u32 - ).expect("Something went wrong in write block"); + self.diskio + .write_sectors( + sector_no as u8, + block_no * sector_per_block as u32, + block.as_ptr() as u32 + ) + .expect("Something went wrong in write block"); } fn write_slice(&mut self, block_no: u32, offset: usize, slice: &[u8]) { @@ -505,8 +501,10 @@ impl Ext2 { use crate::pci::ide; -pub fn read_superblock(diskio: &mut Box) -> Result { - let sector_size = diskio.sector_size(); +pub fn read_superblock( + diskio: &mut Box +) -> Result { + let sector_size = diskio.sector_size(); // superblock is at index 1024 and 1024 bytes long let mut nb_sector = roundup(2048 / sector_size, 1) as usize; // sector_size > 2048 @@ -515,11 +513,7 @@ pub fn read_superblock(diskio: &mut Box) -> Result = vec![0; nb_sector * sector_size]; - diskio.read_sectors( - nb_sector as u8, - 0, - buffer.as_ptr() as u32 - )?; + diskio.read_sectors(nb_sector as u8, 0, buffer.as_ptr() as u32)?; let mut sblock = block::BaseSuperblock::from(&buffer[1024..1024 + 84]); if sblock.version().0 >= 1 { sblock.set_extension(block::ExtendedSuperblock::from( @@ -529,11 +523,9 @@ pub fn read_superblock(diskio: &mut Box) -> Result bool { - Ext2::new(diskno as u8).is_ok_and(|fs| fs.is_valid()) -} -*/ +// pub fn is_ext2(diskno: u8) -> bool { +// Ext2::new(diskno as u8).is_ok_and(|fs| fs.is_valid()) +// } use crate::vec::Vec; @@ -546,7 +538,7 @@ fn get_block_content(block: Vec, size: usize) -> Vec { /// Does not yet check if found entry is really a file. /// Does not yet take into account file bigger than 4096 pub fn get_file_content(ext2: &Ext2, path: &str, inode: usize) -> Vec { - //let ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); + // let ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); let opt = ext2.recurs_find(path, inode); match opt { None => Vec::new(), @@ -649,7 +641,7 @@ pub fn list_dir( path: &str, inode: usize ) -> crate::vec::Vec { - //let ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); + // let ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); let inode = ext2.recurs_find(path, inode); return match inode { None => crate::vec::Vec::new(), @@ -673,7 +665,7 @@ pub fn list_dir( } pub fn create_file(ext2: &mut Ext2, path: &str, inode_no: usize) { - //let mut ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); + // let mut ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); let path = Path::new(path); let filename = path.file_name().unwrap(); let binding = path.parent().unwrap(); @@ -718,7 +710,7 @@ pub fn create_file(ext2: &mut Ext2, path: &str, inode_no: usize) { } pub fn remove_file(ext2: &mut Ext2, path: &str, inode_no: usize) { - //let mut ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); + // let mut ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); let path = Path::new(path); let filename = path.file_name().unwrap(); let binding = path.parent().unwrap(); @@ -746,7 +738,7 @@ pub fn remove_file(ext2: &mut Ext2, path: &str, inode_no: usize) { /// Helper function to create a folder at a given path pub fn create_dir(ext2: &mut Ext2, path: &str, inode_no: usize) { - //let mut ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); + // let mut ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); let path = Path::new(path); let new_dir = path.file_name().unwrap(); let binding = path.parent().unwrap(); @@ -819,7 +811,7 @@ pub fn create_dir(ext2: &mut Ext2, path: &str, inode_no: usize) { } pub fn show_inode_info(ext2: &Ext2, path: &str, inode_no: usize) { - //let ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); + // let ext2 = Ext2::new(diskno).expect("Disk is not a ext2 filesystem."); let inode = ext2.recurs_find(&path, inode_no); match inode { None => { diff --git a/srcs/kinit.rs b/srcs/kinit.rs index ac9eb0dd..75e34ccf 100644 --- a/srcs/kinit.rs +++ b/srcs/kinit.rs @@ -75,9 +75,9 @@ mod interrupts; mod multiboot; #[macro_use] mod syscalls; +mod disk; mod io; mod pci; -mod disk; mod pic; mod proc; mod time; diff --git a/srcs/kmain.rs b/srcs/kmain.rs index 585d1753..1f18d93e 100644 --- a/srcs/kmain.rs +++ b/srcs/kmain.rs @@ -33,19 +33,19 @@ mod poc { } use crate::cli::DISKNO; -use crate::fs::ext2; use crate::disk; +use crate::fs::ext2; #[no_mangle] pub extern "C" fn kmain() -> ! { - // Mounting first ext2 disk found to DISKNO - let disks = disk::discover(); - for i in disks { - if let Ok(ext) = ext2::Ext2::new(i) { - kprintln!("Found an ext2 fs"); - *DISKNO.lock() = Some(ext); - } - } + // Mounting first ext2 disk found to DISKNO + let disks = disk::discover(); + for i in disks { + if let Ok(ext) = ext2::Ext2::new(i) { + kprintln!("Found an ext2 fs"); + *DISKNO.lock() = Some(ext); + } + } kprintln!("Hello World of {}!", 42); change_color!(Color::Red, Color::White); diff --git a/srcs/pci/ide/ata.rs b/srcs/pci/ide/ata.rs index a9f22023..997150e8 100644 --- a/srcs/pci/ide/ata.rs +++ b/srcs/pci/ide/ata.rs @@ -108,13 +108,12 @@ impl ATA { numsects: u8, mut edi: u32 ) -> Result<(), u8> { - let binding = match &device.channel { - Some(x) => x, - None => return Err(0x1) - - }; - let bind = binding.lock(); - let mut channel = bind.borrow_mut(); + let binding = match &device.channel { + Some(x) => x, + None => return Err(0x1) + }; + let bind = binding.lock(); + let mut channel = bind.borrow_mut(); let lba_mode: u8; // 0: CHS, 1: LBA28, 2: LBA48 let dma: u8; // 0: No DMA, 1: DMA let mut lba_io: [u8; 6] = [0; 6]; @@ -173,17 +172,17 @@ impl ATA { dma = 0; // We don't support DMA // (III) Wait if the drive is busy - while (channel.read(ATAReg::STATUS) & ATAStatus::BSY) - != 0 - {} + while (channel.read(ATAReg::STATUS) & ATAStatus::BSY) != 0 {} // (IV) Select Drive from the controller if lba_mode == 0 { // Drive & CHS - channel.write(ATAReg::HDDEVSEL, 0xa0 | ((slavebit as u8) << 4) | head); + channel + .write(ATAReg::HDDEVSEL, 0xa0 | ((slavebit as u8) << 4) | head); } else { // Drive & LBA - channel.write(ATAReg::HDDEVSEL, 0xe0 | ((slavebit as u8) << 4) | head); + channel + .write(ATAReg::HDDEVSEL, 0xe0 | ((slavebit as u8) << 4) | head); } // (V) Write Parameters diff --git a/srcs/pci/ide/atapi.rs b/srcs/pci/ide/atapi.rs index 0292b7c8..4cdbfacb 100644 --- a/srcs/pci/ide/atapi.rs +++ b/srcs/pci/ide/atapi.rs @@ -21,13 +21,12 @@ pub struct ATAPI {} impl ATAPI { pub fn capacity(device: &mut IDEDevice, lba: u32) -> Result { - let binding = match &device.channel { - Some(x) => x, - None => return Err(0x1) - - }; - let bind = binding.lock(); - let mut channel = bind.borrow_mut(); + let binding = match &device.channel { + Some(x) => x, + None => return Err(0x1) + }; + let bind = binding.lock(); + let mut channel = bind.borrow_mut(); let slavebit: u32 = device.drive as u32; let bus: u32 = channel.base as u32; let mut buffer: [u32; 2] = [0; 2]; @@ -35,7 +34,7 @@ impl ATAPI { // Enable IRQs *IDE_IRQ_INVOKED.lock() = 0; channel.n_ien = 0; - let n_ien = channel.n_ien; + let n_ien = channel.n_ien; channel.write(ATAReg::CONTROL, n_ien); // (I) Setup SCSI Packet @@ -107,13 +106,12 @@ impl ATAPI { numsects: u8, mut edi: u32 ) -> Result<(), u8> { - let binding = match &device.channel { - Some(x) => x, - None => return Err(0x1) - - }; - let bind = binding.lock(); - let mut channel = bind.borrow_mut(); + let binding = match &device.channel { + Some(x) => x, + None => return Err(0x1) + }; + let bind = binding.lock(); + let mut channel = bind.borrow_mut(); let slavebit: u32 = device.drive as u32; let bus: u32 = channel.base as u32; // Sector Size @@ -193,13 +191,12 @@ impl ATAPI { } pub fn eject(device: &mut IDEDevice) -> Result<(), u8> { - let binding = match &device.channel { - Some(x) => x, - None => return Err(0x1) - - }; - let bind = binding.lock(); - let mut channel = bind.borrow_mut(); + let binding = match &device.channel { + Some(x) => x, + None => return Err(0x1) + }; + let bind = binding.lock(); + let mut channel = bind.borrow_mut(); let slavebit: u32 = device.drive as u32; let bus: u32 = channel.base as u32; diff --git a/srcs/pci/ide/channel.rs b/srcs/pci/ide/channel.rs index 59b0533c..8ec0c134 100644 --- a/srcs/pci/ide/channel.rs +++ b/srcs/pci/ide/channel.rs @@ -1,23 +1,28 @@ -use crate::io::{inb, insl, outb}; use super::ata::ATAChannel; -use super::ATAStatus; -use super::ATAReg; +use super::{ATAReg, ATAStatus}; +use crate::io::{inb, insl, outb}; #[derive(Clone, Copy)] pub struct IDEChannelRegisters { pub r#type: ATAChannel, // 0 - Primary Channel, 1 - Secondary Channel pub base: u16, // I/O Base - ctrl: u16, // ControlBase - bmide: u16, // Bus Master IDE + ctrl: u16, // ControlBase + bmide: u16, // Bus Master IDE pub n_ien: u8 // nIEN (No Interrupt) } impl IDEChannelRegisters { - pub const fn new(channel: ATAChannel, base: u16, ctrl: u16, bmide: u16, n_ien: u8) -> Self { - Self { r#type: channel, base, ctrl, bmide, n_ien} + pub const fn new( + channel: ATAChannel, + base: u16, + ctrl: u16, + bmide: u16, + n_ien: u8 + ) -> Self { + Self { r#type: channel, base, ctrl, bmide, n_ien } } - pub fn read(&mut self, reg: u8) -> u8 { + pub fn read(&mut self, reg: u8) -> u8 { let mut result: u8 = 0; if reg > 0x07 && reg < 0x0c { self.write(ATAReg::CONTROL, 0x80 | self.n_ien); @@ -37,17 +42,9 @@ impl IDEChannelRegisters { return result; } - pub fn read_buffer( - &mut self, - reg: u8, - buffer: &mut [u32], - quads: u32 - ) { + pub fn read_buffer(&mut self, reg: u8, buffer: &mut [u32], quads: u32) { if reg > 0x07 && reg < 0x0c { - self.write( - ATAReg::CONTROL, - 0x80 | self.n_ien - ); + self.write(ATAReg::CONTROL, 0x80 | self.n_ien); } if reg < 0x08 { insl(self.base + reg as u16 - 0x00, buffer.as_mut_ptr(), quads); @@ -63,9 +60,8 @@ impl IDEChannelRegisters { } } - - pub fn write(&mut self, reg: u8, data: u8) { - if reg > 0x07 && reg < 0x0c { + pub fn write(&mut self, reg: u8, data: u8) { + if reg > 0x07 && reg < 0x0c { self.write(ATAReg::CONTROL, 0x80 | self.n_ien); } if reg < 0x08 { @@ -80,17 +76,16 @@ impl IDEChannelRegisters { if reg > 0x07 && reg < 0x0c { self.write(ATAReg::CONTROL, self.n_ien); } - } - + } - pub fn polling(&mut self, advanced_check: u32) -> Result<(), u8> { + pub fn polling(&mut self, advanced_check: u32) -> Result<(), u8> { for _ in 0..4 { self.read(ATAReg::ALTSTATUS); } // (II) Wait for BSY to be cleared - while (self.read(ATAReg::STATUS) & ATAStatus::BSY as u8) != 0 - { /* Wait for BSY to be zero */ } + while (self.read(ATAReg::STATUS) & ATAStatus::BSY as u8) != 0 { // Wait for BSY to be zero + } if advanced_check != 0 { // Read Status Register @@ -114,6 +109,5 @@ impl IDEChannelRegisters { } // No Error Ok(()) - } - + } } diff --git a/srcs/pci/ide/device.rs b/srcs/pci/ide/device.rs index 9e06fefb..2be30345 100644 --- a/srcs/pci/ide/device.rs +++ b/srcs/pci/ide/device.rs @@ -1,28 +1,22 @@ -use crate::utils::arcm::Arcm; -pub use super::channel::IDEChannelRegisters; -use crate::kprintln; -use core::ffi::CStr; -use super::ata::{ - ATAError, - ATADirection, - ATAReg, - ATA -}; +use super::ata::{ATADirection, ATAError, ATAReg, ATA}; use super::atapi::{self, ATAPI}; +pub use super::channel::IDEChannelRegisters; use super::IDEType; +use crate::kprintln; +use crate::utils::arcm::Arcm; use core::cell::RefCell; - +use core::ffi::CStr; #[derive(Clone)] pub struct IDEDevice { pub reserved: u8, // 0 (Empty) or 1 (This Drive really exists) pub channel: Option>>, - pub drive: u8, // 0 (Master Drive) or 1 (Slave Drive) - pub r#type: u16, // 0: ATA, 1:ATAPI - pub signature: u16, // Drive Signature - pub capabilities: u16, // Features - pub command_sets: u32, // Command Sets Supported - pub size: u32, // Size in Sectors + pub drive: u8, // 0 (Master Drive) or 1 (Slave Drive) + pub r#type: u16, // 0: ATA, 1:ATAPI + pub signature: u16, // Drive Signature + pub capabilities: u16, // Features + pub command_sets: u32, // Command Sets Supported + pub size: u32, // Size in Sectors pub model: [u8; 41] // Model in string } @@ -42,7 +36,6 @@ impl IDEDevice { } pub fn print_error(&self, mut err: u8) -> u8 { - if err == 0 { return err; } @@ -54,7 +47,7 @@ impl IDEDevice { return 23; } }; - let bind = binding.lock(); + let bind = binding.lock(); let channel: &mut IDEChannelRegisters = &mut bind.borrow_mut(); match err { 1 => { @@ -125,7 +118,6 @@ impl IDEDevice { lba: u32, edi: u32 ) -> Result<(), u8> { - // 1- Check if the drive presents if self.reserved == 0 { // Drive not found @@ -178,7 +170,6 @@ impl IDEDevice { lba: u32, edi: u32 ) -> Result<(), u8> { - // 1- Check if the drive presents if self.reserved == 0 { // Drive not found @@ -208,9 +199,4 @@ impl IDEDevice { } Ok(()) } - - - } - - diff --git a/srcs/pci/ide/mod.rs b/srcs/pci/ide/mod.rs index 85547b80..09fbf1a1 100644 --- a/srcs/pci/ide/mod.rs +++ b/srcs/pci/ide/mod.rs @@ -1,16 +1,16 @@ use core::ffi::CStr; use core::mem::size_of; -use core::cell::RefCell; use crate::kprintln; use crate::spin::{KMutex, Mutex}; use crate::time::sleep; use crate::utils::arcm::Arcm; +use core::cell::RefCell; pub mod ata; pub mod atapi; -pub mod device; pub mod channel; +pub mod device; use ata::{ ATAChannel, @@ -22,8 +22,8 @@ use ata::{ ATA }; use atapi::ATAPI; -pub use device::IDEDevice; use channel::IDEChannelRegisters; +pub use device::IDEDevice; static IDE_IRQ_INVOKED: KMutex = KMutex::::new(0); pub static IDE: Mutex = @@ -39,7 +39,7 @@ pub struct IDEController { } impl IDEController { - /// Create a controller with default devices + /// Create a controller with default devices pub const fn new() -> Self { Self { devices: [ @@ -51,11 +51,11 @@ impl IDEController { } } - /// Obtain reference to an existing device. - /// - /// Actually return a reference to the device and should be clone afterward - /// However if the reference is never needed this function will probably - /// be change to return a clone of the device instead + /// Obtain reference to an existing device. + /// + /// Actually return a reference to the device and should be clone afterward + /// However if the reference is never needed this function will probably + /// be change to return a clone of the device instead pub fn get_device(&self, num: u8) -> Option<&IDEDevice> { if num > 3 || self.devices[num as usize].reserved == 0 { return None; @@ -73,32 +73,33 @@ impl IDEController { ) -> Result<(), u8> { let mut ide_buf: [u8; 2048] = [0; 2048]; - let primary = IDEChannelRegisters::new( - ATAChannel::Primary, - (bar0 & 0xfffffffc) as u16, - (bar1 & 0xfffffffc) as u16, - ((bar4 & 0xfffffffc) + 0) as u16, - 0 - ); - let secondary = IDEChannelRegisters::new( - ATAChannel::Secondary, - (bar2 & 0xfffffffc) as u16, - (bar3 & 0xfffffffc) as u16, - ((bar4 & 0xfffffffc) + 8) as u16, - 0 - ); + let primary = IDEChannelRegisters::new( + ATAChannel::Primary, + (bar0 & 0xfffffffc) as u16, + (bar1 & 0xfffffffc) as u16, + ((bar4 & 0xfffffffc) + 0) as u16, + 0 + ); + let secondary = IDEChannelRegisters::new( + ATAChannel::Secondary, + (bar2 & 0xfffffffc) as u16, + (bar3 & 0xfffffffc) as u16, + ((bar4 & 0xfffffffc) + 8) as u16, + 0 + ); let mut channels: [Arcm>; 2] = [ Arcm::new(RefCell::new(primary)), Arcm::new(RefCell::new(secondary)) ]; // 2- Disable IRQs - channels[ATAChannel::Primary as usize].lock().borrow_mut().write( - ATAReg::CONTROL, - 2); - channels[ATAChannel::Secondary as usize].lock().borrow_mut().write( - ATAReg::CONTROL, - 2 - ); + channels[ATAChannel::Primary as usize] + .lock() + .borrow_mut() + .write(ATAReg::CONTROL, 2); + channels[ATAChannel::Secondary as usize] + .lock() + .borrow_mut() + .write(ATAReg::CONTROL, 2); let mut count: usize = 0; // 3- Detect ATA-ATAPI Devices @@ -107,14 +108,17 @@ impl IDEController { let mut err: u8 = 0; let mut r#type: u8 = IDEType::ATA as u8; // (I) Select Drive - channels[i].lock().borrow_mut().write(ATAReg::HDDEVSEL, 0xa0 | (j << 4)); + channels[i] + .lock() + .borrow_mut() + .write(ATAReg::HDDEVSEL, 0xa0 | (j << 4)); sleep(1); // (II) Send ATA Identify Command - channels[i].lock().borrow_mut().write( - ATAReg::COMMAND, - ATACommand::Identify as u8 - ); + channels[i] + .lock() + .borrow_mut() + .write(ATAReg::COMMAND, ATACommand::Identify as u8); sleep(1); // (III) Polling @@ -124,7 +128,8 @@ impl IDEController { } loop { - let status: u8 = channels[i].lock().borrow_mut().read(ATAReg::STATUS); + let status: u8 = + channels[i].lock().borrow_mut().read(ATAReg::STATUS); if (status & ATAStatus::ERR) != 0 { err = 1; break; @@ -138,8 +143,10 @@ impl IDEController { // (IV) Probe for ATAPI Devices if err != 0 { - let cl: u8 = channels[i].lock().borrow_mut().read(ATAReg::LBA1); - let ch: u8 = channels[i].lock().borrow_mut().read(ATAReg::LBA2); + let cl: u8 = + channels[i].lock().borrow_mut().read(ATAReg::LBA1); + let ch: u8 = + channels[i].lock().borrow_mut().read(ATAReg::LBA2); if cl == 0x14 && ch == 0xeb { r#type = IDEType::ATAPI as u8; @@ -257,12 +264,12 @@ impl IDEController { } fn read(channel: &mut IDEChannelRegisters, reg: u8) -> u8 { - channel.read(reg) - } + channel.read(reg) + } fn write(channel: &mut IDEChannelRegisters, reg: u8, data: u8) { - channel.write(reg, data); - } + channel.write(reg, data); + } fn read_buffer( channel: &mut IDEChannelRegisters, @@ -270,14 +277,14 @@ impl IDEController { buffer: &mut [u32], quads: u32 ) { - channel.read_buffer(reg, buffer, quads); + channel.read_buffer(reg, buffer, quads); } fn polling( channel: &mut IDEChannelRegisters, advanced_check: u32 ) -> Result<(), u8> { - channel.polling(advanced_check) + channel.polling(advanced_check) } /// Read sector from a drive @@ -394,7 +401,7 @@ mod test { let to_write = vec!['B' as u8; 512]; let read_from = vec![0x0 as u8; 512]; - let mut device = IDE.lock().get_device(1).unwrap().clone(); + let mut device = IDE.lock().get_device(1).unwrap().clone(); let _ = device.write_sectors(1, 0x0, to_write.as_ptr() as u32); let _ = device.read_sectors(1, 0x0, read_from.as_ptr() as u32); @@ -406,7 +413,7 @@ mod test { let to_write = vec!['A' as u8; 1024]; let read_from = vec![0x0 as u8; 1024]; - let mut device = IDE.lock().get_device(1).unwrap().clone(); + let mut device = IDE.lock().get_device(1).unwrap().clone(); let _ = device.write_sectors(2, 0x0, to_write.as_ptr() as u32); let _ = device.read_sectors(2, 0x0, read_from.as_ptr() as u32); From 67d682f507a82ad6830620f7bd1e8b0742ff8c0f Mon Sep 17 00:00:00 2001 From: Harthann Date: Thu, 16 Nov 2023 11:23:48 +0100 Subject: [PATCH 09/10] Moving sector size verification intot ide device instead --- srcs/disk/ide.rs | 14 ++------------ srcs/pci/ide/device.rs | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/srcs/disk/ide.rs b/srcs/disk/ide.rs index c43c6aa5..0d0308a1 100644 --- a/srcs/disk/ide.rs +++ b/srcs/disk/ide.rs @@ -1,5 +1,5 @@ use super::DiskIO; -use crate::pci::ide::{self, IDEDevice}; +use crate::pci::ide::IDEDevice; pub struct IDEDisk { diskno: u8, @@ -29,16 +29,6 @@ impl DiskIO for IDEDisk { } fn sector_size(&self) -> usize { - match self.device.r#type { - x if x == ide::IDEType::ATA as u16 => { - ide::ata::SECTOR_SIZE as usize - }, - x if x == ide::IDEType::ATAPI as u16 => { - ide::atapi::SECTOR_SIZE as usize - }, - _ => { - panic!("Unrecognized disk.") - } - } + self.device.sector_size() as usize } } diff --git a/srcs/pci/ide/device.rs b/srcs/pci/ide/device.rs index 2be30345..e1e3fe8e 100644 --- a/srcs/pci/ide/device.rs +++ b/srcs/pci/ide/device.rs @@ -1,4 +1,4 @@ -use super::ata::{ATADirection, ATAError, ATAReg, ATA}; +use super::ata::{self, ATADirection, ATAError, ATAReg, ATA}; use super::atapi::{self, ATAPI}; pub use super::channel::IDEChannelRegisters; use super::IDEType; @@ -199,4 +199,21 @@ impl IDEDevice { } Ok(()) } + + pub fn sector_size(&self) -> u32 { + match self.r#type { + x if x == IDEType::ATA as u16 => { + ata::SECTOR_SIZE + }, + x if x == IDEType::ATAPI as u16 => { + atapi::SECTOR_SIZE + }, + _ => { + panic!("Unrecognized disk.") + } + } + } + + + } From 11478bad47823fbda286d0f36d476c5f1242e4d0 Mon Sep 17 00:00:00 2001 From: Harthann Date: Thu, 16 Nov 2023 11:25:36 +0100 Subject: [PATCH 10/10] Formatting --- srcs/disk/ide.rs | 2 +- srcs/pci/ide/device.rs | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/srcs/disk/ide.rs b/srcs/disk/ide.rs index 0d0308a1..aba8bafa 100644 --- a/srcs/disk/ide.rs +++ b/srcs/disk/ide.rs @@ -29,6 +29,6 @@ impl DiskIO for IDEDisk { } fn sector_size(&self) -> usize { - self.device.sector_size() as usize + self.device.sector_size() as usize } } diff --git a/srcs/pci/ide/device.rs b/srcs/pci/ide/device.rs index e1e3fe8e..c54be2cf 100644 --- a/srcs/pci/ide/device.rs +++ b/srcs/pci/ide/device.rs @@ -202,18 +202,11 @@ impl IDEDevice { pub fn sector_size(&self) -> u32 { match self.r#type { - x if x == IDEType::ATA as u16 => { - ata::SECTOR_SIZE - }, - x if x == IDEType::ATAPI as u16 => { - atapi::SECTOR_SIZE - }, + x if x == IDEType::ATA as u16 => ata::SECTOR_SIZE, + x if x == IDEType::ATAPI as u16 => atapi::SECTOR_SIZE, _ => { panic!("Unrecognized disk.") } } } - - - }