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:
parent
b9a0d90a5f
commit
983cbe398c
9 changed files with 245 additions and 44 deletions
|
@ -1,5 +1,9 @@
|
||||||
|
ifeq ($(CONFIG_KERNEL_V2),y)
|
||||||
|
ccflags-y += -I$(srctree)/kernel/unified/include
|
||||||
|
else
|
||||||
ccflags-y += -I$(srctree)/kernel/nanokernel/include
|
ccflags-y += -I$(srctree)/kernel/nanokernel/include
|
||||||
ccflags-y += -I$(srctree)/kernel/microkernel/include
|
ccflags-y += -I$(srctree)/kernel/microkernel/include
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(COMPILER)$(CONFIG_X86_IAMCU),clang)
|
ifeq ($(COMPILER)$(CONFIG_X86_IAMCU),clang)
|
||||||
# We rely on GAS for assembling, so don't use the integrated assembler
|
# We rely on GAS for assembling, so don't use the integrated assembler
|
||||||
|
@ -19,7 +23,9 @@ obj-y += cpuhalt.o \
|
||||||
|
|
||||||
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
|
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
|
||||||
obj-$(CONFIG_FP_SHARING) += float.o
|
obj-$(CONFIG_FP_SHARING) += float.o
|
||||||
|
ifneq ($(CONFIG_KERNEL_V2),y)
|
||||||
obj-$(CONFIG_MICROKERNEL) += strtask.o
|
obj-$(CONFIG_MICROKERNEL) += strtask.o
|
||||||
|
endif
|
||||||
obj-$(CONFIG_GDT_DYNAMIC) += gdt.o
|
obj-$(CONFIG_GDT_DYNAMIC) += gdt.o
|
||||||
obj-$(CONFIG_REBOOT_RST_CNT) += reboot_rst_cnt.o
|
obj-$(CONFIG_REBOOT_RST_CNT) += reboot_rst_cnt.o
|
||||||
|
|
||||||
|
|
|
@ -76,10 +76,12 @@
|
||||||
* system to enable FP resource sharing on its behalf.
|
* system to enable FP resource sharing on its behalf.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if !defined(CONFIG_KERNEL_V2)
|
||||||
#ifdef CONFIG_MICROKERNEL
|
#ifdef CONFIG_MICROKERNEL
|
||||||
#include <microkernel.h>
|
#include <microkernel.h>
|
||||||
#include <micro_private_types.h>
|
#include <micro_private_types.h>
|
||||||
#endif /* CONFIG_MICROKERNEL */
|
#endif /* CONFIG_MICROKERNEL */
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nano_private.h>
|
#include <nano_private.h>
|
||||||
#include <toolchain.h>
|
#include <toolchain.h>
|
||||||
|
@ -265,6 +267,20 @@ void _FpEnable(struct tcs *tcs, unsigned int options)
|
||||||
irq_unlock(imask);
|
irq_unlock(imask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Enable preservation of non-integer context information
|
||||||
|
*
|
||||||
|
* This routine allows a thread to permit any thread (including itself) to
|
||||||
|
* safely share the system's floating point registers with other threads.
|
||||||
|
*
|
||||||
|
* See the description of _FpEnable() for further details.
|
||||||
|
*
|
||||||
|
* @return N/A
|
||||||
|
*/
|
||||||
|
FUNC_ALIAS(_FpEnable, k_float_enable, void);
|
||||||
|
#else
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @brief Enable preservation of non-integer context information
|
* @brief Enable preservation of non-integer context information
|
||||||
|
@ -290,6 +306,7 @@ FUNC_ALIAS(_FpEnable, fiber_float_enable, void);
|
||||||
* @return N/A
|
* @return N/A
|
||||||
*/
|
*/
|
||||||
FUNC_ALIAS(_FpEnable, task_float_enable, void);
|
FUNC_ALIAS(_FpEnable, task_float_enable, void);
|
||||||
|
#endif /* CONFIG_KERNEL_V2 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -350,6 +367,23 @@ void _FpDisable(struct tcs *tcs)
|
||||||
irq_unlock(imask);
|
irq_unlock(imask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Disable preservation of non-integer context information
|
||||||
|
*
|
||||||
|
* This routine allows a thread to disallow any thread (including itself) from
|
||||||
|
* safely sharing any of the system's floating point registers with other
|
||||||
|
* threads.
|
||||||
|
*
|
||||||
|
* WARNING
|
||||||
|
* This routine should only be used to disable floating point support for
|
||||||
|
* a thread that currently has such support enabled.
|
||||||
|
*
|
||||||
|
* @return N/A
|
||||||
|
*/
|
||||||
|
FUNC_ALIAS(_FpDisable, k_float_disable, void);
|
||||||
|
#else
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @brief Disable preservation of non-integer context
|
* @brief Disable preservation of non-integer context
|
||||||
|
@ -382,7 +416,7 @@ FUNC_ALIAS(_FpDisable, fiber_float_disable, void);
|
||||||
* @return N/A
|
* @return N/A
|
||||||
*/
|
*/
|
||||||
FUNC_ALIAS(_FpDisable, task_float_disable, void);
|
FUNC_ALIAS(_FpDisable, task_float_disable, void);
|
||||||
|
#endif /* CONFIG_KERNEL_V2 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -407,7 +441,7 @@ void _FpNotAvailableExcHandler(NANO_ESF * pEsf)
|
||||||
ARG_UNUSED(pEsf);
|
ARG_UNUSED(pEsf);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Assume the exception did not occur in the thread of an ISR.
|
* Assume the exception did not occur in an ISR.
|
||||||
* (In other words, CPU cycles will not be consumed to perform
|
* (In other words, CPU cycles will not be consumed to perform
|
||||||
* error checking to ensure the exception was not generated in an ISR.)
|
* error checking to ensure the exception was not generated in an ISR.)
|
||||||
*/
|
*/
|
||||||
|
@ -415,7 +449,7 @@ void _FpNotAvailableExcHandler(NANO_ESF * pEsf)
|
||||||
PRINTK("_FpNotAvailableExcHandler() exception handler has been "
|
PRINTK("_FpNotAvailableExcHandler() exception handler has been "
|
||||||
"invoked\n");
|
"invoked\n");
|
||||||
|
|
||||||
/* Enable the highest level of FP capability configured into the kernel */
|
/* Enable highest level of FP capability configured into the kernel */
|
||||||
|
|
||||||
#ifdef CONFIG_SSE
|
#ifdef CONFIG_SSE
|
||||||
enableOption = USE_SSE;
|
enableOption = USE_SSE;
|
||||||
|
|
|
@ -45,6 +45,10 @@
|
||||||
|
|
||||||
GTEXT(_Swap)
|
GTEXT(_Swap)
|
||||||
|
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
GTEXT(__must_switch_threads)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SYS_POWER_MANAGEMENT
|
#ifdef CONFIG_SYS_POWER_MANAGEMENT
|
||||||
#if defined(CONFIG_NANOKERNEL) && defined(CONFIG_TICKLESS_IDLE)
|
#if defined(CONFIG_NANOKERNEL) && defined(CONFIG_TICKLESS_IDLE)
|
||||||
GTEXT(_power_save_idle_exit)
|
GTEXT(_power_save_idle_exit)
|
||||||
|
@ -334,17 +338,40 @@ _IntExitWithCli:
|
||||||
jne nestedInterrupt /* 'iret' if nested case */
|
jne nestedInterrupt /* 'iret' if nested case */
|
||||||
|
|
||||||
|
|
||||||
|
movl __tNANO_current_OFFSET (%ecx), %edx
|
||||||
|
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
/*
|
||||||
|
* Determine whether the execution of the ISR requires a context
|
||||||
|
* switch. If the thread is preemptible, scheduler is not locked and
|
||||||
|
* a higher priority thread exists, a _Swap() needs to occur.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* do not reschedule coop threads (negative priority) */
|
||||||
|
cmpl $0, __tTCS_prio_OFFSET (%edx)
|
||||||
|
jl noReschedule
|
||||||
|
|
||||||
|
/* do not reschedule if scheduler is locked */
|
||||||
|
cmpl $0, __tTCS_sched_locked_OFFSET (%edx)
|
||||||
|
jg noReschedule
|
||||||
|
|
||||||
|
|
||||||
|
/* reschedule only if the scheduler says that we must do so */
|
||||||
|
call __must_switch_threads
|
||||||
|
cmpl $0, %eax
|
||||||
|
je noReschedule
|
||||||
|
#else
|
||||||
/*
|
/*
|
||||||
* Determine whether the execution of the ISR requires a context
|
* Determine whether the execution of the ISR requires a context
|
||||||
* switch. If the interrupted thread is PREEMPTIBLE (a task) and
|
* switch. If the interrupted thread is PREEMPTIBLE (a task) and
|
||||||
* _nanokernel.fiber is non-NULL, a _Swap() needs to occur.
|
* _nanokernel.fiber is non-NULL, a _Swap() needs to occur.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
movl __tNANO_current_OFFSET (%ecx), %eax
|
testl $PREEMPTIBLE, __tTCS_flags_OFFSET(%edx)
|
||||||
testl $PREEMPTIBLE, __tTCS_flags_OFFSET(%eax)
|
|
||||||
je noReschedule
|
je noReschedule
|
||||||
cmpl $0, __tNANO_fiber_OFFSET (%ecx)
|
cmpl $0, __tNANO_fiber_OFFSET (%ecx)
|
||||||
je noReschedule
|
je noReschedule
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the INT_ACTIVE bit in the tTCS to allow the upcoming call to
|
* Set the INT_ACTIVE bit in the tTCS to allow the upcoming call to
|
||||||
|
@ -358,7 +385,11 @@ _IntExitWithCli:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_FP_SHARING) || defined(CONFIG_GDB_INFO)
|
#if defined(CONFIG_FP_SHARING) || defined(CONFIG_GDB_INFO)
|
||||||
orl $INT_ACTIVE, __tTCS_flags_OFFSET(%eax)
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
/* reload _nanokernel.current: __must_switch_threads may clobber it */
|
||||||
|
movl _nanokernel + __tNANO_current_OFFSET, %edx
|
||||||
|
#endif
|
||||||
|
orl $INT_ACTIVE, __tTCS_flags_OFFSET(%edx)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -369,7 +400,7 @@ _IntExitWithCli:
|
||||||
* a switch to the new thread.
|
* a switch to the new thread.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
popl %esp /* switch back to kernel stack */
|
popl %esp /* switch back to outgoing thread's stack */
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_INFO
|
#ifdef CONFIG_DEBUG_INFO
|
||||||
popl %ebp /* Discard saved ESP */
|
popl %ebp /* Discard saved ESP */
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
* Intel-specific parts of start_task(). Only FP functionality currently.
|
* Intel-specific parts of start_task(). Only FP functionality currently.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if !defined(CONFIG_KERNEL_V2)
|
||||||
#ifdef CONFIG_MICROKERNEL
|
#ifdef CONFIG_MICROKERNEL
|
||||||
|
|
||||||
#include <start_task_arch.h>
|
#include <start_task_arch.h>
|
||||||
|
@ -78,3 +79,4 @@ void _StartTaskArch(struct k_task *X, unsigned int *pOpt)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_MICROKERNEL */
|
#endif /* CONFIG_MICROKERNEL */
|
||||||
|
#endif
|
||||||
|
|
|
@ -39,6 +39,11 @@
|
||||||
|
|
||||||
/* externs */
|
/* externs */
|
||||||
|
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
GTEXT(_get_next_ready_thread)
|
||||||
|
GDATA(_k_neg_eagain)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -84,7 +89,7 @@
|
||||||
* list (_nanokernel.fiber). If there are no runnable fibers, then schedule
|
* list (_nanokernel.fiber). If there are no runnable fibers, then schedule
|
||||||
* the task (_nanokernel.task). The _nanokernel.task field will never be NULL.
|
* the task (_nanokernel.task). The _nanokernel.task field will never be NULL.
|
||||||
*
|
*
|
||||||
* @return may contain a return value setup by a call to fiberRtnValueSet()
|
* @return -EAGAIN, or a return value set by a call to fiberRtnValueSet()
|
||||||
*
|
*
|
||||||
* C function prototype:
|
* C function prototype:
|
||||||
*
|
*
|
||||||
|
@ -115,13 +120,18 @@ SECTION_FUNC(TEXT, _Swap)
|
||||||
pushl %ebx
|
pushl %ebx
|
||||||
pushl %ebp
|
pushl %ebp
|
||||||
|
|
||||||
|
#if CONFIG_KERNEL_V2
|
||||||
/*
|
/*
|
||||||
* Leave slot for eax register when _Swap() needs to return a value;
|
* Carve space for the return value. Setting it to a defafult of
|
||||||
* pre-populate slot with ebx's value in case _Swap() does not return
|
* -EAGAIN eliminates the need for the timeout code to set it.
|
||||||
* a value.
|
* If another value is ever needed, it can be modified with
|
||||||
|
* fiberRtnValueSet().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
pushl _k_neg_eagain
|
||||||
|
#else
|
||||||
pushl %ebx
|
pushl %ebx
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* save esp into tTCS structure */
|
/* save esp into tTCS structure */
|
||||||
|
@ -134,18 +144,21 @@ SECTION_FUNC(TEXT, _Swap)
|
||||||
call _sys_k_event_logger_context_switch
|
call _sys_k_event_logger_context_switch
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
call _get_next_ready_thread
|
||||||
|
#else
|
||||||
/*
|
/*
|
||||||
* Determine what thread needs to be swapped in.
|
* Determine what thread needs to be swapped in.
|
||||||
* Note that the %edi still contains &_nanokernel.
|
* Note that the %edi still contains &_nanokernel.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
movl __tNANO_fiber_OFFSET (%edi), %ecx
|
movl __tNANO_fiber_OFFSET (%edi), %eax
|
||||||
testl %ecx, %ecx
|
testl %eax, %eax
|
||||||
jz swapTask /* Jump if no ready fibers */
|
jz swapTask /* Jump if no ready fibers */
|
||||||
|
|
||||||
/* remove the head 'TCS *' from the runnable fiber list */
|
/* remove the head 'TCS *' from the runnable fiber list */
|
||||||
|
|
||||||
movl __tTCS_link_OFFSET (%ecx), %ebx
|
movl __tTCS_link_OFFSET (%eax), %ebx
|
||||||
movl %ebx, __tNANO_fiber_OFFSET (%edi)
|
movl %ebx, __tNANO_fiber_OFFSET (%edi)
|
||||||
jmp restoreContext
|
jmp restoreContext
|
||||||
|
|
||||||
|
@ -156,13 +169,14 @@ SECTION_FUNC(TEXT, _Swap)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
swapTask:
|
swapTask:
|
||||||
movl __tNANO_task_OFFSET (%edi), %ecx
|
movl __tNANO_task_OFFSET (%edi), %eax
|
||||||
|
#endif
|
||||||
|
|
||||||
/* fall through to 'restoreContext' */
|
/* fall through to 'restoreContext' */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point, the %ecx register contains the 'tTCS *' of
|
* At this point, the %eax register contains the 'tTCS *' of
|
||||||
* the TASK or FIBER to be swapped in, and %edi still
|
* the TASK or FIBER to be swapped in, and %edi still
|
||||||
* contains &_nanokernel.
|
* contains &_nanokernel.
|
||||||
*/
|
*/
|
||||||
|
@ -193,7 +207,7 @@ restoreContext:
|
||||||
* out preemptively.
|
* out preemptively.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
testl $USE_FP, __tTCS_flags_OFFSET (%ecx)
|
testl $USE_FP, __tTCS_flags_OFFSET (%eax)
|
||||||
je restoreContext_NoFloatSwap
|
je restoreContext_NoFloatSwap
|
||||||
|
|
||||||
|
|
||||||
|
@ -204,7 +218,7 @@ restoreContext:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
movl __tNANO_current_fp_OFFSET (%edi), %ebx
|
movl __tNANO_current_fp_OFFSET (%edi), %ebx
|
||||||
cmpl %ebx, %ecx
|
cmpl %ebx, %eax
|
||||||
je restoreContext_NoFloatSwap
|
je restoreContext_NoFloatSwap
|
||||||
|
|
||||||
|
|
||||||
|
@ -269,21 +283,21 @@ restoreContext_NoFloatSave:
|
||||||
* thread was previously preemptively context switched out.
|
* thread was previously preemptively context switched out.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
testl $INT_OR_EXC_MASK, __tTCS_flags_OFFSET (%ecx)
|
testl $INT_OR_EXC_MASK, __tTCS_flags_OFFSET (%eax)
|
||||||
je restoreContext_NoFloatRestore
|
je restoreContext_NoFloatRestore
|
||||||
|
|
||||||
#ifdef CONFIG_SSE
|
#ifdef CONFIG_SSE
|
||||||
testl $USE_SSE, __tTCS_flags_OFFSET (%ecx)
|
testl $USE_SSE, __tTCS_flags_OFFSET (%eax)
|
||||||
je x87FloatRestore
|
je x87FloatRestore
|
||||||
|
|
||||||
fxrstor __tTCS_preempFloatReg_OFFSET (%ecx)
|
fxrstor __tTCS_preempFloatReg_OFFSET (%eax)
|
||||||
jmp floatRestoreDone
|
jmp floatRestoreDone
|
||||||
|
|
||||||
x87FloatRestore:
|
x87FloatRestore:
|
||||||
|
|
||||||
#endif /* CONFIG_SSE */
|
#endif /* CONFIG_SSE */
|
||||||
|
|
||||||
frstor __tTCS_preempFloatReg_OFFSET (%ecx)
|
frstor __tTCS_preempFloatReg_OFFSET (%eax)
|
||||||
|
|
||||||
/* fall through to 'floatRestoreDone' */
|
/* fall through to 'floatRestoreDone' */
|
||||||
|
|
||||||
|
@ -292,7 +306,7 @@ restoreContext_NoFloatRestore:
|
||||||
|
|
||||||
/* record that the incoming thread "owns" the non-integer registers */
|
/* record that the incoming thread "owns" the non-integer registers */
|
||||||
|
|
||||||
movl %ecx, __tNANO_current_fp_OFFSET (%edi)
|
movl %eax, __tNANO_current_fp_OFFSET (%edi)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -309,7 +323,7 @@ restoreContext_NoFloatSwap:
|
||||||
* instructions
|
* instructions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
testl $USE_FP, __tTCS_flags_OFFSET (%ecx)
|
testl $USE_FP, __tTCS_flags_OFFSET (%eax)
|
||||||
jne CROHandlingDone
|
jne CROHandlingDone
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -332,11 +346,11 @@ CROHandlingDone:
|
||||||
|
|
||||||
/* update _nanokernel.current to reflect incoming thread */
|
/* update _nanokernel.current to reflect incoming thread */
|
||||||
|
|
||||||
movl %ecx, __tNANO_current_OFFSET (%edi)
|
movl %eax, __tNANO_current_OFFSET (%edi)
|
||||||
|
|
||||||
/* recover task/fiber stack pointer from tTCS */
|
/* recover task/fiber stack pointer from tTCS */
|
||||||
|
|
||||||
movl __tTCS_coopReg_OFFSET + __tCoopReg_esp_OFFSET (%ecx), %esp
|
movl __tTCS_coopReg_OFFSET + __tCoopReg_esp_OFFSET (%eax), %esp
|
||||||
|
|
||||||
|
|
||||||
/* load return value from a possible fiberRtnValueSet() */
|
/* load return value from a possible fiberRtnValueSet() */
|
||||||
|
@ -351,15 +365,12 @@ CROHandlingDone:
|
||||||
popl %edi
|
popl %edi
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For a non-preemptive context switch, it is checked that the volatile
|
* %eax may contain one of these values:
|
||||||
* integer registers have the following values:
|
|
||||||
*
|
*
|
||||||
* 1. ECX - points to the task's own TCS structure.
|
* - the return value for _Swap() that was set up by a call to
|
||||||
* 2. EDX - contains the flags field of the task's own TCS structure.
|
* fiberRtnValueSet()
|
||||||
* 3. EAX - may contain one of the two values:
|
* - in legacy kernel, same value as %ebx, which is non-volatile
|
||||||
* (a) the return value for _Swap() that was set up by a
|
* - in unified kernel, -EINVAL
|
||||||
* call to fiberRtnValueSet()
|
|
||||||
* (b) same value as EBX, which is non-volatile
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Utilize the 'eflags' parameter to _Swap() */
|
/* Utilize the 'eflags' parameter to _Swap() */
|
||||||
|
|
|
@ -26,6 +26,15 @@
|
||||||
#include <toolchain.h>
|
#include <toolchain.h>
|
||||||
#include <sections.h>
|
#include <sections.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
#include <nano_private.h> /* to get access to '_current' */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* override PRINTK from nano_private.h */
|
||||||
|
#if defined(CONFIG_KERNEL_V2) && defined(PRINTK)
|
||||||
|
#undef PRINTK
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PRINTK
|
#ifdef CONFIG_PRINTK
|
||||||
#include <misc/printk.h>
|
#include <misc/printk.h>
|
||||||
#define PRINTK(...) printk(__VA_ARGS__)
|
#define PRINTK(...) printk(__VA_ARGS__)
|
||||||
|
@ -66,7 +75,11 @@ FUNC_NORETURN void _SysFatalErrorHandler(unsigned int reason,
|
||||||
if (curCtx == NANO_CTX_TASK) {
|
if (curCtx == NANO_CTX_TASK) {
|
||||||
extern FUNC_NORETURN void _TaskAbort(void);
|
extern FUNC_NORETURN void _TaskAbort(void);
|
||||||
PRINTK("Fatal task error! Aborting task.\n");
|
PRINTK("Fatal task error! Aborting task.\n");
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
k_thread_abort(_current);
|
||||||
|
#else
|
||||||
_TaskAbort();
|
_TaskAbort();
|
||||||
|
#endif
|
||||||
} else
|
} else
|
||||||
#endif /* CONFIG_MICROKERNEL */
|
#endif /* CONFIG_MICROKERNEL */
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,10 +22,12 @@
|
||||||
* processor architecture.
|
* processor architecture.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if !defined(CONFIG_KERNEL_V2)
|
||||||
#ifdef CONFIG_MICROKERNEL
|
#ifdef CONFIG_MICROKERNEL
|
||||||
#include <microkernel.h>
|
#include <microkernel.h>
|
||||||
#include <micro_private_types.h>
|
#include <micro_private_types.h>
|
||||||
#endif /* CONFIG_MICROKERNEL */
|
#endif /* CONFIG_MICROKERNEL */
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_INIT_STACKS
|
#ifdef CONFIG_INIT_STACKS
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif /* CONFIG_INIT_STACKS */
|
#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 pStackMem pointer to thread stack memory
|
||||||
* @param stackSize size of a stack in bytes
|
* @param stackSize size of a stack in bytes
|
||||||
* @param thread priority
|
* @param priority thread priority
|
||||||
* @param options thread options: USE_FP, USE_SSE
|
* @param options thread options: ESSENTIAL, USE_FP, USE_SSE
|
||||||
*
|
*
|
||||||
* @return N/A
|
* @return N/A
|
||||||
*/
|
*/
|
||||||
static void _new_thread_internal(char *pStackMem, unsigned stackSize,
|
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;
|
unsigned long *pInitialCtx;
|
||||||
/* ptr to the new task's tcs */
|
/* ptr to the new task's tcs */
|
||||||
|
@ -75,17 +78,32 @@ static void _new_thread_internal(char *pStackMem, unsigned stackSize,
|
||||||
ARG_UNUSED(options);
|
ARG_UNUSED(options);
|
||||||
#endif /* !CONFIG_FP_SHARING */
|
#endif /* !CONFIG_FP_SHARING */
|
||||||
|
|
||||||
tcs->link = (struct tcs *)NULL; /* thread not inserted into list yet */
|
|
||||||
tcs->prio = priority;
|
tcs->prio = priority;
|
||||||
#if (defined(CONFIG_FP_SHARING) || defined(CONFIG_GDB_INFO))
|
#if (defined(CONFIG_FP_SHARING) || defined(CONFIG_GDB_INFO))
|
||||||
tcs->excNestCount = 0;
|
tcs->excNestCount = 0;
|
||||||
#endif /* CONFIG_FP_SHARING || CONFIG_GDB_INFO */
|
#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)
|
if (priority == -1)
|
||||||
tcs->flags = PREEMPTIBLE | TASK;
|
tcs->flags = PREEMPTIBLE | TASK;
|
||||||
else
|
else
|
||||||
tcs->flags = FIBER;
|
tcs->flags = FIBER;
|
||||||
|
tcs->link = (struct tcs *)NULL; /* thread not inserted into list yet */
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_THREAD_CUSTOM_DATA
|
#ifdef CONFIG_THREAD_CUSTOM_DATA
|
||||||
/* Initialize custom data field (value is opaque to kernel) */
|
/* 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;
|
tcs->custom_data = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_MICROKERNEL
|
#if !defined(CONFIG_KERNEL_V2) && defined(CONFIG_MICROKERNEL)
|
||||||
tcs->uk_task_ptr = uk_task_ptr;
|
tcs->uk_task_ptr = uk_task_ptr;
|
||||||
#else
|
#else
|
||||||
ARG_UNUSED(uk_task_ptr);
|
ARG_UNUSED(uk_task_ptr);
|
||||||
|
@ -130,6 +148,7 @@ static void _new_thread_internal(char *pStackMem, unsigned stackSize,
|
||||||
tcs->coopReg.esp = (unsigned long)pInitialCtx;
|
tcs->coopReg.esp = (unsigned long)pInitialCtx;
|
||||||
PRINTK("\nInitial context ESP = 0x%x\n", tcs->coopReg.esp);
|
PRINTK("\nInitial context ESP = 0x%x\n", tcs->coopReg.esp);
|
||||||
|
|
||||||
|
#ifndef CONFIG_KERNEL_V2
|
||||||
#ifdef CONFIG_FP_SHARING
|
#ifdef CONFIG_FP_SHARING
|
||||||
/*
|
/*
|
||||||
* Indicate if the thread is permitted to use floating point instructions.
|
* 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);
|
tcs->flags |= (options | USE_FP);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_FP_SHARING */
|
#endif /* CONFIG_FP_SHARING */
|
||||||
|
#endif /* CONFIG_KERNEL_V2 */
|
||||||
|
|
||||||
PRINTK("\nstruct tcs * = 0x%x", tcs);
|
PRINTK("\nstruct tcs * = 0x%x", tcs);
|
||||||
|
|
||||||
|
@ -304,8 +324,8 @@ __asm__("\t.globl _thread_entry\n"
|
||||||
* @param parameter1 first param to entry point
|
* @param parameter1 first param to entry point
|
||||||
* @param parameter2 second param to entry point
|
* @param parameter2 second param to entry point
|
||||||
* @param parameter3 third param to entry point
|
* @param parameter3 third param to entry point
|
||||||
* @param priority thread priority
|
* @param priority thread priority
|
||||||
* @param options thread options: USE_FP, USE_SSE
|
* @param options thread options: ESSENTIAL, USE_FP, USE_SSE
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @return opaque pointer to initialized TCS structure
|
* @return opaque pointer to initialized TCS structure
|
||||||
|
|
|
@ -40,8 +40,13 @@
|
||||||
#include <exception.h>
|
#include <exception.h>
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#ifndef _ASMLANGUAGE
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
#include <kernel.h> /* public kernel API */
|
||||||
|
#include <../../../kernel/unified/include/nano_internal.h>
|
||||||
|
#else
|
||||||
#include <nanokernel.h> /* public nanokernel API */
|
#include <nanokernel.h> /* public nanokernel API */
|
||||||
#include <../../../kernel/nanokernel/include/nano_internal.h>
|
#include <../../../kernel/nanokernel/include/nano_internal.h>
|
||||||
|
#endif
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
/*
|
/*
|
||||||
* This pulls in the code shared with the IDT generator that actually
|
* This pulls in the code shared with the IDT generator that actually
|
||||||
|
@ -67,13 +72,28 @@
|
||||||
* nanokernel/x86/arch.h.
|
* nanokernel/x86/arch.h.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
#define K_STATIC 0x00000800
|
||||||
|
|
||||||
|
#define K_READY 0x00000000 /* Thread is ready to run */
|
||||||
|
#define K_TIMING 0x00001000 /* Thread is waiting on a timeout */
|
||||||
|
#define K_PENDING 0x00002000 /* Thread is waiting on an object */
|
||||||
|
#define K_PRESTART 0x00004000 /* Thread has not yet started */
|
||||||
|
#define K_DEAD 0x00008000 /* Thread has terminated */
|
||||||
|
#define K_SUSPENDED 0x00010000 /* Thread is suspended */
|
||||||
|
#define K_DUMMY 0x00020000 /* Not a real thread */
|
||||||
|
#define K_EXECUTION_MASK (K_TIMING | K_PENDING | K_PRESTART | \
|
||||||
|
K_DEAD | K_SUSPENDED | K_DUMMY)
|
||||||
|
#else
|
||||||
#define FIBER 0
|
#define FIBER 0
|
||||||
#define TASK 0x1 /* 1 = task, 0 = fiber */
|
#define TASK 0x1 /* 1 = task, 0 = fiber */
|
||||||
|
#define PREEMPTIBLE 0x100 /* 1 = preemptible thread */
|
||||||
|
#endif
|
||||||
|
|
||||||
#define INT_ACTIVE 0x2 /* 1 = executing context is interrupt handler */
|
#define INT_ACTIVE 0x2 /* 1 = executing context is interrupt handler */
|
||||||
#define EXC_ACTIVE 0x4 /* 1 = executing context is exception handler */
|
#define EXC_ACTIVE 0x4 /* 1 = executing context is exception handler */
|
||||||
#define USE_FP 0x10 /* 1 = thread uses floating point unit */
|
#define USE_FP 0x10 /* 1 = thread uses floating point unit */
|
||||||
#define USE_SSE 0x20 /* 1 = thread uses SSEx instructions */
|
#define USE_SSE 0x20 /* 1 = thread uses SSEx instructions */
|
||||||
#define PREEMPTIBLE 0x100 /* 1 = preemptible thread */
|
|
||||||
#define ESSENTIAL 0x200 /* 1 = system thread that must not abort */
|
#define ESSENTIAL 0x200 /* 1 = system thread that must not abort */
|
||||||
#define NO_METRICS 0x400 /* 1 = _Swap() not to update task metrics */
|
#define NO_METRICS 0x400 /* 1 = _Swap() not to update task metrics */
|
||||||
#define NO_METRICS_BIT_OFFSET 0xa /* Bit position of NO_METRICS */
|
#define NO_METRICS_BIT_OFFSET 0xa /* Bit position of NO_METRICS */
|
||||||
|
@ -613,6 +633,16 @@ typedef struct s_preempFloatReg {
|
||||||
} floatRegsUnion;
|
} floatRegsUnion;
|
||||||
} tPreempFloatReg;
|
} tPreempFloatReg;
|
||||||
|
|
||||||
|
#if CONFIG_KERNEL_V2
|
||||||
|
/* 'struct tcs_base' must match the beginning of 'struct tcs' */
|
||||||
|
struct tcs_base {
|
||||||
|
sys_dnode_t k_q_node;
|
||||||
|
uint32_t flags;
|
||||||
|
int prio; /* thread priority used to sort linked list */
|
||||||
|
void *swap_data;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The thread control stucture definition. It contains the
|
* The thread control stucture definition. It contains the
|
||||||
* various fields to manage a _single_ thread. The TCS will be aligned
|
* various fields to manage a _single_ thread. The TCS will be aligned
|
||||||
|
@ -627,6 +657,12 @@ struct tcs {
|
||||||
* nanokernel FIFO).
|
* nanokernel FIFO).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if CONFIG_KERNEL_V2
|
||||||
|
sys_dnode_t k_q_node; /* node object in any kernel queue */
|
||||||
|
int flags;
|
||||||
|
int prio; /* thread priority used to sort linked list */
|
||||||
|
void *swap_data;
|
||||||
|
#else
|
||||||
struct tcs *link;
|
struct tcs *link;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -638,6 +674,8 @@ struct tcs {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int flags;
|
int flags;
|
||||||
|
int prio; /* thread priority used to sort linked list */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Storage space for integer registers. These must also remain near
|
* Storage space for integer registers. These must also remain near
|
||||||
|
@ -656,7 +694,6 @@ struct tcs {
|
||||||
void *esfPtr; /* pointer to exception stack frame saved by */
|
void *esfPtr; /* pointer to exception stack frame saved by */
|
||||||
/* outermost exception wrapper */
|
/* outermost exception wrapper */
|
||||||
#endif /* CONFIG_GDB_INFO */
|
#endif /* CONFIG_GDB_INFO */
|
||||||
int prio; /* thread priority used to sort linked list */
|
|
||||||
#if (defined(CONFIG_FP_SHARING) || defined(CONFIG_GDB_INFO))
|
#if (defined(CONFIG_FP_SHARING) || defined(CONFIG_GDB_INFO))
|
||||||
/*
|
/*
|
||||||
* Nested exception count to maintain setting of EXC_ACTIVE flag across
|
* Nested exception count to maintain setting of EXC_ACTIVE flag across
|
||||||
|
@ -670,7 +707,7 @@ struct tcs {
|
||||||
void *custom_data; /* available for custom use */
|
void *custom_data; /* available for custom use */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NANO_TIMEOUTS
|
#if !defined(CONFIG_KERNEL_V2) && defined(CONFIG_NANO_TIMEOUTS)
|
||||||
struct _nano_timeout nano_timeout;
|
struct _nano_timeout nano_timeout;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -678,9 +715,20 @@ struct tcs {
|
||||||
int errno_var;
|
int errno_var;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(CONFIG_KERNEL_V2)
|
||||||
#ifdef CONFIG_MICROKERNEL
|
#ifdef CONFIG_MICROKERNEL
|
||||||
void *uk_task_ptr;
|
void *uk_task_ptr;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
#ifdef CONFIG_NANO_TIMEOUTS
|
||||||
|
struct _timeout timeout;
|
||||||
|
#endif
|
||||||
|
atomic_t sched_locked;
|
||||||
|
void *init_data;
|
||||||
|
void (*fn_abort)(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The location of all floating point related structures/fields MUST be
|
* The location of all floating point related structures/fields MUST be
|
||||||
|
@ -700,14 +748,25 @@ struct tcs {
|
||||||
tPreempFloatReg preempFloatReg; /* volatile float register storage */
|
tPreempFloatReg preempFloatReg; /* volatile float register storage */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
struct ready_q {
|
||||||
|
uint32_t prio_bmap[1];
|
||||||
|
sys_dlist_t q[K_NUM_PRIORITIES];
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The nanokernel structure definition. It contains various fields to
|
* The nanokernel structure definition. It contains various fields to
|
||||||
* manage _all_ the threads in the nanokernel (system level).
|
* manage _all_ the threads in the nanokernel (system level).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct s_NANO {
|
typedef struct s_NANO {
|
||||||
|
#if !defined(CONFIG_KERNEL_V2)
|
||||||
struct tcs *fiber; /* singly linked list of runnable fibers */
|
struct tcs *fiber; /* singly linked list of runnable fibers */
|
||||||
struct tcs *task; /* pointer to runnable task */
|
struct tcs *task; /* pointer to runnable task */
|
||||||
|
#endif
|
||||||
struct tcs *current; /* currently scheduled thread (fiber or task) */
|
struct tcs *current; /* currently scheduled thread (fiber or task) */
|
||||||
#if defined(CONFIG_THREAD_MONITOR)
|
#if defined(CONFIG_THREAD_MONITOR)
|
||||||
struct tcs *threads; /* singly linked list of ALL fiber+tasks */
|
struct tcs *threads; /* singly linked list of ALL fiber+tasks */
|
||||||
|
@ -740,6 +799,9 @@ typedef struct s_NANO {
|
||||||
sys_dlist_t timeout_q;
|
sys_dlist_t timeout_q;
|
||||||
int32_t task_timeout;
|
int32_t task_timeout;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
struct ready_q ready_q;
|
||||||
|
#endif
|
||||||
} tNANO;
|
} tNANO;
|
||||||
|
|
||||||
/* stack alignment related macros: STACK_ALIGN_SIZE is defined above */
|
/* stack alignment related macros: STACK_ALIGN_SIZE is defined above */
|
||||||
|
@ -819,6 +881,21 @@ static inline void fiberRtnValueSet(struct tcs *fiber, unsigned int value)
|
||||||
*(unsigned int *)(fiber->coopReg.esp) = value;
|
*(unsigned int *)(fiber->coopReg.esp) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
#define _current _nanokernel.current
|
||||||
|
#define _ready_q _nanokernel.ready_q
|
||||||
|
#define _timeout_q _nanokernel.timeout_q
|
||||||
|
#define _set_thread_return_value fiberRtnValueSet
|
||||||
|
static ALWAYS_INLINE void
|
||||||
|
_set_thread_return_value_with_data(struct k_thread *thread, unsigned int value,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
_set_thread_return_value(thread, value);
|
||||||
|
thread->swap_data = data;
|
||||||
|
}
|
||||||
|
#define _IDLE_THREAD_PRIO (CONFIG_NUM_PREEMPT_PRIORITIES)
|
||||||
|
#endif /* CONFIG_KERNEL_V2 */
|
||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
|
|
||||||
extern void nano_cpu_atomic_idle(unsigned int imask);
|
extern void nano_cpu_atomic_idle(unsigned int imask);
|
||||||
|
@ -846,6 +923,7 @@ extern unsigned char _idt_base_address[];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _IS_IN_ISR() (_nanokernel.nested != 0)
|
#define _IS_IN_ISR() (_nanokernel.nested != 0)
|
||||||
|
#define _is_in_isr() (_nanokernel.nested != 0)
|
||||||
|
|
||||||
#endif /* _ASMLANGUAGE */
|
#endif /* _ASMLANGUAGE */
|
||||||
|
|
||||||
|
|
|
@ -428,6 +428,10 @@ extern void _arch_irq_enable(unsigned int irq);
|
||||||
extern void _arch_irq_disable(unsigned int irq);
|
extern void _arch_irq_disable(unsigned int irq);
|
||||||
|
|
||||||
#ifdef CONFIG_FP_SHARING
|
#ifdef CONFIG_FP_SHARING
|
||||||
|
#ifdef CONFIG_KERNEL_V2
|
||||||
|
extern void k_float_enable(k_tid_t thread_id, unsigned int options);
|
||||||
|
extern void k_float_disable(k_tid_t thread_id);
|
||||||
|
#else
|
||||||
/**
|
/**
|
||||||
* @brief Enable floating point hardware resources sharing
|
* @brief Enable floating point hardware resources sharing
|
||||||
* Dynamically enable/disable the capability of a thread to share floating
|
* Dynamically enable/disable the capability of a thread to share floating
|
||||||
|
@ -440,6 +444,8 @@ extern void task_float_enable(nano_thread_id_t thread_id,
|
||||||
unsigned int options);
|
unsigned int options);
|
||||||
extern void fiber_float_disable(nano_thread_id_t thread_id);
|
extern void fiber_float_disable(nano_thread_id_t thread_id);
|
||||||
extern void task_float_disable(nano_thread_id_t thread_id);
|
extern void task_float_disable(nano_thread_id_t thread_id);
|
||||||
|
|
||||||
|
#endif /* CONFIG_KERNEL_V2 */
|
||||||
#endif /* CONFIG_FP_SHARING */
|
#endif /* CONFIG_FP_SHARING */
|
||||||
|
|
||||||
#include <stddef.h> /* for size_t */
|
#include <stddef.h> /* for size_t */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue