/*
 * Copyright (c) 2019 Synopsys.
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#ifndef ZEPHYR_ARCH_ARC_CORE_MPU_ARC_MPU_V4_INTERNAL_H_
#define ZEPHYR_ARCH_ARC_CORE_MPU_ARC_MPU_V4_INTERNAL_H_

#define AUX_MPU_RPER_SID1       0x10000
/* valid mask: SID1+secure+valid */
#define AUX_MPU_RPER_VALID_MASK ((0x1) | AUX_MPU_RPER_SID1 | AUX_MPU_ATTR_S)

#define AUX_MPU_RPER_ATTR_MASK (0x1FF)

/* For MPU version 4, the minimum protection region size is 32 bytes */
#define ARC_FEATURE_MPU_ALIGNMENT_BITS 5

#define CALC_REGION_END_ADDR(start, size) \
	(start + size - (1 << ARC_FEATURE_MPU_ALIGNMENT_BITS))

/* ARC MPU version 4 does not support mpu region overlap in hardware
 * so if we want to allocate MPU region dynamically, e.g. thread stack,
 * memory domain from a background region, a dynamic region splitting
 * approach is designed. pls see comments in
 *          _dynamic_region_allocate_and_init
 * But this approach has an impact on performance of thread switch.
 * As a trade off, we can use the default mpu region as the background region
 * to avoid the dynamic region splitting. This will give more privilege to
 * codes in kernel mode which can access the memory region not covered by
 * explicit mpu entry. Considering  memory protection is mainly used to
 * isolate malicious codes in user mode, it makes sense to get better
 * thread switch performance through default mpu region.
 * CONFIG_MPU_GAP_FILLING is used to turn this on/off.
 *
 */
#if defined(CONFIG_MPU_GAP_FILLING)

#if defined(CONFIG_USERSPACE) && defined(CONFIG_MPU_STACK_GUARD)
/* 1 for stack guard , 1 for user thread, 1 for split */
#define MPU_REGION_NUM_FOR_THREAD 3
#elif defined(CONFIG_USERSPACE) || defined(CONFIG_MPU_STACK_GUARD)
/* 1 for stack guard or user thread stack , 1 for split */
#define MPU_REGION_NUM_FOR_THREAD 2
#else
#define MPU_REGION_NUM_FOR_THREAD 0
#endif

#define MPU_DYNAMIC_REGION_AREAS_NUM 2

/**
 * @brief internal structure holding information of
 * memory areas where dynamic MPU programming is allowed.
 */
struct dynamic_region_info {
	uint8_t index;
	uint32_t base;
	uint32_t size;
	uint32_t attr;
};

static uint8_t dynamic_regions_num;
static uint8_t dynamic_region_index;

/**
 * Global array, holding the MPU region index of
 * the memory region inside which dynamic memory
 * regions may be configured.
 */
static struct dynamic_region_info dyn_reg_info[MPU_DYNAMIC_REGION_AREAS_NUM];
#endif /* CONFIG_MPU_GAP_FILLING */

static uint8_t static_regions_num;

#ifdef CONFIG_ARC_NORMAL_FIRMWARE
/* \todo through secure service to access mpu */
static inline void _region_init(uint32_t index, uint32_t region_addr, uint32_t size,
				uint32_t region_attr)
{
}

static inline void _region_set_attr(uint32_t index, uint32_t attr)
{

}

static inline uint32_t _region_get_attr(uint32_t index)
{
	return 0;
}

static inline uint32_t _region_get_start(uint32_t index)
{
	return 0;
}

static inline void _region_set_start(uint32_t index, uint32_t start)
{

}

static inline uint32_t _region_get_end(uint32_t index)
{
	return 0;
}

static inline void _region_set_end(uint32_t index, uint32_t end)
{
}

/**
 * This internal function probes the given addr's MPU index.if not
 * in MPU, returns error
 */
static inline int _mpu_probe(uint32_t addr)
{
	return -EINVAL;
}

/**
 * This internal function checks if MPU region is enabled or not
 */
static inline bool _is_enabled_region(uint32_t r_index)
{
	return false;
}

/**
 * This internal function check if the region is user accessible or not
 */
