/*
 *
 * (C) COPYRIGHT 2008-2013, 2017 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * A copy of the licence is included with the program, and can also be obtained
 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 *
 */





/* module headers */
#include <linux/ump.h>
#include <linux/ump-ioctl.h>

/* local headers */
#include <common/ump_kernel_core.h>
#include <common/ump_kernel_descriptor_mapping.h>
#include <ump_arch.h>
#include <common/ump_kernel_priv.h>

#define UMP_FLAGS_RANGE ((UMP_PROT_SHAREABLE<<1) - 1u)

static umpp_device device;

ump_result umpp_core_constructor(void)
{
	mutex_init(&device.secure_id_map_lock);
	device.secure_id_map = umpp_descriptor_mapping_create(UMP_EXPECTED_IDS, UMP_MAX_IDS);
	if (NULL != device.secure_id_map)
	{
		if (UMP_OK == umpp_device_initialize())
		{
			return UMP_OK;
		}
		umpp_descriptor_mapping_destroy(device.secure_id_map);
	}
	mutex_destroy(&device.secure_id_map_lock);

	return UMP_ERROR;
}

void umpp_core_destructor(void)
{
	umpp_device_terminate();
	umpp_descriptor_mapping_destroy(device.secure_id_map);
	mutex_destroy(&device.secure_id_map_lock);
}

umpp_session *umpp_core_session_start(void)
{
	umpp_session * session;

	session = kzalloc(sizeof(*session), GFP_KERNEL);
	if (NULL != session)
	{
		mutex_init(&session->session_lock);

		INIT_LIST_HEAD(&session->memory_usage);

		/* try to create import client session, not a failure if they fail to initialize */
		umpp_import_handlers_init(session);
	}

	return session;
}

void umpp_core_session_end(umpp_session *session)
{
	umpp_session_memory_usage * usage, *_usage;
	UMP_ASSERT(session);

	list_for_each_entry_safe(usage, _usage, &session->memory_usage, link)
	{
		printk(KERN_WARNING "UMP: Memory usage cleanup, releasing secure ID %d\n", ump_dd_secure_id_get(usage->mem));
		ump_dd_release(usage->mem);
		kfree(usage);

	}

	/* we should now not hold any imported memory objects,
	 * detatch all import handlers */
	umpp_import_handlers_term(session);

	mutex_destroy(&session->session_lock);
	kfree(session);
}

ump_dd_handle ump_dd_allocate_64(uint64_t size, ump_alloc_flags flags, ump_dd_security_filter filter_func, ump_dd_final_release_callback final_release_func, void* callback_data)
{
	umpp_allocation * alloc;
	int i;

	UMP_ASSERT(size);

	if (flags & (~UMP_FLAGS_RANGE))
	{
		printk(KERN_WARNING "UMP: allocation flags out of allowed bits range\n");
		return UMP_DD_INVALID_MEMORY_HANDLE;
	}

	if( ( flags & (UMP_PROT_CPU_RD | UMP_PROT_W_RD | UMP_PROT_X_RD | UMP_PROT_Y_RD | UMP_PROT_Z_RD ) ) == 0 ||
	    ( flags & (UMP_PROT_CPU_WR | UMP_PROT_W_WR | UMP_PROT_X_WR | UMP_PROT_Y_WR | UMP_PROT_Z_WR )) == 0 )
	{
		printk(KERN_WARNING "UMP: allocation flags should have at least one read and one write permission bit set\n");
		return UMP_DD_INVALID_MEMORY_HANDLE;
	}

	/*check permission flags to be set if hit flags are set too*/
	for (i = UMP_DEVICE_CPU_SHIFT; i<=UMP_DEVICE_Z_SHIFT; i+=4)
	{
		if (flags & (UMP_HINT_DEVICE_RD<<i))
		{
			UMP_ASSERT(flags & (UMP_PROT_DEVICE_RD<<i));
		}
		if (flags & (UMP_HINT_DEVICE_WR<<i))
		{
			UMP_ASSERT(flags & (UMP_PROT_DEVICE_WR<<i));
		}
	}

	alloc = kzalloc(sizeof(*alloc), GFP_KERNEL | __GFP_HARDWALL);

	if (NULL == alloc)
		goto out1;

	alloc->flags = flags;
	alloc->filter_func = filter_func;
	alloc->final_release_func = final_release_func;
	alloc->callback_data = callback_data;
	alloc->size = size;

	mutex_init(&alloc->map_list_lock);
	INIT_LIST_HEAD(&alloc->map_list);
	atomic_set(&alloc->refcount, 1);

	if (!(alloc->flags & UMP_PROT_SHAREABLE))
	{
		alloc->owner = get_current()->pid;
	}

	if (0 != umpp_phys_commit(alloc))
	{
		goto out2;
	}

	/* all set up, allocate an ID for it */

	mutex_lock(&device.secure_id_map_lock);
	alloc->id = umpp_descriptor_mapping_allocate(device.secure_id_map, (void*)alloc);
	mutex_unlock(&device.secure_id_map_lock);

	if ((int)alloc->id == 0)
	{
		/* failed to allocate a secure_id */
		goto out3;
	}

	return alloc;

out3:
	umpp_phys_free(alloc);
out2:
	kfree(alloc);
out1:
	return UMP_DD_INVALID_MEMORY_HANDLE;
}

