/*
 * Copyright (C) 2010-2014, 2016 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.
 */

#include "mali_kernel_common.h"
#include "mali_osk.h"
#include "mali_osk_bitops.h"
#include "mali_osk_list.h"
#include "ump_osk.h"
#include "ump_uk_types.h"
#include "ump_ukk.h"
#include "ump_kernel_common.h"
#include "ump_kernel_descriptor_mapping.h"
#include "ump_kernel_memory_backend.h"



/**
 * Define the initial and maximum size of number of secure_ids on the system
 */
#define UMP_SECURE_ID_TABLE_ENTRIES_INITIAL (128  )
#define UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM (4096 )


/**
 * Define the initial and maximum size of the ump_session_data::cookies_map,
 * which is a \ref ump_descriptor_mapping. This limits how many secure_ids
 * may be mapped into a particular process using _ump_ukk_map_mem().
 */

#define UMP_COOKIES_PER_SESSION_INITIAL (UMP_SECURE_ID_TABLE_ENTRIES_INITIAL )
#define UMP_COOKIES_PER_SESSION_MAXIMUM (UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM)

struct ump_dev device;

_mali_osk_errcode_t ump_kernel_constructor(void)
{
	_mali_osk_errcode_t err;

	/* Perform OS Specific initialization */
	err = _ump_osk_init();
	if (_MALI_OSK_ERR_OK != err) {
		MSG_ERR(("Failed to initiaze the UMP Device Driver"));
		return err;
	}

	/* Init the global device */
	_mali_osk_memset(&device, 0, sizeof(device));

	/* Create the descriptor map, which will be used for mapping secure ID to ump_dd_mem structs */
	device.secure_id_map = ump_random_mapping_create();
	if (NULL == device.secure_id_map) {
		MSG_ERR(("Failed to create secure id lookup table\n"));
		return _MALI_OSK_ERR_NOMEM;
	}

	/* Init memory backend */
	device.backend = ump_memory_backend_create();
	if (NULL == device.backend) {
		MSG_ERR(("Failed to create memory backend\n"));
		ump_random_mapping_destroy(device.secure_id_map);
		return _MALI_OSK_ERR_NOMEM;
	}

	return _MALI_OSK_ERR_OK;
}

void ump_kernel_destructor(void)
{
	DEBUG_ASSERT_POINTER(device.secure_id_map);

	ump_random_mapping_destroy(device.secure_id_map);
	device.secure_id_map = NULL;

	device.backend->shutdown(device.backend);
	device.backend = NULL;

	ump_memory_backend_destroy();

	_ump_osk_term();
}

/** Creates a new UMP session
 */
_mali_osk_errcode_t _ump_ukk_open(void **context)
{
	struct ump_session_data *session_data;

	/* allocated struct to track this session */
	session_data = (struct ump_session_data *)_mali_osk_malloc(sizeof(struct ump_session_data));
	if (NULL == session_data) {
		MSG_ERR(("Failed to allocate ump_session_data in ump_file_open()\n"));
		return _MALI_OSK_ERR_NOMEM;
	}

	session_data->lock = _mali_osk_mutex_init(_MALI_OSK_LOCKFLAG_UNORDERED, 0);
	if (NULL == session_data->lock) {
		MSG_ERR(("Failed to initialize lock for ump_session_data in ump_file_open()\n"));
		_mali_osk_free(session_data);
		return _MALI_OSK_ERR_NOMEM;
	}

	session_data->cookies_map = ump_descriptor_mapping_create(
					    UMP_COOKIES_PER_SESSION_INITIAL,
					    UMP_COOKIES_PER_SESSION_MAXIMUM);

	if (NULL == session_data->cookies_map) {
		MSG_ERR(("Failed to create descriptor mapping for _ump_ukk_map_mem cookies\n"));

		_mali_osk_mutex_term(session_data->lock);
		_mali_osk_free(session_data);
		return _MALI_OSK_ERR_NOMEM;
	}

	_MALI_OSK_INIT_LIST_HEAD(&session_data->list_head_session_memory_list);

	_MALI_OSK_INIT_LIST_HEAD(&session_data->list_head_session_memory_mappings_list);

	/* Since initial version of the UMP interface did not use the API_VERSION ioctl we have to assume
	   that it is this version, and not the "latest" one: UMP_IOCTL_API_VERSION
	   Current and later API versions would do an additional call to this IOCTL and update this variable
	   to the correct one.*/
	session_data->api_version = MAKE_VERSION_ID(1);

	*context = (void *)session_data;

	session_data->cache_operations_ongoing = 0 ;
	session_data->has_pending_level1_cache_flush = 0;

	DBG_MSG(2, ("New session opened\n"));

	return _MALI_OSK_ERR_OK;
}

