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}