static inline bool _is_user_accessible_region(uint32_t r_index, int write)
{
	return false;
}
#else /* CONFIG_ARC_NORMAL_FIRMWARE */
/* the following functions are prepared for SECURE_FIRMWARE */
static inline void _region_init(uint32_t index, uint32_t region_addr, uint32_t size,
				uint32_t region_attr)
{
	if (size < (1 << ARC_FEATURE_MPU_ALIGNMENT_BITS)) {
		size = (1 << ARC_FEATURE_MPU_ALIGNMENT_BITS);
	}

	if (region_attr) {
		region_attr &= AUX_MPU_RPER_ATTR_MASK;
		region_attr |=  AUX_MPU_RPER_VALID_MASK;
	}

	z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index);
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_RSTART, region_addr);
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_REND,
			CALC_REGION_END_ADDR(region_addr, size));
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_RPER, region_attr);
}

static inline void _region_set_attr(uint32_t index, uint32_t attr)
{
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index);
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_RPER, attr |
				 AUX_MPU_RPER_VALID_MASK);
}

static inline uint32_t _region_get_attr(uint32_t index)
{
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index);

	return z_arc_v2_aux_reg_read(_ARC_V2_MPU_RPER);
}

static inline uint32_t _region_get_start(uint32_t index)
{
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index);

	return z_arc_v2_aux_reg_read(_ARC_V2_MPU_RSTART);
}

static inline void _region_set_start(uint32_t index, uint32_t start)
{
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index);
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_RSTART, start);
}

static inline uint32_t _region_get_end(uint32_t index)
{
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index);

	return z_arc_v2_aux_reg_read(_ARC_V2_MPU_REND) +
		(1 << ARC_FEATURE_MPU_ALIGNMENT_BITS);
}

static inline void _region_set_end(uint32_t index, uint32_t end)
{
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, index);
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_REND, end -
		(1 << ARC_FEATURE_MPU_ALIGNMENT_BITS));
}

/**
 * This internal function probes the given addr's MPU index.if not
 * in MPU, returns error
 */
static inline int _mpu_probe(uint32_t addr)
{
	uint32_t val;

	z_arc_v2_aux_reg_write(_ARC_V2_MPU_PROBE, addr);
	val = z_arc_v2_aux_reg_read(_ARC_V2_MPU_INDEX);

	/* if no match or multiple regions match, return error */
	if (val & 0xC0000000) {
		return -EINVAL;
	} else {
		return val;
	}
}

/**
 * This internal function checks if MPU region is enabled or not
 */
static inline bool _is_enabled_region(uint32_t r_index)
{
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, r_index);
	return ((z_arc_v2_aux_reg_read(_ARC_V2_MPU_RPER) &
		 AUX_MPU_RPER_VALID_MASK) == AUX_MPU_RPER_VALID_MASK);
}

/**
 * This internal function check if the region is user accessible or not
 */
static inline bool _is_user_accessible_region(uint32_t r_index, int write)
{
	uint32_t r_ap;

	z_arc_v2_aux_reg_write(_ARC_V2_MPU_INDEX, r_index);
	r_ap = z_arc_v2_aux_reg_read(_ARC_V2_MPU_RPER);
	r_ap &= AUX_MPU_RPER_ATTR_MASK;

	if (write) {
		return ((r_ap & (AUX_MPU_ATTR_UW | AUX_MPU_ATTR_KW)) ==
			(AUX_MPU_ATTR_UW | AUX_MPU_ATTR_KW));
	}

	return ((r_ap & (AUX_MPU_ATTR_UR | AUX_MPU_ATTR_KR)) ==
		(AUX_MPU_ATTR_UR | AUX_MPU_ATTR_KR));
}

#endif /* CONFIG_ARC_NORMAL_FIRMWARE */

/**
 * This internal function checks the area given by (start, size)
 * and returns the index if the area match one MPU entry
 */
static inline int _get_region_index(uint32_t start, uint32_t size)
{
	int index = _mpu_probe(start);

	if (index > 0 && index == _mpu_probe(start + size - 1)) {
		return index;
	}

	return -EINVAL;
}

#if defined(CONFIG_MPU_GAP_FILLING)
/**
 * This internal function allocates a dynamic MPU region and returns
 * the index or error
 */
static inline int _dynamic_region_allocate_index(void)
{
	if (dynamic_region_index >= get_num_regions()) {
		LOG_ERR("no enough mpu entries %d", dynamic_region_index);
		return -EINVAL;
	}

	return dynamic_region_index++;
}

/* @brief allocate and init a dynamic MPU region
 *
 * This internal function performs the allocation and initialization of
 * a dynamic MPU region
 *
 * @param base region base
 * @param size region size
 * @param attr region attribute
 * @return  <0 failure, >0  allocated dynamic region index
 */
