MLIR-AIE
memory_allocator_ion.cpp
Go to the documentation of this file.
1//===- memory_allocator.h ---------------------------------------*- C++ -*-===//
2//
3// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7// (c) Copyright 2020 Xilinx Inc.
8// (c) Copyright 2023 Advanced Micro Devices, Inc.
9//
10//===----------------------------------------------------------------------===//
11
12// This code is heavily based on aienginev2_v3_0/src/io_backend/ext/xaie_linux.c
13// Current version of this library no longer implements memory allocation, so we
14// have to do it ourselves.
15
16/***************************** Include Files *********************************/
17#include <errno.h>
18#include <fcntl.h>
19#include <limits.h>
20#include <linux/dma-buf.h>
21#include <pthread.h>
22#include <stdint.h>
23#include <stdlib.h>
24#include <string.h>
25#include <sys/ioctl.h>
26#include <sys/mman.h>
27#include <sys/stat.h>
28#include <sys/types.h>
29#include <unistd.h>
30
31#include "ion.h"
32#include "memory_allocator.h"
33
34/***************************** Macro Definitions *****************************/
35#define XAIE_128BIT_ALIGN_MASK 0xFF
36
37/**
38 * This is the memory function to allocate a memory
39 *
40 * @param handle: Device Instance
41 * @param size: Size of the memory
42 *
43 * @return Pointer to the allocated memory instance.
44 *******************************************************************************/
46 int size) {
47 int RC;
48 int Fd, Ret;
49 uint32_t HeapNum;
50 void *VAddr;
51 struct ion_allocation_data AllocArgs;
52 struct ion_heap_query Query;
53 struct ion_heap_data *Heaps;
54 u64 DevAddr = 0;
55
56 Fd = open("/dev/ion", O_RDONLY);
57 if (Fd < 0) {
58 XAIE_ERROR("Failed to open ion.\n");
59 return NULL;
60 }
61
62 memset(&Query, 0, sizeof(Query));
63 Ret = ioctl(Fd, ION_IOC_HEAP_QUERY, &Query);
64 if (Ret != 0) {
65 XAIE_ERROR("Failed to enquire ion heaps.\n");
66 goto error_ion;
67 }
68
69 Heaps = (struct ion_heap_data *)calloc(Query.cnt, sizeof(*Heaps));
70 if (Heaps == NULL) {
71 XAIE_ERROR("Failed to allocate memory for heap details\n");
72 goto error_ion;
73 }
74
75 Query.heaps = (uint64_t)Heaps;
76 Ret = ioctl(Fd, ION_IOC_HEAP_QUERY, &Query);
77 if (Ret != 0) {
78 XAIE_ERROR("Failed to enquire ion heap details.\n");
79 free(Heaps);
80 goto error_ion;
81 }
82
83 HeapNum = UINT_MAX;
84 for (uint32_t i = 0; i < Query.cnt; i++) {
85 XAIE_DBG("Heap id: %u, Heap name: %s, Heap type: %u\n", Heaps[i].heap_id,
86 Heaps[i].name, Heaps[i].type);
87 if (Heaps[i].type == ION_HEAP_TYPE_SYSTEM_CONTIG) {
88 HeapNum = i;
89 break;
90 }
91 }
92
93 if (HeapNum == UINT_MAX) {
94 XAIE_ERROR("Failed to find contiguous heap\n");
95 free(Heaps);
96 goto error_ion;
97 }
98
99 memset(&AllocArgs, 0, sizeof(AllocArgs));
100 AllocArgs.len = size;
101 AllocArgs.heap_id_mask = 1 << Heaps[HeapNum].heap_id;
102 free(Heaps);
103 // if(Cache == XAIE_MEM_CACHEABLE) {
104 // AllocArgs.flags = ION_FLAG_CACHED;
105 // }
106
107 Ret = ioctl(Fd, ION_IOC_ALLOC, &AllocArgs);
108 if (Ret != 0) {
109 XAIE_ERROR("Failed to allocate memory of %lu bytes\n");
110 goto error_ion;
111 }
112
113 VAddr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, AllocArgs.fd, 0);
114 if (VAddr == NULL) {
115 XAIE_ERROR("Failed to mmap\n");
116 goto error_alloc_fd;
117 }
118
119 handle.fd = AllocArgs.fd;
120 handle.virtualAddr = VAddr;
121 handle.size = size;
122
123 // Map the memory
124 if (XAie_MemAttach(&(ctx->DevInst), &(handle.MemInst), DevAddr, (u64)VAddr,
125 size, XAIE_MEM_NONCACHEABLE, handle.fd) != XAIE_OK) {
126 XAIE_ERROR("dmabuf map failed\n");
127 goto error_map;
128 }
129
130 close(Fd);
131 return (int *)VAddr;
132
133error_map:
134 munmap(VAddr, size);
135error_alloc_fd:
136 close(handle.fd);
137error_ion:
138 close(Fd);
139 return NULL;
140}
141
142/*****************************************************************************/
143/**
144 *
145 * This is function to attach the allocated memory descriptor to kernel driver
146 *
147 * @param IOInst: Linux IO instance pointer
148 * @param MemInst: Linux Memory instance pointer.
149 *
150 * @return XAIE_OK on success, Error code on failure.
151 *
152 * @note Internal only.
153 *
154 *******************************************************************************/
155// static int _XAie_LinuxMemDetach(XAie_LinuxIO *IOInst, XAie_LinuxMem *MemInst)
156// {
157// int Ret;
158
159// Ret = ioctl(IOInst->PartitionFd, AIE_DETACH_DMABUF_IOCTL,
160// MemInst->BufferFd);
161// if(Ret != 0) {
162// XAIE_ERROR("Failed to detach dmabuf\n");
163// return XAIE_ERR;
164// }
165
166// return XAIE_OK;
167// }
168
169/*****************************************************************************/
170/**
171 *
172 * This is the memory function to free the memory
173 *
174 * @param MemInst: Memory instance pointer.
175 *
176 * @return XAIE_OK on success, Error code on failure.
177 *
178 * @note Internal only.
179 *
180 *******************************************************************************/
181// static int XAie_LinuxMemFree(XAie_MemInst *MemInst)
182// {
183// int RC;
184// XAie_LinuxMem *LinuxMemInst =
185// (XAie_LinuxMem *)MemInst->BackendHandle;
186
187// RC = _XAie_LinuxMemDetach((XAie_LinuxIO *)MemInst->DevInst->IOInst,
188// LinuxMemInst);
189// if(RC != XAIE_OK) {
190// return RC;
191// }
192
193// munmap(MemInst->VAddr, MemInst->Size);
194// close(LinuxMemInst->BufferFd);
195// free(LinuxMemInst);
196// free(MemInst);
197
198// return XAIE_OK;
199// }
200
201/*****************************************************************************/
202/**
203 *
204 * This is the memory function to sync the memory for CPU.
205 *
206 * @param MemInst: Memory instance pointer.
207 *
208 * @return XAIE_OK on success, Error code on failure.
209 *
210 * @note Internal only.
211 *
212 *******************************************************************************/
214 struct dma_buf_sync Sync;
215 int Ret;
216
217 memset(&Sync, 0, sizeof(Sync));
218 Sync.flags = DMA_BUF_SYNC_RW | DMA_BUF_SYNC_START;
219 Ret = ioctl(handle.fd, DMA_BUF_IOCTL_SYNC, &Sync);
220 if (Ret != 0) {
221 XAIE_ERROR("Failed to sync, %s.\n", strerror(errno));
222 // return XAIE_ERR;
223 }
224
225 // return XAIE_OK;
226}
227
228/*****************************************************************************/
229/**
230 *
231 * This is the memory function to sync the memory for Device.
232 *
233 * @param MemInst: Memory instance pointer.
234 *
235 * @return XAIE_OK on success, Error code on failure.
236 *
237 * @note Internal only.
238 *
239 *******************************************************************************/
241 struct dma_buf_sync Sync;
242 int Ret;
243
244 memset(&Sync, 0, sizeof(Sync));
245 Sync.flags = DMA_BUF_SYNC_RW | DMA_BUF_SYNC_END;
246 Ret = ioctl(handle.fd, DMA_BUF_IOCTL_SYNC, &Sync);
247 if (Ret != 0) {
248 XAIE_ERROR("Failed to sync, %s.\n", strerror(errno));
249 // return;
250 // return XAIE_ERR;
251 }
252
253 // return XAIE_OK;
254}
255
256u64 mlir_aie_get_device_address(struct aie_libxaie_ctx_t *_xaie, void *VA) {
257 return (u64)VA; // LibXAIE will take care of converting this for us.
258}
259
260/** @} */
#define ION_IOC_ALLOC
DOC: ION_IOC_ALLOC - allocate memory.
Definition ion.h:115
#define ION_IOC_HEAP_QUERY
DOC: ION_IOC_HEAP_QUERY - information about available heaps.
Definition ion.h:123
@ ION_HEAP_TYPE_SYSTEM_CONTIG
Definition ion.h:28
int * mlir_aie_mem_alloc(struct aie_libxaie_ctx_t *ctx, ext_mem_model_t &handle, int size)
This is the memory function to allocate a memory.
void mlir_aie_sync_mem_dev(ext_mem_model_t &handle)
This is the memory function to sync the memory for Device.
void mlir_aie_sync_mem_cpu(ext_mem_model_t &handle)
This is function to attach the allocated memory descriptor to kernel driver.
u64 mlir_aie_get_device_address(struct aie_libxaie_ctx_t *_xaie, void *VA)
Return a device address corresponding to the given host address.
XAie_DevInst DevInst
Definition target.h:33
XAie_MemInst MemInst
Definition target.h:28
size_t size
Definition target.h:26
void * virtualAddr
Definition target.h:24
DOC: Ion Userspace API.
Definition ion.h:69
__u32 heap_id_mask
Definition ion.h:71
__u32 type
Definition ion.h:87
char name[MAX_HEAP_NAME]
Definition ion.h:86
__u32 heap_id
Definition ion.h:88
struct ion_heap_query - collection of data about all heaps @cnt - total number of heaps to be copied ...
Definition ion.h:99
__u64 heaps
Definition ion.h:102
__u32 cnt
Definition ion.h:100