/*
 * Copyright (c) 2016 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Measure time
 *
 */
#include <kernel.h>
#include <zephyr.h>
#include <tc_util.h>
#include <ksched.h>
#include "timing_info.h"
#include <app_memory/app_memdomain.h>

K_APPMEM_PARTITION_DEFINE(bench_ptn);
struct k_mem_domain bench_domain;

extern char sline[256];
extern u64_t __end_drop_to_usermode_time;

u32_t drop_to_user_mode_end_time, drop_to_user_mode_start_time;
u32_t user_thread_creation_end_time, user_thread_creation_start_time;

struct k_thread my_thread_user;
K_THREAD_STACK_EXTERN(my_stack_area);
K_THREAD_STACK_EXTERN(my_stack_area_0);


/******************************************************************************/
/* syscall needed to read timer value when in user space */
u32_t z_impl_userspace_read_timer_value(void)
{
	TIMING_INFO_PRE_READ();
	return TIMING_INFO_GET_TIMER_VALUE();
}

Z_SYSCALL_HANDLER(userspace_read_timer_value)
{
	TIMING_INFO_PRE_READ();
	return TIMING_INFO_GET_TIMER_VALUE();
}

/******************************************************************************/

void drop_to_user_mode(void);
void user_thread_creation(void);
void syscall_overhead(void);
void validation_overhead(void);

void userspace_bench(void)
{
	struct k_mem_partition *parts[] = {
		&bench_ptn
	};

	k_mem_domain_init(&bench_domain, ARRAY_SIZE(parts), parts);
	k_mem_domain_add_thread(&bench_domain, k_current_get());

	drop_to_user_mode();

	user_thread_creation();

	syscall_overhead();

	validation_overhead();
}
/******************************************************************************/

void test_drop_to_user_mode_1(void *p1, void *p2, void *p3)
{
	volatile u32_t dummy = 100U;

	dummy++;
}

void drop_to_user_mode_thread(void *p1, void *p2, void *p3)
{
	TIMING_INFO_PRE_READ();
	drop_to_user_mode_start_time = TIMING_INFO_GET_TIMER_VALUE();
	k_thread_user_mode_enter(test_drop_to_user_mode_1, NULL, NULL, NULL);
}


void drop_to_user_mode(void)
{
#ifdef SysTick
	/* Reset the counter so that a interrupt doesn't happen inbetween
	 * the benchmark test
	 */
	SysTick->VAL = 0;
#endif

	/* Test time to drop to usermode from SU */

	k_thread_create(&my_thread_user, my_stack_area_0, STACK_SIZE,
			drop_to_user_mode_thread,
			NULL, NULL, NULL,
			-1 /*priority*/, K_INHERIT_PERMS, 0);

	k_yield();

	drop_to_user_mode_end_time = (u32_t)
		SUBTRACT_CLOCK_CYCLES(__end_drop_to_usermode_time);

	u32_t tmp_start_time =
		SUBTRACT_CLOCK_CYCLES(drop_to_user_mode_start_time);

	u32_t total_drop_to_user_mode_time =
		CYCLES_TO_NS((u32_t)
			     ((drop_to_user_mode_end_time - tmp_start_time) &
			      0xFFFFFFFFULL));

	PRINT_STATS("Drop to user mode",
		    (u32_t)((drop_to_user_mode_end_time - tmp_start_time) &
		     0xFFFFFFFFULL),
		    (u32_t) (total_drop_to_user_mode_time  & 0xFFFFFFFFULL));



}

/******************************************************************************/
void user_thread_creation(void)
{
	u32_t total_user_thread_creation_time;

	TIMING_INFO_PRE_READ();
	user_thread_creation_start_time = TIMING_INFO_GET_TIMER_VALUE();

	k_thread_create(&my_thread_user, my_stack_area, STACK_SIZE,
			test_drop_to_user_mode_1,
			NULL, NULL, NULL,
			0 /*priority*/, K_INHERIT_PERMS | K_USER, 0);

	TIMING_INFO_PRE_READ();
	user_thread_creation_end_time = TIMING_INFO_GET_TIMER_VALUE();
	k_thread_abort(&my_thread_user);

	u32_t total_cycles = (u32_t)
		((SUBTRACT_CLOCK_CYCLES(user_thread_creation_end_time) -
		  SUBTRACT_CLOCK_CYCLES(user_thread_creation_start_time)) &
		 0xFFFFFFFFULL);

	total_user_thread_creation_time = CYCLES_TO_NS(total_cycles);

	PRINT_STATS("User thread Creation",
		    total_cycles,
		    (u32_t) (total_user_thread_creation_time  & 0xFFFFFFFFULL));

}

