/*
 * Copyright (c) 2021 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Common Memory Management Driver Code
 *
 * This file provides common implementation of memory management driver
 * functions, for example, sys_mm_drv_map_region() can use
 * sys_mm_drv_map_page() to map page by page for the whole region.
 * This avoids duplicate implementations of same functionality in
 * different drivers. The implementations here are marked as
 * weak functions so they can be overridden by the driver.
 */

#include <zephyr/kernel.h>
#include <string.h>
#include <zephyr/toolchain.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/check.h>
#include <zephyr/sys/util.h>

#include <zephyr/drivers/mm/system_mm.h>

#include "mm_drv_common.h"

struct k_spinlock sys_mm_drv_common_lock;

bool sys_mm_drv_is_addr_array_aligned(uintptr_t *addr, size_t cnt)
{
	size_t idx;
	bool ret = true;

	for (idx = 0; idx < cnt; idx++) {
		if (!sys_mm_drv_is_addr_aligned(addr[idx])) {
			ret = false;
			break;
		}
	}

	return ret;
}

bool sys_mm_drv_is_virt_region_mapped(void *virt, size_t size)
{
	size_t offset;
	bool ret = true;

	for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) {
		uint8_t *va = (uint8_t *)virt + offset;

		if (sys_mm_drv_page_phys_get(va, NULL) != 0) {
			ret = false;
			break;
		}
	}

	return ret;
}

bool sys_mm_drv_is_virt_region_unmapped(void *virt, size_t size)
{
	size_t offset;
	bool ret = true;

	for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) {
		uint8_t *va = (uint8_t *)virt + offset;

		if (sys_mm_drv_page_phys_get(va, NULL) != -EFAULT) {
			ret = false;
			break;
		}
	}

	return ret;
}

int sys_mm_drv_simple_map_region(void *virt, uintptr_t phys,
				 size_t size, uint32_t flags)
{
	k_spinlock_key_t key;
	int ret = 0;
	size_t offset;

	CHECKIF(!sys_mm_drv_is_addr_aligned(phys) ||
		!sys_mm_drv_is_virt_addr_aligned(virt) ||
		!sys_mm_drv_is_size_aligned(size)) {
		ret = -EINVAL;
		goto out;
	}

	key = k_spin_lock(&sys_mm_drv_common_lock);

	for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) {
		uint8_t *va = (uint8_t *)virt + offset;
		uintptr_t pa = phys + offset;

		int ret2 = sys_mm_drv_map_page(va, pa, flags);

		if (ret2 != 0) {
			__ASSERT(false, "cannot map 0x%lx to %p\n", pa, va);

			ret = ret2;
		}
	}

	k_spin_unlock(&sys_mm_drv_common_lock, key);

out:
	return ret;
}

__weak FUNC_ALIAS(sys_mm_drv_simple_map_region,
		  sys_mm_drv_map_region, int);

int sys_mm_drv_simple_map_array(void *virt, uintptr_t *phys,
				size_t cnt, uint32_t flags)
{
	k_spinlock_key_t key;
	int ret = 0;
	size_t idx, offset;

	CHECKIF(!sys_mm_drv_is_addr_array_aligned(phys, cnt) ||
		!sys_mm_drv_is_virt_addr_aligned(virt)) {
		ret = -EINVAL;
		goto out;
	}

	key = k_spin_lock(&sys_mm_drv_common_lock);

	offset = 0;
	idx = 0;
	while (idx < cnt) {
		uint8_t *va = (uint8_t *)virt + offset;

		int ret2 = sys_mm_drv_map_page(va, phys[idx], flags);

		if (ret2 != 0) {
			__ASSERT(false, "cannot map 0x%lx to %p\n", phys[idx], va);

			ret = ret2;
		}

		offset += CONFIG_MM_DRV_PAGE_SIZE;
		idx++;
	}

	k_spin_unlock(&sys_mm_drv_common_lock, key);

out:
	return ret;
}

__weak FUNC_ALIAS(sys_mm_drv_simple_map_array, sys_mm_drv_map_array, int);

int sys_mm_drv_simple_unmap_region(void *virt, size_t size)
{
	k_spinlock_key_t key;
	int ret = 0;
	size_t offset;

	CHECKIF(!sys_mm_drv_is_virt_addr_aligned(virt) ||
		!sys_mm_drv_is_size_aligned(size)) {
		ret = -EINVAL;
		goto out;
	}

	key = k_spin_lock(&sys_mm_drv_common_lock);

	for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) {
		uint8_t *va = (uint8_t *)virt + offset;

		int ret2 = sys_mm_drv_unmap_page(va);

		if (ret2 != 0) {
			__ASSERT(false, "cannot unmap %p\n", va);

			ret = ret2;
		}
	}

	k_spin_unlock(&sys_mm_drv_common_lock, key);

