/*
 * Copyright (c) 2017 Linaro Limited.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <device.h>
#include <init.h>
#include <kernel.h>
#include <soc.h>

#include <arch/arm/cortex_m/mpu/arm_core_mpu_dev.h>
#include <linker/linker-defs.h>

#define LOG_LEVEL CONFIG_MPU_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(mpu);

/*
 * Maximum number of dynamic memory partitions that may be supplied to the MPU
 * driver for programming during run-time. Note that the actual number of the
 * available MPU regions for dynamic programming depends on the number of the
 * static MPU regions currently being programmed, and the total number of HW-
 * available MPU regions. This macro is only used internally in function
 * z_arch_configure_dynamic_mpu_regions(), to reserve sufficient area for the
 * array of dynamic regions passed to the underlying driver.
 */
#if defined(CONFIG_USERSPACE)
#define _MAX_DYNAMIC_MPU_REGIONS_NUM \
	CONFIG_MAX_DOMAIN_PARTITIONS + /* User thread stack */ 1 + \
	(IS_ENABLED(CONFIG_MPU_STACK_GUARD) ? 1 : 0)
#else
#define _MAX_DYNAMIC_MPU_REGIONS_NUM \
	(IS_ENABLED(CONFIG_MPU_STACK_GUARD) ? 1 : 0)
#endif /* CONFIG_USERSPACE */

/* Convenience macros to denote the start address and the size of the system
 * memory area, where dynamic memory regions may be programmed at run-time.
 */
#if defined(CONFIG_USERSPACE)
#define _MPU_DYNAMIC_REGIONS_AREA_START ((u32_t)&_app_smem_start)
#else
#define _MPU_DYNAMIC_REGIONS_AREA_START ((u32_t)&__kernel_ram_start)
#endif /* CONFIG_USERSPACE */
#define _MPU_DYNAMIC_REGIONS_AREA_SIZE ((u32_t)&__kernel_ram_end - \
		_MPU_DYNAMIC_REGIONS_AREA_START)

/**
 * @brief Use the HW-specific MPU driver to program
 *        the static MPU regions.
 *
 * Program the static MPU regions using the HW-specific MPU driver. The
 * function is meant to be invoked only once upon system initialization.
 *
 * If the function attempts to configure a number of regions beyond the
 * MPU HW limitations, the system behavior will be undefined.
 *
 * For some MPU architectures, such as the unmodified ARMv8-M MPU,
 * the function must execute with MPU enabled.
 */
void z_arch_configure_static_mpu_regions(void)
{
#if defined(CONFIG_COVERAGE_GCOV) && defined(CONFIG_USERSPACE)
		const struct k_mem_partition gcov_region =
		{
		.start = (u32_t)&__gcov_bss_start,
		.size = (u32_t)&__gcov_bss_size,
		.attr = K_MEM_PARTITION_P_RW_U_RW,
		};
#endif /* CONFIG_COVERAGE_GCOV && CONFIG_USERSPACE */
#if defined(CONFIG_NOCACHE_MEMORY)
		const struct k_mem_partition nocache_region =
		{
		.start = (u32_t)&_nocache_ram_start,
		.size = (u32_t)&_nocache_ram_size,
		.attr = K_MEM_PARTITION_P_RW_U_NA_NOCACHE,
		};
#endif /* CONFIG_NOCACHE_MEMORY */
#if defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT)
		const struct k_mem_partition ramfunc_region =
		{
		.start = (u32_t)&_ramfunc_ram_start,
		.size = (u32_t)&_ramfunc_ram_size,
		.attr = K_MEM_PARTITION_P_RX_U_RX,
		};
#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */

	/* Define a constant array of k_mem_partition objects
	 * to hold the configuration of the respective static
	 * MPU regions.
	 */
	const struct k_mem_partition *static_regions[] = {
#if defined(CONFIG_COVERAGE_GCOV) && defined(CONFIG_USERSPACE)
		&gcov_region,
#endif /* CONFIG_COVERAGE_GCOV && CONFIG_USERSPACE */
#if defined(CONFIG_NOCACHE_MEMORY)
		&nocache_region,
#endif /* CONFIG_NOCACHE_MEMORY */
#if defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT)
		&ramfunc_region
#endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */
	};

	/* Configure the static MPU regions within firmware SRAM boundaries.
	 * Start address of the image is given by _image_ram_start. The end
	 * of the firmware SRAM area is marked by __kernel_ram_end, taking
	 * into account the unused SRAM area, as well.
	 */
	arm_core_mpu_configure_static_mpu_regions(static_regions,
		ARRAY_SIZE(static_regions),
		(u32_t)&_image_ram_start,
		(u32_t)&__kernel_ram_end);

#if defined(CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS)
	/* Define a constant array of k_mem_partition objects that holds the
	 * boundaries of the areas, inside which dynamic region programming
	 * is allowed. The information is passed to the underlying driver at
	 * initialization.
	 */
	const struct k_mem_partition dyn_region_areas[] = {
		{
		.start = _MPU_DYNAMIC_REGIONS_AREA_START,
		.size =  _MPU_DYNAMIC_REGIONS_AREA_SIZE,
		}
	};

	arm_core_mpu_mark_areas_for_dynamic_regions(dyn_region_areas,
		ARRAY_SIZE(dyn_region_areas));
#endif /* CONFIG_MPU_REQUIRES_NON_OVERLAPPING_REGIONS */
}