static int _dynamic_region_allocate_and_init(uint32_t base, uint32_t size,
	 uint32_t attr)
{
	int u_region_index = _get_region_index(base, size);
	int region_index;

	LOG_DBG("Region info: base 0x%x size 0x%x attr 0x%x", base, size, attr);

	if (u_region_index == -EINVAL) {
		/* no underlying region */

		region_index = _dynamic_region_allocate_index();

		if (region_index > 0) {
		/* a new region */
			_region_init(region_index, base, size, attr);
		}

		return region_index;
	}

	/*
	 * The new memory region is to be placed inside the underlying
	 * region, possibly splitting the underlying region into two.
	 */

	uint32_t u_region_start = _region_get_start(u_region_index);
	uint32_t u_region_end = _region_get_end(u_region_index);
	uint32_t u_region_attr = _region_get_attr(u_region_index);
	uint32_t end = base + size;


	if ((base == u_region_start) && (end == u_region_end)) {
		/* The new region overlaps entirely with the
		 * underlying region. In this case we simply
		 * update the partition attributes of the
		 * underlying region with those of the new
		 * region.
		 */
		_region_init(u_region_index, base, size, attr);
		region_index = u_region_index;
	} else if (base == u_region_start) {
		/* The new region starts exactly at the start of the
		 * underlying region; the start of the underlying
		 * region needs to be set to the end of the new region.
		 */
		_region_set_start(u_region_index, base + size);
		_region_set_attr(u_region_index, u_region_attr);

		region_index = _dynamic_region_allocate_index();

		if (region_index > 0) {
			_region_init(region_index, base, size, attr);
		}

	} else if (end == u_region_end) {
		/* The new region ends exactly at the end of the
		 * underlying region; the end of the underlying
		 * region needs to be set to the start of the
		 * new region.
		 */
		_region_set_end(u_region_index, base);
		_region_set_attr(u_region_index, u_region_attr);

		region_index = _dynamic_region_allocate_index();

		if (region_index > 0) {
			_region_init(region_index, base, size, attr);
		}

	} else {
		/* The new region lies strictly inside the
		 * underlying region, which needs to split
		 * into two regions.
		 */

		_region_set_end(u_region_index, base);
		_region_set_attr(u_region_index, u_region_attr);

		region_index = _dynamic_region_allocate_index();

		if (region_index > 0) {
			_region_init(region_index, base, size, attr);

			region_index = _dynamic_region_allocate_index();

			if (region_index > 0) {
				_region_init(region_index, base + size,
				 u_region_end - end, u_region_attr);
			}
		}
	}

	return region_index;
}

/* @brief reset the dynamic MPU regions
 *
 * This internal function performs the reset of dynamic MPU regions
 */
static void _mpu_reset_dynamic_regions(void)
{
	uint32_t i;
	uint32_t num_regions = get_num_regions();

	for (i = static_regions_num; i < num_regions; i++) {
		_region_init(i, 0, 0, 0);
	}

	for (i = 0U; i < dynamic_regions_num; i++) {
		_region_init(
			dyn_reg_info[i].index,
			dyn_reg_info[i].base,
			dyn_reg_info[i].size,
			dyn_reg_info[i].attr);
	}

	/* dynamic regions are after static regions */
	dynamic_region_index = static_regions_num;
}

/**
 * @brief configure the base address and size for an MPU region
 *
 * @param   type    MPU region type
 * @param   base    base address in RAM
 * @param   size    size of the region
 */
static inline int _mpu_configure(uint8_t type, uint32_t base, uint32_t size)
{
	uint32_t region_attr = get_region_attr_by_type(type);

	return _dynamic_region_allocate_and_init(base, size, region_attr);
}
#else
/**
 * This internal function is utilized by the MPU driver to parse the intent
 * type (i.e. THREAD_STACK_REGION) and return the correct region index.
 */
static inline int get_region_index_by_type(uint32_t type)
{
	/*
	 * The new MPU regions are allocated per type after the statically
	 * configured regions. The type is one-indexed rather than
	 * zero-indexed.
	 *
	 * For ARC MPU v2, the smaller index has higher priority, so the
	 * index is allocated in reverse order. Static regions start from
	 * the biggest index, then thread related regions.
	 *
	 */
	switch (type) {
	case THREAD_STACK_USER_REGION:
		return static_regions_num + THREAD_STACK_REGION;
	case THREAD_STACK_REGION:
	case THREAD_APP_DATA_REGION:
	case THREAD_STACK_GUARD_REGION:
		return static_regions_num + type;
	case THREAD_DOMAIN_PARTITION_REGION:
#if defined(CONFIG_MPU_STACK_GUARD)
		return static_regions_num + type;
#else
		/*
		 * Start domain partition region from stack guard region
		 * since stack guard is not enabled.
		 */
		return static_regions_num + type - 1;
#endif
	default:
		__ASSERT(0, "Unsupported type");
		return -EINVAL;
	}
}