uint64_t ump_dd_size_get_64(const ump_dd_handle mem)
{
	umpp_allocation * alloc;

	UMP_ASSERT(mem);

	alloc = (umpp_allocation*)mem;

	return alloc->size;
}

/*
 * UMP v1 API
 */
unsigned long ump_dd_size_get(ump_dd_handle mem)
{
	umpp_allocation * alloc;

	UMP_ASSERT(mem);

	alloc = (umpp_allocation*)mem;

	UMP_ASSERT(alloc->flags & UMP_CONSTRAINT_32BIT_ADDRESSABLE);
	UMP_ASSERT(alloc->size <= UMP_UINT32_MAX);

	return (unsigned long)alloc->size;
}

ump_secure_id ump_dd_secure_id_get(const ump_dd_handle mem)
{
	umpp_allocation * alloc;

	UMP_ASSERT(mem);

	alloc = (umpp_allocation*)mem;

	return alloc->id;
}

ump_alloc_flags ump_dd_allocation_flags_get(const ump_dd_handle mem)
{
	const umpp_allocation * alloc;

	UMP_ASSERT(mem);
	alloc = (const umpp_allocation *)mem;

	return alloc->flags;
}

ump_dd_handle ump_dd_from_secure_id(ump_secure_id secure_id)
{
	umpp_allocation * alloc = UMP_DD_INVALID_MEMORY_HANDLE;

	mutex_lock(&device.secure_id_map_lock);

	if (0 == umpp_descriptor_mapping_lookup(device.secure_id_map, secure_id, (void**)&alloc))
	{
		if (NULL != alloc->filter_func)
		{
			if (!alloc->filter_func(secure_id, alloc, alloc->callback_data))
			{
				alloc = UMP_DD_INVALID_MEMORY_HANDLE; /* the filter denied access */
			}
		}

		/* check permission to access it */
		if ((UMP_DD_INVALID_MEMORY_HANDLE != alloc) && !(alloc->flags & UMP_PROT_SHAREABLE))
		{
			if (alloc->owner != get_current()->pid)
			{
				alloc = UMP_DD_INVALID_MEMORY_HANDLE; /*no rights for the current process*/
			}
		}

		if (UMP_DD_INVALID_MEMORY_HANDLE != alloc)
		{
			if( ump_dd_retain(alloc) != UMP_DD_SUCCESS)
			{
				alloc = UMP_DD_INVALID_MEMORY_HANDLE;
			}
		}
	}
	mutex_unlock(&device.secure_id_map_lock);

	return alloc;
}

/*
 * UMP v1 API
 */
ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id)
{
	return ump_dd_from_secure_id(secure_id);
}

int ump_dd_retain(ump_dd_handle mem)
{
	umpp_allocation * alloc;

	UMP_ASSERT(mem);

	alloc = (umpp_allocation*)mem;

	/* check for overflow */
	while(1)
	{
		int refcnt = atomic_read(&alloc->refcount);
		if (refcnt + 1 > 0)
		{
			if(atomic_cmpxchg(&alloc->refcount, refcnt, refcnt + 1) == refcnt)
			{
				return 0;
			}
		}
		else
		{
			return -EBUSY;
		}
	}
}

/*
 * UMP v1 API
 */
void ump_dd_reference_add(ump_dd_handle mem)
{
	ump_dd_retain(mem);
}