/**
 * @brief Use the HW-specific MPU driver to program
 *        the dynamic MPU regions.
 *
 * Program the dynamic MPU regions using the HW-specific MPU
 * driver. This function is meant to be invoked every time the
 * memory map is to be re-programmed, e.g during thread context
 * switch, entering user mode, reconfiguring memory domain, etc.
 *
 * For some MPU architectures, such as the unmodified ARMv8-M MPU,
 * the function must execute with MPU enabled.
 */
void z_arch_configure_dynamic_mpu_regions(struct k_thread *thread)
{
	/* Define an array of k_mem_partition objects to hold the configuration
	 * of the respective dynamic MPU regions to be programmed for
	 * the given thread. The array of partitions (along with its
	 * actual size) will be supplied to the underlying MPU driver.
	 */
	struct k_mem_partition *dynamic_regions[_MAX_DYNAMIC_MPU_REGIONS_NUM];

	u8_t region_num = 0U;

#if defined(CONFIG_USERSPACE)
	struct k_mem_partition thread_stack;

	/* Memory domain */
	LOG_DBG("configure thread %p's domain", thread);
	struct k_mem_domain *mem_domain = thread->mem_domain_info.mem_domain;

	if (mem_domain) {
		LOG_DBG("configure domain: %p", mem_domain);
		u32_t num_partitions = mem_domain->num_partitions;
		struct k_mem_partition partition;
		int i;

		LOG_DBG("configure domain: %p", mem_domain);

		for (i = 0; i < CONFIG_MAX_DOMAIN_PARTITIONS; i++) {
			partition = mem_domain->partitions[i];
			if (partition.size == 0) {
				/* Zero size indicates a non-existing
				 * memory partition.
				 */
				continue;
			}
			LOG_DBG("set region 0x%x 0x%x",
				partition.start, partition.size);
			__ASSERT(region_num < _MAX_DYNAMIC_MPU_REGIONS_NUM,
				"Out-of-bounds error for dynamic region map.");
			dynamic_regions[region_num] =
				&mem_domain->partitions[i];

			region_num++;
			num_partitions--;
			if (num_partitions == 0U) {
				break;
			}
		}
	}
	/* Thread user stack */
	LOG_DBG("configure user thread %p's context", thread);
	if (thread->arch.priv_stack_start) {
		u32_t base = (u32_t)thread->stack_obj;
		u32_t size = thread->stack_info.size +
			(thread->stack_info.start - base);

		__ASSERT(region_num < _MAX_DYNAMIC_MPU_REGIONS_NUM,
			"Out-of-bounds error for dynamic region map.");
		thread_stack = (const struct k_mem_partition)
			{base, size, K_MEM_PARTITION_P_RW_U_RW};

		dynamic_regions[region_num] = &thread_stack;

		region_num++;
	}
#endif /* CONFIG_USERSPACE */

#if defined(CONFIG_MPU_STACK_GUARD)
	struct k_mem_partition guard;

	/* Privileged stack guard */
	u32_t guard_start;
#if defined(CONFIG_USERSPACE)
	if (thread->arch.priv_stack_start) {
		guard_start = thread->arch.priv_stack_start;
	} else {
		guard_start = thread->stack_info.start -
			MPU_GUARD_ALIGN_AND_SIZE;
		__ASSERT((u32_t)thread->stack_obj == guard_start,
		"Guard start (0x%x) not beginning at stack object (0x%x)\n",
		guard_start, (u32_t)thread->stack_obj);
	}
#else
	guard_start = thread->stack_info.start -
		MPU_GUARD_ALIGN_AND_SIZE;
#endif /* CONFIG_USERSPACE */

	__ASSERT(region_num < _MAX_DYNAMIC_MPU_REGIONS_NUM,
		"Out-of-bounds error for dynamic region map.");
	guard = (const struct k_mem_partition)
	{
		guard_start,
		MPU_GUARD_ALIGN_AND_SIZE,
		K_MEM_PARTITION_P_RO_U_NA
	};
	dynamic_regions[region_num] = &guard;

	region_num++;
#endif /* CONFIG_MPU_STACK_GUARD */

	/* Configure the dynamic MPU regions */
	arm_core_mpu_configure_dynamic_mpu_regions(
		(const struct k_mem_partition **)dynamic_regions,
		region_num);
}