/**
 * @brief configure the base address and size for an MPU region
 *
 * @param   type    MPU region type
 * @param   base    base address in RAM
 * @param   size    size of the region
 */
static inline int _mpu_configure(uint8_t type, uint32_t base, uint32_t size)
{
	int region_index =  get_region_index_by_type(type);
	uint32_t region_attr = get_region_attr_by_type(type);

	LOG_DBG("Region info: 0x%x 0x%x", base, size);

	if (region_attr == 0U || region_index < 0) {
		return -EINVAL;
	}

	_region_init(region_index, base, size, region_attr);

	return 0;
}
#endif

/* ARC Core MPU Driver API Implementation for ARC MPUv3 */

/**
 * @brief enable the MPU
 */
void arc_core_mpu_enable(void)
{
#ifdef CONFIG_ARC_SECURE_FIRMWARE
/* the default region:
 * secure:0x8000, SID:0x10000, KW:0x100 KR:0x80
 */
#define MPU_ENABLE_ATTR	0x18180
#else
#define MPU_ENABLE_ATTR	0
#endif
	arc_core_mpu_default(MPU_ENABLE_ATTR);
}

/**
 * @brief disable the MPU
 */
void arc_core_mpu_disable(void)
{
	/* MPU is always enabled, use default region to
	 * simulate MPU disable
	 */
	arc_core_mpu_default(REGION_ALL_ATTR | AUX_MPU_ATTR_S |
				AUX_MPU_RPER_SID1);
}

/**
 * @brief configure the thread's mpu regions
 *
 * @param thread the target thread
 */
void arc_core_mpu_configure_thread(struct k_thread *thread)
{
#if defined(CONFIG_MPU_GAP_FILLING)
/* the mpu entries of ARC MPUv4 are divided into 2 parts:
 * static entries: global mpu entries, not changed in context switch
 * dynamic entries: MPU entries changed in context switch and
 * memory domain configure, including:
 *    MPU entries for user thread stack
 *    MPU entries for stack guard
 *    MPU entries for mem domain
 *    MPU entries for other thread specific regions
 * before configuring thread specific mpu entries, need to reset dynamic
 * entries
 */
	_mpu_reset_dynamic_regions();
#endif
#if defined(CONFIG_MPU_STACK_GUARD)
	uint32_t guard_start;

	/* Set location of guard area when the thread is running in
	 * supervisor mode. For a supervisor thread, this is just low
	 * memory in the stack buffer. For a user thread, it only runs
	 * in supervisor mode when handling a system call on the privilege
	 * elevation stack.
	 */
#if defined(CONFIG_USERSPACE)
	if ((thread->base.user_options & K_USER) != 0U) {
		guard_start = thread->arch.priv_stack_start;
	} else
#endif
	{
		guard_start = thread->stack_info.start;
	}
	guard_start -= Z_ARC_STACK_GUARD_SIZE;

	if (_mpu_configure(THREAD_STACK_GUARD_REGION, guard_start,
		Z_ARC_STACK_GUARD_SIZE) < 0) {
		LOG_ERR("thread %p's stack guard failed", thread);
		return;
	}
#endif /* CONFIG_MPU_STACK_GUARD */

#if defined(CONFIG_USERSPACE)
	/* configure stack region of user thread */
	if (thread->base.user_options & K_USER) {
		LOG_DBG("configure user thread %p's stack", thread);
		if (_mpu_configure(THREAD_STACK_USER_REGION,
				   (uint32_t)thread->stack_info.start,
				   thread->stack_info.size) < 0) {
			LOG_ERR("thread %p's stack failed", thread);
			return;
		}
	}

#if defined(CONFIG_MPU_GAP_FILLING)
	uint32_t num_partitions;
	struct k_mem_partition *pparts;
	struct k_mem_domain *mem_domain = thread->mem_domain_info.mem_domain;

	/* configure thread's memory domain */
	if (mem_domain) {
		LOG_DBG("configure thread %p's domain: %p",
		 thread, mem_domain);
		num_partitions = mem_domain->num_partitions;
		pparts = mem_domain->partitions;
	} else {
		num_partitions = 0U;
		pparts = NULL;
	}

	for (uint32_t i = 0; i < num_partitions; i++) {
		if (pparts->size) {
			if (_dynamic_region_allocate_and_init(pparts->start,
				pparts->size, pparts->attr) < 0) {
				LOG_ERR(
				"thread %p's mem region: %p failed",
				 thread, pparts);
				return;
			}
		}
		pparts++;
	}
#else
	arc_core_mpu_configure_mem_domain(thread);
#endif
#endif
}

