// SPDX-License-Identifier: GPL-2.0

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>

#include <linux/dma-buf.h>
#include <drm/drm.h>

#include "../../../../include/uapi/linux/dma-heap.h"

#define DEVPATH "/dev/dma_heap"

static int check_vgem(int fd)
{
	drm_version_t version = { 0 };
	char name[5];
	int ret;

	version.name_len = 4;
	version.name = name;

	ret = ioctl(fd, DRM_IOCTL_VERSION, &version);
	if (ret)
		return 0;

	return !strcmp(name, "vgem");
}

static int open_vgem(void)
{
	int i, fd;
	const char *drmstr = "/dev/dri/card";

	fd = -1;
	for (i = 0; i < 16; i++) {
		char name[80];

		snprintf(name, 80, "%s%u", drmstr, i);

		fd = open(name, O_RDWR);
		if (fd < 0)
			continue;

		if (!check_vgem(fd)) {
			close(fd);
			fd = -1;
			continue;
		} else {
			break;
		}
	}
	return fd;
}

static int import_vgem_fd(int vgem_fd, int dma_buf_fd, uint32_t *handle)
{
	struct drm_prime_handle import_handle = {
		.fd = dma_buf_fd,
		.flags = 0,
		.handle = 0,
	 };
	int ret;

	ret = ioctl(vgem_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &import_handle);
	if (ret == 0)
		*handle = import_handle.handle;
	return ret;
}

static void close_handle(int vgem_fd, uint32_t handle)
{
	struct drm_gem_close close = {
		.handle = handle,
	};

	ioctl(vgem_fd, DRM_IOCTL_GEM_CLOSE, &close);
}

static int dmabuf_heap_open(char *name)
{
	int ret, fd;
	char buf[256];

	ret = snprintf(buf, 256, "%s/%s", DEVPATH, name);
	if (ret < 0) {
		printf("snprintf failed!\n");
		return ret;
	}

	fd = open(buf, O_RDWR);
	if (fd < 0)
		printf("open %s failed!\n", buf);
	return fd;
}

static int dmabuf_heap_alloc_fdflags(int fd, size_t len, unsigned int fd_flags,
				     unsigned int heap_flags, int *dmabuf_fd)
{
	struct dma_heap_allocation_data data = {
		.len = len,
		.fd = 0,
		.fd_flags = fd_flags,
		.heap_flags = heap_flags,
	};
	int ret;

	if (!dmabuf_fd)
		return -EINVAL;

	ret = ioctl(fd, DMA_HEAP_IOCTL_ALLOC, &data);
	if (ret < 0)
		return ret;
	*dmabuf_fd = (int)data.fd;
	return ret;
}

static int dmabuf_heap_alloc(int fd, size_t len, unsigned int flags,
			     int *dmabuf_fd)
{
	return dmabuf_heap_alloc_fdflags(fd, len, O_RDWR | O_CLOEXEC, flags,
					 dmabuf_fd);
}

static int dmabuf_sync(int fd, int start_stop)
{
	struct dma_buf_sync sync = {
		.flags = start_stop | DMA_BUF_SYNC_RW,
	};

	return ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync);
}

#define ONE_MEG (1024 * 1024)

static int test_alloc_and_import(char *heap_name)
{
	int heap_fd = -1, dmabuf_fd = -1, importer_fd = -1;
	uint32_t handle = 0;
	void *p = NULL;
	int ret;

	heap_fd = dmabuf_heap_open(heap_name);
	if (heap_fd < 0)
		return -1;

	printf("  Testing allocation and importing:  ");
	ret = dmabuf_heap_alloc(heap_fd, ONE_MEG, 0, &dmabuf_fd);
	if (ret) {
		printf("FAIL (Allocation Failed!)\n");
		ret = -1;
		goto out;
	}
	/* mmap and write a simple pattern */
	p = mmap(NULL,
		 ONE_MEG,
		 PROT_READ | PROT_WRITE,
		 MAP_SHARED,
		 dmabuf_fd,
		 0);
	if (p == MAP_FAILED) {
		printf("FAIL (mmap() failed)\n");
		ret = -1;
		goto out;
	}

	dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_START);
	memset(p, 1, ONE_MEG / 2);
	memset((char *)p + ONE_MEG / 2, 0, ONE_MEG / 2);
	dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_END);

	importer_fd = open_vgem();
	if (importer_fd < 0) {
		ret = importer_fd;
		printf("(Could not open vgem - skipping):  ");
	} else {
		ret = import_vgem_fd(importer_fd, dmabuf_fd, &handle);
		if (ret < 0) {
			printf("FAIL (Failed to import buffer)\n");
			goto out;
		}
	}

	ret = dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_START);
	if (ret < 0) {
		printf("FAIL (DMA_BUF_SYNC_START failed!)\n");
		goto out;
	}

	memset(p, 0xff, ONE_MEG);
	ret = dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_END);
	if (ret < 0) {
		printf("FAIL (DMA_BUF_SYNC_END failed!)\n");
		goto out;
	}

	close_handle(importer_fd, handle);
	ret = 0;
	printf(" OK\n");