void ump_dd_release(ump_dd_handle mem)
{
	umpp_allocation * alloc;
	uint32_t new_cnt;

	UMP_ASSERT(mem);

	alloc = (umpp_allocation*)mem;

	/* secure the id for lookup while releasing */
	mutex_lock(&device.secure_id_map_lock);

	/* do the actual release */
	new_cnt = atomic_sub_return(1, &alloc->refcount);
	if (0 == new_cnt)
	{
		/* remove from the table as this was the last ref */
		umpp_descriptor_mapping_remove(device.secure_id_map, alloc->id);
	}

	/* release the lock as early as possible */
	mutex_unlock(&device.secure_id_map_lock);

	if (0 != new_cnt)
	{
		/* exit if still have refs */
		return;
	}

	UMP_ASSERT(list_empty(&alloc->map_list));

	/* cleanup */
	if (NULL != alloc->final_release_func)
	{
		alloc->final_release_func(alloc, alloc->callback_data);
	}

	if (0 == (alloc->management_flags & UMP_MGMT_EXTERNAL))
	{
		umpp_phys_free(alloc);
	}
	else
	{
		kfree(alloc->block_array);
	}

	mutex_destroy(&alloc->map_list_lock);

	kfree(alloc);
}

/*
 * UMP v1 API
 */
void ump_dd_reference_release(ump_dd_handle mem)
{
	ump_dd_release(mem);
}

void ump_dd_phys_blocks_get_64(const ump_dd_handle mem, uint64_t * const pCount, const ump_dd_physical_block_64 ** const pArray)
{
	const umpp_allocation * alloc;
	UMP_ASSERT(pCount);
	UMP_ASSERT(pArray);
	UMP_ASSERT(mem);
	alloc = (const umpp_allocation *)mem;
	*pCount = alloc->blocksCount;
	*pArray = alloc->block_array;
}

/*
 * UMP v1 API
 */
ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle mem, ump_dd_physical_block * const blocks, unsigned long num_blocks)
{
	const umpp_allocation * alloc;
	unsigned long i;
	UMP_ASSERT(mem);
	UMP_ASSERT(blocks);
	UMP_ASSERT(num_blocks);

	alloc = (const umpp_allocation *)mem;

	UMP_ASSERT(alloc->flags & UMP_CONSTRAINT_32BIT_ADDRESSABLE);

	if((uint64_t)num_blocks != alloc->blocksCount)
	{
		return UMP_DD_INVALID;
	}

	for( i = 0; i < num_blocks; i++)
	{
		UMP_ASSERT(alloc->block_array[i].addr <= UMP_UINT32_MAX);
		UMP_ASSERT(alloc->block_array[i].size <= UMP_UINT32_MAX);

		blocks[i].addr = (unsigned long)alloc->block_array[i].addr;
		blocks[i].size = (unsigned long)alloc->block_array[i].size;
	}

	return UMP_DD_SUCCESS;
}
/*
 * UMP v1 API
 */
ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle mem, unsigned long index, ump_dd_physical_block * const block)
{
	const umpp_allocation * alloc;
	UMP_ASSERT(mem);
	UMP_ASSERT(block);
	alloc = (const umpp_allocation *)mem;

	UMP_ASSERT(alloc->flags & UMP_CONSTRAINT_32BIT_ADDRESSABLE);

	UMP_ASSERT(alloc->block_array[index].addr <= UMP_UINT32_MAX);
	UMP_ASSERT(alloc->block_array[index].size <= UMP_UINT32_MAX);

	block->addr = (unsigned long)alloc->block_array[index].addr;
	block->size = (unsigned long)alloc->block_array[index].size;

	return UMP_DD_SUCCESS;
}

/*
 * UMP v1 API
 */
unsigned long ump_dd_phys_block_count_get(ump_dd_handle mem)
{
	const umpp_allocation * alloc;
	UMP_ASSERT(mem);
	alloc = (const umpp_allocation *)mem;

	UMP_ASSERT(alloc->flags & UMP_CONSTRAINT_32BIT_ADDRESSABLE);
	UMP_ASSERT(alloc->blocksCount <= UMP_UINT32_MAX);

	return (unsigned long)alloc->blocksCount;
}

umpp_cpu_mapping * umpp_dd_find_enclosing_mapping(umpp_allocation * alloc, void *uaddr, size_t size)
{
	umpp_cpu_mapping *map;

	void *target_first = uaddr;
	void *target_last = (void*)((uintptr_t)uaddr - 1 + size);

	if (target_last < target_first) /* wrapped */
	{
		return NULL;
	}

	mutex_lock(&alloc->map_list_lock);
	list_for_each_entry(map, &alloc->map_list, link)
	{
		if ( map->vaddr_start <= target_first &&
		   (void*)((uintptr_t)map->vaddr_start + (map->nr_pages << PAGE_SHIFT) - 1) >= target_last)
		{
			goto out;
		}
	}
	map = NULL;
out:
	mutex_unlock(&alloc->map_list_lock);

	return map;
}

