/*
 * Copyright (c) 2010-2015 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Thread support primitives
 *
 * This module provides core thread related primitives for the IA-32
 * processor architecture.
 */

#ifdef CONFIG_INIT_STACKS
#include <string.h>
#endif /* CONFIG_INIT_STACKS */

#include <toolchain.h>
#include <linker/sections.h>
#include <kernel_structs.h>
#include <wait_q.h>
#include <mmustructs.h>
#include <misc/printk.h>

/* forward declaration */

/* Initial thread stack frame, such that everything is laid out as expected
 * for when _Swap() switches to it for the first time.
 */
struct _x86_initial_frame {
	u32_t swap_retval;
	u32_t ebp;
	u32_t ebx;
	u32_t esi;
	u32_t edi;
	void *_thread_entry;
	u32_t eflags;
	k_thread_entry_t entry;
	void *p1;
	void *p2;
	void *p3;
};

/**
 * @brief Create a new kernel execution thread
 *
 * Initializes the k_thread object and sets up initial stack frame.
 *
 * @param thread pointer to thread struct memory, including any space needed
 *		for extra coprocessor context
 * @param stack the pointer to aligned stack memory
 * @param stack_size the stack size in bytes
 * @param entry thread entry point routine
 * @param parameter1 first param to entry point
 * @param parameter2 second param to entry point
 * @param parameter3 third param to entry point
 * @param priority thread priority
 * @param options thread options: K_ESSENTIAL, K_FP_REGS, K_SSE_REGS
 */
void _new_thread(struct k_thread *thread, k_thread_stack_t *stack,
		 size_t stack_size, k_thread_entry_t entry,
		 void *parameter1, void *parameter2, void *parameter3,
		 int priority, unsigned int options)
{
	char *stack_buf;
	char *stack_high;
	struct _x86_initial_frame *initial_frame;

	_ASSERT_VALID_PRIO(priority, entry);
	stack_buf = K_THREAD_STACK_BUFFER(stack);
	_new_thread_init(thread, stack_buf, stack_size, priority, options);

#if CONFIG_X86_USERSPACE
	if (!(options & K_USER)) {
		/* Running in kernel mode, kernel stack region is also a guard
		 * page */
		_x86_mmu_set_flags((void *)(stack_buf - MMU_PAGE_SIZE),
				   MMU_PAGE_SIZE, MMU_ENTRY_NOT_PRESENT,
				   MMU_PTE_P_MASK);
	}
#endif /* CONFIG_X86_USERSPACE */

#if CONFIG_X86_STACK_PROTECTION
	_x86_mmu_set_flags(stack, MMU_PAGE_SIZE, MMU_ENTRY_NOT_PRESENT,
			   MMU_PTE_P_MASK);
#endif

	stack_high = (char *)STACK_ROUND_DOWN(stack_buf + stack_size);

	/* Create an initial context on the stack expected by _Swap() */
	initial_frame = (struct _x86_initial_frame *)
		(stack_high - sizeof(struct _x86_initial_frame));
	/* _thread_entry() arguments */
	initial_frame->entry = entry;
	initial_frame->p1 = parameter1;
	initial_frame->p2 = parameter2;
	initial_frame->p3 = parameter3;
	/* initial EFLAGS; only modify IF and IOPL bits */
	initial_frame->eflags = (EflagsGet() & ~EFLAGS_MASK) | EFLAGS_INITIAL;
#ifdef CONFIG_X86_USERSPACE
	if (options & K_USER) {
#ifdef _THREAD_WRAPPER_REQUIRED
		initial_frame->edi = (u32_t)_arch_user_mode_enter;
		initial_frame->_thread_entry = _x86_thread_entry_wrapper;
#else
		initial_frame->_thread_entry = _arch_user_mode_enter;
#endif /* _THREAD_WRAPPER_REQUIRED */
	} else
#endif /* CONFIG_X86_USERSPACE */
	{
#ifdef _THREAD_WRAPPER_REQUIRED
		initial_frame->edi = (u32_t)_thread_entry;
		initial_frame->_thread_entry = _x86_thread_entry_wrapper;
#else
		initial_frame->_thread_entry = _thread_entry;
#endif
	}
	/* Remaining _x86_initial_frame members can be garbage, _thread_entry()
	 * doesn't care about their state when execution begins
	 */
	thread->callee_saved.esp = (unsigned long)initial_frame;

#if defined(CONFIG_FP_SHARING)
	thread->arch.excNestCount = 0;
#endif /* CONFIG_FP_SHARING */
#ifdef CONFIG_THREAD_MONITOR
	thread->entry = (struct __thread_entry *)&initial_frame->entry;
	thread_monitor_init(thread);
#endif
}

#ifdef CONFIG_X86_USERSPACE
void _x86_swap_update_page_tables(struct k_thread *incoming,
				  struct k_thread *outgoing)
{
	/* Outgoing thread stack no longer accessible */
	_x86_mmu_set_flags((void *)outgoing->stack_info.start,
			   ROUND_UP(outgoing->stack_info.size, MMU_PAGE_SIZE),
			   MMU_ENTRY_SUPERVISOR, MMU_PTE_US_MASK);


	/* Userspace can now access the incoming thread's stack */
	_x86_mmu_set_flags((void *)incoming->stack_info.start,
			   ROUND_UP(incoming->stack_info.size, MMU_PAGE_SIZE),
			   MMU_ENTRY_USER, MMU_PTE_US_MASK);

	/* In case of privilege elevation, use the incoming thread's kernel
	 * stack, the top of the thread stack is the bottom of the kernel stack
	 */
	_main_tss.esp0 = incoming->stack_info.start;

	/* If either thread defines different memory domains, efficiently
	 * switch between them
	 */
	if (incoming->mem_domain_info.mem_domain !=
	   outgoing->mem_domain_info.mem_domain){

		 /* Ensure that the outgoing mem domain configuration
		  * is set back to default state.
		  */
		_arch_mem_domain_destroy(outgoing->mem_domain_info.mem_domain);
		_arch_mem_domain_configure(incoming);
	}
}


FUNC_NORETURN void _arch_user_mode_enter(k_thread_entry_t user_entry,
					 void *p1, void *p2, void *p3)
{
	u32_t stack_end;

	/* Transition will reset stack pointer to initial, discarding
	 * any old context since this is a one-way operation
	 */
	stack_end = STACK_ROUND_DOWN(_current->stack_info.start +
				     _current->stack_info.size);

	/* Set up the kernel stack used during privilege elevation */
	_x86_mmu_set_flags((void *)(_current->stack_info.start - MMU_PAGE_SIZE),
			   MMU_PAGE_SIZE,
			   (MMU_ENTRY_PRESENT | MMU_ENTRY_WRITE |
			    MMU_ENTRY_SUPERVISOR),
			   (MMU_PTE_P_MASK | MMU_PTE_RW_MASK |
			    MMU_PTE_US_MASK));

	_x86_userspace_enter(user_entry, p1, p2, p3, stack_end,
			     _current->stack_info.start);
	CODE_UNREACHABLE;
}


/* Implemented in userspace.S */
extern void _x86_syscall_entry_stub(void);

/* Syscalls invoked by 'int 0x80'. Installed in the IDT at DPL=3 so that
 * userspace can invoke it.
 */
NANO_CPU_INT_REGISTER(_x86_syscall_entry_stub, -1, -1, 0x80, 3);

#endif /* CONFIG_X86_USERSPACE */