out:
	if (p)
		munmap(p, ONE_MEG);
	if (importer_fd >= 0)
		close(importer_fd);
	if (dmabuf_fd >= 0)
		close(dmabuf_fd);
	if (heap_fd >= 0)
		close(heap_fd);

	return ret;
}

static int test_alloc_zeroed(char *heap_name, size_t size)
{
	int heap_fd = -1, dmabuf_fd[32];
	int i, j, ret;
	void *p = NULL;
	char *c;

	printf("  Testing alloced %ldk buffers are zeroed:  ", size / 1024);
	heap_fd = dmabuf_heap_open(heap_name);
	if (heap_fd < 0)
		return -1;

	/* Allocate and fill a bunch of buffers */
	for (i = 0; i < 32; i++) {
		ret = dmabuf_heap_alloc(heap_fd, size, 0, &dmabuf_fd[i]);
		if (ret < 0) {
			printf("FAIL (Allocation (%i) failed)\n", i);
			goto out;
		}
		/* mmap and fill with simple pattern */
		p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, dmabuf_fd[i], 0);
		if (p == MAP_FAILED) {
			printf("FAIL (mmap() failed!)\n");
			ret = -1;
			goto out;
		}
		dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_START);
		memset(p, 0xff, size);
		dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_END);
		munmap(p, size);
	}
	/* close them all */
	for (i = 0; i < 32; i++)
		close(dmabuf_fd[i]);

	/* Allocate and validate all buffers are zeroed */
	for (i = 0; i < 32; i++) {
		ret = dmabuf_heap_alloc(heap_fd, size, 0, &dmabuf_fd[i]);
		if (ret < 0) {
			printf("FAIL (Allocation (%i) failed)\n", i);
			goto out;
		}

		/* mmap and validate everything is zero */
		p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, dmabuf_fd[i], 0);
		if (p == MAP_FAILED) {
			printf("FAIL (mmap() failed!)\n");
			ret = -1;
			goto out;
		}
		dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_START);
		c = (char *)p;
		for (j = 0; j < size; j++) {
			if (c[j] != 0) {
				printf("FAIL (Allocated buffer not zeroed @ %i)\n", j);
				break;
			}
		}
		dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_END);
		munmap(p, size);
	}
	/* close them all */
	for (i = 0; i < 32; i++)
		close(dmabuf_fd[i]);

	close(heap_fd);
	printf("OK\n");
	return 0;

out:
	while (i > 0) {
		close(dmabuf_fd[i]);
		i--;
	}
	close(heap_fd);
	return ret;
}

/* Test the ioctl version compatibility w/ a smaller structure then expected */
static int dmabuf_heap_alloc_older(int fd, size_t len, unsigned int flags,
				   int *dmabuf_fd)
{
	int ret;
	unsigned int older_alloc_ioctl;
	struct dma_heap_allocation_data_smaller {
		__u64 len;
		__u32 fd;
		__u32 fd_flags;
	} data = {
		.len = len,
		.fd = 0,
		.fd_flags = O_RDWR | O_CLOEXEC,
	};

	older_alloc_ioctl = _IOWR(DMA_HEAP_IOC_MAGIC, 0x0,
				  struct dma_heap_allocation_data_smaller);
	if (!dmabuf_fd)
		return -EINVAL;

	ret = ioctl(fd, older_alloc_ioctl, &data);
	if (ret < 0)
		return ret;
	*dmabuf_fd = (int)data.fd;
	return ret;
}