/**
 * @brief configure the default region
 *
 * @param region_attr region attribute of default region
 */
void arc_core_mpu_default(uint32_t region_attr)
{
#ifdef CONFIG_ARC_NORMAL_FIRMWARE
/* \todo through secure service to access mpu */
#else
	z_arc_v2_aux_reg_write(_ARC_V2_MPU_EN, region_attr);
#endif
}

/**
 * @brief configure the MPU region
 *
 * @param index MPU region index
 * @param base  base address
 * @param size  region size
 * @param region_attr region attribute
 */
int arc_core_mpu_region(uint32_t index, uint32_t base, uint32_t size,
			 uint32_t region_attr)
{
	if (index >= get_num_regions()) {
		return -EINVAL;
	}

	region_attr &= AUX_MPU_RPER_ATTR_MASK;

	_region_init(index, base, size, region_attr);

	return 0;
}

#if defined(CONFIG_USERSPACE)
/**
 * @brief configure MPU regions for the memory partitions of the memory domain
 *
 * @param thread the thread which has memory domain
 */
#if defined(CONFIG_MPU_GAP_FILLING)
void arc_core_mpu_configure_mem_domain(struct k_thread *thread)
{
	arc_core_mpu_configure_thread(thread);
}
#else
void arc_core_mpu_configure_mem_domain(struct k_thread *thread)
{
	uint32_t region_index;
	uint32_t num_partitions;
	uint32_t num_regions;
	struct k_mem_partition *pparts;
	struct k_mem_domain *mem_domain = NULL;

	if (thread) {
		mem_domain = thread->mem_domain_info.mem_domain;
	}

	if (mem_domain) {
		LOG_DBG("configure domain: %p", mem_domain);
		num_partitions = mem_domain->num_partitions;
		pparts = mem_domain->partitions;
	} else {
		LOG_DBG("disable domain partition regions");
		num_partitions = 0U;
		pparts = NULL;
	}

	num_regions = get_num_regions();
	region_index = get_region_index_by_type(THREAD_DOMAIN_PARTITION_REGION);

	while (num_partitions && region_index < num_regions) {
		if (pparts->size > 0) {
			LOG_DBG("set region 0x%x 0x%lx 0x%x",
				region_index, pparts->start, pparts->size);
			_region_init(region_index, pparts->start,
				     pparts->size, pparts->attr);
			region_index++;
		}
		pparts++;
		num_partitions--;
	}

	while (region_index < num_regions) {
		/* clear the left mpu entries */
		_region_init(region_index, 0, 0, 0);
		region_index++;
	}
}
#endif

/**
 * @brief remove MPU regions for the memory partitions of the memory domain
 *
 * @param mem_domain the target memory domain
 */
void arc_core_mpu_remove_mem_domain(struct k_mem_domain *mem_domain)
{
	uint32_t num_partitions;
	struct k_mem_partition *pparts;
	int index;

	if (mem_domain) {
		LOG_DBG("configure domain: %p", mem_domain);
		num_partitions = mem_domain->num_partitions;
		pparts = mem_domain->partitions;
	} else {
		LOG_DBG("disable domain partition regions");
		num_partitions = 0U;
		pparts = NULL;
	}

	for (uint32_t i = 0; i < num_partitions; i++) {
		if (pparts->size) {
			index = _get_region_index(pparts->start,
			 pparts->size);
			if (index > 0) {
#if defined(CONFIG_MPU_GAP_FILLING)
				_region_set_attr(index,
				REGION_KERNEL_RAM_ATTR);
#else
				_region_init(index, 0, 0, 0);
#endif
			}
		}
		pparts++;
	}
}

/**
 * @brief reset MPU region for a single memory partition
 *
 * @param partition_id  memory partition id
 */
