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