/* Test the ioctl version compatibility w/ a larger structure then expected */
static int dmabuf_heap_alloc_newer(int fd, size_t len, unsigned int flags,
				   int *dmabuf_fd)
{
	int ret;
	unsigned int newer_alloc_ioctl;
	struct dma_heap_allocation_data_bigger {
		__u64 len;
		__u32 fd;
		__u32 fd_flags;
		__u64 heap_flags;
		__u64 garbage1;
		__u64 garbage2;
		__u64 garbage3;
	} data = {
		.len = len,
		.fd = 0,
		.fd_flags = O_RDWR | O_CLOEXEC,
		.heap_flags = flags,
		.garbage1 = 0xffffffff,
		.garbage2 = 0x88888888,
		.garbage3 = 0x11111111,
	};

	newer_alloc_ioctl = _IOWR(DMA_HEAP_IOC_MAGIC, 0x0,
				  struct dma_heap_allocation_data_bigger);
	if (!dmabuf_fd)
		return -EINVAL;

	ret = ioctl(fd, newer_alloc_ioctl, &data);
	if (ret < 0)
		return ret;

	*dmabuf_fd = (int)data.fd;
	return ret;
}

static int test_alloc_compat(char *heap_name)
{
	int heap_fd = -1, dmabuf_fd = -1;
	int ret;

	heap_fd = dmabuf_heap_open(heap_name);
	if (heap_fd < 0)
		return -1;

	printf("  Testing (theoretical)older alloc compat:  ");
	ret = dmabuf_heap_alloc_older(heap_fd, ONE_MEG, 0, &dmabuf_fd);
	if (ret) {
		printf("FAIL (Older compat allocation failed!)\n");
		ret = -1;
		goto out;
	}
	close(dmabuf_fd);
	printf("OK\n");

	printf("  Testing (theoretical)newer alloc compat:  ");
	ret = dmabuf_heap_alloc_newer(heap_fd, ONE_MEG, 0, &dmabuf_fd);
	if (ret) {
		printf("FAIL (Newer compat allocation failed!)\n");
		ret = -1;
		goto out;
	}
	printf("OK\n");
out:
	if (dmabuf_fd >= 0)
		close(dmabuf_fd);
	if (heap_fd >= 0)
		close(heap_fd);

	return ret;
}

static int test_alloc_errors(char *heap_name)
{
	int heap_fd = -1, dmabuf_fd = -1;
	int ret;

	heap_fd = dmabuf_heap_open(heap_name);
	if (heap_fd < 0)
		return -1;

	printf("  Testing expected error cases:  ");
	ret = dmabuf_heap_alloc(0, ONE_MEG, 0x111111, &dmabuf_fd);
	if (!ret) {
		printf("FAIL (Did not see expected error (invalid fd)!)\n");
		ret = -1;
		goto out;
	}

	ret = dmabuf_heap_alloc(heap_fd, ONE_MEG, 0x111111, &dmabuf_fd);
	if (!ret) {
		printf("FAIL (Did not see expected error (invalid heap flags)!)\n");
		ret = -1;
		goto out;
	}

	ret = dmabuf_heap_alloc_fdflags(heap_fd, ONE_MEG,
					~(O_RDWR | O_CLOEXEC), 0, &dmabuf_fd);
	if (!ret) {
		printf("FAIL (Did not see expected error (invalid fd flags)!)\n");
		ret = -1;
		goto out;
	}

	printf("OK\n");
	ret = 0;
out:
	if (dmabuf_fd >= 0)
		close(dmabuf_fd);
	if (heap_fd >= 0)
		close(heap_fd);

	return ret;
}

int main(void)
{
	DIR *d;
	struct dirent *dir;
	int ret = -1;

	d = opendir(DEVPATH);
	if (!d) {
		printf("No %s directory?\n", DEVPATH);
		return -1;
	}

	while ((dir = readdir(d)) != NULL) {
		if (!strncmp(dir->d_name, ".", 2))
			continue;
		if (!strncmp(dir->d_name, "..", 3))
			continue;

		printf("Testing heap: %s\n", dir->d_name);
		printf("=======================================\n");
		ret = test_alloc_and_import(dir->d_name);
		if (ret)
			break;

		ret = test_alloc_zeroed(dir->d_name, 4 * 1024);
		if (ret)
			break;

		ret = test_alloc_zeroed(dir->d_name, ONE_MEG);
		if (ret)
			break;

		ret = test_alloc_compat(dir->d_name);
		if (ret)
			break;

		ret = test_alloc_errors(dir->d_name);
		if (ret)
			break;
	}
	closedir(d);

	return ret;
}
