forked from koniifer/ableos
IDE device discovery
This commit is contained in:
parent
012452dec1
commit
ca3826bfe5
|
@ -6,6 +6,7 @@
|
|||
|
||||
use core::num::TryFromIntError;
|
||||
|
||||
use x86_64::instructions::interrupts;
|
||||
use x86_64::structures::paging::{FrameAllocator, FrameDeallocator};
|
||||
// FIXME: platform agnostic paging stuff
|
||||
use x86_64::structures::paging::{mapper::MapToError, Mapper, Page, PhysFrame, Size4KiB};
|
||||
|
@ -34,6 +35,9 @@ const PRIMARY_COMMAND: u16 = 0x01F0;
|
|||
/// Secondary command block offset
|
||||
const SECONDARY_COMMAND: u16 = 0x0170;
|
||||
|
||||
/// Data register offset
|
||||
const DATA_OFFSET: u16 = 0;
|
||||
|
||||
/// Drive/Head register offset
|
||||
const DRIVE_HEAD_OFFSET: u16 = 6;
|
||||
|
||||
|
@ -80,6 +84,7 @@ impl Piix {
|
|||
|
||||
unsafe {
|
||||
select_drive(drive, channel);
|
||||
// FIXME: clear sector count and lba0, lba1, lba2 registers
|
||||
let status = ata_send_command(CMD_IDENTIFY, channel);
|
||||
if status == 0 {
|
||||
continue; // If status = 0, no device
|
||||
|
@ -105,6 +110,49 @@ impl Piix {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Read identification space of device
|
||||
let addr = if channel.secondary() {
|
||||
SECONDARY_COMMAND
|
||||
} else {
|
||||
PRIMARY_COMMAND
|
||||
} + DATA_OFFSET;
|
||||
let mut buffer = [0_u8; 512];
|
||||
read_dword_buffer(addr, buffer.as_mut_ptr() as *mut _, 128);
|
||||
// for (i, byte) in buffer.iter().enumerate() {
|
||||
// if byte.is_ascii() {
|
||||
// trace!("byte {i}: {byte:b}, ascii: {}", *byte as char);
|
||||
// } else {
|
||||
// trace!("byte {i}: {byte:b}");
|
||||
// }
|
||||
// }
|
||||
|
||||
if buffer[99] & 1 != 1 {
|
||||
// FIXME: PIO mode support
|
||||
error!("IDE drive {channel:?}/{drive:?} does not support DMA");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buffer[167] >> 2) & 1 != 1 {
|
||||
// FIXME: 24-bit LBA and CHS support
|
||||
error!("IDE drive {channel:?}/{drive:?} does not support 48-bit LBA");
|
||||
}
|
||||
|
||||
let size = buffer[200] as u64
|
||||
| (buffer[201] as u64) << 8
|
||||
| (buffer[202] as u64) << 16
|
||||
| (buffer[203] as u64) << 24
|
||||
| (buffer[204] as u64) << 32
|
||||
| (buffer[205] as u64) << 40
|
||||
| (buffer[206] as u64) << 48
|
||||
| (buffer[207] as u64) << 54;
|
||||
trace!("IDE drive {channel:?}/{drive:?} has {size} sectors");
|
||||
|
||||
ide_devices.push(IdeDevice {
|
||||
channel,
|
||||
drive,
|
||||
size,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -332,13 +380,24 @@ unsafe fn ata_delay(channel: Channel) {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe fn read_dword_buffer(port: u16, buffer: *mut u32, mut count: u32) {
|
||||
// FIXME: this assumes x86-64
|
||||
interrupts::without_interrupts(|| {
|
||||
asm!("
|
||||
cld
|
||||
repne
|
||||
insd",
|
||||
in("di") buffer,
|
||||
in("dx") port,
|
||||
inout("cx") count,
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
struct IdeDevice {
|
||||
pub channel: Channel,
|
||||
pub drive: Drive,
|
||||
pub signature: u16,
|
||||
pub capabilities: u16,
|
||||
pub command_sets: u32,
|
||||
pub size: u64,
|
||||
pub size: u64, // in sectors
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
|
Loading…
Reference in a new issue