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

#include <init.h>
#include <kernel.h>
#include <kernel_structs.h>
#include <nano_internal.h>


static u8_t max_partitions;


void k_mem_domain_init(struct k_mem_domain *domain, u32_t num_parts,
		struct k_mem_partition *parts[])
{
	unsigned int key;

	__ASSERT(domain && (!num_parts || parts), "");
	__ASSERT(num_parts <= max_partitions, "");

	key = irq_lock();

	domain->num_partitions = num_parts;
	memset(domain->partitions, 0, sizeof(domain->partitions));

	if (num_parts) {
		u32_t i;

		for (i = 0; i < num_parts; i++) {
			__ASSERT(parts[i], "");
			domain->partitions[i] = *parts[i];
		}
	}

	sys_dlist_init(&domain->mem_domain_q);

	irq_unlock(key);
}

void k_mem_domain_destroy(struct k_mem_domain *domain)
{
	unsigned int key;
	sys_dnode_t *node, *next_node;

	__ASSERT(domain, "");

	key = irq_lock();

	SYS_DLIST_FOR_EACH_NODE_SAFE(&domain->mem_domain_q, node, next_node) {
		struct k_thread *thread =
			CONTAINER_OF(node, struct k_thread, mem_domain_info);

		sys_dlist_remove(&thread->mem_domain_info.mem_domain_q_node);
		thread->mem_domain_info.mem_domain = NULL;
	}

	irq_unlock(key);
}

void k_mem_domain_add_partition(struct k_mem_domain *domain,
			       struct k_mem_partition *part)
{
	int p_idx;
	unsigned int key;

	__ASSERT(domain && part, "");
	__ASSERT(part->start + part->size > part->start, "");

	key = irq_lock();

	for (p_idx = 0; p_idx < max_partitions; p_idx++) {
		/* A zero-sized partition denotes it's a free partition */
		if (domain->partitions[p_idx].size == 0) {
			break;
		}
	}

	/* Assert if there is no free partition */
	__ASSERT(p_idx < max_partitions, "");

	domain->partitions[p_idx].start = part->start;
	domain->partitions[p_idx].size = part->size;
	domain->partitions[p_idx].attr = part->attr;

	domain->num_partitions++;

	irq_unlock(key);
}

void k_mem_domain_remove_partition(struct k_mem_domain *domain,
				  struct k_mem_partition *part)
{
	int p_idx;
	unsigned int key;

	__ASSERT(domain && part, "");

	key = irq_lock();

	/* find a partition that matches the given start and size */
	for (p_idx = 0; p_idx < max_partitions; p_idx++) {
		if (domain->partitions[p_idx].start == part->start &&
		    domain->partitions[p_idx].size == part->size) {
			break;
		}
	}

	/* Assert if not found */
	__ASSERT(p_idx < max_partitions, "");

	domain->partitions[p_idx].start = 0;
	domain->partitions[p_idx].size = 0;
	domain->partitions[p_idx].attr = 0;

	domain->num_partitions--;

	irq_unlock(key);
}

void k_mem_domain_add_thread(struct k_mem_domain *domain, k_tid_t thread)
{
	unsigned int key;

	__ASSERT(domain && thread && !thread->mem_domain_info.mem_domain, "");

	key = irq_lock();

	sys_dlist_append(&domain->mem_domain_q,
			 &thread->mem_domain_info.mem_domain_q_node);
	thread->mem_domain_info.mem_domain = domain;

	irq_unlock(key);
}

void k_mem_domain_remove_thread(k_tid_t thread)
{
	unsigned int key;

	__ASSERT(thread && thread->mem_domain_info.mem_domain, "");

	key = irq_lock();

	sys_dlist_remove(&thread->mem_domain_info.mem_domain_q_node);
	thread->mem_domain_info.mem_domain = NULL;

	irq_unlock(key);
}

static int init_mem_domain_module(struct device *arg)
{
	ARG_UNUSED(arg);

	max_partitions = _arch_mem_domain_max_partitions_get();
	/*
	 * max_partitions must be less than or equal to
	 * CONFIG_MAX_DOMAIN_PARTITIONS, or would encounter array index
	 * out of bounds error.
	 */
	__ASSERT(max_partitions <= CONFIG_MAX_DOMAIN_PARTITIONS, "");

	return 0;
}

SYS_INIT(init_mem_domain_module, PRE_KERNEL_1,
	 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
