vmcore/
isa_dma_channel.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Infrastructure to support legacy ISA DMA channels.
5
6/// ISA DMA transfer direction
7#[derive(PartialEq, Debug)]
8pub enum IsaDmaDirection {
9    /// Device is writing data to the buffer
10    Write,
11    /// Device is reading data from the buffer
12    Read,
13}
14
15/// Location of DMA buffer in guest memory
16#[derive(Debug)]
17pub struct IsaDmaBuffer {
18    /// GPA of the DMA buffer
19    pub address: u64,
20    /// Size of the DMA buffer
21    pub size: usize,
22}
23
24/// A handle to an ISA DMA channel.
25///
26/// This trait does not "leak" which partiuclar ISA DMA channel a device is
27/// connected to.
28///
29/// Devices that use ISA DMA should simply accept an instance of `Box<dyn
30/// IsaDmaChannel>`, leaving the details of DMA channel assignment to
31/// upper-level system init code that backs the `IsaDmaChannel` trait object.
32pub trait IsaDmaChannel: Send {
33    /// Check the value of the DMA channel's configured transfer size.
34    fn check_transfer_size(&mut self) -> u16;
35    /// Requests an access to ISA DMA channel buffer.
36    ///
37    /// Returns `None` if the channel has not been configured correctly.
38    fn request(&mut self, direction: IsaDmaDirection) -> Option<IsaDmaBuffer>;
39    /// Signals to the DMA controller that the transfer is concluded.
40    fn complete(&mut self);
41}
42
43/// A floating DMA channel that is not connected to any device.
44pub struct FloatingDmaChannel;
45
46impl IsaDmaChannel for FloatingDmaChannel {
47    fn check_transfer_size(&mut self) -> u16 {
48        0
49    }
50
51    fn request(&mut self, direction: IsaDmaDirection) -> Option<IsaDmaBuffer> {
52        tracing::warn!(?direction, "called `request` on floating DMA channel");
53        None
54    }
55
56    fn complete(&mut self) {
57        tracing::warn!("called `complete` on floating DMA channel");
58    }
59}