void umpp_dd_add_cpu_mapping(umpp_allocation * alloc, umpp_cpu_mapping * map)
{
	UMP_ASSERT(alloc);
	UMP_ASSERT(map);
	mutex_lock(&alloc->map_list_lock);
	list_add(&map->link, &alloc->map_list);
	mutex_unlock(&alloc->map_list_lock);
}

void umpp_dd_remove_cpu_mapping(umpp_allocation * alloc, umpp_cpu_mapping * target)
{
	umpp_cpu_mapping * map;

	UMP_ASSERT(alloc);
	UMP_ASSERT(target);

	mutex_lock(&alloc->map_list_lock);
	list_for_each_entry(map, &alloc->map_list, link)
	{
		if (map == target)
		{
			list_del(&target->link);
			kfree(target);
			mutex_unlock(&alloc->map_list_lock);
			return;
		}
	}

	/* not found, error */
	UMP_ASSERT(0);
}

int umpp_dd_find_start_block(const umpp_allocation * alloc, uint64_t offset, uint64_t * const  block_index, uint64_t * const block_internal_offset)
{
	uint64_t i;

	for (i = 0 ; i < alloc->blocksCount; i++)
	{
		if (offset < alloc->block_array[i].size)
		{
			/* found the block_array element containing this offset */
			*block_index = i;
			*block_internal_offset = offset;
			return 0;
		}
		offset -= alloc->block_array[i].size;
	}

	return -ENXIO;
}

void umpp_dd_cpu_msync_now(ump_dd_handle mem, ump_cpu_msync_op op, void * address, size_t size)
{
	umpp_allocation * alloc;
	void *vaddr;
	umpp_cpu_mapping * mapping;
	uint64_t virt_page_off; /* offset of given address from beginning of the virtual mapping */
	uint64_t phys_page_off; /* offset of the virtual mapping from the beginning of the physical buffer */
	uint64_t page_count; /* number of pages to sync */
	uint64_t i;
	uint64_t block_idx;
	uint64_t block_offset;
	uint64_t paddr;

	UMP_ASSERT((UMP_MSYNC_CLEAN == op) || (UMP_MSYNC_CLEAN_AND_INVALIDATE == op));

	alloc = (umpp_allocation*)mem;
	vaddr = (void*)(uintptr_t)address;

	if((alloc->flags & UMP_CONSTRAINT_UNCACHED) != 0)
	{
		/* mapping is not cached */
		return;
	}

	mapping = umpp_dd_find_enclosing_mapping(alloc, vaddr, size);
	if (NULL == mapping)
	{
		printk(KERN_WARNING "UMP: Illegal cache sync address %lx\n", (uintptr_t)vaddr);
		return; /* invalid pointer or size causes out-of-bounds */
	}

	/* we already know that address + size don't wrap around as umpp_dd_find_enclosing_mapping didn't fail */
	page_count = ((((((uintptr_t)address + size - 1) & PAGE_MASK) - ((uintptr_t)address & PAGE_MASK))) >> PAGE_SHIFT) + 1;
	virt_page_off = (vaddr - mapping->vaddr_start) >> PAGE_SHIFT;
	phys_page_off = mapping->page_off;

	if (umpp_dd_find_start_block(alloc, (virt_page_off + phys_page_off) << PAGE_SHIFT, &block_idx, &block_offset))
	{
		/* should not fail as a valid mapping was found, so the phys mem must exists */
		printk(KERN_WARNING "UMP: Unable to find physical start block with offset %llx\n", virt_page_off + phys_page_off);
		UMP_ASSERT(0);
		return;
	}

	paddr = alloc->block_array[block_idx].addr + block_offset + (((uintptr_t)vaddr) & ((1u << PAGE_SHIFT)-1));

	for (i = 0; i < page_count; i++)
	{
		size_t offset = ((uintptr_t)vaddr) & ((1u << PAGE_SHIFT)-1);
		size_t sz = min((size_t)PAGE_SIZE - offset, size);

		/* check if we've overrrun the current block, if so move to the next block */
		if (paddr >= (alloc->block_array[block_idx].addr + alloc->block_array[block_idx].size))
		{
			block_idx++;
			UMP_ASSERT(block_idx < alloc->blocksCount);
			paddr = alloc->block_array[block_idx].addr;
		}

		if (UMP_MSYNC_CLEAN == op)
		{
			ump_sync_to_memory(paddr, vaddr, sz);
		}
		else /* (UMP_MSYNC_CLEAN_AND_INVALIDATE == op) already validated on entry */
		{
			ump_sync_to_cpu(paddr, vaddr, sz);
		}

		/* advance to next page  */
		vaddr = (void*)((uintptr_t)vaddr + sz);
		size -= sz;
		paddr += sz;
	}
}

UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_create_from_phys_blocks_64(const ump_dd_physical_block_64 * blocks, uint64_t num_blocks, ump_alloc_flags flags, ump_dd_security_filter filter_func, ump_dd_final_release_callback final_release_func, void* callback_data)
{
	uint64_t size = 0;
	uint64_t i;
	umpp_allocation * alloc;

	UMP_ASSERT(blocks);
	UMP_ASSERT(num_blocks);

	for (i = 0; i < num_blocks; i++)
	{
		size += blocks[i].size;
	}
	UMP_ASSERT(size);

	if (flags & (~UMP_FLAGS_RANGE))
	{
		printk(KERN_WARNING "UMP: allocation flags out of allowed bits range\n");
		return UMP_DD_INVALID_MEMORY_HANDLE;
	}

	if( ( flags & (UMP_PROT_CPU_RD | UMP_PROT_W_RD | UMP_PROT_X_RD | UMP_PROT_Y_RD | UMP_PROT_Z_RD
	    | UMP_PROT_CPU_WR | UMP_PROT_W_WR | UMP_PROT_X_WR | UMP_PROT_Y_WR | UMP_PROT_Z_WR )) == 0 )
	{
		printk(KERN_WARNING "UMP: allocation flags should have at least one read or write permission bit set\n");
		return UMP_DD_INVALID_MEMORY_HANDLE;
	}

	/*check permission flags to be set if hit flags are set too*/
	for (i = UMP_DEVICE_CPU_SHIFT; i<=UMP_DEVICE_Z_SHIFT; i+=4)
	{
		if (flags & (UMP_HINT_DEVICE_RD<<i))
		{
			UMP_ASSERT(flags & (UMP_PROT_DEVICE_RD<<i));
		}
		if (flags & (UMP_HINT_DEVICE_WR<<i))
		{
			UMP_ASSERT(flags & (UMP_PROT_DEVICE_WR<<i));
		}
	}

	alloc = kzalloc(sizeof(*alloc),__GFP_HARDWALL | GFP_KERNEL);

	if (NULL == alloc)
	{
		goto out1;
	}

	alloc->block_array = kzalloc(sizeof(ump_dd_physical_block_64) * num_blocks,__GFP_HARDWALL | GFP_KERNEL);
	if (NULL == alloc->block_array)
	{
		goto out2;
	}

	memcpy(alloc->block_array, blocks, sizeof(ump_dd_physical_block_64) * num_blocks);

	alloc->size = size;
	alloc->blocksCount = num_blocks;
	alloc->flags = flags;
	alloc->filter_func = filter_func;
	alloc->final_release_func = final_release_func;
	alloc->callback_data = callback_data;

	if (!(alloc->flags & UMP_PROT_SHAREABLE))
	{
		alloc->owner = get_current()->pid;
	}

	mutex_init(&alloc->map_list_lock);
	INIT_LIST_HEAD(&alloc->map_list);
	atomic_set(&alloc->refcount, 1);

	/* all set up, allocate an ID */

	mutex_lock(&device.secure_id_map_lock);
	alloc->id = umpp_descriptor_mapping_allocate(device.secure_id_map, (void*)alloc);
	mutex_unlock(&device.secure_id_map_lock);

	if ((int)alloc->id == 0)
	{
		/* failed to allocate a secure_id */
		goto out3;
	}

	alloc->management_flags |= UMP_MGMT_EXTERNAL;

	return alloc;

out3:
	kfree(alloc->block_array);
out2:
	kfree(alloc);
out1:
	return UMP_DD_INVALID_MEMORY_HANDLE;
}


/*
 * UMP v1 API
 */
UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks)
{
	ump_dd_handle mem;
	ump_dd_physical_block_64 *block_64_array;
	ump_alloc_flags flags = UMP_V1_API_DEFAULT_ALLOCATION_FLAGS;
	unsigned long i;

	UMP_ASSERT(blocks);
	UMP_ASSERT(num_blocks);

	block_64_array = kzalloc(num_blocks * sizeof(*block_64_array), __GFP_HARDWALL | GFP_KERNEL);

	if(block_64_array == NULL)
	{
		return UMP_DD_INVALID_MEMORY_HANDLE;
	}

	/* copy physical blocks */
	for( i = 0; i < num_blocks; i++)
	{
		block_64_array[i].addr = blocks[i].addr;
		block_64_array[i].size = blocks[i].size;
	}

	mem = ump_dd_create_from_phys_blocks_64(block_64_array, num_blocks, flags, NULL, NULL, NULL);

	kfree(block_64_array);

	return mem;

}
