kernel: expose struct k_thread implementation

Historically, space for struct k_thread was always carved out of the
thread's stack region. However, we want more control on where this data
will reside; in memory protection scenarios the stack may only be used
for actual stack data and nothing else.

On some platforms (particularly ARM), including kernel_arch_data.h from
the toplevel kernel.h exposes intractable circular dependency issues.
We create a new per-arch header "kernel_arch_thread.h" with very limited
scope; it only defines the three data structures necessary to instantiate
the arch-specific bits of a struct k_thread.

Change-Id: I3a55b4ed4270512e58cf671f327bb033ad7f4a4f
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2017-04-04 13:19:13 -07:00 committed by Anas Nashif
parent 94b44f03e1
commit 73abd32a7d
17 changed files with 939 additions and 727 deletions

View file

@ -28,6 +28,7 @@ extern "C" {
#include <sections.h>
#include <arch/cpu.h>
#include <vector_table.h>
#include <kernel_arch_thread.h>
#ifndef _ASMLANGUAGE
#include <kernel.h>
@ -38,16 +39,6 @@ extern "C" {
#endif
#ifndef _ASMLANGUAGE
struct _caller_saved {
/*
* Saved on the stack as part of handling a regular IRQ or by the
* kernel when calling the FIRQ return code.
*/
};
typedef struct _caller_saved _caller_saved_t;
struct _irq_stack_frame {
u32_t r0;
u32_t r1;
@ -83,11 +74,6 @@ struct _irq_stack_frame {
typedef struct _irq_stack_frame _isf_t;
struct _callee_saved {
u32_t sp; /* r28 */
};
typedef struct _callee_saved _callee_saved_t;
/* callee-saved registers pushed on the stack, not in k_thread */
struct _callee_saved_stack {
u32_t r13;
@ -116,45 +102,6 @@ struct _callee_saved_stack {
typedef struct _callee_saved_stack _callee_saved_stack_t;
#endif /* _ASMLANGUAGE */
/* stacks */
#define STACK_ALIGN_SIZE 4
#define STACK_ROUND_UP(x) ROUND_UP(x, STACK_ALIGN_SIZE)
#define STACK_ROUND_DOWN(x) ROUND_DOWN(x, STACK_ALIGN_SIZE)
/*
* Reason a thread has relinquished control: fibers can only be in the NONE
* or COOP state, tasks can be one in the four.
*/
#define _CAUSE_NONE 0
#define _CAUSE_COOP 1
#define _CAUSE_RIRQ 2
#define _CAUSE_FIRQ 3
#ifndef _ASMLANGUAGE
struct _thread_arch {
/* interrupt key when relinquishing control */
u32_t intlock_key;
/* one of the _CAUSE_xxxx definitions above */
int relinquish_cause;
/* return value from _Swap */
unsigned int return_value;
#ifdef CONFIG_ARC_STACK_CHECKING
/* top of stack for hardware stack checking */
u32_t stack_top;
#endif
};
typedef struct _thread_arch _thread_arch_t;
struct _kernel_arch {
char *rirq_sp; /* regular IRQ stack pointer base */
@ -170,6 +117,13 @@ typedef struct _kernel_arch _kernel_arch_t;
#endif /* _ASMLANGUAGE */
/* stacks */
#define STACK_ALIGN_SIZE 4
#define STACK_ROUND_UP(x) ROUND_UP(x, STACK_ALIGN_SIZE)
#define STACK_ROUND_DOWN(x) ROUND_DOWN(x, STACK_ALIGN_SIZE)
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Per-arch thread definition
*
* This file contains defintions for
*
* struct _thread_arch
* struct _callee_saved
* struct _caller_saved
*
* necessary to instantiate instances of struct k_thread.
*/
#ifndef _kernel_arch_thread__h_
#define _kernel_arch_thread__h_
/*
* Reason a thread has relinquished control: fibers can only be in the NONE
* or COOP state, tasks can be one in the four.
*/
#define _CAUSE_NONE 0
#define _CAUSE_COOP 1
#define _CAUSE_RIRQ 2
#define _CAUSE_FIRQ 3
#ifndef _ASMLANGUAGE
#include <zephyr/types.h>
struct _caller_saved {
/*
* Saved on the stack as part of handling a regular IRQ or by the
* kernel when calling the FIRQ return code.
*/
};
typedef struct _caller_saved _caller_saved_t;
struct _callee_saved {
u32_t sp; /* r28 */
};
typedef struct _callee_saved _callee_saved_t;
struct _thread_arch {
/* interrupt key when relinquishing control */
u32_t intlock_key;
/* one of the _CAUSE_xxxx definitions above */
int relinquish_cause;
/* return value from _Swap */
unsigned int return_value;
#ifdef CONFIG_ARC_STACK_CHECKING
/* top of stack for hardware stack checking */
u32_t stack_top;
#endif
};
typedef struct _thread_arch _thread_arch_t;
#endif /* _ASMLANGUAGE */
#endif /* _kernel_arch_thread__h_ */

View file

@ -27,6 +27,7 @@ extern "C" {
#include <toolchain.h>
#include <sections.h>
#include <arch/cpu.h>
#include <kernel_arch_thread.h>
#ifndef _ASMLANGUAGE
#include <kernel.h>
@ -38,40 +39,6 @@ extern "C" {
#ifndef _ASMLANGUAGE
struct _caller_saved {
/*
* Unused for Cortex-M, which automatically saves the necessary
* registers in its exception stack frame.
*
* For Cortex-A, this may be:
*
* u32_t a1; // r0
* u32_t a2; // r1
* u32_t a3; // r2
* u32_t a4; // r3
* u32_t ip; // r12
* u32_t lr; // r14
* u32_t pc; // r15
* u32_t xpsr;
*/
};
typedef struct _caller_saved _caller_saved_t;
struct _callee_saved {
u32_t v1; /* r4 */
u32_t v2; /* r5 */
u32_t v3; /* r6 */
u32_t v4; /* r7 */
u32_t v5; /* r8 */
u32_t v6; /* r9 */
u32_t v7; /* r10 */
u32_t v8; /* r11 */
u32_t psp; /* r13 */
};
typedef struct _callee_saved _callee_saved_t;
typedef struct __esf _esf_t;
#endif /* _ASMLANGUAGE */
@ -88,47 +55,6 @@ typedef struct __esf _esf_t;
#ifndef _ASMLANGUAGE
#ifdef CONFIG_FLOAT
struct _preempt_float {
float s16;
float s17;
float s18;
float s19;
float s20;
float s21;
float s22;
float s23;
float s24;
float s25;
float s26;
float s27;
float s28;
float s29;
float s30;
float s31;
};
#endif
struct _thread_arch {
/* interrupt locking key */
u32_t basepri;
/* r0 in stack frame cannot be written to reliably */
u32_t swap_return_value;
#ifdef CONFIG_FLOAT
/*
* No cooperative floating point register set structure exists for
* the Cortex-M as it automatically saves the necessary registers
* in its exception stack frame.
*/
struct _preempt_float preempt_float;
#endif
};
typedef struct _thread_arch _thread_arch_t;
struct _kernel_arch {
/* empty */
};

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Per-arch thread definition
*
* This file contains defintions for
*
* struct _thread_arch
* struct _callee_saved
* struct _caller_saved
*
* necessary to instantiate instances of struct k_thread.
*/
#ifndef _kernel_arch_thread_h_
#define _kernel_arch_thread_h_
#ifndef _ASMLANGUAGE
#include <zephyr/types.h>
struct _caller_saved {
/*
* Unused for Cortex-M, which automatically saves the necessary
* registers in its exception stack frame.
*
* For Cortex-A, this may be:
*
* u32_t a1; // r0
* u32_t a2; // r1
* u32_t a3; // r2
* u32_t a4; // r3
* u32_t ip; // r12
* u32_t lr; // r14
* u32_t pc; // r15
* u32_t xpsr;
*/
};
typedef struct _caller_saved _caller_saved_t;
struct _callee_saved {
u32_t v1; /* r4 */
u32_t v2; /* r5 */
u32_t v3; /* r6 */
u32_t v4; /* r7 */
u32_t v5; /* r8 */
u32_t v6; /* r9 */
u32_t v7; /* r10 */
u32_t v8; /* r11 */
u32_t psp; /* r13 */
};
typedef struct _callee_saved _callee_saved_t;
#ifdef CONFIG_FLOAT
struct _preempt_float {
float s16;
float s17;
float s18;
float s19;
float s20;
float s21;
float s22;
float s23;
float s24;
float s25;
float s26;
float s27;
float s28;
float s29;
float s30;
float s31;
};
#endif
struct _thread_arch {
/* interrupt locking key */
u32_t basepri;
/* r0 in stack frame cannot be written to reliably */
u32_t swap_return_value;
#ifdef CONFIG_FLOAT
/*
* No cooperative floating point register set structure exists for
* the Cortex-M as it automatically saves the necessary registers
* in its exception stack frame.
*/
struct _preempt_float preempt_float;
#endif
};
typedef struct _thread_arch _thread_arch_t;
#endif /* _ASMLANGUAGE */
#endif /* _kernel_arch_thread__h_ */

View file

@ -28,6 +28,7 @@ extern "C" {
#include <toolchain.h>
#include <sections.h>
#include <arch/cpu.h>
#include <kernel_arch_thread.h>
#ifndef _ASMLANGUAGE
#include <kernel.h>
@ -46,52 +47,6 @@ extern "C" {
#ifndef _ASMLANGUAGE
struct _caller_saved {
/*
* Nothing here, the exception code puts all the caller-saved
* registers onto the stack.
*/
};
typedef struct _caller_saved _caller_saved_t;
struct _callee_saved {
/* General purpose callee-saved registers */
u32_t r16;
u32_t r17;
u32_t r18;
u32_t r19;
u32_t r20;
u32_t r21;
u32_t r22;
u32_t r23;
/* Normally used for the frame pointer but also a general purpose
* register if frame pointers omitted
*/
u32_t r28;
/* Return address */
u32_t ra;
/* Stack pointer */
u32_t sp;
/* IRQ status before irq_lock() and call to _Swap() */
u32_t key;
/* Return value of _Swap() */
u32_t retval;
};
typedef struct _callee_saved _callee_saved_t;
struct _thread_arch {
/* nothing for now */
};
typedef struct _thread_arch _thread_arch_t;
struct _kernel_arch {
/* nothing for now */
};

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Per-arch thread definition
*
* This file contains defintions for
*
* struct _thread_arch
* struct _callee_saved
* struct _caller_saved
*
* necessary to instantiate instances of struct k_thread.
*/
#ifndef _kernel_arch_thread__h_
#define _kernel_arch_thread__h_
#ifndef _ASMLANGUAGE
#include <zephyr/types.h>
struct _caller_saved {
/*
* Nothing here, the exception code puts all the caller-saved
* registers onto the stack.
*/
};
typedef struct _caller_saved _caller_saved_t;
struct _callee_saved {
/* General purpose callee-saved registers */
u32_t r16;
u32_t r17;
u32_t r18;
u32_t r19;
u32_t r20;
u32_t r21;
u32_t r22;
u32_t r23;
/* Normally used for the frame pointer but also a general purpose
* register if frame pointers omitted
*/
u32_t r28;
/* Return address */
u32_t ra;
/* Stack pointer */
u32_t sp;
/* IRQ status before irq_lock() and call to _Swap() */
u32_t key;
/* Return value of _Swap() */
u32_t retval;
};
typedef struct _callee_saved _callee_saved_t;
struct _thread_arch {
/* nothing for now */
};
typedef struct _thread_arch _thread_arch_t;
#endif /* _ASMLANGUAGE */
#endif /* _kernel_arch_thread__h_ */

View file

@ -22,6 +22,7 @@ extern "C" {
#include <toolchain.h>
#include <sections.h>
#include <arch/cpu.h>
#include <kernel_arch_thread.h>
#ifndef _ASMLANGUAGE
#include <kernel.h>
@ -30,43 +31,6 @@ extern "C" {
#include <misc/dlist.h>
#include <nano_internal.h>
/*
* The following structure defines the list of registers that need to be
* saved/restored when a cooperative context switch occurs.
*/
struct _callee_saved {
u32_t sp; /* Stack pointer, (x2 register) */
u32_t s0; /* saved register/frame pointer */
u32_t s1; /* saved register */
u32_t s2; /* saved register */
u32_t s3; /* saved register */
u32_t s4; /* saved register */
u32_t s5; /* saved register */
u32_t s6; /* saved register */
u32_t s7; /* saved register */
u32_t s8; /* saved register */
u32_t s9; /* saved register */
u32_t s10; /* saved register */
u32_t s11; /* saved register */
};
typedef struct _callee_saved _callee_saved_t;
struct _caller_saved {
/*
* Nothing here, the exception code puts all the caller-saved
* registers onto the stack.
*/
};
typedef struct _caller_saved _caller_saved_t;
struct _thread_arch {
u32_t swap_return_value; /* Return value of _Swap() */
};
typedef struct _thread_arch _thread_arch_t;
struct _kernel_arch {
/* nothing for now */
};

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Per-arch thread definition
*
* This file contains defintions for
*
* struct _thread_arch
* struct _callee_saved
* struct _caller_saved
*
* necessary to instantiate instances of struct k_thread.
*/
#ifndef _kernel_arch_thread__h_
#define _kernel_arch_thread__h_
#ifndef _ASMLANGUAGE
#include <zephyr/types.h>
/*
* The following structure defines the list of registers that need to be
* saved/restored when a cooperative context switch occurs.
*/
struct _callee_saved {
u32_t sp; /* Stack pointer, (x2 register) */
u32_t s0; /* saved register/frame pointer */
u32_t s1; /* saved register */
u32_t s2; /* saved register */
u32_t s3; /* saved register */
u32_t s4; /* saved register */
u32_t s5; /* saved register */
u32_t s6; /* saved register */
u32_t s7; /* saved register */
u32_t s8; /* saved register */
u32_t s9; /* saved register */
u32_t s10; /* saved register */
u32_t s11; /* saved register */
};
typedef struct _callee_saved _callee_saved_t;
struct _caller_saved {
/*
* Nothing here, the exception code puts all the caller-saved
* registers onto the stack.
*/
};
typedef struct _caller_saved _caller_saved_t;
struct _thread_arch {
u32_t swap_return_value; /* Return value of _Swap() */
};
typedef struct _thread_arch _thread_arch_t;
#endif /* _ASMLANGUAGE */
#endif /* _kernel_arch_thread__h_ */

View file

@ -30,6 +30,7 @@
#include <sections.h>
#include <asm_inline.h>
#include <exception.h>
#include <kernel_arch_thread.h>
#ifndef _ASMLANGUAGE
#include <kernel.h>
@ -390,243 +391,6 @@
extern "C" {
#endif
/*
* The following structure defines the set of 'volatile' integer registers.
* These registers need not be preserved by a called C function. Given that
* they are not preserved across function calls, they must be save/restored
* (along with the struct _caller_saved) when a preemptive context switch
* occurs.
*/
struct _caller_saved {
/*
* The volatile registers 'eax', 'ecx' and 'edx' area not included in
* the definition of 'tPreempReg' since the interrupt and exception
* handling routunes use the stack to save and restore the values of
* these registers in order to support interrupt nesting. The stubs
* do _not_ copy the saved values from the stack into the TCS.
*
* unsigned long eax;
* unsigned long ecx;
* unsigned long edx;
*/
};
typedef struct _caller_saved _caller_saved_t;
/*
* The following structure defines the set of 'non-volatile' integer registers.
* These registers must be preserved by a called C function. These are the
* only registers that need to be saved/restored when a cooperative context
* switch occurs.
*/
struct _callee_saved {
unsigned long esp;
/*
* The following registers are considered non-volatile, i.e.
* callee-save,
* but their values are pushed onto the stack rather than stored in the
* TCS
* structure:
*
* unsigned long ebp;
* unsigned long ebx;
* unsigned long esi;
* unsigned long edi;
*/
};
typedef struct _callee_saved _callee_saved_t;
/*
* The macro CONFIG_FP_SHARING shall be set to indicate that the
* saving/restoring of the traditional x87 floating point (and MMX) registers
* are supported by the kernel's context swapping code. The macro
* CONFIG_SSE shall _also_ be set if saving/restoring of the XMM
* registers is also supported in the kernel's context swapping code.
*/
#ifdef CONFIG_FP_SHARING
/* definition of a single x87 (floating point / MMX) register */
typedef struct s_FpReg {
unsigned char reg[10]; /* 80 bits: ST[0-7] */
} tFpReg;
/*
* The following is the "normal" floating point register save area, or
* more accurately the save area required by the 'fnsave' and 'frstor'
* instructions. The structure matches the layout described in the
* "Intel® 64 and IA-32 Architectures Software Developers Manual
* Volume 1: Basic Architecture": Protected Mode x87 FPU State Image in
* Memory, 32-Bit Format.
*/
typedef struct s_FpRegSet { /* # of bytes: name of register */
unsigned short fcw; /* 2 : x87 FPU control word */
unsigned short pad1; /* 2 : N/A */
unsigned short fsw; /* 2 : x87 FPU status word */
unsigned short pad2; /* 2 : N/A */
unsigned short ftw; /* 2 : x87 FPU tag word */
unsigned short pad3; /* 2 : N/A */
unsigned int fpuip; /* 4 : x87 FPU instruction pointer offset */
unsigned short cs; /* 2 : x87 FPU instruction pointer selector */
unsigned short fop : 11; /* 2 : x87 FPU opcode */
unsigned short pad4 : 5; /* : 5 bits = 00000 */
unsigned int fpudp; /* 4 : x87 FPU instr operand ptr offset */
unsigned short ds; /* 2 : x87 FPU instr operand ptr selector */
unsigned short pad5; /* 2 : N/A */
tFpReg fpReg[8]; /* 80 : ST0 -> ST7 */
} tFpRegSet __aligned(FP_REG_SET_ALIGN);
#ifdef CONFIG_SSE
/* definition of a single x87 (floating point / MMX) register */
typedef struct s_FpRegEx {
unsigned char reg[10]; /* 80 bits: ST[0-7] or MM[0-7] */
unsigned char rsrvd[6]; /* 48 bits: reserved */
} tFpRegEx;
/* definition of a single XMM register */
typedef struct s_XmmReg {
unsigned char reg[16]; /* 128 bits: XMM[0-7] */
} tXmmReg;
/*
* The following is the "extended" floating point register save area, or
* more accurately the save area required by the 'fxsave' and 'fxrstor'
* instructions. The structure matches the layout described in the
* "Intel 64 and IA-32 Architectures Software Developer's Manual
* Volume 2A: Instruction Set Reference, A-M", except for the bytes from offset
* 464 to 511 since these "are available to software use. The processor does
* not write to bytes 464:511 of an FXSAVE area".
*
* This structure must be aligned on a 16 byte boundary when the instructions
* fxsave/fxrstor are used to write/read the data to/from the structure.
*/
typedef struct s_FpRegSetEx /* # of bytes: name of register */
{
unsigned short fcw; /* 2 : x87 FPU control word */
unsigned short fsw; /* 2 : x87 FPU status word */
unsigned char ftw; /* 1 : x87 FPU abridged tag word */
unsigned char rsrvd0; /* 1 : reserved */
unsigned short fop; /* 2 : x87 FPU opcode */
unsigned int fpuip; /* 4 : x87 FPU instruction pointer offset */
unsigned short cs; /* 2 : x87 FPU instruction pointer selector */
unsigned short rsrvd1; /* 2 : reserved */
unsigned int fpudp; /* 4 : x87 FPU instr operand ptr offset */
unsigned short ds; /* 2 : x87 FPU instr operand ptr selector */
unsigned short rsrvd2; /* 2 : reserved */
unsigned int mxcsr; /* 4 : MXCSR register state */
unsigned int mxcsrMask; /* 4 : MXCSR register mask */
tFpRegEx fpReg[8]; /* 128 : x87 FPU/MMX registers */
tXmmReg xmmReg[8]; /* 128 : XMM registers */
unsigned char rsrvd3[176]; /* 176 : reserved */
} tFpRegSetEx __aligned(FP_REG_SET_ALIGN);
#else /* CONFIG_SSE == 0 */
typedef struct s_FpRegSetEx {
} tFpRegSetEx;
#endif /* CONFIG_SSE == 0 */
#else /* CONFIG_FP_SHARING == 0 */
/* empty floating point register definition */
typedef struct s_FpRegSet {
} tFpRegSet;
typedef struct s_FpRegSetEx {
} tFpRegSetEx;
#endif /* CONFIG_FP_SHARING == 0 */
/*
* The following structure defines the set of 'non-volatile' x87 FPU/MMX/SSE
* registers. These registers must be preserved by a called C function.
* These are the only registers that need to be saved/restored when a
* cooperative context switch occurs.
*/
typedef struct s_coopFloatReg {
/*
* This structure intentionally left blank, i.e. the ST[0] -> ST[7] and
* XMM0 -> XMM7 registers are all 'volatile'.
*/
} tCoopFloatReg;
/*
* The following structure defines the set of 'volatile' x87 FPU/MMX/SSE
* registers. These registers need not be preserved by a called C function.
* Given that they are not preserved across function calls, they must be
* save/restored (along with s_coopFloatReg) when a preemptive context
* switch occurs.
*/
typedef struct s_preempFloatReg {
union {
/* threads with K_FP_REGS utilize this format */
tFpRegSet fpRegs;
/* threads with K_SSE_REGS utilize this format */
tFpRegSetEx fpRegsEx;
} floatRegsUnion;
} tPreempFloatReg;
/*
* The thread control stucture definition. It contains the
* various fields to manage a _single_ thread. The TCS will be aligned
* to the appropriate architecture specific boundary via the
* _new_thread() call.
*/
struct _thread_arch {
#ifdef CONFIG_GDB_INFO
/* pointer to ESF saved by outermost exception wrapper */
void *esf;
#endif
#if (defined(CONFIG_FP_SHARING) || defined(CONFIG_GDB_INFO))
/*
* Nested exception count to maintain setting of EXC_ACTIVE flag across
* outermost exception. EXC_ACTIVE is used by _Swap() lazy FP
* save/restore and by debug tools.
*/
unsigned excNestCount; /* nested exception count */
#endif /* CONFIG_FP_SHARING || CONFIG_GDB_INFO */
/*
* The location of all floating point related structures/fields MUST be
* located at the end of struct tcs. This way only the
* fibers/tasks that actually utilize non-integer capabilities need to
* account for the increased memory required for storing FP state when
* sizing stacks.
*
* Given that stacks "grow down" on IA-32, and the TCS is located
* at the start of a thread's "workspace" memory, the stacks of
* fibers/tasks that do not utilize floating point instruction can
* effectively consume the memory occupied by the 'tCoopFloatReg' and
* 'tPreempFloatReg' structures without ill effect.
*/
tCoopFloatReg coopFloatReg; /* non-volatile float register storage */
tPreempFloatReg preempFloatReg; /* volatile float register storage */
};
typedef struct _thread_arch _thread_arch_t;
struct _kernel_arch {
#if defined(CONFIG_DEBUG_INFO)

View file

@ -0,0 +1,280 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Per-arch thread definition
*
* This file contains defintions for
*
* struct _thread_arch
* struct _callee_saved
* struct _caller_saved
*
* necessary to instantiate instances of struct k_thread.
*/
#ifndef _kernel_arch_thread__h_
#define _kernel_arch_thread__h_
/**
* Floating point register set alignment.
*
* If support for SSEx extensions is enabled a 16 byte boundary is required,
* since the 'fxsave' and 'fxrstor' instructions require this. In all other
* cases a 4 byte boundary is sufficient.
*/
#ifdef CONFIG_SSE
#define FP_REG_SET_ALIGN 16
#else
#define FP_REG_SET_ALIGN 4
#endif
#ifndef _ASMLANGUAGE
#include <stdint.h>
/*
* The following structure defines the set of 'volatile' integer registers.
* These registers need not be preserved by a called C function. Given that
* they are not preserved across function calls, they must be save/restored
* (along with the struct _caller_saved) when a preemptive context switch
* occurs.
*/
struct _caller_saved {
/*
* The volatile registers 'eax', 'ecx' and 'edx' area not included in
* the definition of 'tPreempReg' since the interrupt and exception
* handling routunes use the stack to save and restore the values of
* these registers in order to support interrupt nesting. The stubs
* do _not_ copy the saved values from the stack into the TCS.
*
* unsigned long eax;
* unsigned long ecx;
* unsigned long edx;
*/
};
typedef struct _caller_saved _caller_saved_t;
/*
* The following structure defines the set of 'non-volatile' integer registers.
* These registers must be preserved by a called C function. These are the
* only registers that need to be saved/restored when a cooperative context
* switch occurs.
*/
struct _callee_saved {
unsigned long esp;
/*
* The following registers are considered non-volatile, i.e.
* callee-save,
* but their values are pushed onto the stack rather than stored in the
* TCS
* structure:
*
* unsigned long ebp;
* unsigned long ebx;
* unsigned long esi;
* unsigned long edi;
*/
};
typedef struct _callee_saved _callee_saved_t;
/*
* The macro CONFIG_FP_SHARING shall be set to indicate that the
* saving/restoring of the traditional x87 floating point (and MMX) registers
* are supported by the kernel's context swapping code. The macro
* CONFIG_SSE shall _also_ be set if saving/restoring of the XMM
* registers is also supported in the kernel's context swapping code.
*/
#ifdef CONFIG_FP_SHARING
/* definition of a single x87 (floating point / MMX) register */
typedef struct s_FpReg {
unsigned char reg[10]; /* 80 bits: ST[0-7] */
} tFpReg;
/*
* The following is the "normal" floating point register save area, or
* more accurately the save area required by the 'fnsave' and 'frstor'
* instructions. The structure matches the layout described in the
* "Intel® 64 and IA-32 Architectures Software Developers Manual
* Volume 1: Basic Architecture": Protected Mode x87 FPU State Image in
* Memory, 32-Bit Format.
*/
typedef struct s_FpRegSet { /* # of bytes: name of register */
unsigned short fcw; /* 2 : x87 FPU control word */
unsigned short pad1; /* 2 : N/A */
unsigned short fsw; /* 2 : x87 FPU status word */
unsigned short pad2; /* 2 : N/A */
unsigned short ftw; /* 2 : x87 FPU tag word */
unsigned short pad3; /* 2 : N/A */
unsigned int fpuip; /* 4 : x87 FPU instruction pointer offset */
unsigned short cs; /* 2 : x87 FPU instruction pointer selector */
unsigned short fop : 11; /* 2 : x87 FPU opcode */
unsigned short pad4 : 5; /* : 5 bits = 00000 */
unsigned int fpudp; /* 4 : x87 FPU instr operand ptr offset */
unsigned short ds; /* 2 : x87 FPU instr operand ptr selector */
unsigned short pad5; /* 2 : N/A */
tFpReg fpReg[8]; /* 80 : ST0 -> ST7 */
} tFpRegSet __aligned(FP_REG_SET_ALIGN);
#ifdef CONFIG_SSE
/* definition of a single x87 (floating point / MMX) register */
typedef struct s_FpRegEx {
unsigned char reg[10]; /* 80 bits: ST[0-7] or MM[0-7] */
unsigned char rsrvd[6]; /* 48 bits: reserved */
} tFpRegEx;
/* definition of a single XMM register */
typedef struct s_XmmReg {
unsigned char reg[16]; /* 128 bits: XMM[0-7] */
} tXmmReg;
/*
* The following is the "extended" floating point register save area, or
* more accurately the save area required by the 'fxsave' and 'fxrstor'
* instructions. The structure matches the layout described in the
* "Intel 64 and IA-32 Architectures Software Developer's Manual
* Volume 2A: Instruction Set Reference, A-M", except for the bytes from offset
* 464 to 511 since these "are available to software use. The processor does
* not write to bytes 464:511 of an FXSAVE area".
*
* This structure must be aligned on a 16 byte boundary when the instructions
* fxsave/fxrstor are used to write/read the data to/from the structure.
*/
typedef struct s_FpRegSetEx /* # of bytes: name of register */
{
unsigned short fcw; /* 2 : x87 FPU control word */
unsigned short fsw; /* 2 : x87 FPU status word */
unsigned char ftw; /* 1 : x87 FPU abridged tag word */
unsigned char rsrvd0; /* 1 : reserved */
unsigned short fop; /* 2 : x87 FPU opcode */
unsigned int fpuip; /* 4 : x87 FPU instruction pointer offset */
unsigned short cs; /* 2 : x87 FPU instruction pointer selector */
unsigned short rsrvd1; /* 2 : reserved */
unsigned int fpudp; /* 4 : x87 FPU instr operand ptr offset */
unsigned short ds; /* 2 : x87 FPU instr operand ptr selector */
unsigned short rsrvd2; /* 2 : reserved */
unsigned int mxcsr; /* 4 : MXCSR register state */
unsigned int mxcsrMask; /* 4 : MXCSR register mask */
tFpRegEx fpReg[8]; /* 128 : x87 FPU/MMX registers */
tXmmReg xmmReg[8]; /* 128 : XMM registers */
unsigned char rsrvd3[176]; /* 176 : reserved */
} tFpRegSetEx __aligned(FP_REG_SET_ALIGN);
#else /* CONFIG_SSE == 0 */
typedef struct s_FpRegSetEx {
} tFpRegSetEx;
#endif /* CONFIG_SSE == 0 */
#else /* CONFIG_FP_SHARING == 0 */
/* empty floating point register definition */
typedef struct s_FpRegSet {
} tFpRegSet;
typedef struct s_FpRegSetEx {
} tFpRegSetEx;
#endif /* CONFIG_FP_SHARING == 0 */
/*
* The following structure defines the set of 'non-volatile' x87 FPU/MMX/SSE
* registers. These registers must be preserved by a called C function.
* These are the only registers that need to be saved/restored when a
* cooperative context switch occurs.
*/
typedef struct s_coopFloatReg {
/*
* This structure intentionally left blank, i.e. the ST[0] -> ST[7] and
* XMM0 -> XMM7 registers are all 'volatile'.
*/
} tCoopFloatReg;
/*
* The following structure defines the set of 'volatile' x87 FPU/MMX/SSE
* registers. These registers need not be preserved by a called C function.
* Given that they are not preserved across function calls, they must be
* save/restored (along with s_coopFloatReg) when a preemptive context
* switch occurs.
*/
typedef struct s_preempFloatReg {
union {
/* threads with K_FP_REGS utilize this format */
tFpRegSet fpRegs;
/* threads with K_SSE_REGS utilize this format */
tFpRegSetEx fpRegsEx;
} floatRegsUnion;
} tPreempFloatReg;
/*
* The thread control stucture definition. It contains the
* various fields to manage a _single_ thread. The TCS will be aligned
* to the appropriate architecture specific boundary via the
* _new_thread() call.
*/
struct _thread_arch {
#ifdef CONFIG_GDB_INFO
/* pointer to ESF saved by outermost exception wrapper */
void *esf;
#endif
#if (defined(CONFIG_FP_SHARING) || defined(CONFIG_GDB_INFO))
/*
* Nested exception count to maintain setting of EXC_ACTIVE flag across
* outermost exception. EXC_ACTIVE is used by _Swap() lazy FP
* save/restore and by debug tools.
*/
unsigned excNestCount; /* nested exception count */
#endif /* CONFIG_FP_SHARING || CONFIG_GDB_INFO */
/*
* The location of all floating point related structures/fields MUST be
* located at the end of struct tcs. This way only the
* fibers/tasks that actually utilize non-integer capabilities need to
* account for the increased memory required for storing FP state when
* sizing stacks.
*
* Given that stacks "grow down" on IA-32, and the TCS is located
* at the start of a thread's "workspace" memory, the stacks of
* fibers/tasks that do not utilize floating point instruction can
* effectively consume the memory occupied by the 'tCoopFloatReg' and
* 'tPreempFloatReg' structures without ill effect.
*/
tCoopFloatReg coopFloatReg; /* non-volatile float register storage */
tPreempFloatReg preempFloatReg; /* volatile float register storage */
};
typedef struct _thread_arch _thread_arch_t;
#endif /* _ASMLANGUAGE */
#endif /* _kernel_arch_thread__h_ */

View file

@ -27,7 +27,7 @@ extern "C" {
#include <toolchain.h>
#include <sections.h>
#include <arch/cpu.h>
#include <xtensa_context.h>
#include <kernel_arch_thread.h>
#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
#include <kernel.h> /* public kernel API */
@ -45,130 +45,8 @@ extern "C" {
/* thread uses floating point unit */
#define USE_FP 0x010
/*
* The following structure defines the set of 'volatile' integer registers.
* These registers need not be preserved by a called C function. Given that
* they are not preserved across function calls, they must be save/restored
* (along with the struct _caller_saved) when a preemptive context switch
* occurs.
*/
struct _caller_saved {
/*
* The volatile registers area not included in the definition of
* 'tPreempReg' since the interrupt stubs (_IntEnt/_IntExit)
* and exception stubs (_ExcEnt/_ExcEnter) use the stack to save and
* restore the values of these registers in order to support interrupt
* nesting. The stubs do _not_ copy the saved values from the stack
* into the k_thread.
*/
};
typedef struct _caller_saved _caller_saved_t;
/*
* The following structure defines the set of 'non-volatile' integer registers.
* These registers must be preserved by a called C function. These are the
* only registers that need to be saved/restored when a cooperative context
* switch occurs.
*/
struct _callee_saved {
/*
* The following registers are considered non-volatile, i.e.
* callee-saved, but their values are pushed onto the stack rather than
* stored in the k_thread structure:
*/
u32_t retval; /* a2 */
XtExcFrame *topOfStack; /* a1 = sp */
};
typedef struct _callee_saved _callee_saved_t;
typedef struct __esf __esf_t;
/*
* The following structure defines the set of 'non-volatile' x87 FPU/MMX/SSE
* registers. These registers must be preserved by a called C function.
* These are the only registers that need to be saved/restored when a
* cooperative context switch occurs.
*/
typedef struct s_coopCoprocReg {
/*
* This structure intentionally left blank. Coprocessor's registers are
* all 'volatile' and saved using the lazy context switch mechanism.
*/
} tCoopCoprocReg;
/*
* The following structure defines the set of 'volatile' coprocessor
* registers. These registers need not be preserved by a called C function.
* Given that they are not preserved across function calls, they must be
* save/restored (along with s_coopCoprocReg) when a preemptive context switch
* occurs.
*/
typedef struct s_preempCoprocReg {
/*
* This structure reserves coprocessor control and save area memory.
*/
#if XCHAL_CP_NUM > 0
char __aligned(4) cpStack[XT_CP_SIZE];
#endif
} tPreempCoprocReg;
/*
* The thread control stucture definition. It contains the
* various fields to manage a _single_ thread.
*/
struct _thread_arch {
/*
* See the above flag definitions above for valid bit settings. This
* field must remain near the start of struct k_thread, specifically
* before any #ifdef'ed fields since the host tools currently use a
* fixed offset to read the 'flags' field.
*/
u32_t flags;
#ifdef CONFIG_THREAD_CUSTOM_DATA
void *custom_data; /* available for custom use */
#endif
#if defined(CONFIG_THREAD_MONITOR)
/* thread entry and parameters description */
struct __thread_entry *entry;
/* next item in list of ALL threads n*/
struct k_thread *next_thread;
#endif
#ifdef CONFIG_ERRNO
int errno_var;
#endif
/*
* The location of all floating point related structures/fields MUST be
* located at the end of struct k_thread. This way only the threads
* that actually utilize non-integer capabilities need to account for
* the increased memory required for storing FP state when sizing
* stacks.
*
* Given that stacks "grow down" on Xtensa, and the k_thread is located
* at the start of a thread's "workspace" memory, the stacks of threads
* that do not utilize floating point instruction can effectively
* consume the memory occupied by the 'tCoopCoprocReg' and
* 'tPreempCoprocReg' structures without ill effect.
*
* TODO: Move Xtensa coprocessor's stack here to get rid of extra
* indirection
*/
/* non-volatile coprocessor's register storage */
tCoopCoprocReg coopCoprocReg;
/* volatile coprocessor's register storage */
tPreempCoprocReg preempCoprocReg;
};
typedef struct _thread_arch _thread_arch_t;
struct _kernel_arch {
#if defined(CONFIG_DEBUG_INFO)
NANO_ISF *isf; /* ptr to interrupt stack frame */

View file

@ -0,0 +1,153 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Per-arch thread definition
*
* This file contains defintions for
*
* struct _thread_arch
* struct _callee_saved
* struct _caller_saved
*
* necessary to instantiate instances of struct k_thread.
*/
#ifndef _kernel_arch_thread__h_
#define _kernel_arch_thread__h_
#ifndef _ASMLANGUAGE
#include <zephyr/types.h>
#include <xtensa_context.h>
/*
* The following structure defines the set of 'volatile' integer registers.
* These registers need not be preserved by a called C function. Given that
* they are not preserved across function calls, they must be save/restored
* (along with the struct _caller_saved) when a preemptive context switch
* occurs.
*/
struct _caller_saved {
/*
* The volatile registers area not included in the definition of
* 'tPreempReg' since the interrupt stubs (_IntEnt/_IntExit)
* and exception stubs (_ExcEnt/_ExcEnter) use the stack to save and
* restore the values of these registers in order to support interrupt
* nesting. The stubs do _not_ copy the saved values from the stack
* into the k_thread.
*/
};
typedef struct _caller_saved _caller_saved_t;
/*
* The following structure defines the set of 'non-volatile' integer registers.
* These registers must be preserved by a called C function. These are the
* only registers that need to be saved/restored when a cooperative context
* switch occurs.
*/
struct _callee_saved {
/*
* The following registers are considered non-volatile, i.e.
* callee-saved, but their values are pushed onto the stack rather than
* stored in the k_thread structure:
*/
u32_t retval; /* a2 */
XtExcFrame *topOfStack; /* a1 = sp */
};
typedef struct _callee_saved _callee_saved_t;
/*
* The following structure defines the set of 'non-volatile' x87 FPU/MMX/SSE
* registers. These registers must be preserved by a called C function.
* These are the only registers that need to be saved/restored when a
* cooperative context switch occurs.
*/
typedef struct s_coopCoprocReg {
/*
* This structure intentionally left blank. Coprocessor's registers are
* all 'volatile' and saved using the lazy context switch mechanism.
*/
} tCoopCoprocReg;
/*
* The following structure defines the set of 'volatile' x87 FPU/MMX/SSE
* registers. These registers need not be preserved by a called C function.
* Given that they are not preserved across function calls, they must be
* save/restored (along with s_coopCoprocReg) when a preemptive context switch
* occurs.
*/
typedef struct s_preempCoprocReg {
/*
* This structure intentionally left blank, as for now coprocessor's
* stack is positioned at top of the stack.
*/
#if XCHAL_CP_NUM > 0
char *cpStack;
#endif
} tPreempCoprocReg;
/*
* The thread control stucture definition. It contains the
* various fields to manage a _single_ thread.
*/
struct _thread_arch {
/*
* See the above flag definitions above for valid bit settings. This
* field must remain near the start of struct k_thread, specifically
* before any #ifdef'ed fields since the host tools currently use a
* fixed offset to read the 'flags' field.
*/
u32_t flags;
#ifdef CONFIG_THREAD_CUSTOM_DATA
void *custom_data; /* available for custom use */
#endif
#if defined(CONFIG_THREAD_MONITOR)
/* thread entry and parameters description */
struct __thread_entry *entry;
/* next item in list of ALL threads n*/
struct k_thread *next_thread;
#endif
#ifdef CONFIG_ERRNO
int errno_var;
#endif
/*
* The location of all floating point related structures/fields MUST be
* located at the end of struct k_thread. This way only the threads
* that actually utilize non-integer capabilities need to account for
* the increased memory required for storing FP state when sizing
* stacks.
*
* Given that stacks "grow down" on Xtensa, and the k_thread is located
* at the start of a thread's "workspace" memory, the stacks of threads
* that do not utilize floating point instruction can effectively
* consume the memory occupied by the 'tCoopCoprocReg' and
* 'tPreempCoprocReg' structures without ill effect.
*
* TODO: Move Xtensa coprocessor's stack here to get rid of extra
* indirection
*/
/* non-volatile coprocessor's register storage */
tCoopCoprocReg coopCoprocReg;
/* volatile coprocessor's register storage */
tPreempCoprocReg preempCoprocReg;
};
typedef struct _thread_arch _thread_arch_t;
#endif /* _ASMLANGUAGE */
#endif /* _kernel_arch_thread__h_ */

View file

@ -16,6 +16,7 @@
#include <irq.h>
#include <arch/x86/irq_controller.h>
#include <kernel_arch_thread.h>
#ifndef _ASMLANGUAGE
#include <arch/x86/asm_inline.h>
@ -49,20 +50,6 @@ void _int_latency_stop(void);
/* interrupt/exception/error related definitions */
/**
* Floating point register set alignment.
*
* If support for SSEx extensions is enabled a 16 byte boundary is required,
* since the 'fxsave' and 'fxrstor' instructions require this. In all other
* cases a 4 byte boundary is sufficient.
*/
#ifdef CONFIG_SSE
#define FP_REG_SET_ALIGN 16
#else
#define FP_REG_SET_ALIGN 4
#endif
/*
* The TCS must be aligned to the same boundary as that used by the floating
* point register set. This applies even for threads that don't initially

View file

@ -27,6 +27,7 @@
#include <misc/util.h>
#include <kernel_version.h>
#include <drivers/rand32.h>
#include <kernel_arch_thread.h>
#ifdef __cplusplus
extern "C" {
@ -105,7 +106,6 @@ typedef sys_dlist_t _wait_q_t;
#define _POLL_EVENT
#endif
#define tcs k_thread
struct k_thread;
struct k_mutex;
struct k_sem;
@ -123,7 +123,138 @@ struct k_timer;
struct k_poll_event;
struct k_poll_signal;
/* timeouts */
struct _timeout;
typedef void (*_timeout_func_t)(struct _timeout *t);
struct _timeout {
sys_dnode_t node;
struct k_thread *thread;
sys_dlist_t *wait_q;
s32_t delta_ticks_from_prev;
_timeout_func_t func;
};
extern s32_t _timeout_remaining_get(struct _timeout *timeout);
/* Threads */
typedef void (*_thread_entry_t)(void *, void *, void *);
#ifdef CONFIG_THREAD_MONITOR
struct __thread_entry {
_thread_entry_t pEntry;
void *parameter1;
void *parameter2;
void *parameter3;
};
#endif
/* can be used for creating 'dummy' threads, e.g. for pending on objects */
struct _thread_base {
/* this thread's entry in a ready/wait queue */
sys_dnode_t k_q_node;
/* user facing 'thread options'; values defined in include/kernel.h */
u8_t user_options;
/* thread state */
u8_t thread_state;
/*
* scheduler lock count and thread priority
*
* These two fields control the preemptibility of a thread.
*
* When the scheduler is locked, sched_locked is decremented, which
* means that the scheduler is locked for values from 0xff to 0x01. A
* thread is coop if its prio is negative, thus 0x80 to 0xff when
* looked at the value as unsigned.
*
* By putting them end-to-end, this means that a thread is
* non-preemptible if the bundled value is greater than or equal to
* 0x0080.
*/
union {
struct {
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
u8_t sched_locked;
s8_t prio;
#else /* LITTLE and PDP */
s8_t prio;
u8_t sched_locked;
#endif
};
u16_t preempt;
};
/* data returned by APIs */
void *swap_data;
#ifdef CONFIG_SYS_CLOCK_EXISTS
/* this thread's entry in a timeout queue */
struct _timeout timeout;
#endif
};
typedef struct _thread_base _thread_base_t;
#if defined(CONFIG_THREAD_STACK_INFO)
/* Contains the stack information of a thread */
struct _thread_stack_info {
/* Stack Start */
u32_t start;
/* Stack Size */
u32_t size;
};
#endif /* CONFIG_THREAD_STACK_INFO */
struct k_thread {
struct _thread_base base;
/* defined by the architecture, but all archs need these */
struct _caller_saved caller_saved;
struct _callee_saved callee_saved;
/* static thread init data */
void *init_data;
/* abort function */
void (*fn_abort)(void);
#if defined(CONFIG_THREAD_MONITOR)
/* thread entry and parameters description */
struct __thread_entry *entry;
/* next item in list of all threads */
struct k_thread *next_thread;
#endif
#ifdef CONFIG_THREAD_CUSTOM_DATA
/* crude thread-local storage */
void *custom_data;
#endif
#ifdef CONFIG_ERRNO
/* per-thread errno variable */
int errno_var;
#endif
#if defined(CONFIG_THREAD_STACK_INFO)
/* Stack Info */
struct _thread_stack_info stack_info;
#endif /* CONFIG_THREAD_STACK_INFO */
/* arch-specifics: must always be at the end */
struct _thread_arch arch;
};
typedef struct k_thread _thread_t;
typedef struct k_thread *k_tid_t;
#define tcs k_thread
enum execution_context_types {
K_ISR = 0,
@ -751,29 +882,6 @@ static inline s64_t __ticks_to_ms(s64_t ticks)
#endif
}
/* timeouts */
struct _timeout;
typedef void (*_timeout_func_t)(struct _timeout *t);
struct _timeout {
sys_dnode_t node;
struct k_thread *thread;
sys_dlist_t *wait_q;
s32_t delta_ticks_from_prev;
_timeout_func_t func;
};
extern s32_t _timeout_remaining_get(struct _timeout *timeout);
/**
* INTERNAL_HIDDEN @endcond
*/
/**
* @cond INTERNAL_HIDDEN
*/
struct k_timer {
/*
* _timeout structure must be first here if we want to use

View file

@ -56,119 +56,6 @@
#if !defined(_ASMLANGUAGE)
#ifdef CONFIG_THREAD_MONITOR
struct __thread_entry {
_thread_entry_t pEntry;
void *parameter1;
void *parameter2;
void *parameter3;
};
#endif
#if defined(CONFIG_THREAD_STACK_INFO)
/* Contains the stack information of a thread */
struct _thread_stack_info {
/* Stack Start */
u32_t start;
/* Stack Size */
u32_t size;
};
#endif /* CONFIG_THREAD_STACK_INFO */
/* can be used for creating 'dummy' threads, e.g. for pending on objects */
struct _thread_base {
/* this thread's entry in a ready/wait queue */
sys_dnode_t k_q_node;
/* user facing 'thread options'; values defined in include/kernel.h */
u8_t user_options;
/* thread state */
u8_t thread_state;
/*
* scheduler lock count and thread priority
*
* These two fields control the preemptibility of a thread.
*
* When the scheduler is locked, sched_locked is decremented, which
* means that the scheduler is locked for values from 0xff to 0x01. A
* thread is coop if its prio is negative, thus 0x80 to 0xff when
* looked at the value as unsigned.
*
* By putting them end-to-end, this means that a thread is
* non-preemptible if the bundled value is greater than or equal to
* 0x0080.
*/
union {
struct {
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
u8_t sched_locked;
s8_t prio;
#else /* LITTLE and PDP */
s8_t prio;
u8_t sched_locked;
#endif
};
u16_t preempt;
};
/* data returned by APIs */
void *swap_data;
#ifdef CONFIG_SYS_CLOCK_EXISTS
/* this thread's entry in a timeout queue */
struct _timeout timeout;
#endif
};
typedef struct _thread_base _thread_base_t;
struct k_thread {
struct _thread_base base;
/* defined by the architecture, but all archs need these */
struct _caller_saved caller_saved;
struct _callee_saved callee_saved;
/* static thread init data */
void *init_data;
/* abort function */
void (*fn_abort)(void);
#if defined(CONFIG_THREAD_MONITOR)
/* thread entry and parameters description */
struct __thread_entry *entry;
/* next item in list of all threads */
struct k_thread *next_thread;
#endif
#ifdef CONFIG_THREAD_CUSTOM_DATA
/* crude thread-local storage */
void *custom_data;
#endif
#ifdef CONFIG_ERRNO
/* per-thread errno variable */
int errno_var;
#endif
#if defined(CONFIG_THREAD_STACK_INFO)
/* Stack Info */
struct _thread_stack_info stack_info;
#endif /* CONFIG_THREAD_STACK_INFO */
/* arch-specifics: must always be at the end */
struct _thread_arch arch;
};
typedef struct k_thread _thread_t;
struct _ready_q {
/* always contains next thread to run: cannot be NULL */

View file

@ -14,6 +14,8 @@
#ifndef _NANO_INTERNAL__H_
#define _NANO_INTERNAL__H_
#include <kernel.h>
#define K_NUM_PRIORITIES \
(CONFIG_NUM_COOP_PRIORITIES + CONFIG_NUM_PREEMPT_PRIORITIES + 1)
@ -38,10 +40,6 @@ static inline void _data_copy(void)
#endif
FUNC_NORETURN void _Cstart(void);
/* helper type alias for thread control structure */
typedef void (*_thread_entry_t)(void *, void *, void *);
extern void _thread_entry(void (*)(void *, void *, void *),
void *, void *, void *);

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Per-arch thread definition
*
* This file contains defintions for
*
* struct _thread_arch
* struct _callee_saved
* struct _caller_saved
*
* necessary to instantiate instances of struct k_thread.
*/
#ifndef _kernel_arch_thread__h_
#define _kernel_arch_thread__h_
#ifndef _ASMLANGUAGE
struct _caller_saved {
};
typedef struct _caller_saved _caller_saved_t;
struct _callee_saved {
};
typedef struct _callee_saved _callee_saved_t;
struct _thread_arch {
};
typedef struct _thread_arch _thread_arch_t;
#endif /* _ASMLANGUAGE */
#endif /* _kernel_arch_thread__h_ */