_mali_osk_errcode_t _ump_ukk_close(void **context)
{
	struct ump_session_data *session_data;
	ump_session_memory_list_element *item;
	ump_session_memory_list_element *tmp;

	session_data = (struct ump_session_data *)*context;
	if (NULL == session_data) {
		MSG_ERR(("Session data is NULL in _ump_ukk_close()\n"));
		return _MALI_OSK_ERR_INVALID_ARGS;
	}

	/* Unmap any descriptors mapped in. */
	if (0 == _mali_osk_list_empty(&session_data->list_head_session_memory_mappings_list)) {
		ump_memory_allocation *descriptor;
		ump_memory_allocation *temp;

		DBG_MSG(1, ("Memory mappings found on session usage list during session termination\n"));

		/* use the 'safe' list iterator, since freeing removes the active block from the list we're iterating */
		_MALI_OSK_LIST_FOREACHENTRY(descriptor, temp, &session_data->list_head_session_memory_mappings_list, ump_memory_allocation, list) {
			_ump_uk_unmap_mem_s unmap_args;
			DBG_MSG(4, ("Freeing block with phys address 0x%x size 0x%x mapped in user space at 0x%x\n",
				    descriptor->phys_addr, descriptor->size, descriptor->mapping));
			unmap_args.ctx = (void *)session_data;
			unmap_args.mapping = descriptor->mapping;
			unmap_args.size = descriptor->size;
			unmap_args._ukk_private = NULL; /* NOTE: unused */
			unmap_args.cookie = descriptor->cookie;

			/* NOTE: This modifies the list_head_session_memory_mappings_list */
			_ump_ukk_unmap_mem(&unmap_args);
		}
	}

	/* ASSERT that we really did free everything, because _ump_ukk_unmap_mem()
	 * can fail silently. */
	DEBUG_ASSERT(_mali_osk_list_empty(&session_data->list_head_session_memory_mappings_list));

	_MALI_OSK_LIST_FOREACHENTRY(item, tmp, &session_data->list_head_session_memory_list, ump_session_memory_list_element, list) {
		_mali_osk_list_del(&item->list);
		DBG_MSG(2, ("Releasing UMP memory %u as part of file close\n", item->mem->secure_id));
		ump_dd_reference_release(item->mem);
		_mali_osk_free(item);
	}

	ump_descriptor_mapping_destroy(session_data->cookies_map);

	_mali_osk_mutex_term(session_data->lock);
	_mali_osk_free(session_data);

	DBG_MSG(2, ("Session closed\n"));

	return _MALI_OSK_ERR_OK;
}

_mali_osk_errcode_t _ump_ukk_map_mem(_ump_uk_map_mem_s *args)
{
	struct ump_session_data *session_data;
	ump_memory_allocation *descriptor;   /* Describes current mapping of memory */
	_mali_osk_errcode_t err;
	unsigned long offset = 0;
	unsigned long left;
	ump_dd_handle handle;  /* The real UMP handle for this memory. Its real datatype is ump_dd_mem*  */
	ump_dd_mem *mem;       /* The real UMP memory. It is equal to the handle, but with exposed struct */
	u32 block;
	int map_id;

	session_data = (ump_session_data *)args->ctx;
	if (NULL == session_data) {
		MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n"));
		return _MALI_OSK_ERR_INVALID_ARGS;
	}

	descriptor = (ump_memory_allocation *) _mali_osk_calloc(1, sizeof(ump_memory_allocation));
	if (NULL == descriptor) {
		MSG_ERR(("ump_ukk_map_mem: descriptor allocation failed\n"));
		return _MALI_OSK_ERR_NOMEM;
	}

	handle = ump_dd_handle_create_from_secure_id(args->secure_id);
	if (UMP_DD_HANDLE_INVALID == handle) {
		_mali_osk_free(descriptor);
		DBG_MSG(1, ("Trying to map unknown secure ID %u\n", args->secure_id));
		return _MALI_OSK_ERR_FAULT;
	}

	mem = (ump_dd_mem *)handle;
	DEBUG_ASSERT(mem);
	if (mem->size_bytes != args->size) {
		_mali_osk_free(descriptor);
		ump_dd_reference_release(handle);
		DBG_MSG(1, ("Trying to map too much or little. ID: %u, virtual size=%lu, UMP size: %lu\n", args->secure_id, args->size, mem->size_bytes));
		return _MALI_OSK_ERR_FAULT;
	}

	map_id = ump_descriptor_mapping_allocate_mapping(session_data->cookies_map, (void *) descriptor);

	if (map_id < 0) {
		_mali_osk_free(descriptor);
		ump_dd_reference_release(handle);
		DBG_MSG(1, ("ump_ukk_map_mem: unable to allocate a descriptor_mapping for return cookie\n"));

		return _MALI_OSK_ERR_NOMEM;
	}

	descriptor->size = args->size;
	descriptor->handle = handle;
	descriptor->phys_addr = args->phys_addr;
	descriptor->process_mapping_info = args->_ukk_private;
	descriptor->ump_session = session_data;
	descriptor->cookie = (u32)map_id;

	if (mem->is_cached) {
		descriptor->is_cached = 1;
		DBG_MSG(3, ("Mapping UMP secure_id: %d as cached.\n", args->secure_id));
	} else {
		descriptor->is_cached = 0;
		DBG_MSG(3, ("Mapping UMP secure_id: %d  as Uncached.\n", args->secure_id));
	}

	_mali_osk_list_init(&descriptor->list);

	err = _ump_osk_mem_mapregion_init(descriptor);
	if (_MALI_OSK_ERR_OK != err) {
		DBG_MSG(1, ("Failed to initialize memory mapping in _ump_ukk_map_mem(). ID: %u\n", args->secure_id));
		ump_descriptor_mapping_free(session_data->cookies_map, map_id);
		_mali_osk_free(descriptor);
		ump_dd_reference_release(mem);
		return err;
	}

	DBG_MSG(4, ("Mapping virtual to physical memory: ID: %u, size:%lu, first physical addr: 0x%08lx, number of regions: %lu\n",
		    mem->secure_id,
		    mem->size_bytes,
		    ((NULL != mem->block_array) ? mem->block_array->addr : 0),
		    mem->nr_blocks));

	left = descriptor->size;
	/* loop over all blocks and map them in */
	for (block = 0; block < mem->nr_blocks; block++) {
		unsigned long size_to_map;

		if (left >  mem->block_array[block].size) {
			size_to_map = mem->block_array[block].size;
		} else {
			size_to_map = left;
		}

		if (_MALI_OSK_ERR_OK != _ump_osk_mem_mapregion_map(descriptor, offset, (u32 *) & (mem->block_array[block].addr), size_to_map)) {
			DBG_MSG(1, ("WARNING: _ump_ukk_map_mem failed to map memory into userspace\n"));
			ump_descriptor_mapping_free(session_data->cookies_map, map_id);
			ump_dd_reference_release(mem);
			_ump_osk_mem_mapregion_term(descriptor);
			_mali_osk_free(descriptor);
			return _MALI_OSK_ERR_FAULT;
		}
		left -= size_to_map;
		offset += size_to_map;
	}

	/* Add to the ump_memory_allocation tracking list */
	_mali_osk_mutex_wait(session_data->lock);
	_mali_osk_list_add(&descriptor->list, &session_data->list_head_session_memory_mappings_list);
	_mali_osk_mutex_signal(session_data->lock);

	args->mapping = descriptor->mapping;
	args->cookie = descriptor->cookie;

	return _MALI_OSK_ERR_OK;
}

void _ump_ukk_unmap_mem(_ump_uk_unmap_mem_s *args)
{
	struct ump_session_data *session_data;
	ump_memory_allocation *descriptor;
	ump_dd_handle handle;

	session_data = (ump_session_data *)args->ctx;

	if (NULL == session_data) {
		MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n"));
		return;
	}

	if (0 != ump_descriptor_mapping_get(session_data->cookies_map, (int)args->cookie, (void **)&descriptor)) {
		MSG_ERR(("_ump_ukk_map_mem: cookie 0x%X not found for this session\n", args->cookie));
		return;
	}

	DEBUG_ASSERT_POINTER(descriptor);

	handle = descriptor->handle;
	if (UMP_DD_HANDLE_INVALID == handle) {
		DBG_MSG(1, ("WARNING: Trying to unmap unknown handle: UNKNOWN\n"));
		return;
	}

	/* Remove the ump_memory_allocation from the list of tracked mappings */
	_mali_osk_mutex_wait(session_data->lock);
	_mali_osk_list_del(&descriptor->list);
	_mali_osk_mutex_signal(session_data->lock);

	ump_descriptor_mapping_free(session_data->cookies_map, (int)args->cookie);

	ump_dd_reference_release(handle);

	_ump_osk_mem_mapregion_term(descriptor);
	_mali_osk_free(descriptor);
}

u32 _ump_ukk_report_memory_usage(void)
{
	if (device.backend->stat)
		return device.backend->stat(device.backend);
	else
		return 0;
}
