⚠️ VeridianOS Kernel Documentation - This is low-level kernel code. All functions are unsafe unless explicitly marked otherwise. no_std

veridian_kernel/drivers/
storage.rs

1//! Storage Device Drivers
2//!
3//! Implements storage drivers including ATA/IDE, AHCI/SATA, and NVMe.
4
5use alloc::{boxed::Box, string::String, vec, vec::Vec};
6
7use spin::Mutex;
8
9use crate::{
10    error::KernelError,
11    services::driver_framework::{DeviceClass, DeviceInfo, DeviceStatus, Driver},
12    sync::once_lock::OnceLock,
13};
14
15/// Storage device types
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17pub enum StorageType {
18    HardDisk,
19    SolidState,
20    OpticalDisk,
21    FloppyDisk,
22    Unknown,
23}
24
25/// Storage interface types
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub enum StorageInterface {
28    ATA,  // IDE/PATA
29    SATA, // Serial ATA
30    SCSI, // Small Computer System Interface
31    NVMe, // NVM Express
32    USB,  // USB Mass Storage
33    Unknown,
34}
35
36/// Storage device information
37#[derive(Debug, Clone)]
38pub struct StorageInfo {
39    pub model: String,
40    pub serial: String,
41    pub firmware: String,
42    pub capacity: u64,    // in bytes
43    pub sector_size: u32, // in bytes
44    pub storage_type: StorageType,
45    pub interface: StorageInterface,
46    pub removable: bool,
47    pub read_only: bool,
48}
49
50/// Storage device statistics
51#[derive(Debug, Clone, Default)]
52pub struct StorageStats {
53    pub reads: u64,
54    pub writes: u64,
55    pub bytes_read: u64,
56    pub bytes_written: u64,
57    pub read_errors: u64,
58    pub write_errors: u64,
59    pub read_time_ms: u64,
60    pub write_time_ms: u64,
61}
62
63/// Storage device trait
64pub trait StorageDevice: Send + Sync {
65    /// Get device name
66    fn name(&self) -> &str;
67
68    /// Get device information
69    fn get_info(&self) -> StorageInfo;
70
71    /// Get device statistics
72    fn get_stats(&self) -> StorageStats;
73
74    /// Reset statistics
75    fn reset_stats(&mut self);
76
77    /// Read sectors
78    fn read_sectors(&mut self, lba: u64, count: u32, buffer: &mut [u8])
79        -> Result<u32, KernelError>;
80
81    /// Write sectors
82    fn write_sectors(&mut self, lba: u64, count: u32, data: &[u8]) -> Result<u32, KernelError>;
83
84    /// Flush cache
85    fn flush(&mut self) -> Result<(), KernelError>;
86
87    /// Check if device is ready
88    fn is_ready(&self) -> bool;
89
90    /// Get maximum transfer size in sectors
91    fn max_transfer_sectors(&self) -> u32;
92}
93
94/// ATA (IDE) driver implementation
95#[allow(dead_code)] // Future-phase driver stub
96pub struct AtaDriver {
97    name: String,
98    base_port: u16,
99    control_port: u16,
100    is_master: bool,
101    info: StorageInfo,
102    stats: Mutex<StorageStats>,
103    device_info: DeviceInfo,
104}
105
106impl AtaDriver {
107    /// Create a new ATA driver
108    pub fn new(name: String, base_port: u16, is_master: bool, device_info: DeviceInfo) -> Self {
109        let control_port = base_port + 0x206;
110
111        Self {
112            name: name.clone(),
113            base_port,
114            control_port,
115            is_master,
116            info: StorageInfo {
117                model: String::from("ATA Drive"),
118                serial: String::from("Unknown"),
119                firmware: String::from("Unknown"),
120                capacity: 0,
121                sector_size: 512,
122                storage_type: StorageType::HardDisk,
123                interface: StorageInterface::ATA,
124                removable: false,
125                read_only: false,
126            },
127            stats: Mutex::new(StorageStats::default()),
128            device_info,
129        }
130    }
131
132    /// Initialize ATA device
133    pub fn init(&mut self) -> Result<(), KernelError> {
134        crate::println!(
135            "[ATA] Initializing {} at port 0x{:x}",
136            self.name,
137            self.base_port
138        );
139
140        // Select drive
141        let drive_select = if self.is_master { 0xA0 } else { 0xB0 };
142        self.write_register(6, drive_select);
143        self.wait_busy()?;
144
145        // Send IDENTIFY command
146        self.write_register(7, 0xEC);
147        self.wait_busy()?;
148
149        // Check if device exists
150        let status = self.read_register(7);
151        if status == 0 {
152            return Err(KernelError::HardwareError {
153                device: "ata",
154                code: 0,
155            });
156        }
157
158        // Read identification data
159        let mut identify_data = [0u16; 256];
160        for item in &mut identify_data {
161            *item = self.read_data();
162        }
163
164        // Parse identification data
165        self.parse_identify_data(&identify_data);
166
167        crate::println!(
168            "[ATA] Initialized {}: {} ({} sectors)",
169            self.name,
170            self.info.model,
171            self.info.capacity / self.info.sector_size as u64
172        );
173
174        Ok(())
175    }
176
177    /// Parse IDENTIFY data
178    #[allow(clippy::needless_range_loop)]
179    fn parse_identify_data(&mut self, data: &[u16; 256]) {
180        // Model string (words 27-46)
181        let mut model = String::new();
182        for word in data.iter().take(47).skip(27) {
183            let bytes = [(word >> 8) as u8, *word as u8];
184            for &byte in &bytes {
185                if byte != 0 && byte != b' ' {
186                    model.push(byte as char);
187                }
188            }
189        }
190        self.info.model = model.trim().into();
191
192        // Serial number (words 10-19)
193        let mut serial = String::new();
194        for word in data.iter().take(20).skip(10) {
195            let bytes = [(word >> 8) as u8, *word as u8];
196            for &byte in &bytes {
197                if byte != 0 && byte != b' ' {
198                    serial.push(byte as char);
199                }
200            }
201        }
202        self.info.serial = serial.trim().into();
203
204        // Capacity (words 60-61 for 28-bit LBA)
205        let capacity_sectors = data[60] as u64 | ((data[61] as u64) << 16);
206        self.info.capacity = capacity_sectors * self.info.sector_size as u64;
207
208        // Check for 48-bit LBA support
209        if data[83] & (1 << 10) != 0 {
210            let capacity_48 = data[100] as u64
211                | ((data[101] as u64) << 16)
212                | ((data[102] as u64) << 32)
213                | ((data[103] as u64) << 48);
214            if capacity_48 > capacity_sectors {
215                self.info.capacity = capacity_48 * self.info.sector_size as u64;
216            }
217        }
218    }
219
220    /// Read ATA register
221    fn read_register(&self, offset: u8) -> u8 {
222        // SAFETY: Reading an ATA register via I/O port at base_port + offset. The base
223        // port (e.g. 0x1F0 for primary IDE) is a standard x86 I/O port for ATA devices.
224        // We are in kernel mode with full I/O privilege.
225        unsafe { crate::arch::inb(self.base_port + offset as u16) }
226    }
227
228    /// Write ATA register
229    fn write_register(&self, offset: u8, value: u8) {
230        // SAFETY: Writing an ATA register. Same invariants as read_register.
231        unsafe {
232            crate::arch::outb(self.base_port + offset as u16, value);
233        }
234    }
235
236    /// Read data port
237    fn read_data(&self) -> u16 {
238        // SAFETY: Reading the 16-bit ATA data port at base_port. This is the standard
239        // mechanism for reading sector data from an ATA drive.
240        unsafe { crate::arch::inw(self.base_port) }
241    }
242
243    /// Write data port
244    fn write_data(&self, value: u16) {
245        // SAFETY: Writing the 16-bit ATA data port. Same invariants as read_data.
246        unsafe {
247            crate::arch::outw(self.base_port, value);
248        }
249    }
250
251    /// Wait for device to not be busy
252    fn wait_busy(&self) -> Result<(), KernelError> {
253        for _ in 0..10000 {
254            let status = self.read_register(7);
255            if status & 0x80 == 0 {
256                // BSY bit clear
257                return Ok(());
258            }
259            // Small delay
260            for _ in 0..100 {
261                core::hint::spin_loop();
262            }
263        }
264        Err(KernelError::Timeout {
265            operation: "ata wait busy",
266            duration_ms: 0,
267        })
268    }
269
270    /// Wait for device ready
271    fn wait_ready(&self) -> Result<(), KernelError> {
272        for _ in 0..10000 {
273            let status = self.read_register(7);
274            if status & 0x80 == 0 && status & 0x40 != 0 {
275                // BSY clear, RDY set
276                return Ok(());
277            }
278            // Small delay
279            for _ in 0..100 {
280                core::hint::spin_loop();
281            }
282        }
283        Err(KernelError::Timeout {
284            operation: "ata wait ready",
285            duration_ms: 0,
286        })
287    }
288
289    /// Select drive and set LBA
290    fn select_drive_lba(&self, lba: u64) -> Result<(), KernelError> {
291        let drive_select = if self.is_master { 0xE0 } else { 0xF0 };
292
293        // LBA mode, drive select
294        self.write_register(6, drive_select | ((lba >> 24) & 0x0F) as u8);
295        self.write_register(2, 1); // Sector count
296        self.write_register(3, lba as u8); // LBA 0-7
297        self.write_register(4, (lba >> 8) as u8); // LBA 8-15
298        self.write_register(5, (lba >> 16) as u8); // LBA 16-23
299
300        self.wait_ready()
301    }
302}
303
304impl StorageDevice for AtaDriver {
305    fn name(&self) -> &str {
306        &self.name
307    }
308
309    fn get_info(&self) -> StorageInfo {
310        self.info.clone()
311    }
312
313    fn get_stats(&self) -> StorageStats {
314        self.stats.lock().clone()
315    }
316
317    fn reset_stats(&mut self) {
318        *self.stats.lock() = StorageStats::default();
319    }
320
321    fn read_sectors(
322        &mut self,
323        lba: u64,
324        count: u32,
325        buffer: &mut [u8],
326    ) -> Result<u32, KernelError> {
327        if buffer.len() < (count * self.info.sector_size) as usize {
328            return Err(KernelError::InvalidArgument {
329                name: "buffer",
330                value: "too small for requested sector count",
331            });
332        }
333
334        let mut sectors_read = 0;
335        let mut current_lba = lba;
336        let mut buffer_offset = 0;
337
338        while sectors_read < count {
339            // Read one sector at a time for simplicity
340            self.select_drive_lba(current_lba)?;
341
342            // Send READ SECTORS command
343            self.write_register(7, 0x20);
344            self.wait_ready()?;
345
346            // Read sector data
347            for i in 0..256 {
348                // 512 bytes = 256 words
349                let word = self.read_data();
350                buffer[buffer_offset + i * 2] = word as u8;
351                buffer[buffer_offset + i * 2 + 1] = (word >> 8) as u8;
352            }
353
354            sectors_read += 1;
355            current_lba += 1;
356            buffer_offset += self.info.sector_size as usize;
357
358            // Update statistics
359            let mut stats = self.stats.lock();
360            stats.reads += 1;
361            stats.bytes_read += self.info.sector_size as u64;
362        }
363
364        Ok(sectors_read)
365    }
366
367    fn write_sectors(&mut self, lba: u64, count: u32, data: &[u8]) -> Result<u32, KernelError> {
368        if data.len() < (count * self.info.sector_size) as usize {
369            return Err(KernelError::InvalidArgument {
370                name: "data",
371                value: "too small for requested sector count",
372            });
373        }
374
375        if self.info.read_only {
376            return Err(KernelError::PermissionDenied {
377                operation: "write to read-only device",
378            });
379        }
380
381        let mut sectors_written = 0;
382        let mut current_lba = lba;
383        let mut data_offset = 0;
384
385        while sectors_written < count {
386            // Write one sector at a time
387            self.select_drive_lba(current_lba)?;
388
389            // Send WRITE SECTORS command
390            self.write_register(7, 0x30);
391            self.wait_ready()?;
392
393            // Write sector data
394            for i in 0..256 {
395                // 512 bytes = 256 words
396                let word = data[data_offset + i * 2] as u16
397                    | ((data[data_offset + i * 2 + 1] as u16) << 8);
398                self.write_data(word);
399            }
400
401            // Wait for completion
402            self.wait_ready()?;
403
404            sectors_written += 1;
405            current_lba += 1;
406            data_offset += self.info.sector_size as usize;
407
408            // Update statistics
409            let mut stats = self.stats.lock();
410            stats.writes += 1;
411            stats.bytes_written += self.info.sector_size as u64;
412        }
413
414        Ok(sectors_written)
415    }
416
417    fn flush(&mut self) -> Result<(), KernelError> {
418        // Send FLUSH CACHE command
419        self.write_register(7, 0xE7);
420        self.wait_ready()
421    }
422
423    fn is_ready(&self) -> bool {
424        let status = self.read_register(7);
425        status & 0x80 == 0 && status & 0x40 != 0 // BSY clear, RDY set
426    }
427
428    fn max_transfer_sectors(&self) -> u32 {
429        256 // ATA can transfer up to 256 sectors per command
430    }
431}
432
433impl Driver for AtaDriver {
434    fn name(&self) -> &str {
435        "ata"
436    }
437
438    fn supported_classes(&self) -> Vec<DeviceClass> {
439        vec![DeviceClass::Storage]
440    }
441
442    fn supports_device(&self, device: &DeviceInfo) -> bool {
443        device.class == DeviceClass::Storage
444            && device.bus == "pci"
445            && device.device_id.as_ref().is_some_and(|id| {
446                // Check for IDE/ATA controller class codes
447                id.class_code == 0x01 && // Mass storage
448            (id.subclass == 0x01 || id.subclass == 0x05) // IDE or ATA
449            })
450    }
451
452    fn probe(&mut self, _device: &DeviceInfo) -> Result<(), KernelError> {
453        crate::println!("[ATA] Probing device: {}", _device.name);
454
455        // Try to initialize the ATA device
456        self.init()
457    }
458
459    fn attach(&mut self, _device: &DeviceInfo) -> Result<(), KernelError> {
460        crate::println!("[ATA] Attaching to device: {}", _device.name);
461
462        // Device should already be initialized from probe
463        crate::println!("[ATA] Successfully attached to {}", _device.name);
464        Ok(())
465    }
466
467    fn detach(&mut self, _device: &DeviceInfo) -> Result<(), KernelError> {
468        crate::println!("[ATA] Detaching from device: {}", _device.name);
469
470        // Flush any pending writes
471        self.flush().ok();
472
473        crate::println!("[ATA] Successfully detached from {}", _device.name);
474        Ok(())
475    }
476
477    fn suspend(&mut self) -> Result<(), KernelError> {
478        // Flush cache and put device in standby
479        self.flush()?;
480
481        // Send STANDBY command
482        self.write_register(7, 0xE2);
483        self.wait_ready()?;
484
485        crate::println!("[ATA] Device suspended");
486        Ok(())
487    }
488
489    fn resume(&mut self) -> Result<(), KernelError> {
490        // Device should wake up automatically on next access
491        self.wait_ready()?;
492        crate::println!("[ATA] Device resumed");
493        Ok(())
494    }
495
496    fn handle_interrupt(&mut self, _irq: u8) -> Result<(), KernelError> {
497        crate::println!("[ATA] Handling interrupt {} for {}", _irq, self.name);
498
499        // Read status to clear interrupt
500        let status = self.read_register(7);
501
502        // Check for errors
503        if status & 0x01 != 0 {
504            // ERR bit set
505            let _error = self.read_register(1);
506            crate::println!("[ATA] Error detected: 0x{:02x}", _error);
507            return Err(KernelError::HardwareError {
508                device: "ata",
509                code: _error as u32,
510            });
511        }
512
513        Ok(())
514    }
515
516    fn read(&mut self, offset: u64, buffer: &mut [u8]) -> Result<usize, KernelError> {
517        // Convert byte offset to sector
518        let sector_size = self.info.sector_size as u64;
519        let lba = offset / sector_size;
520        let sector_offset = (offset % sector_size) as usize;
521
522        // Calculate number of sectors to read
523        let bytes_needed = buffer.len() + sector_offset;
524        let sectors_needed = bytes_needed.div_ceil(sector_size as usize);
525
526        // Allocate temporary buffer for sector-aligned reads
527        let mut sector_buffer = vec![0u8; sectors_needed * sector_size as usize];
528
529        // Read sectors
530        let _sectors_read = self.read_sectors(lba, sectors_needed as u32, &mut sector_buffer)?;
531
532        // Copy requested data
533        let copy_len = buffer.len().min(sector_buffer.len() - sector_offset);
534        buffer[..copy_len].copy_from_slice(&sector_buffer[sector_offset..sector_offset + copy_len]);
535
536        Ok(copy_len)
537    }
538
539    fn write(&mut self, offset: u64, data: &[u8]) -> Result<usize, KernelError> {
540        // Convert byte offset to sector
541        let sector_size = self.info.sector_size as u64;
542        let lba = offset / sector_size;
543        let sector_offset = (offset % sector_size) as usize;
544
545        // For simplicity, require sector-aligned writes
546        if sector_offset != 0 {
547            return Err(KernelError::InvalidArgument {
548                name: "offset",
549                value: "must be sector-aligned",
550            });
551        }
552
553        if !data.len().is_multiple_of(sector_size as usize) {
554            return Err(KernelError::InvalidArgument {
555                name: "data length",
556                value: "must be multiple of sector size",
557            });
558        }
559
560        let sectors_to_write = data.len() / sector_size as usize;
561        let sectors_written = self.write_sectors(lba, sectors_to_write as u32, data)?;
562
563        Ok(sectors_written as usize * sector_size as usize)
564    }
565
566    fn ioctl(&mut self, cmd: u32, _arg: u64) -> Result<u64, KernelError> {
567        match cmd {
568            0x3000 => {
569                // Get capacity
570                Ok(self.info.capacity)
571            }
572            0x3001 => {
573                // Get sector size
574                Ok(self.info.sector_size as u64)
575            }
576            0x3002 => {
577                // Flush cache
578                self.flush()?;
579                Ok(0)
580            }
581            0x3003 => {
582                // Get device ready status
583                Ok(if self.is_ready() { 1 } else { 0 })
584            }
585            0x3004 => {
586                // Reset statistics
587                self.reset_stats();
588                Ok(0)
589            }
590            _ => Err(KernelError::InvalidArgument {
591                name: "ioctl_cmd",
592                value: "unknown",
593            }),
594        }
595    }
596}
597
598/// Storage manager for managing multiple storage devices
599pub struct StorageManager {
600    devices: Vec<Box<dyn StorageDevice>>,
601}
602
603impl Default for StorageManager {
604    fn default() -> Self {
605        Self::new()
606    }
607}
608
609impl StorageManager {
610    pub fn new() -> Self {
611        Self {
612            devices: Vec::new(),
613        }
614    }
615
616    /// Add a storage device
617    pub fn add_device(&mut self, device: Box<dyn StorageDevice>) {
618        crate::println!("[STORAGE] Added storage device: {}", device.name());
619        self.devices.push(device);
620    }
621
622    /// Get device by index
623    pub fn get_device(&mut self, index: usize) -> Option<&mut dyn StorageDevice> {
624        match self.devices.get_mut(index) {
625            Some(device) => Some(device.as_mut()),
626            None => None,
627        }
628    }
629
630    /// List all devices
631    pub fn list_devices(&self) -> Vec<StorageInfo> {
632        self.devices.iter().map(|d| d.get_info()).collect()
633    }
634
635    /// Get total storage capacity
636    pub fn get_total_capacity(&self) -> u64 {
637        self.devices.iter().map(|d| d.get_info().capacity).sum()
638    }
639}
640
641/// Global storage manager instance
642static STORAGE_MANAGER: OnceLock<Mutex<StorageManager>> = OnceLock::new();
643
644/// Initialize storage subsystem
645pub fn init() {
646    let storage_manager = StorageManager::new();
647    let _ = STORAGE_MANAGER.set(Mutex::new(storage_manager));
648
649    // Register ATA driver with driver framework
650    let driver_framework = crate::services::driver_framework::get_driver_framework();
651
652    // Create dummy ATA driver for demonstration
653    let dummy_device = DeviceInfo {
654        id: 0,
655        name: String::from("IDE Controller"),
656        class: DeviceClass::Storage,
657        device_id: Some(crate::services::driver_framework::DeviceId {
658            vendor_id: 0x8086,
659            device_id: 0x7010,
660            class_code: 0x01, // Mass storage
661            subclass: 0x01,   // IDE
662            prog_if: 0x80,
663            revision: 0x01,
664        }),
665        driver: None,
666        bus: String::from("pci"),
667        address: 0x1F0,
668        irq: Some(14),
669        dma_channels: Vec::new(),
670        io_ports: vec![(0x1F0, 0x1F7), (0x3F6, 0x3F6)],
671        memory_regions: Vec::new(),
672        status: DeviceStatus::Uninitialized,
673    };
674
675    let ata_driver = AtaDriver::new(
676        String::from("ata0"),
677        0x1F0, // Primary IDE base port
678        true,  // Master drive
679        dummy_device,
680    );
681
682    if let Err(_e) = driver_framework.register_driver(Box::new(ata_driver)) {
683        crate::println!("[STORAGE] Failed to register ATA driver: {}", _e);
684    } else {
685        crate::println!("[STORAGE] Storage subsystem initialized");
686    }
687}
688
689/// Get the global storage manager
690pub fn get_storage_manager() -> &'static Mutex<StorageManager> {
691    STORAGE_MANAGER
692        .get()
693        .expect("Storage manager not initialized")
694}