浏览代码

Use heap rather than DMA buffer for console RX buffer.

The buffer is shared with the device via the HAL when it's added to the
queue, so it doesn't need to be a DMA buffer itself.
Andrew Walbran 1 年之前
父节点
当前提交
d5f0ae0f90
共有 3 个文件被更改,包括 20 次插入13 次删除
  1. 17 13
      src/device/console.rs
  2. 1 0
      src/device/mod.rs
  3. 2 0
      src/lib.rs

+ 17 - 13
src/device/console.rs

@@ -1,10 +1,11 @@
 //! Driver for VirtIO console devices.
 //! Driver for VirtIO console devices.
 
 
-use crate::hal::{BufferDirection, Dma, Hal};
+use crate::hal::Hal;
 use crate::queue::VirtQueue;
 use crate::queue::VirtQueue;
 use crate::transport::Transport;
 use crate::transport::Transport;
 use crate::volatile::{volread, ReadOnly, WriteOnly};
 use crate::volatile::{volread, ReadOnly, WriteOnly};
-use crate::Result;
+use crate::{Result, PAGE_SIZE};
+use alloc::boxed::Box;
 use bitflags::bitflags;
 use bitflags::bitflags;
 use core::ptr::NonNull;
 use core::ptr::NonNull;
 use log::info;
 use log::info;
@@ -38,13 +39,12 @@ const QUEUE_SIZE: usize = 2;
 /// # Ok(())
 /// # Ok(())
 /// # }
 /// # }
 /// ```
 /// ```
-pub struct VirtIOConsole<'a, H: Hal, T: Transport> {
+pub struct VirtIOConsole<H: Hal, T: Transport> {
     transport: T,
     transport: T,
     config_space: NonNull<Config>,
     config_space: NonNull<Config>,
     receiveq: VirtQueue<H, QUEUE_SIZE>,
     receiveq: VirtQueue<H, QUEUE_SIZE>,
     transmitq: VirtQueue<H, QUEUE_SIZE>,
     transmitq: VirtQueue<H, QUEUE_SIZE>,
-    queue_buf_dma: Dma<H>,
-    queue_buf_rx: &'a mut [u8],
+    queue_buf_rx: Box<[u8; PAGE_SIZE]>,
     cursor: usize,
     cursor: usize,
     pending_len: usize,
     pending_len: usize,
     /// The token of the outstanding receive request, if there is one.
     /// The token of the outstanding receive request, if there is one.
@@ -62,7 +62,7 @@ pub struct ConsoleInfo {
     pub max_ports: u32,
     pub max_ports: u32,
 }
 }
 
 