#if defined(CONFIG_USERSPACE)

/**
 * @brief Get the maximum number of partitions for a memory domain
 *        that is supported by the MPU hardware, and with respect
 *        to the current static memory region configuration.
 */
int z_arch_mem_domain_max_partitions_get(void)
{
	int available_regions = arm_core_mpu_get_max_available_dyn_regions();

	available_regions -=
		ARM_CORE_MPU_NUM_MPU_REGIONS_FOR_THREAD_STACK;

	if (IS_ENABLED(CONFIG_MPU_STACK_GUARD)) {
		available_regions -=
			ARM_CORE_MPU_NUM_MPU_REGIONS_FOR_MPU_STACK_GUARD;
	}

	return ARM_CORE_MPU_MAX_DOMAIN_PARTITIONS_GET(available_regions);
}

/**
 * @brief Configure the memory domain of the thread.
 */
void z_arch_mem_domain_configure(struct k_thread *thread)
{
	/* Request to configure memory domain for a thread.
	 * This triggers re-programming of the entire dynamic
	 * memory map.
	 */
	z_arch_configure_dynamic_mpu_regions(thread);
}

/*
 * @brief Reset the MPU configuration related to the memory domain
 *        partitions
 *
 * @param domain pointer to the memory domain (must be valid)
 */
void z_arch_mem_domain_destroy(struct k_mem_domain *domain)
{
	/* This function will reset the access permission configuration
	 * of the active partitions of the memory domain.
	 */
	int i;
	struct k_mem_partition partition;
	/* Partitions belonging to the memory domain will be reset
	 * to default (Privileged RW, Unprivileged NA) permissions.
	 */
	k_mem_partition_attr_t reset_attr = K_MEM_PARTITION_P_RW_U_NA;

	for (i = 0; i < CONFIG_MAX_DOMAIN_PARTITIONS; i++) {
		partition = domain->partitions[i];
		if (partition.size == 0U) {
			/* Zero size indicates a non-existing
			 * memory partition.
			 */
			continue;
		}
		arm_core_mpu_mem_partition_config_update(&partition,
			&reset_attr);
	}
}

/*
 * @brief Remove a partition from the memory domain
 *
 * @param domain pointer to the memory domain (must be valid
 * @param partition_id the ID (sequence) number of the memory domain
 *        partition (must be a valid partition).
 */
void z_arch_mem_domain_partition_remove(struct k_mem_domain *domain,
				       u32_t  partition_id)
{
	/* Request to remove a partition from a memory domain.
	 * This resets the access permissions of the partition
	 * to default (Privileged RW, Unprivileged NA).
	 */
	k_mem_partition_attr_t reset_attr = K_MEM_PARTITION_P_RW_U_NA;

	arm_core_mpu_mem_partition_config_update(
		&domain->partitions[partition_id], &reset_attr);
}

void z_arch_mem_domain_partition_add(struct k_mem_domain *domain,
				    u32_t partition_id)
{
	/* No-op on this architecture */
}

/*
 * Validate the given buffer is user accessible or not
 */
int z_arch_buffer_validate(void *addr, size_t size, int write)
{
	return arm_core_mpu_buffer_validate(addr, size, write);
}

#endif /* CONFIG_USERSPACE */
