/*
 *
 * (C) COPYRIGHT 2008-2013 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);

#ifdef CONFIG_KDS
	kds_resource_init(&alloc->kds_res);
#endif

	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;
}

#ifdef CONFIG_KDS
struct kds_resource * ump_dd_kds_resource_get(const ump_dd_handle mem)
{
	umpp_allocation * alloc;

	UMP_ASSERT(mem);

	alloc = (umpp_allocation*)mem;

	return &alloc->kds_res;
}
#endif

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));

#ifdef CONFIG_KDS
	if (kds_resource_term(&alloc->kds_res))
	{
		printk(KERN_ERR "ump_dd_release: kds_resource_term failed,"
				"unable to release UMP allocation\n");
		return;
	}
#endif
	/* 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);

#ifdef CONFIG_KDS
	kds_resource_init(&alloc->kds_res);
#endif
	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;

}
