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