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}