1#![cfg_attr(not(test), no_std)]
2#![doc = include_str!("../README.md")]
3
4extern crate alloc;
6
7use core::{alloc::Layout, ptr::NonNull};
8
9mod dma;
10
11pub use dma::alloc::{r#box::DBox, vec::DVec};
12pub use dma::slice::{DSlice, DSliceMut};
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum Direction {
16 ToDevice,
17 FromDevice,
18 Bidirectional,
19}
20
21pub trait Impl {
22 fn map(addr: NonNull<u8>, size: usize, direction: Direction) -> u64;
24 fn unmap(addr: NonNull<u8>, size: usize);
26 fn flush(addr: NonNull<u8>, size: usize);
28 fn invalidate(addr: NonNull<u8>, size: usize);
30
31 #[allow(unused_variables)]
37 unsafe fn alloc(layout: Layout) -> *mut u8 {
38 #[cfg(feature = "alloc")]
39 unsafe {
40 alloc::alloc::alloc(layout)
41 }
42 #[cfg(not(feature = "alloc"))]
43 core::ptr::null_mut()
44 }
45
46 #[allow(unused_variables)]
59 unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
60 #[cfg(feature = "alloc")]
61 unsafe {
62 alloc::alloc::dealloc(ptr, layout)
63 }
64 }
65}
66
67extern "Rust" {
68 fn __dma_api_map(addr: NonNull<u8>, size: usize, direction: Direction) -> u64;
69 fn __dma_api_unmap(addr: NonNull<u8>, size: usize);
70 fn __dma_api_flush(addr: NonNull<u8>, size: usize);
71 fn __dma_api_invalidate(addr: NonNull<u8>, size: usize);
72 fn __dma_api_alloc(layout: Layout) -> *mut u8;
73 fn __dma_api_dealloc(ptr: *mut u8, layout: Layout);
74}
75
76fn map(addr: NonNull<u8>, size: usize, direction: Direction) -> u64 {
77 unsafe { __dma_api_map(addr, size, direction) }
78}
79
80fn unmap(addr: NonNull<u8>, size: usize) {
81 unsafe { __dma_api_unmap(addr, size) }
82}
83
84fn flush(addr: NonNull<u8>, size: usize) {
85 unsafe { __dma_api_flush(addr, size) }
86}
87
88fn invalidate(addr: NonNull<u8>, size: usize) {
89 unsafe { __dma_api_invalidate(addr, size) }
90}
91
92unsafe fn alloc(layout: Layout) -> *mut u8 {
93 unsafe { __dma_api_alloc(layout) }
94}
95
96unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
97 unsafe { __dma_api_dealloc(ptr, layout) }
98}
99
100#[macro_export]
101macro_rules! set_impl {
102 ($t: ty) => {
103 #[no_mangle]
104 fn __dma_api_map(
105 addr: core::ptr::NonNull<u8>,
106 size: usize,
107 direction: $crate::Direction,
108 ) -> u64 {
109 <$t as $crate::Impl>::map(addr, size, direction)
110 }
111 #[no_mangle]
112 fn __dma_api_unmap(addr: core::ptr::NonNull<u8>, size: usize) {
113 <$t as $crate::Impl>::unmap(addr, size)
114 }
115 #[no_mangle]
116 fn __dma_api_flush(addr: core::ptr::NonNull<u8>, size: usize) {
117 <$t as $crate::Impl>::flush(addr, size)
118 }
119 #[no_mangle]
120 fn __dma_api_invalidate(addr: core::ptr::NonNull<u8>, size: usize) {
121 <$t as $crate::Impl>::invalidate(addr, size)
122 }
123 #[no_mangle]
124 fn __dma_api_alloc(layout: core::alloc::Layout) -> *mut u8 {
125 unsafe { <$t as $crate::Impl>::alloc(layout) }
126 }
127 #[no_mangle]
128 fn __dma_api_dealloc(ptr: *mut u8, layout: core::alloc::Layout) {
129 unsafe { <$t as $crate::Impl>::dealloc(ptr, layout) }
130 }
131 };
132}