/*
 * Copyright (c) 2024, Tenstorrent AI ULC
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <stddef.h>
#include <sys/types.h>

#include <kernel_arch_interface.h>
#include <zephyr/kernel.h>
#include <zephyr/kernel/mm.h>
#include <zephyr/sys/fdtable.h>
#include <zephyr/posix/sys/mman.h>
#include <zephyr/posix/unistd.h>

#define _page_size COND_CODE_1(CONFIG_MMU, (CONFIG_MMU_PAGE_SIZE), (PAGE_SIZE))

int zvfs_ioctl(int fd, int cmd, va_list args);

static int p2z(int prot, int pflags)
{
	bool rw = (prot & PROT_WRITE) != 0;
	bool ex = (prot & PROT_EXEC) != 0;
	bool fixed = (pflags & MAP_FIXED) != 0;
	bool shared = (pflags & MAP_SHARED) != 0;
	bool private = (pflags & MAP_PRIVATE) != 0;

	if (!(shared ^ private)) {
		return -1;
	}

	return (rw * K_MEM_PERM_RW) | (ex * K_MEM_PERM_EXEC) | (fixed * K_MEM_DIRECT_MAP);
}

static inline int zvfs_ioctl_wrap(int fd, int cmd, ...)
{
	int ret;
	va_list args;

	va_start(args, cmd);
	ret = zvfs_ioctl(fd, cmd, args);
	va_end(args);

	return ret;
}

void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off)
{
	void *virt;
	uintptr_t phys;
	int zflags = p2z(prot, flags);

	if ((len == 0) || (zflags == -1)) {
		errno = EINVAL;
		return MAP_FAILED;
	}

	if ((flags & MAP_ANONYMOUS) != 0) {
		/* force behaviour to be in-line with Linux, fd is ignored */
		fd = -1;
	}

	if (fd > 0) {
		/* non-anonymous mapping */
		virt = NULL;
		if (zvfs_ioctl_wrap(fd, ZFD_IOCTL_MMAP, addr, len, prot, flags, off, &virt) < 0) {
			return MAP_FAILED;
		}

		return virt;
	}

	if (!IS_ENABLED(CONFIG_MMU)) {
		errno = ENOTSUP;
		return MAP_FAILED;
	}

	if ((flags & MAP_FIXED) == 0) {
		/* anonymous mapping */
		virt = k_mem_map(len, zflags);
	} else {
		/* a physical mapping. Care should be taken not to map the same page twice */
		virt = NULL;
		phys = POINTER_TO_UINT(addr);
		k_mem_map_phys_bare((uint8_t **)&virt, phys, (size_t)ROUND_UP(len, _page_size),
				    zflags);
	}

	if (virt == NULL) {
		errno = ENOMEM;
		return MAP_FAILED;
	}

	return virt;
}

int msync(void *addr, size_t length, int flags)
{
	ARG_UNUSED(addr);
	ARG_UNUSED(length);
	ARG_UNUSED(flags);

	return 0;
}

int munmap(void *addr, size_t len)
{
	if (len == 0) {
		errno = EINVAL;
		return -1;
	}

	if (!IS_ENABLED(CONFIG_MMU)) {
		/* cannot munmap without an MPU */
		errno = ENOTSUP;
		return -1;
	}

	uintptr_t phys = 0;

	if (arch_page_phys_get(addr, &phys) == 0) {
		k_mem_unmap(addr, ROUND_UP(len, _page_size));
	}

	return 0;
}