-impl<H: Hal, T: Transport> VirtIOConsole<'_, H, T> {
+impl<H: Hal, T: Transport> VirtIOConsole<H, T> {
     /// Creates a new VirtIO console driver.
     /// Creates a new VirtIO console driver.
     pub fn new(mut transport: T) -> Result<Self> {
     pub fn new(mut transport: T) -> Result<Self> {
         transport.begin_init(|features| {
         transport.begin_init(|features| {
@@ -74,12 +74,11 @@ impl<H: Hal, T: Transport> VirtIOConsole<'_, H, T> {
         let config_space = transport.config_space::<Config>()?;
         let config_space = transport.config_space::<Config>()?;
         let receiveq = VirtQueue::new(&mut transport, QUEUE_RECEIVEQ_PORT_0)?;
         let receiveq = VirtQueue::new(&mut transport, QUEUE_RECEIVEQ_PORT_0)?;
         let transmitq = VirtQueue::new(&mut transport, QUEUE_TRANSMITQ_PORT_0)?;
         let transmitq = VirtQueue::new(&mut transport, QUEUE_TRANSMITQ_PORT_0)?;
-        let queue_buf_dma = Dma::new(1, BufferDirection::DeviceToDriver)?;
 
 
         // Safe because no alignment or initialisation is required for [u8], the DMA buffer is
         // Safe because no alignment or initialisation is required for [u8], the DMA buffer is
         // dereferenceable, and the lifetime of the reference matches the lifetime of the DMA buffer
         // dereferenceable, and the lifetime of the reference matches the lifetime of the DMA buffer
         // (which we don't otherwise access).
         // (which we don't otherwise access).
-        let queue_buf_rx = unsafe { queue_buf_dma.raw_slice().as_mut() };
+        let queue_buf_rx = Box::new([0; PAGE_SIZE]);
 
 
         transport.finish_init();
         transport.finish_init();
         let mut console = VirtIOConsole {
         let mut console = VirtIOConsole {
@@ -87,7 +86,6 @@ impl<H: Hal, T: Transport> VirtIOConsole<'_, H, T> {
             config_space,
             config_space,
             receiveq,
             receiveq,
             transmitq,
             transmitq,
-            queue_buf_dma,
             queue_buf_rx,
             queue_buf_rx,
             cursor: 0,
             cursor: 0,
             pending_len: 0,
             pending_len: 0,
@@ -118,7 +116,10 @@ impl<H: Hal, T: Transport> VirtIOConsole<'_, H, T> {
         if self.receive_token.is_none() && self.cursor == self.pending_len {
         if self.receive_token.is_none() && self.cursor == self.pending_len {
             // Safe because the buffer lasts at least as long as the queue, and there are no other
             // Safe because the buffer lasts at least as long as the queue, and there are no other
             // outstanding requests using the buffer.
             // outstanding requests using the buffer.
-            self.receive_token = Some(unsafe { self.receiveq.add(&[], &mut [self.queue_buf_rx]) }?);
+            self.receive_token = Some(unsafe {
+                self.receiveq
+                    .add(&[], &mut [self.queue_buf_rx.as_mut_slice()])
+            }?);
             if self.receiveq.should_notify() {
             if self.receiveq.should_notify() {
                 self.transport.notify(QUEUE_RECEIVEQ_PORT_0);
                 self.transport.notify(QUEUE_RECEIVEQ_PORT_0);
             }
             }
@@ -148,8 +149,11 @@ impl<H: Hal, T: Transport> VirtIOConsole<'_, H, T> {
                 // Safe because we are passing the same buffer as we passed to `VirtQueue::add` in
                 // Safe because we are passing the same buffer as we passed to `VirtQueue::add` in
                 // `poll_retrieve` and it is still valid.
                 // `poll_retrieve` and it is still valid.
                 let len = unsafe {
                 let len = unsafe {
-                    self.receiveq
-                        .pop_used(receive_token, &[], &mut [self.queue_buf_rx])?
+                    self.receiveq.pop_used(
+                        receive_token,
+                        &[],
+                        &mut [self.queue_buf_rx.as_mut_slice()],
+                    )?
                 };
                 };
                 flag = true;
                 flag = true;
                 assert_ne!(len, 0);
                 assert_ne!(len, 0);
@@ -188,7 +192,7 @@ impl<H: Hal, T: Transport> VirtIOConsole<'_, H, T> {
     }
     }
 }
 }
 
 
-impl<H: Hal, T: Transport> Drop for VirtIOConsole<'_, H, T> {
+impl<H: Hal, T: Transport> Drop for VirtIOConsole<H, T> {
     fn drop(&mut self) {
     fn drop(&mut self) {
         // Clear any pointers pointing to DMA regions, so the device doesn't try to access them
         // Clear any pointers pointing to DMA regions, so the device doesn't try to access them
         // after they have been freed.
         // after they have been freed.

+ 1 - 0
src/device/mod.rs

@@ -1,6 +1,7 @@
 //! Drivers for specific VirtIO devices.
 //! Drivers for specific VirtIO devices.
 
 
 pub mod blk;
 pub mod blk;
+#[cfg(feature = "alloc")]
 pub mod console;
 pub mod console;
 pub mod gpu;
 pub mod gpu;
 #[cfg(feature = "alloc")]
 #[cfg(feature = "alloc")]

+ 2 - 0
src/lib.rs

@@ -24,12 +24,14 @@
 //!
 //!
 //! ```
 //! ```
 //! # use virtio_drivers::Hal;
 //! # use virtio_drivers::Hal;
+//! # #[cfg(feature = "alloc")]
 //! use virtio_drivers::{
 //! use virtio_drivers::{
 //!     device::console::VirtIOConsole,
 //!     device::console::VirtIOConsole,
 //!     transport::{mmio::MmioTransport, DeviceType, Transport},
 //!     transport::{mmio::MmioTransport, DeviceType, Transport},
 //! };
 //! };
 
 
 //!
 //!
+//! # #[cfg(feature = "alloc")]
 //! # fn example<HalImpl: Hal>(transport: MmioTransport) {
 //! # fn example<HalImpl: Hal>(transport: MmioTransport) {
 //! if transport.device_type() == DeviceType::Console {
 //! if transport.device_type() == DeviceType::Console {
 //!     let mut console = VirtIOConsole::<HalImpl, _>::new(transport).unwrap();
 //!     let mut console = VirtIOConsole::<HalImpl, _>::new(transport).unwrap();