void arc_core_mpu_remove_mem_partition(struct k_mem_domain *domain,
			uint32_t partition_id)
{
	struct k_mem_partition *partition = &domain->partitions[partition_id];

	int region_index = _get_region_index(partition->start,
			 partition->size);

	if (region_index < 0) {
		return;
	}

	LOG_DBG("remove region 0x%x", region_index);
#if defined(CONFIG_MPU_GAP_FILLING)
	_region_set_attr(region_index, REGION_KERNEL_RAM_ATTR);
#else
	_region_init(region_index, 0, 0, 0);
#endif
}

/**
 * @brief get the maximum number of free regions for memory domain partitions
 */
int arc_core_mpu_get_max_domain_partition_regions(void)
{
#if defined(CONFIG_MPU_GAP_FILLING)
	/* consider the worst case: each partition requires split */
	return (get_num_regions() - MPU_REGION_NUM_FOR_THREAD) / 2;
#else
	return get_num_regions() -
	       get_region_index_by_type(THREAD_DOMAIN_PARTITION_REGION) - 1;
#endif
}

/**
 * @brief validate the given buffer is user accessible or not
 */
int arc_core_mpu_buffer_validate(void *addr, size_t size, int write)
{
	int r_index;
	int key = arch_irq_lock();

	/*
	 * For ARC MPU v4, overlapping is not supported.
	 * we can stop the iteration immediately once we find the
	 * matched region that grants permission or denies access.
	 */
	r_index = _mpu_probe((uint32_t)addr);
	/*  match and the area is in one region */
	if (r_index >= 0 && r_index == _mpu_probe((uint32_t)addr + (size - 1))) {
		if (_is_user_accessible_region(r_index, write)) {
			r_index = 0;
		} else {
			r_index = -EPERM;
		}
	} else {
		r_index = -EPERM;
	}

	arch_irq_unlock(key);

	return r_index;
}
#endif /* CONFIG_USERSPACE */

/* ARC MPU Driver Initial Setup */
/*
 * @brief MPU default initialization and configuration
 *
 * This function provides the default configuration mechanism for the Memory
 * Protection Unit (MPU).
 */
static int arc_mpu_init(const struct device *arg)
{
	ARG_UNUSED(arg);
	uint32_t num_regions;
	uint32_t i;

	num_regions = get_num_regions();

	/* ARC MPU supports up to 16 Regions */
	if (mpu_config.num_regions > num_regions) {
		__ASSERT(0,
		"Request to configure: %u regions (supported: %u)\n",
		mpu_config.num_regions, num_regions);
		return -EINVAL;
	}

	static_regions_num = 0U;

	/* Disable MPU */
	arc_core_mpu_disable();

	for (i = 0U; i < mpu_config.num_regions; i++) {
		/* skip empty region */
		if (mpu_config.mpu_regions[i].size == 0) {
			continue;
		}
#if defined(CONFIG_MPU_GAP_FILLING)
		_region_init(static_regions_num,
			     mpu_config.mpu_regions[i].base,
			     mpu_config.mpu_regions[i].size,
			     mpu_config.mpu_regions[i].attr);

		/* record the static region which can be split */
		if (mpu_config.mpu_regions[i].attr & REGION_DYNAMIC) {
			if (dynamic_regions_num >=
			MPU_DYNAMIC_REGION_AREAS_NUM) {
				LOG_ERR("not enough dynamic regions %d",
				 dynamic_regions_num);
				return -EINVAL;
			}

			dyn_reg_info[dynamic_regions_num].index = i;
			dyn_reg_info[dynamic_regions_num].base =
				mpu_config.mpu_regions[i].base;
			dyn_reg_info[dynamic_regions_num].size =
				mpu_config.mpu_regions[i].size;
			dyn_reg_info[dynamic_regions_num].attr =
				mpu_config.mpu_regions[i].attr;

			dynamic_regions_num++;
		}
		static_regions_num++;
#else
		/* dynamic region will be covered by default mpu setting
		 * no need to configure
		 */
		if (!(mpu_config.mpu_regions[i].attr & REGION_DYNAMIC)) {
			_region_init(static_regions_num,
			     mpu_config.mpu_regions[i].base,
			     mpu_config.mpu_regions[i].size,
			     mpu_config.mpu_regions[i].attr);
			static_regions_num++;
		}
#endif
	}

	for (i = static_regions_num; i < num_regions; i++) {
		_region_init(i, 0, 0, 0);
	}

	/* Enable MPU */
	arc_core_mpu_enable();

	return 0;
}

SYS_INIT(arc_mpu_init, PRE_KERNEL_1,
	 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

#endif /* ZEPHYR_ARCH_ARC_CORE_MPU_ARC_MPU_V4_INTERNAL_H_ */