/******************************************************************************/
/* dummy syscalls creation */
K_APP_BMEM(bench_ptn) u32_t syscall_overhead_start_time,
	syscall_overhead_end_time;

int z_impl_k_dummy_syscall(void)
{
	return 0;
}

Z_SYSCALL_HANDLER(k_dummy_syscall)
{
	TIMING_INFO_PRE_READ();
	syscall_overhead_end_time = TIMING_INFO_GET_TIMER_VALUE();
	return 0;
}


void syscall_overhead_user_thread(void *p1, void *p2, void *p3)
{
	syscall_overhead_start_time = userspace_read_timer_value();
	int val = k_dummy_syscall();

	val |= 0xFF;
}


void syscall_overhead(void)
{
	u32_t total_syscall_overhead_time;

	k_thread_create(&my_thread_user, my_stack_area_0, STACK_SIZE,
			syscall_overhead_user_thread,
			NULL, NULL, NULL,
			-1 /*priority*/, K_INHERIT_PERMS | K_USER, 0);


	u32_t total_cycles = (u32_t)
		((SUBTRACT_CLOCK_CYCLES(syscall_overhead_end_time) -
		  SUBTRACT_CLOCK_CYCLES(syscall_overhead_start_time)) &
		 0xFFFFFFFFULL);

	total_syscall_overhead_time = CYCLES_TO_NS(total_cycles);

	PRINT_STATS("Syscall overhead",
		    total_cycles,
		    (u32_t) (total_syscall_overhead_time  & 0xFFFFFFFFULL));

}

/******************************************************************************/
K_SEM_DEFINE(test_sema, 1, 10);
u32_t validation_overhead_obj_init_start_time;
u32_t validation_overhead_obj_init_end_time;
u32_t validation_overhead_obj_start_time;
u32_t validation_overhead_obj_end_time;

int z_impl_validation_overhead_syscall(void)
{
	return 0;
}

Z_SYSCALL_HANDLER(validation_overhead_syscall)
{
	TIMING_INFO_PRE_READ();
	validation_overhead_obj_init_start_time = TIMING_INFO_GET_TIMER_VALUE();

	bool status_0 = Z_SYSCALL_OBJ_INIT(&test_sema, K_OBJ_SEM);

	TIMING_INFO_PRE_READ();
	validation_overhead_obj_init_end_time = TIMING_INFO_GET_TIMER_VALUE();


	TIMING_INFO_PRE_READ();
	validation_overhead_obj_start_time = TIMING_INFO_GET_TIMER_VALUE();

	bool status_1 = Z_SYSCALL_OBJ(&test_sema, K_OBJ_SEM);

	TIMING_INFO_PRE_READ();
	validation_overhead_obj_end_time = TIMING_INFO_GET_TIMER_VALUE();
	return status_0 || status_1;
}


void validation_overhead_user_thread(void *p1, void *p2, void *p3)
{
	/* get validation numbers */
	validation_overhead_syscall();
}

void validation_overhead(void)
{
	k_thread_access_grant(k_current_get(), &test_sema);


	k_thread_create(&my_thread_user, my_stack_area, STACK_SIZE,
			validation_overhead_user_thread,
			NULL, NULL, NULL,
			-1 /*priority*/, K_INHERIT_PERMS | K_USER, 0);


	u32_t total_cycles_obj_init = (u32_t)
		((SUBTRACT_CLOCK_CYCLES(validation_overhead_obj_init_end_time) -
		  SUBTRACT_CLOCK_CYCLES(validation_overhead_obj_init_start_time)
		  ) & 0xFFFFFFFFULL);

	u32_t total_cycles_obj = (u32_t)
		((SUBTRACT_CLOCK_CYCLES(validation_overhead_obj_end_time) -
		  SUBTRACT_CLOCK_CYCLES(validation_overhead_obj_start_time)) &
		 0xFFFFFFFFULL);

	u32_t total_validation_overhead_obj_init_time =
		CYCLES_TO_NS(total_cycles_obj_init);

	u32_t  total_validation_overhead_obj_time =
		CYCLES_TO_NS(total_cycles_obj);

	PRINT_STATS("Validation overhead k object init",
		    total_cycles_obj_init,
		    (u32_t) (total_validation_overhead_obj_init_time  &
			     0xFFFFFFFFULL));

	PRINT_STATS("Validation overhead k object permission",
		    total_cycles_obj,
		    (u32_t) (total_validation_overhead_obj_time  &
			     0xFFFFFFFFULL));


}