out:
	return ret;
}

__weak FUNC_ALIAS(sys_mm_drv_simple_unmap_region,
		  sys_mm_drv_unmap_region, int);

int sys_mm_drv_simple_remap_region(void *virt_old, size_t size,
				   void *virt_new)
{
	k_spinlock_key_t key;
	size_t offset;
	int ret = 0;

	CHECKIF(!sys_mm_drv_is_virt_addr_aligned(virt_old) ||
		!sys_mm_drv_is_virt_addr_aligned(virt_new) ||
		!sys_mm_drv_is_size_aligned(size)) {
		ret = -EINVAL;
		goto out;
	}

	if ((POINTER_TO_UINT(virt_new) >= POINTER_TO_UINT(virt_old)) &&
	    (POINTER_TO_UINT(virt_new) < (POINTER_TO_UINT(virt_old) + size))) {
		ret = -EINVAL; /* overlaps */
		goto out;
	}

	key = k_spin_lock(&sys_mm_drv_common_lock);

	if (!sys_mm_drv_is_virt_region_mapped(virt_old, size) ||
	    !sys_mm_drv_is_virt_region_unmapped(virt_new, size)) {
		ret = -EINVAL;
		goto unlock_out;
	}

	for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) {
		uint8_t *va_old = (uint8_t *)virt_old + offset;
		uint8_t *va_new = (uint8_t *)virt_new + offset;
		uintptr_t pa;
		uint32_t flags;
		int ret2;
		bool to_map;

		/*
		 * va_old is mapped as checked above, so no need
		 * to check for return value here.
		 */
		(void)sys_mm_drv_page_phys_get(va_old, &pa);

		to_map = true;
		ret2 = sys_mm_drv_page_flag_get(va_old, &flags);
		if (ret2 != 0) {
			__ASSERT(false, "cannot query page %p\n", va_old);

			ret = ret2;
			to_map = false;
		}

		ret2 = sys_mm_drv_unmap_page(va_old);
		if (ret2 != 0) {
			__ASSERT(false, "cannot unmap %p\n", va_old);

			ret = ret2;
		}

		if (!to_map) {
			/*
			 * Cannot retrieve flags of mapped virtual memory.
			 * Skip mapping this page as we don't want to map
			 * with unknown random flags.
			 */
			continue;
		}

		ret2 = sys_mm_drv_map_page(va_new, pa, flags);
		if (ret2 != 0) {
			__ASSERT(false, "cannot map 0x%lx to %p\n", pa, va_new);

			ret = ret2;
		}
	}

unlock_out:
	k_spin_unlock(&sys_mm_drv_common_lock, key);

out:
	return ret;
}

__weak FUNC_ALIAS(sys_mm_drv_simple_remap_region,
		  sys_mm_drv_remap_region, int);

int sys_mm_drv_simple_move_region(void *virt_old, size_t size,
				  void *virt_new, uintptr_t phys_new)
{
	k_spinlock_key_t key;
	size_t offset;
	int ret = 0;

	CHECKIF(!sys_mm_drv_is_addr_aligned(phys_new) ||
		!sys_mm_drv_is_virt_addr_aligned(virt_old) ||
		!sys_mm_drv_is_virt_addr_aligned(virt_new) ||
		!sys_mm_drv_is_size_aligned(size)) {
		ret = -EINVAL;
		goto out;
	}

	if ((POINTER_TO_UINT(virt_new) >= POINTER_TO_UINT(virt_old)) &&
	    (POINTER_TO_UINT(virt_new) < (POINTER_TO_UINT(virt_old) + size))) {
		ret = -EINVAL; /* overlaps */
		goto out;
	}

	key = k_spin_lock(&sys_mm_drv_common_lock);

	if (!sys_mm_drv_is_virt_region_mapped(virt_old, size) ||
	    !sys_mm_drv_is_virt_region_unmapped(virt_new, size)) {
		ret = -EINVAL;
		goto unlock_out;
	}

	for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) {
		uint8_t *va_old = (uint8_t *)virt_old + offset;
		uint8_t *va_new = (uint8_t *)virt_new + offset;
		uintptr_t pa = phys_new + offset;
		uint32_t flags;
		int ret2;

		ret2 = sys_mm_drv_page_flag_get(va_old, &flags);
		if (ret2 != 0) {
			__ASSERT(false, "cannot query page %p\n", va_old);

			ret = ret2;
		} else {
			/*
			 * Only map the new page when we can retrieve
			 * flags of the old mapped page as We don't
			 * want to map with unknown random flags.
			 */
			ret2 = sys_mm_drv_map_page(va_new, pa, flags);
			if (ret2 != 0) {
				__ASSERT(false, "cannot map 0x%lx to %p\n", pa, va_new);

				ret = ret2;
			} else {
				(void)memcpy(va_new, va_old,
					     CONFIG_MM_DRV_PAGE_SIZE);
			}
		}

		ret2 = sys_mm_drv_unmap_page(va_old);
		if (ret2 != 0) {
			__ASSERT(false, "cannot unmap %p\n", va_old);

			ret = ret2;
		}
	}

