1#![cfg_attr(not(test), no_std)]
2#![doc = include_str!("../README.md")]
3
4#[cfg(feature = "alloc")]
5extern crate alloc;
6
7use core::ptr::NonNull;
8
9mod dma;
10
11#[cfg(feature = "alloc")]
12pub use dma::alloc::{r#box::DBox, vec::DVec};
13pub use dma::slice::{DSlice, DSliceMut};
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum Direction {
17 ToDevice,
18 FromDevice,
19 Bidirectional,
20}
21
22pub trait Impl {
23 fn map(addr: NonNull<u8>, size: usize, direction: Direction) -> u64;
25 fn unmap(addr: NonNull<u8>, size: usize);
27 fn flush(addr: NonNull<u8>, size: usize);
29 fn invalidate(addr: NonNull<u8>, size: usize);
31}
32
33extern "Rust" {
34 fn __dma_api_map(addr: NonNull<u8>, size: usize, direction: Direction) -> u64;
35 fn __dma_api_unmap(addr: NonNull<u8>, size: usize);
36 fn __dma_api_flush(addr: NonNull<u8>, size: usize);
37 fn __dma_api_invalidate(addr: NonNull<u8>, size: usize);
38}
39
40fn map(addr: NonNull<u8>, size: usize, direction: Direction) -> u64 {
41 unsafe { __dma_api_map(addr, size, direction) }
42}
43
44fn unmap(addr: NonNull<u8>, size: usize) {
45 unsafe { __dma_api_unmap(addr, size) }
46}
47
48fn flush(addr: NonNull<u8>, size: usize) {
49 unsafe { __dma_api_flush(addr, size) }
50}
51
52fn invalidate(addr: NonNull<u8>, size: usize) {
53 unsafe { __dma_api_invalidate(addr, size) }
54}
55
56#[macro_export]
57macro_rules! set_impl {
58 ($t: ty) => {
59 #[no_mangle]
60 fn __dma_api_map(
61 addr: core::ptr::NonNull<u8>,
62 size: usize,
63 direction: $crate::Direction,
64 ) -> u64 {
65 <$t as $crate::Impl>::map(addr, size, direction)
66 }
67 #[no_mangle]
68 fn __dma_api_unmap(addr: core::ptr::NonNull<u8>, size: usize) {
69 <$t as $crate::Impl>::unmap(addr, size)
70 }
71 #[no_mangle]
72 fn __dma_api_flush(addr: core::ptr::NonNull<u8>, size: usize) {
73 <$t as $crate::Impl>::flush(addr, size)
74 }
75 #[no_mangle]
76 fn __dma_api_invalidate(addr: core::ptr::NonNull<u8>, size: usize) {
77 <$t as $crate::Impl>::invalidate(addr, size)
78 }
79 };
80}