unified/x86: add unified kernel support for x86 arch

The x86 architecture port is fitted with support for the unified kernel,
namely:

- the interrupt exit code now calls _Swap() if the current
  thread is not a coop thread and if the scheduler is not locked

- there is no 'task' fields in the _nanokernel anymore: _Swap()
  now calls _get_next_ready_thread instead

- the _nanokernel.fiber field is replaced by a more sophisticated
  ready_q, based on the microkernel's priority-bitmap-based one

- nano_private includes nano_internal.h from the unified directory

- the FIBER, TASK and PREEMPTIBLE flags do not exist anymore: the thread
  priority drives the behaviour

- the tcs uses a dlist for queuing in both ready and wait queues instead
  of a custom singly-linked list

- other new fields in the tcs include a schedule-lock count, a
  back-pointer to init data (when the task is static) and a pointer to
  swap data, needed when a thread pending on _Swap() must be passed more
  then just one value (e.g. k_stack_pop() needs an error code and data)

- fiberRtnValueSet() is aliased to _set_thread_return_value since it
  also operates on preempt threads now

- _set_thread_return_value_with_data() sets the swap_data field in
  addition to a return value from _Swap()

- convenience aliases are created for shorter names:

  - _current is defined as _nanokernel.current
  - _ready_q is defined as _nanokernel.ready_q

- _Swap() sets the threads's return code to -EAGAIN before swapping out
  to prevent timeouts to have to set it (solves hard issues in some
  kernel objects).

- Floating point support.

Note that, in _Swap(), the register holding the thread to be swapped in has
been changed from %ecx to %eax in both the legacy kernel and the unified kernel
to take advantage of the fact that the return value of _get_next_ready_thread()
is stored in %eax, and this avoids moving it to %ecx.

Work by: Dmitriy Korovkin <dmitriy.korovkin@windriver.com>
         Allan Stephens <allan.stephens@windriver.com>
	 Benjamin Walsh <benjamin.walsh@windriver.com>

Change-Id: I4ce2bd47bcdc62034c669b5e889fc0f29480c43b
Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
This commit is contained in:
Benjamin Walsh 2016-09-02 16:34:35 -04:00
commit 983cbe398c
9 changed files with 245 additions and 44 deletions

View file

@ -22,10 +22,12 @@
* processor architecture.
*/
#if !defined(CONFIG_KERNEL_V2)
#ifdef CONFIG_MICROKERNEL
#include <microkernel.h>
#include <micro_private_types.h>
#endif /* CONFIG_MICROKERNEL */
#endif
#ifdef CONFIG_INIT_STACKS
#include <string.h>
#endif /* CONFIG_INIT_STACKS */
@ -59,13 +61,14 @@ void _thread_entry_wrapper(_thread_entry_t, _thread_arg_t,
*
* @param pStackMem pointer to thread stack memory
* @param stackSize size of a stack in bytes
* @param thread priority
* @param options thread options: USE_FP, USE_SSE
* @param priority thread priority
* @param options thread options: ESSENTIAL, USE_FP, USE_SSE
*
* @return N/A
*/
static void _new_thread_internal(char *pStackMem, unsigned stackSize,
void *uk_task_ptr, int priority, unsigned options)
void *uk_task_ptr, int priority,
unsigned options)
{
unsigned long *pInitialCtx;
/* ptr to the new task's tcs */
@ -75,17 +78,32 @@ static void _new_thread_internal(char *pStackMem, unsigned stackSize,
ARG_UNUSED(options);
#endif /* !CONFIG_FP_SHARING */
tcs->link = (struct tcs *)NULL; /* thread not inserted into list yet */
tcs->prio = priority;
#if (defined(CONFIG_FP_SHARING) || defined(CONFIG_GDB_INFO))
tcs->excNestCount = 0;
#endif /* CONFIG_FP_SHARING || CONFIG_GDB_INFO */
#ifdef CONFIG_KERNEL_V2
/* k_q_node initialized upon first insertion in a list */
#ifdef CONFIG_FP_SHARING
/* ensure USE_FP is set when USE_SSE is set */
if (options & USE_SSE) {
options |= USE_FP;
}
#endif
tcs->flags = options | K_PRESTART;
tcs->sched_locked = 0;
/* static threads overwrite it afterwards with real value */
tcs->init_data = NULL;
tcs->fn_abort = NULL;
#else
if (priority == -1)
tcs->flags = PREEMPTIBLE | TASK;
else
tcs->flags = FIBER;
tcs->link = (struct tcs *)NULL; /* thread not inserted into list yet */
#endif
#ifdef CONFIG_THREAD_CUSTOM_DATA
/* Initialize custom data field (value is opaque to kernel) */
@ -93,7 +111,7 @@ static void _new_thread_internal(char *pStackMem, unsigned stackSize,
tcs->custom_data = NULL;
#endif
#ifdef CONFIG_MICROKERNEL
#if !defined(CONFIG_KERNEL_V2) && defined(CONFIG_MICROKERNEL)
tcs->uk_task_ptr = uk_task_ptr;
#else
ARG_UNUSED(uk_task_ptr);
@ -130,6 +148,7 @@ static void _new_thread_internal(char *pStackMem, unsigned stackSize,
tcs->coopReg.esp = (unsigned long)pInitialCtx;
PRINTK("\nInitial context ESP = 0x%x\n", tcs->coopReg.esp);
#ifndef CONFIG_KERNEL_V2
#ifdef CONFIG_FP_SHARING
/*
* Indicate if the thread is permitted to use floating point instructions.
@ -184,6 +203,7 @@ static void _new_thread_internal(char *pStackMem, unsigned stackSize,
tcs->flags |= (options | USE_FP);
}
#endif /* CONFIG_FP_SHARING */
#endif /* CONFIG_KERNEL_V2 */
PRINTK("\nstruct tcs * = 0x%x", tcs);
@ -304,8 +324,8 @@ __asm__("\t.globl _thread_entry\n"
* @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: USE_FP, USE_SSE
* @param priority thread priority
* @param options thread options: ESSENTIAL, USE_FP, USE_SSE
*
*
* @return opaque pointer to initialized TCS structure