unlock_out:
	k_spin_unlock(&sys_mm_drv_common_lock, key);

out:
	return ret;
}

__weak FUNC_ALIAS(sys_mm_drv_simple_move_region,
		  sys_mm_drv_move_region, int);

int sys_mm_drv_simple_move_array(void *virt_old, size_t size,
				 void *virt_new,
				 uintptr_t *phys_new, size_t phys_cnt)
{
	k_spinlock_key_t key;
	size_t idx, offset;
	int ret = 0;

	CHECKIF(!sys_mm_drv_is_addr_array_aligned(phys_new, phys_cnt) ||
		!sys_mm_drv_is_virt_addr_aligned(virt_old) ||
		!sys_mm_drv_is_virt_addr_aligned(virt_new) ||
		!sys_mm_drv_is_size_aligned(size)) {
		ret = -EINVAL;
		goto out;
	}

	if ((POINTER_TO_UINT(virt_new) >= POINTER_TO_UINT(virt_old)) &&
	    (POINTER_TO_UINT(virt_new) < (POINTER_TO_UINT(virt_old) + size))) {
		ret = -EINVAL; /* overlaps */
		goto out;
	}

	key = k_spin_lock(&sys_mm_drv_common_lock);

	if (!sys_mm_drv_is_virt_region_mapped(virt_old, size) ||
	    !sys_mm_drv_is_virt_region_unmapped(virt_new, size)) {
		ret = -EINVAL;
		goto unlock_out;
	}

	offset = 0;
	idx = 0;
	while (idx < phys_cnt) {
		uint8_t *va_old = (uint8_t *)virt_old + offset;
		uint8_t *va_new = (uint8_t *)virt_new + offset;
		uint32_t flags;
		int ret2;

		ret2 = sys_mm_drv_page_flag_get(va_old, &flags);
		if (ret2 != 0) {
			__ASSERT(false, "cannot query page %p\n", va_old);

			ret = ret2;
		} else {
			/*
			 * Only map the new page when we can retrieve
			 * flags of the old mapped page as We don't
			 * want to map with unknown random flags.
			 */
			ret2 = sys_mm_drv_map_page(va_new, phys_new[idx], flags);
			if (ret2 != 0) {
				__ASSERT(false, "cannot map 0x%lx to %p\n",
					 phys_new[idx], va_new);

				ret = ret2;
			} else {
				(void)memcpy(va_new, va_old,
					     CONFIG_MM_DRV_PAGE_SIZE);
			}
		}

		ret2 = sys_mm_drv_unmap_page(va_old);

		if (ret2 != 0) {
			__ASSERT(false, "cannot unmap %p\n", va_old);

			ret = ret2;
		}

		offset += CONFIG_MM_DRV_PAGE_SIZE;
		idx++;
	}

unlock_out:
	k_spin_unlock(&sys_mm_drv_common_lock, key);

out:
	return ret;
}

__weak FUNC_ALIAS(sys_mm_drv_simple_move_array,
		  sys_mm_drv_move_array, int);

int sys_mm_drv_simple_update_region_flags(void *virt, size_t size, uint32_t flags)
{
	k_spinlock_key_t key;
	int ret = 0;
	size_t offset;

	CHECKIF(!sys_mm_drv_is_virt_addr_aligned(virt) ||
		!sys_mm_drv_is_size_aligned(size)) {
		ret = -EINVAL;
		goto out;
	}

	key = k_spin_lock(&sys_mm_drv_common_lock);

	for (offset = 0; offset < size; offset += CONFIG_MM_DRV_PAGE_SIZE) {
		uint8_t *va = (uint8_t *)virt + offset;

		int ret2 = sys_mm_drv_update_page_flags(va, flags);

		if (ret2 != 0) {
			__ASSERT(false, "cannot update flags %p\n", va);

			ret = ret2;
		}
	}

	k_spin_unlock(&sys_mm_drv_common_lock, key);

out:
	return ret;
}

__weak FUNC_ALIAS(sys_mm_drv_simple_update_region_flags,
		  sys_mm_drv_update_region_flags, int);
