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:
parent
94b44f03e1
commit
73abd32a7d
|
@ -28,6 +28,7 @@ extern "C" {
|
||||||
#include <sections.h>
|
#include <sections.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <vector_table.h>
|
#include <vector_table.h>
|
||||||
|
#include <kernel_arch_thread.h>
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#ifndef _ASMLANGUAGE
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
@ -38,16 +39,6 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#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 {
|
struct _irq_stack_frame {
|
||||||
u32_t r0;
|
u32_t r0;
|
||||||
u32_t r1;
|
u32_t r1;
|
||||||
|
@ -83,11 +74,6 @@ struct _irq_stack_frame {
|
||||||
|
|
||||||
typedef struct _irq_stack_frame _isf_t;
|
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 */
|
/* callee-saved registers pushed on the stack, not in k_thread */
|
||||||
struct _callee_saved_stack {
|
struct _callee_saved_stack {
|
||||||
u32_t r13;
|
u32_t r13;
|
||||||
|
@ -116,45 +102,6 @@ struct _callee_saved_stack {
|
||||||
|
|
||||||
typedef struct _callee_saved_stack _callee_saved_stack_t;
|
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 {
|
struct _kernel_arch {
|
||||||
|
|
||||||
char *rirq_sp; /* regular IRQ stack pointer base */
|
char *rirq_sp; /* regular IRQ stack pointer base */
|
||||||
|
@ -170,6 +117,13 @@ typedef struct _kernel_arch _kernel_arch_t;
|
||||||
|
|
||||||
#endif /* _ASMLANGUAGE */
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
70
arch/arc/include/kernel_arch_thread.h
Normal file
70
arch/arc/include/kernel_arch_thread.h
Normal 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_ */
|
|
@ -27,6 +27,7 @@ extern "C" {
|
||||||
#include <toolchain.h>
|
#include <toolchain.h>
|
||||||
#include <sections.h>
|
#include <sections.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
|
#include <kernel_arch_thread.h>
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#ifndef _ASMLANGUAGE
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
@ -38,40 +39,6 @@ extern "C" {
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#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;
|
typedef struct __esf _esf_t;
|
||||||
|
|
||||||
#endif /* _ASMLANGUAGE */
|
#endif /* _ASMLANGUAGE */
|
||||||
|
@ -88,47 +55,6 @@ typedef struct __esf _esf_t;
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#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 {
|
struct _kernel_arch {
|
||||||
/* empty */
|
/* empty */
|
||||||
};
|
};
|
||||||
|
|
103
arch/arm/include/kernel_arch_thread.h
Normal file
103
arch/arm/include/kernel_arch_thread.h
Normal 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_ */
|
|
@ -28,6 +28,7 @@ extern "C" {
|
||||||
#include <toolchain.h>
|
#include <toolchain.h>
|
||||||
#include <sections.h>
|
#include <sections.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
|
#include <kernel_arch_thread.h>
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#ifndef _ASMLANGUAGE
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
@ -46,52 +47,6 @@ extern "C" {
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#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 {
|
struct _kernel_arch {
|
||||||
/* nothing for now */
|
/* nothing for now */
|
||||||
};
|
};
|
||||||
|
|
75
arch/nios2/include/kernel_arch_thread.h
Normal file
75
arch/nios2/include/kernel_arch_thread.h
Normal 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_ */
|
||||||
|
|
|
@ -22,6 +22,7 @@ extern "C" {
|
||||||
#include <toolchain.h>
|
#include <toolchain.h>
|
||||||
#include <sections.h>
|
#include <sections.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
|
#include <kernel_arch_thread.h>
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#ifndef _ASMLANGUAGE
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
@ -30,43 +31,6 @@ extern "C" {
|
||||||
#include <misc/dlist.h>
|
#include <misc/dlist.h>
|
||||||
#include <nano_internal.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 {
|
struct _kernel_arch {
|
||||||
/* nothing for now */
|
/* nothing for now */
|
||||||
};
|
};
|
||||||
|
|
66
arch/riscv32/include/kernel_arch_thread.h
Normal file
66
arch/riscv32/include/kernel_arch_thread.h
Normal 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_ */
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <sections.h>
|
#include <sections.h>
|
||||||
#include <asm_inline.h>
|
#include <asm_inline.h>
|
||||||
#include <exception.h>
|
#include <exception.h>
|
||||||
|
#include <kernel_arch_thread.h>
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#ifndef _ASMLANGUAGE
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
@ -390,243 +391,6 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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 Developer’s 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 {
|
struct _kernel_arch {
|
||||||
#if defined(CONFIG_DEBUG_INFO)
|
#if defined(CONFIG_DEBUG_INFO)
|
||||||
|
|
280
arch/x86/include/kernel_arch_thread.h
Normal file
280
arch/x86/include/kernel_arch_thread.h
Normal 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 Developer’s 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_ */
|
|
@ -27,7 +27,7 @@ extern "C" {
|
||||||
#include <toolchain.h>
|
#include <toolchain.h>
|
||||||
#include <sections.h>
|
#include <sections.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <xtensa_context.h>
|
#include <kernel_arch_thread.h>
|
||||||
|
|
||||||
#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
|
#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
|
||||||
#include <kernel.h> /* public kernel API */
|
#include <kernel.h> /* public kernel API */
|
||||||
|
@ -45,130 +45,8 @@ extern "C" {
|
||||||
/* thread uses floating point unit */
|
/* thread uses floating point unit */
|
||||||
#define USE_FP 0x010
|
#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;
|
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 {
|
struct _kernel_arch {
|
||||||
#if defined(CONFIG_DEBUG_INFO)
|
#if defined(CONFIG_DEBUG_INFO)
|
||||||
NANO_ISF *isf; /* ptr to interrupt stack frame */
|
NANO_ISF *isf; /* ptr to interrupt stack frame */
|
||||||
|
|
153
arch/xtensa/include/kernel_arch_thread.h
Normal file
153
arch/xtensa/include/kernel_arch_thread.h
Normal 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_ */
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <irq.h>
|
#include <irq.h>
|
||||||
#include <arch/x86/irq_controller.h>
|
#include <arch/x86/irq_controller.h>
|
||||||
|
#include <kernel_arch_thread.h>
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#ifndef _ASMLANGUAGE
|
||||||
#include <arch/x86/asm_inline.h>
|
#include <arch/x86/asm_inline.h>
|
||||||
|
@ -49,20 +50,6 @@ void _int_latency_stop(void);
|
||||||
|
|
||||||
/* interrupt/exception/error related definitions */
|
/* 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
|
* 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
|
* point register set. This applies even for threads that don't initially
|
||||||
|
|
156
include/kernel.h
156
include/kernel.h
|
@ -27,6 +27,7 @@
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
#include <kernel_version.h>
|
#include <kernel_version.h>
|
||||||
#include <drivers/rand32.h>
|
#include <drivers/rand32.h>
|
||||||
|
#include <kernel_arch_thread.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -105,7 +106,6 @@ typedef sys_dlist_t _wait_q_t;
|
||||||
#define _POLL_EVENT
|
#define _POLL_EVENT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define tcs k_thread
|
|
||||||
struct k_thread;
|
struct k_thread;
|
||||||
struct k_mutex;
|
struct k_mutex;
|
||||||
struct k_sem;
|
struct k_sem;
|
||||||
|
@ -123,7 +123,138 @@ struct k_timer;
|
||||||
struct k_poll_event;
|
struct k_poll_event;
|
||||||
struct k_poll_signal;
|
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;
|
typedef struct k_thread *k_tid_t;
|
||||||
|
#define tcs k_thread
|
||||||
|
|
||||||
enum execution_context_types {
|
enum execution_context_types {
|
||||||
K_ISR = 0,
|
K_ISR = 0,
|
||||||
|
@ -751,29 +882,6 @@ static inline s64_t __ticks_to_ms(s64_t ticks)
|
||||||
#endif
|
#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 {
|
struct k_timer {
|
||||||
/*
|
/*
|
||||||
* _timeout structure must be first here if we want to use
|
* _timeout structure must be first here if we want to use
|
||||||
|
|
|
@ -56,119 +56,6 @@
|
||||||
|
|
||||||
#if !defined(_ASMLANGUAGE)
|
#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 {
|
struct _ready_q {
|
||||||
|
|
||||||
/* always contains next thread to run: cannot be NULL */
|
/* always contains next thread to run: cannot be NULL */
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#ifndef _NANO_INTERNAL__H_
|
#ifndef _NANO_INTERNAL__H_
|
||||||
#define _NANO_INTERNAL__H_
|
#define _NANO_INTERNAL__H_
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
|
|
||||||
#define K_NUM_PRIORITIES \
|
#define K_NUM_PRIORITIES \
|
||||||
(CONFIG_NUM_COOP_PRIORITIES + CONFIG_NUM_PREEMPT_PRIORITIES + 1)
|
(CONFIG_NUM_COOP_PRIORITIES + CONFIG_NUM_PREEMPT_PRIORITIES + 1)
|
||||||
|
|
||||||
|
@ -38,10 +40,6 @@ static inline void _data_copy(void)
|
||||||
#endif
|
#endif
|
||||||
FUNC_NORETURN void _Cstart(void);
|
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 *),
|
extern void _thread_entry(void (*)(void *, void *, void *),
|
||||||
void *, void *, void *);
|
void *, void *, void *);
|
||||||
|
|
||||||
|
|
44
tests/ztest/include/kernel_arch_thread.h
Normal file
44
tests/ztest/include/kernel_arch_thread.h
Normal 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_ */
|
||||||
|
|
Loading…
Reference in a new issue