IDE: clean everything up

master
TheOddGarlic 2022-08-17 13:25:53 +03:00
parent 775ded8e23
commit 21de068685
3 changed files with 61 additions and 45 deletions

View File

@ -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;

View File

@ -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<Vec<u8>, 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,
}

View File

@ -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();
}