1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#include <bits/null.h>
4#include <fcntl.h>
5#include <mos/mm/mm_types.h>
6#include <mos/syscall/usermode.h>
7#include <mos/types.h>
8#include <sys/mman.h>
9#include <unistd.h>
10
11// #define LIBDMA_DEBUG
12
13#if defined(LIBDMA_DEBUG)
14#include <stdio.h>
15#define libdma_debug(fmt, ...) printf("libdma: " fmt "\n"__VA_OPT__(, ) __VA_ARGS__)
16#else
17#define libdma_debug(...)
18#endif
19
20static fd_t sysmem_fd = -1;
21
22void libdma_init(void)
23{
24 sysmem_fd = open(path: "/sys/mem", O_RDWR);
25 libdma_debug("libdma is initialized, /sys/mem fd=%d", sysmem_fd);
26}
27
28bool libdma_alloc(size_t n_pages, ptr_t *phys, ptr_t *virt)
29{
30 return syscall_dmabuf_alloc(n_pages, out_paddr: phys, out_vaddr: virt);
31}
32
33bool libdma_dealloc(ptr_t virt, ptr_t phys, size_t n_pages)
34{
35 MOS_UNUSED(n_pages);
36 return syscall_dmabuf_free(vaddr: virt, paddr: phys);
37}
38
39bool libdma_share_buffer(void *buffer, size_t size, ptr_t *phyaddr)
40{
41 bool result = syscall_dmabuf_share(buf: buffer, bufsize: size, out_paddr: phyaddr);
42 libdma_debug("share buffer: phyaddr=" PTR_FMT ", buffer=%p, size=%zu", *phyaddr, buffer, size);
43 return result;
44}
45
46bool libdma_unshare_buffer(ptr_t phyaddr, void *buffer, size_t size)
47{
48 bool result = syscall_dmabuf_unshare(paddr: phyaddr, size, vaddr: buffer);
49 libdma_debug("unshare buffer: phyaddr=" PTR_FMT ", buffer=%p, size=%zu", phyaddr, buffer, size);
50 return result;
51}
52
53ptr_t libdma_map_physical_address(ptr_t paddr, size_t n_pages, ptr_t vaddr)
54{
55 paddr = ALIGN_DOWN_TO_PAGE(paddr);
56 mmap_flags_t flags = MMAP_SHARED;
57 if (vaddr)
58 flags |= MMAP_EXACT;
59 return (ptr_t) syscall_mmap_file(hint_addr: vaddr, size: n_pages * MOS_PAGE_SIZE, perm: MEM_PERM_READ | MEM_PERM_WRITE, flags, fd: sysmem_fd, offset: paddr);
60}
61
62void libdma_exit(void)
63{
64 close(fd: sysmem_fd);
65 libdma_debug("libdma exits");
66}
67