Forráskód Böngészése

add some docs. fix FFI.

Runji Wang 5 éve
szülő
commit
74f1dc883e
3 módosított fájl, 92 hozzáadás és 37 törlés
  1. 20 1
      src/blk.rs
  2. 44 1
      src/header.rs
  3. 28 35
      src/lib.rs

+ 20 - 1
src/blk.rs

@@ -3,8 +3,8 @@ use core::mem::size_of;
 use super::*;
 use super::*;
 use crate::header::VirtIOHeader;
 use crate::header::VirtIOHeader;
 use crate::queue::VirtQueue;
 use crate::queue::VirtQueue;
-use bitflags::_core::sync::atomic::spin_loop_hint;
 use bitflags::*;
 use bitflags::*;
+use core::sync::atomic::spin_loop_hint;
 use log::*;
 use log::*;
 use volatile::Volatile;
 use volatile::Volatile;
 
 
@@ -122,6 +122,9 @@ struct BlkResp {
 enum ReqType {
 enum ReqType {
     In = 0,
     In = 0,
     Out = 1,
     Out = 1,
+    Flush = 4,
+    Discard = 11,
+    WriteZeroes = 13,
 }
 }
 
 
 #[repr(u32)]
 #[repr(u32)]
@@ -144,17 +147,33 @@ const BLK_SIZE: usize = 512;
 
 
 bitflags! {
 bitflags! {
     struct BlkFeature: u64 {
     struct BlkFeature: u64 {
+        /// Device supports request barriers. (legacy)
         const BARRIER       = 1 << 0;
         const BARRIER       = 1 << 0;
+        /// Maximum size of any single segment is in `size_max`.
         const SIZE_MAX      = 1 << 1;
         const SIZE_MAX      = 1 << 1;
+        /// Maximum number of segments in a request is in `seg_max`.
         const SEG_MAX       = 1 << 2;
         const SEG_MAX       = 1 << 2;
+        /// Disk-style geometry specified in geometry.
         const GEOMETRY      = 1 << 4;
         const GEOMETRY      = 1 << 4;
+        /// Device is read-only.
         const RO            = 1 << 5;
         const RO            = 1 << 5;
+        /// Block size of disk is in `blk_size`.
         const BLK_SIZE      = 1 << 6;
         const BLK_SIZE      = 1 << 6;
+        /// Device supports scsi packet commands. (legacy)
         const SCSI          = 1 << 7;
         const SCSI          = 1 << 7;
+        /// Cache flush command support.
         const FLUSH         = 1 << 9;
         const FLUSH         = 1 << 9;
+        /// Device exports information on optimal I/O alignment.
         const TOPOLOGY      = 1 << 10;
         const TOPOLOGY      = 1 << 10;
+        /// Device can toggle its cache between writeback and writethrough modes.
         const CONFIG_WCE    = 1 << 11;
         const CONFIG_WCE    = 1 << 11;
+        /// Device can support discard command, maximum discard sectors size in
+        /// `max_discard_sectors` and maximum discard segment number in
+        /// `max_discard_seg`.
         const DISCARD       = 1 << 13;
         const DISCARD       = 1 << 13;
+        /// Device can support write zeroes command, maximum write zeroes sectors
+        /// size in `max_write_zeroes_sectors` and maximum write zeroes segment
+        /// number in `max_write_zeroes_seg`.
         const WRITE_ZEROES  = 1 << 14;
         const WRITE_ZEROES  = 1 << 14;
 
 
         // device independent
         // device independent

+ 44 - 1
src/header.rs

@@ -152,6 +152,19 @@ impl VirtIOHeader {
         self.magic.read() == 0x74726976 && self.version.read() == 1 && self.device_id.read() != 0
         self.magic.read() == 0x74726976 && self.version.read() == 1 && self.device_id.read() != 0
     }
     }
 
 
+    /// Get the device type.
+    pub fn device_type(&self) -> DeviceType {
+        match self.device_id.read() {
+            x @ 1..=13 | x @ 16..=24 => unsafe { core::mem::transmute(x as u8) },
+            _ => DeviceType::Invalid,
+        }
+    }
+
+    /// Get the vendor ID.
+    pub fn vendor_id(&self) -> u32 {
+        self.vendor_id.read()
+    }
+
     /// Begin initializing the device.
     /// Begin initializing the device.
     ///
     ///
     /// Ref: virtio 3.1.1 Device Initialization
     /// Ref: virtio 3.1.1 Device Initialization
@@ -263,4 +276,34 @@ bitflags! {
     }
     }
 }
 }
 
 
-pub const CONFIG_SPACE_OFFSET: usize = 0x100;
+const CONFIG_SPACE_OFFSET: usize = 0x100;
+
+/// Types of virtio devices.
+#[repr(u8)]
+#[derive(Debug, Eq, PartialEq)]
+#[allow(missing_docs)]
+pub enum DeviceType {
+    Invalid = 0,
+    Network = 1,
+    Block = 2,
+    Console = 3,
+    EntropySource = 4,
+    MemoryBallooning = 5,
+    IoMemory = 6,
+    Rpmsg = 7,
+    ScsiHost = 8,
+    _9P = 9,
+    Mac80211 = 10,
+    RprocSerial = 11,
+    VirtioCAIF = 12,
+    MemoryBalloon = 13,
+    GPU = 16,
+    Timer = 17,
+    Input = 18,
+    Socket = 19,
+    Crypto = 20,
+    SignalDistributionModule = 21,
+    Pstore = 22,
+    IOMMU = 23,
+    Memory = 24,
+}

+ 28 - 35
src/lib.rs

@@ -8,26 +8,44 @@ mod header;
 mod queue;
 mod queue;
 
 
 pub use self::blk::VirtIOBlk;
 pub use self::blk::VirtIOBlk;
+pub use self::header::*;
 
 
 const PAGE_SIZE: usize = 0x1000;
 const PAGE_SIZE: usize = 0x1000;
 
 
 type VirtAddr = usize;
 type VirtAddr = usize;
 type PhysAddr = usize;
 type PhysAddr = usize;
 
 
-fn alloc_dma(_pages: usize) -> Result<(VirtAddr, PhysAddr)> {
-    unimplemented!()
+fn alloc_dma(pages: usize) -> Result<(VirtAddr, PhysAddr)> {
+    let (vaddr, paddr) = unsafe { virtio_alloc_dma(pages) };
+    if vaddr == 0 {
+        Err(Error::DmaError)
+    } else {
+        Ok((vaddr, paddr))
+    }
 }
 }
 
 
-fn dealloc_dma(_paddr: PhysAddr, _pages: usize) -> Result {
-    unimplemented!()
+fn dealloc_dma(paddr: PhysAddr, pages: usize) -> Result {
+    let ok = unsafe { virtio_dealloc_dma(paddr, pages) };
+    if ok {
+        Ok(())
+    } else {
+        Err(Error::DmaError)
+    }
 }
 }
 
 
-fn phys_to_virt(_paddr: PhysAddr) -> VirtAddr {
-    unimplemented!()
+fn phys_to_virt(paddr: PhysAddr) -> VirtAddr {
+    unsafe { virtio_phys_to_virt(paddr) }
 }
 }
 
 
-fn virt_to_phys(_vaddr: VirtAddr) -> PhysAddr {
-    unimplemented!()
+fn virt_to_phys(vaddr: VirtAddr) -> PhysAddr {
+    unsafe { virtio_virt_to_phys(vaddr) }
+}
+
+extern "C" {
+    fn virtio_alloc_dma(pages: usize) -> (VirtAddr, PhysAddr);
+    fn virtio_dealloc_dma(paddr: PhysAddr, pages: usize) -> bool;
+    fn virtio_phys_to_virt(paddr: PhysAddr) -> VirtAddr;
+    fn virtio_virt_to_phys(vaddr: VirtAddr) -> PhysAddr;
 }
 }
 
 
 /// The type returned by driver methods.
 /// The type returned by driver methods.
@@ -49,31 +67,6 @@ pub enum Error {
     AlreadyUsed,
     AlreadyUsed,
     /// Invalid parameter.
     /// Invalid parameter.
     InvalidParam,
     InvalidParam,
-}
-
-/// Types of virtio devices.
-enum DeviceType {
-    Invalid = 0,
-    Network = 1,
-    Block = 2,
-    Console = 3,
-    EntropySource = 4,
-    MemoryBallooning = 5,
-    IoMemory = 6,
-    Rpmsg = 7,
-    ScsiHost = 8,
-    _9P = 9,
-    Mac80211 = 10,
-    RprocSerial = 11,
-    VirtioCAIF = 12,
-    MemoryBalloon = 13,
-    GPU = 16,
-    Timer = 17,
-    Input = 18,
-    Socket = 19,
-    Crypto = 20,
-    SignalDistributionModule = 21,
-    Pstore = 22,
-    IOMMU = 23,
-    Memory = 24,
+    /// Failed to alloc DMA memory.
+    DmaError,
 }
 }