headers: Refactor kernel and arch headers.
This commit refactors kernel and arch headers to establish a boundary between private and public interface headers. The refactoring strategy used in this commit is detailed in the issue This commit introduces the following major changes: 1. Establish a clear boundary between private and public headers by removing "kernel/include" and "arch/*/include" from the global include paths. Ideally, only kernel/ and arch/*/ source files should reference the headers in these directories. If these headers must be used by a component, these include paths shall be manually added to the CMakeLists.txt file of the component. This is intended to discourage applications from including private kernel and arch headers either knowingly and unknowingly. - kernel/include/ (PRIVATE) This directory contains the private headers that provide private kernel definitions which should not be visible outside the kernel and arch source code. All public kernel definitions must be added to an appropriate header located under include/. - arch/*/include/ (PRIVATE) This directory contains the private headers that provide private architecture-specific definitions which should not be visible outside the arch and kernel source code. All public architecture- specific definitions must be added to an appropriate header located under include/arch/*/. - include/ AND include/sys/ (PUBLIC) This directory contains the public headers that provide public kernel definitions which can be referenced by both kernel and application code. - include/arch/*/ (PUBLIC) This directory contains the public headers that provide public architecture-specific definitions which can be referenced by both kernel and application code. 2. Split arch_interface.h into "kernel-to-arch interface" and "public arch interface" divisions. - kernel/include/kernel_arch_interface.h * provides private "kernel-to-arch interface" definition. * includes arch/*/include/kernel_arch_func.h to ensure that the interface function implementations are always available. * includes sys/arch_interface.h so that public arch interface definitions are automatically included when including this file. - arch/*/include/kernel_arch_func.h * provides architecture-specific "kernel-to-arch interface" implementation. * only the functions that will be used in kernel and arch source files are defined here. - include/sys/arch_interface.h * provides "public arch interface" definition. * includes include/arch/arch_inlines.h to ensure that the architecture-specific public inline interface function implementations are always available. - include/arch/arch_inlines.h * includes architecture-specific arch_inlines.h in include/arch/*/arch_inline.h. - include/arch/*/arch_inline.h * provides architecture-specific "public arch interface" inline function implementation. * supersedes include/sys/arch_inline.h. 3. Refactor kernel and the existing architecture implementations. - Remove circular dependency of kernel and arch headers. The following general rules should be observed: * Never include any private headers from public headers * Never include kernel_internal.h in kernel_arch_data.h * Always include kernel_arch_data.h from kernel_arch_func.h * Never include kernel.h from kernel_struct.h either directly or indirectly. Only add the kernel structures that must be referenced from public arch headers in this file. - Relocate syscall_handler.h to include/ so it can be used in the public code. This is necessary because many user-mode public codes reference the functions defined in this header. - Relocate kernel_arch_thread.h to include/arch/*/thread.h. This is necessary to provide architecture-specific thread definition for 'struct k_thread' in kernel.h. - Remove any private header dependencies from public headers using the following methods: * If dependency is not required, simply omit * If dependency is required, - Relocate a portion of the required dependencies from the private header to an appropriate public header OR - Relocate the required private header to make it public. This commit supersedes #20047, addresses #19666, and fixes #3056. Signed-off-by: Stephanos Ioannidis <root@stephanos.io>
This commit is contained in:
parent
8bb99dc9ce
commit
2d7460482d
244 changed files with 1542 additions and 1297 deletions
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <generated_dts_board.h>
|
||||
#include <sw_isr_table.h>
|
||||
#include <arch/arc/thread.h>
|
||||
#ifdef CONFIG_CPU_ARCV2
|
||||
#include <arch/arc/v2/exc.h>
|
||||
#include <arch/arc/v2/irq.h>
|
||||
|
|
33
include/arch/arc/arch_inlines.h
Normal file
33
include/arch/arc/arch_inlines.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2016 Wind River Systems, Inc.
|
||||
* Copyright (c) 2019 Stephanos Ioannidis <root@stephanos.io>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_ARCH_INLINES_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_XTENSA_ARCH_INLINES_H_
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
#include <kernel_structs.h>
|
||||
|
||||
#ifdef CONFIG_CPU_ARCV2
|
||||
#include <arch/arc/v2/aux_regs.h>
|
||||
#endif
|
||||
|
||||
static ALWAYS_INLINE _cpu_t *z_arch_curr_cpu(void)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
u32_t core;
|
||||
|
||||
core = z_arc_v2_core_id();
|
||||
|
||||
return &_kernel.cpus[core];
|
||||
#else
|
||||
return &_kernel.cpus[0];
|
||||
#endif /* CONFIG_SMP */
|
||||
}
|
||||
|
||||
#endif /* !_ASMLANGUAGE */
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_ARCH_INLINES_H_ */
|
73
include/arch/arc/thread.h
Normal file
73
include/arch/arc/thread.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Per-arch thread definition
|
||||
*
|
||||
* This file contains definitions for
|
||||
*
|
||||
* struct _thread_arch
|
||||
* struct _callee_saved
|
||||
*
|
||||
* necessary to instantiate instances of struct k_thread.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARC_THREAD_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARC_THREAD_H_
|
||||
|
||||
/*
|
||||
* Reason a thread has relinquished control.
|
||||
*/
|
||||
#define _CAUSE_NONE 0
|
||||
#define _CAUSE_COOP 1
|
||||
#define _CAUSE_RIRQ 2
|
||||
#define _CAUSE_FIRQ 3
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct _callee_saved {
|
||||
u32_t sp; /* r28 */
|
||||
};
|
||||
typedef struct _callee_saved _callee_saved_t;
|
||||
|
||||
struct _thread_arch {
|
||||
|
||||
/* one of the _CAUSE_xxxx definitions above */
|
||||
int relinquish_cause;
|
||||
|
||||
#ifdef CONFIG_ARC_STACK_CHECKING
|
||||
/* High address of stack region, stack grows downward from this
|
||||
* location. Usesd for hardware stack checking
|
||||
*/
|
||||
u32_t k_stack_base;
|
||||
u32_t k_stack_top;
|
||||
#ifdef CONFIG_USERSPACE
|
||||
u32_t u_stack_base;
|
||||
u32_t u_stack_top;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
u32_t priv_stack_start;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct _thread_arch _thread_arch_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARC_THREAD_H_ */
|
23
include/arch/arch_inlines.h
Normal file
23
include/arch/arch_inlines.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* arch_inlines.h - automatically selects the correct arch_inlines.h file to
|
||||
* include based on the selected architecture.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Stephanos Ioannidis <root@stephanos.io>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_INLINES_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_INLINES_H_
|
||||
|
||||
#if defined(CONFIG_X86) || defined(CONFIG_X86_64)
|
||||
#include <arch/x86/arch_inlines.h>
|
||||
#elif defined(CONFIG_ARC)
|
||||
#include <arch/arc/arch_inlines.h>
|
||||
#elif defined(CONFIG_XTENSA)
|
||||
#include <arch/xtensa/arch_inlines.h>
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_INLINES_H_ */
|
|
@ -22,6 +22,7 @@
|
|||
/* ARM GPRs are often designated by two different names */
|
||||
#define sys_define_gpr_with_alias(name1, name2) union { u32_t name1, name2; }
|
||||
|
||||
#include <arch/arm/thread.h>
|
||||
#include <arch/arm/exc.h>
|
||||
#include <arch/arm/irq.h>
|
||||
#include <arch/arm/error.h>
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_ASM_INLINE_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_ASM_INLINE_H_
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_H_
|
||||
|
||||
/*
|
||||
* The file must not be included directly
|
||||
|
@ -20,4 +20,4 @@
|
|||
#include <arch/arm/asm_inline_other.h>
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_ASM_INLINE_H_ */
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_H_ */
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
/* Either public functions or macros or invoked by public functions */
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_ASM_INLINE_GCC_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_ASM_INLINE_GCC_H_
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_GCC_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_GCC_H_
|
||||
|
||||
/*
|
||||
* The file must not be included directly
|
||||
|
@ -112,4 +112,4 @@ static ALWAYS_INLINE bool z_arch_irq_unlocked(unsigned int key)
|
|||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_ASM_INLINE_GCC_H_ */
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_ASM_INLINE_GCC_H_ */
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
* ARM-specific kernel error handling interface. Included by arm/arch.h.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_ERROR_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_ERROR_H_
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_ERROR_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_ERROR_H_
|
||||
|
||||
#include <arch/arm/syscall.h>
|
||||
#include <arch/arm/exc.h>
|
||||
|
@ -62,4 +62,4 @@ do { \
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_ERROR_H_ */
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_ERROR_H_ */
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
* ARM-specific kernel exception handling interface. Included by arm/arch.h.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_EXC_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_EXC_H_
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_EXC_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_EXC_H_
|
||||
|
||||
/* for assembler, only works with constants */
|
||||
#define Z_EXC_PRIO(pri) (((pri) << (8 - DT_NUM_IRQ_PRIO_BITS)) & 0xff)
|
||||
|
@ -72,4 +72,4 @@ extern void z_arm_exc_exit(void);
|
|||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_EXC_H_ */
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_EXC_H_ */
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
* ARM-specific kernel interrupt handling interface. Included by arm/arch.h.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_IRQ_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_IRQ_H_
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_IRQ_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_IRQ_H_
|
||||
|
||||
#include <irq.h>
|
||||
#include <sw_isr_table.h>
|
||||
|
@ -149,4 +149,4 @@ extern void _isr_wrapper(void);
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_IRQ_H_ */
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_IRQ_H_ */
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
* ARM-specific kernel miscellaneous interface. Included by arm/arch.h.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MISC_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MISC_H_
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_MISC_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_MISC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -37,4 +37,4 @@ static ALWAYS_INLINE void z_arch_nop(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_MISC_H_ */
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_MISC_H_ */
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_NMI_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_NMI_H_
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_NMI_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_NMI_H_
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
#ifdef CONFIG_RUNTIME_NMI
|
||||
|
@ -22,4 +22,4 @@ extern void z_arm_nmi_init(void);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_CORTEX_M_NMI_H_ */
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_NMI_H_ */
|
||||
|
|
95
include/arch/arm/thread.h
Normal file
95
include/arch/arm/thread.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Per-arch thread definition
|
||||
*
|
||||
* This file contains definitions for
|
||||
*
|
||||
* struct _thread_arch
|
||||
* struct _callee_saved
|
||||
*
|
||||
* necessary to instantiate instances of struct k_thread.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_ARM_THREAD_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_ARM_THREAD_H_
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
#include <zephyr/types.h>
|
||||
|
||||
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 */
|
||||
#if defined(CONFIG_CPU_CORTEX_R)
|
||||
u32_t spsr;/* r12 */
|
||||
u32_t psp; /* r13 */
|
||||
u32_t lr; /* r14 */
|
||||
#else
|
||||
u32_t psp; /* r13 */
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct _callee_saved _callee_saved_t;
|
||||
|
||||
#if defined(CONFIG_FLOAT) && defined(CONFIG_FP_SHARING)
|
||||
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;
|
||||
|
||||
#if defined(CONFIG_FLOAT) && defined(CONFIG_FP_SHARING)
|
||||
/*
|
||||
* 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
|
||||
|
||||
#if defined(CONFIG_USERSPACE) || defined(CONFIG_FP_SHARING)
|
||||
u32_t mode;
|
||||
#if defined(CONFIG_USERSPACE)
|
||||
u32_t priv_stack_start;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct _thread_arch _thread_arch_t;
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_ARM_THREAD_H_ */
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef ZEPHYR_INCLUDE_ARCH_CPU_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_CPU_H_
|
||||
|
||||
#include <sys/arch_inlines.h>
|
||||
#include <sys/arch_interface.h>
|
||||
|
||||
#if defined(CONFIG_X86)
|
||||
#include <arch/x86/arch.h>
|
||||
|
|
|
@ -15,10 +15,12 @@
|
|||
#define ZEPHYR_INCLUDE_ARCH_NIOS2_ARCH_H_
|
||||
|
||||
#include <system.h>
|
||||
|
||||
#include <arch/nios2/thread.h>
|
||||
#include <arch/nios2/asm_inline.h>
|
||||
#include <arch/common/addr_types.h>
|
||||
#include <generated_dts_board.h>
|
||||
#include "nios2.h"
|
||||
#include <arch/nios2/nios2.h>
|
||||
#include <arch/common/sys_io.h>
|
||||
#include <arch/common/ffs.h>
|
||||
|
||||
|
|
65
include/arch/nios2/thread.h
Normal file
65
include/arch/nios2/thread.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Per-arch thread definition
|
||||
*
|
||||
* This file contains definitions for
|
||||
*
|
||||
* struct _thread_arch
|
||||
* struct _callee_saved
|
||||
*
|
||||
* necessary to instantiate instances of struct k_thread.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_NIOS2_THREAD_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_NIOS2_THREAD_H_
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
#include <zephyr/types.h>
|
||||
|
||||
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 z_swap() */
|
||||
u32_t key;
|
||||
|
||||
/* Return value of z_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 /* ZEPHYR_INCLUDE_ARCH_NIOS2_THREAD_H_ */
|
||||
|
|
@ -23,9 +23,10 @@
|
|||
#include <toolchain.h>
|
||||
#include <irq.h>
|
||||
#include <arch/posix/asm_inline.h>
|
||||
#include <arch/posix/thread.h>
|
||||
#include <board_irq.h> /* Each board must define this */
|
||||
#include <sw_isr_table.h>
|
||||
#include <posix_soc_if.h>
|
||||
#include <arch/posix/posix_soc_if.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <zephyr/types.h>
|
||||
#include <arch/common/sys_io.h>
|
||||
#include <arch/common/ffs.h>
|
||||
#include "posix_soc_if.h"
|
||||
#include <arch/posix/posix_soc_if.h>
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
|
|
42
include/arch/posix/posix_soc_if.h
Normal file
42
include/arch/posix/posix_soc_if.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Oticon A/S
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_POSIX_POSIX_SOC_IF_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_POSIX_POSIX_SOC_IF_H_
|
||||
|
||||
/*
|
||||
* This file lists the functions the POSIX architecture core expects the
|
||||
* SOC or board will provide
|
||||
*
|
||||
* All functions listed here must be provided by the implementation of the SOC
|
||||
* or all its boards
|
||||
*/
|
||||
|
||||
#include <arch/posix/posix_trace.h>
|
||||
#include "soc_irq.h" /* Must exist and define _ARCH_IRQ/ISR_* macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void posix_halt_cpu(void);
|
||||
void posix_atomic_halt_cpu(unsigned int imask);
|
||||
|
||||
void posix_irq_enable(unsigned int irq);
|
||||
void posix_irq_disable(unsigned int irq);
|
||||
int posix_irq_is_enabled(unsigned int irq);
|
||||
unsigned int posix_irq_lock(void);
|
||||
void posix_irq_unlock(unsigned int key);
|
||||
void posix_irq_full_unlock(void);
|
||||
int posix_get_current_irq(void);
|
||||
#ifdef CONFIG_IRQ_OFFLOAD
|
||||
void posix_irq_offload(void (*routine)(void *), void *parameter);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_POSIX_POSIX_SOC_IF_H_ */
|
34
include/arch/posix/posix_trace.h
Normal file
34
include/arch/posix/posix_trace.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Oticon A/S
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_POSIX_POSIX_TRACE_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_POSIX_POSIX_TRACE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void posix_print_error_and_exit(const char *format, ...);
|
||||
void posix_print_warning(const char *format, ...);
|
||||
void posix_print_trace(const char *format, ...);
|
||||
/*
|
||||
* Return 1 if traces to <output> will go to a tty.
|
||||
* When printing to a terminal we may use ASCII escapes for color or other
|
||||
* niceties.
|
||||
* But when redirecting to files, or piping to other commands, those should be
|
||||
* disabled by default.
|
||||
*
|
||||
* Where the <output> should be set to 0 to query about posix_print_trace output
|
||||
* (typically STDOUT)
|
||||
* and 1 to query about the warning and error output (posix_print_error/warning)
|
||||
* outputs (typically STDERR)
|
||||
*/
|
||||
int posix_trace_over_tty(int output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
55
include/arch/posix/thread.h
Normal file
55
include/arch/posix/thread.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
* Copyright (c) 2017 Oticon A/S
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Per-arch thread definition
|
||||
*
|
||||
* This file contains definitions for
|
||||
*
|
||||
* struct _thread_arch
|
||||
* struct _callee_saved
|
||||
*
|
||||
* necessary to instantiate instances of struct k_thread.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_POSIX_THREAD_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_POSIX_THREAD_H_
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct _callee_saved {
|
||||
/* IRQ status before irq_lock() and call to z_swap() */
|
||||
u32_t key;
|
||||
|
||||
/* Return value of z_swap() */
|
||||
u32_t retval;
|
||||
|
||||
/* Thread status pointer */
|
||||
void *thread_status;
|
||||
};
|
||||
|
||||
|
||||
struct _thread_arch {
|
||||
/* nothing for now */
|
||||
int dummy;
|
||||
};
|
||||
|
||||
typedef struct _thread_arch _thread_arch_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_POSIX_THREAD_H_ */
|
|
@ -15,7 +15,8 @@
|
|||
#ifndef ZEPHYR_INCLUDE_ARCH_RISCV_ARCH_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_RISCV_ARCH_H_
|
||||
|
||||
#include "exp.h"
|
||||
#include <arch/riscv/thread.h>
|
||||
#include <arch/riscv/exp.h>
|
||||
#include <arch/common/sys_io.h>
|
||||
#include <arch/common/ffs.h>
|
||||
|
||||
|
|
55
include/arch/riscv/thread.h
Normal file
55
include/arch/riscv/thread.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Per-arch thread definition
|
||||
*
|
||||
* This file contains definitions for
|
||||
*
|
||||
* struct _thread_arch
|
||||
* struct _callee_saved
|
||||
*
|
||||
* necessary to instantiate instances of struct k_thread.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_RISCV_THREAD_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_RISCV_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 {
|
||||
ulong_t sp; /* Stack pointer, (x2 register) */
|
||||
|
||||
ulong_t s0; /* saved register/frame pointer */
|
||||
ulong_t s1; /* saved register */
|
||||
ulong_t s2; /* saved register */
|
||||
ulong_t s3; /* saved register */
|
||||
ulong_t s4; /* saved register */
|
||||
ulong_t s5; /* saved register */
|
||||
ulong_t s6; /* saved register */
|
||||
ulong_t s7; /* saved register */
|
||||
ulong_t s8; /* saved register */
|
||||
ulong_t s9; /* saved register */
|
||||
ulong_t s10; /* saved register */
|
||||
ulong_t s11; /* saved register */
|
||||
};
|
||||
typedef struct _callee_saved _callee_saved_t;
|
||||
|
||||
struct _thread_arch {
|
||||
u32_t swap_return_value; /* Return value of z_swap() */
|
||||
};
|
||||
|
||||
typedef struct _thread_arch _thread_arch_t;
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_RISCV_THREAD_H_ */
|
33
include/arch/x86/arch_inlines.h
Normal file
33
include/arch/x86/arch_inlines.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Intel Corporation
|
||||
* Copyright (c) 2019 Stephanos Ioannidis <root@stephanos.io>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_X86_ARCH_INLINES_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_X86_ARCH_INLINES_H_
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
#if defined(CONFIG_X86_64)
|
||||
|
||||
#include <arch/x86/intel64/thread.h>
|
||||
#include <kernel_structs.h>
|
||||
|
||||
static inline struct _cpu *z_arch_curr_cpu(void)
|
||||
{
|
||||
struct _cpu *cpu;
|
||||
|
||||
__asm__ volatile("movq %%gs:(%c1), %0"
|
||||
: "=r" (cpu)
|
||||
: "i" (offsetof(x86_tss64_t, cpu)));
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_X86_64 */
|
||||
|
||||
#endif /* !_ASMLANGUAGE */
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_X86_ARCH_INLINES_H_ */
|
|
@ -16,10 +16,10 @@
|
|||
|
||||
#include "sys_io.h"
|
||||
#include <drivers/interrupt_controller/sysapic.h>
|
||||
#include <kernel_arch_thread.h>
|
||||
#include <stdbool.h>
|
||||
#include <arch/common/ffs.h>
|
||||
#include <misc/util.h>
|
||||
#include <arch/x86/ia32/thread.h>
|
||||
#include <arch/x86/ia32/syscall.h>
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
|
240
include/arch/x86/ia32/thread.h
Normal file
240
include/arch/x86/ia32/thread.h
Normal file
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Per-arch thread definition
|
||||
*
|
||||
* This file contains definitions for
|
||||
*
|
||||
* struct _thread_arch
|
||||
* struct _callee_saved
|
||||
*
|
||||
* necessary to instantiate instances of struct k_thread.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_X86_IA32_THREAD_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_X86_IA32_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
|
||||
|
||||
/*
|
||||
* Bits for _thread_arch.flags, see their use in intstub.S et al.
|
||||
*/
|
||||
|
||||
#define X86_THREAD_FLAG_INT 0x01
|
||||
#define X86_THREAD_FLAG_EXC 0x02
|
||||
#define X86_THREAD_FLAG_ALL (X86_THREAD_FLAG_INT | X86_THREAD_FLAG_EXC)
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
#include <stdint.h>
|
||||
#include <arch/x86/mmustructs.h>
|
||||
|
||||
/*
|
||||
* 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 macros CONFIG_{LAZY|EAGER}_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.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_EAGER_FP_SHARING) || defined(CONFIG_LAZY_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(r) 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_LAZY_FP_SHARING && !CONFIG_EAGER_FP_SHARING */
|
||||
|
||||
/* empty floating point register definition */
|
||||
|
||||
typedef struct s_FpRegSet {
|
||||
} tFpRegSet;
|
||||
|
||||
typedef struct s_FpRegSetEx {
|
||||
} tFpRegSetEx;
|
||||
|
||||
#endif /* CONFIG_LAZY_FP_SHARING || CONFIG_EAGER_FP_SHARING */
|
||||
|
||||
/*
|
||||
* 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 structure definition. It contains the
|
||||
* various fields to manage a _single_ thread. The TCS will be aligned
|
||||
* to the appropriate architecture specific boundary via the
|
||||
* z_arch_new_thread() call.
|
||||
*/
|
||||
|
||||
struct _thread_arch {
|
||||
u8_t flags;
|
||||
|
||||
#if defined(CONFIG_LAZY_FP_SHARING)
|
||||
/*
|
||||
* Nested exception count to maintain setting of EXC_ACTIVE flag across
|
||||
* outermost exception. EXC_ACTIVE is used by z_swap() lazy FP
|
||||
* save/restore and by debug tools.
|
||||
*/
|
||||
unsigned excNestCount; /* nested exception count */
|
||||
#endif /* CONFIG_LAZY_FP_SHARING */
|
||||
|
||||
/*
|
||||
* 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 IA-32, and the TCS 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 'tPreempFloatReg'
|
||||
* struct without ill effect.
|
||||
*/
|
||||
tPreempFloatReg preempFloatReg; /* volatile float register storage */
|
||||
};
|
||||
|
||||
typedef struct _thread_arch _thread_arch_t;
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_X86_IA32_THREAD_H_ */
|
|
@ -6,7 +6,7 @@
|
|||
#ifndef ZEPHYR_INCLUDE_ARCH_X86_INTEL64_ARCH_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_X86_INTEL64_ARCH_H_
|
||||
|
||||
#include <kernel_arch_thread.h>
|
||||
#include <arch/x86/intel64/thread.h>
|
||||
|
||||
#define STACK_ALIGN 16
|
||||
#define STACK_SIZE_ALIGN 16
|
||||
|
|
121
include/arch/x86/intel64/thread.h
Normal file
121
include/arch/x86/intel64/thread.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Intel Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_X86_INTEL64_THREAD_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_X86_INTEL64_THREAD_H_
|
||||
|
||||
#define X86_THREAD_FLAG_ALL 0x01 /* _thread_arch.flags: entire state saved */
|
||||
|
||||
/*
|
||||
* GDT selectors - these must agree with the GDT layout in locore.S.
|
||||
*/
|
||||
|
||||
#define X86_KERNEL_CS_32 0x08 /* 32-bit kernel code */
|
||||
#define X86_KERNEL_DS_32 0x10 /* 32-bit kernel data */
|
||||
#define X86_KERNEL_CS 0x18 /* 64-bit kernel code */
|
||||
#define X86_KERNEL_DS 0x20 /* 64-bit kernel data */
|
||||
|
||||
#define X86_KERNEL_CPU0_GS 0x30 /* data selector covering TSS */
|
||||
#define X86_KERNEL_CPU0_TR 0x40 /* 64-bit task state segment */
|
||||
#define X86_KERNEL_CPU1_GS 0x50 /* data selector covering TSS */
|
||||
#define X86_KERNEL_CPU1_TR 0x60 /* 64-bit task state segment */
|
||||
#define X86_KERNEL_CPU2_GS 0x70 /* data selector covering TSS */
|
||||
#define X86_KERNEL_CPU2_TR 0x80 /* 64-bit task state segment */
|
||||
#define X86_KERNEL_CPU3_GS 0x90 /* data selector covering TSS */
|
||||
#define X86_KERNEL_CPU3_TR 0xA0 /* 64-bit task state segment */
|
||||
|
||||
/*
|
||||
* Some SSE definitions. Ideally these will ultimately be shared with 32-bit.
|
||||
*/
|
||||
|
||||
#define X86_FXSAVE_SIZE 512 /* size and alignment of buffer ... */
|
||||
#define X86_FXSAVE_ALIGN 16 /* ... for FXSAVE/FXRSTOR ops */
|
||||
#define X86_MXCSR_SANE 0x1dc0 /* enable division-by-zero exception */
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
#include <zephyr/types.h>
|
||||
|
||||
/*
|
||||
* 64-bit Task State Segment. One defined per CPU.
|
||||
*/
|
||||
|
||||
struct x86_tss64 {
|
||||
/*
|
||||
* Architecturally-defined portion. It is somewhat tedious to
|
||||
* enumerate each member specifically (rather than using arrays)
|
||||
* but we need to get (some of) their offsets from assembly.
|
||||
*/
|
||||
|
||||
u8_t reserved0[4];
|
||||
|
||||
u64_t rsp0; /* privileged stacks */
|
||||
u64_t rsp1;
|
||||
u64_t rsp2;
|
||||
|
||||
u8_t reserved[8];
|
||||
|
||||
u64_t ist1; /* interrupt stacks */
|
||||
u64_t ist2;
|
||||
u64_t ist3;
|
||||
u64_t ist4;
|
||||
u64_t ist5;
|
||||
u64_t ist6;
|
||||
u64_t ist7;
|
||||
|
||||
u8_t reserved1[10];
|
||||
|
||||
u16_t iomapb; /* offset to I/O base */
|
||||
|
||||
/*
|
||||
* Zephyr specific portion. Stash per-CPU data here for convenience.
|
||||
*/
|
||||
|
||||
struct _cpu *cpu;
|
||||
} __packed __aligned(8);
|
||||
|
||||
typedef struct x86_tss64 x86_tss64_t;
|
||||
|
||||
/*
|
||||
* The _callee_saved registers are unconditionally saved/restored across
|
||||
* context switches; the _thread_arch registers are only preserved when
|
||||
* the thread is interrupted. _arch_thread.flags tells __resume when to
|
||||
* cheat and only restore the first set. For more details see locore.S.
|
||||
*/
|
||||
|
||||
struct _callee_saved {
|
||||
u64_t rsp;
|
||||
u64_t rbx;
|
||||
u64_t rbp;
|
||||
u64_t r12;
|
||||
u64_t r13;
|
||||
u64_t r14;
|
||||
u64_t r15;
|
||||
u64_t rip;
|
||||
u64_t rflags;
|
||||
};
|
||||
|
||||
typedef struct _callee_saved _callee_saved_t;
|
||||
|
||||
struct _thread_arch {
|
||||
u8_t flags;
|
||||
|
||||
u64_t rax;
|
||||
u64_t rcx;
|
||||
u64_t rdx;
|
||||
u64_t rsi;
|
||||
u64_t rdi;
|
||||
u64_t r8;
|
||||
u64_t r9;
|
||||
u64_t r10;
|
||||
u64_t r11;
|
||||
char __aligned(X86_FXSAVE_ALIGN) sse[X86_FXSAVE_SIZE];
|
||||
};
|
||||
|
||||
typedef struct _thread_arch _thread_arch_t;
|
||||
|
||||
#endif /* _ASMLANGUAGE */
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_X86_INTEL64_THREAD_H_ */
|
|
@ -17,10 +17,11 @@
|
|||
|
||||
#include <generated_dts_board.h>
|
||||
#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
|
||||
#include <zephyr/types.h>
|
||||
#include <arch/common/sys_io.h>
|
||||
#include <arch/common/ffs.h>
|
||||
#include <zephyr/types.h>
|
||||
#include <sw_isr_table.h>
|
||||
#include <arch/xtensa/thread.h>
|
||||
#include <arch/xtensa/irq.h>
|
||||
#include <xtensa/config/core.h>
|
||||
#include <arch/common/addr_types.h>
|
||||
|
|
36
include/arch/xtensa/arch_inlines.h
Normal file
36
include/arch/xtensa/arch_inlines.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* Copyright (c) 2019 Stephanos Ioannidis <root@stephanos.io>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_ARCH_INLINES_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_XTENSA_ARCH_INLINES_H_
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
|
||||
#include <kernel_structs.h>
|
||||
|
||||
#define RSR(sr) \
|
||||
({u32_t v; \
|
||||
__asm__ volatile ("rsr." sr " %0" : "=a"(v)); \
|
||||
v; })
|
||||
|
||||
#define WSR(sr, v) \
|
||||
do { \
|
||||
__asm__ volatile ("wsr." sr " %0" : : "r"(v)); \
|
||||
} while (false)
|
||||
|
||||
static ALWAYS_INLINE _cpu_t *z_arch_curr_cpu(void)
|
||||
{
|
||||
_cpu_t *cpu;
|
||||
|
||||
cpu = (_cpu_t *)RSR(CONFIG_XTENSA_KERNEL_CPU_PTR_SR);
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
||||
#endif /* !_ASMLANGUAGE */
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_ARCH_XTENSA_ARCH_INLINES_H_ */
|
|
@ -6,7 +6,7 @@
|
|||
#ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_IRQ_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_XTENSA_XTENSA_IRQ_H_
|
||||
|
||||
#include <xtensa_api.h>
|
||||
#include <arch/xtensa/xtensa_api.h>
|
||||
#include <xtensa/xtruntime.h>
|
||||
|
||||
#define CONFIG_GEN_IRQ_START_VECTOR 0
|
||||
|
|
116
include/arch/xtensa/thread.h
Normal file
116
include/arch/xtensa/thread.h
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Per-arch thread definition
|
||||
*
|
||||
* This file contains definitions for
|
||||
*
|
||||
* struct _thread_arch
|
||||
* struct _callee_saved
|
||||
*
|
||||
* necessary to instantiate instances of struct k_thread.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_ARCH_XTENSA_THREAD_H_
|
||||
#define ZEPHYR_INCLUDE_ARCH_XTENSA_THREAD_H_
|
||||
|
||||
#ifndef _ASMLANGUAGE
|
||||
#include <zephyr/types.h>
|
||||
#include <arch/xtensa/xtensa_context.h>
|
||||
|
||||
/*
|
||||
* 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 reserved coprocessor control and save area memory.
|
||||
*/
|
||||
#if XCHAL_CP_NUM > 0
|
||||
char __aligned(4) cpStack[XT_CP_SIZE];
|
||||
#endif
|
||||
} tPreempCoprocReg;
|
||||
|
||||
/*
|
||||
* The thread control structure 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_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.
|
||||
*/
|
||||
|
||||
/* 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 /* ZEPHYR_INCLUDE_ARCH_XTENSA_THREAD_H_ */
|
||||
|
60
include/arch/xtensa/xtensa_api.h
Normal file
60
include/arch/xtensa/xtensa_api.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_API_H_
|
||||
#define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_API_H_
|
||||
|
||||
#include <xtensa/hal.h>
|
||||
#include "xtensa_rtos.h"
|
||||
#include "xtensa_context.h"
|
||||
|
||||
/*
|
||||
* Call this function to enable the specified interrupts.
|
||||
*
|
||||
* mask - Bit mask of interrupts to be enabled.
|
||||
*/
|
||||
static inline void z_xt_ints_on(unsigned int mask)
|
||||
{
|
||||
int val;
|
||||
|
||||
__asm__ volatile("rsr.intenable %0" : "=r"(val));
|
||||
val |= mask;
|
||||
__asm__ volatile("wsr.intenable %0; rsync" : : "r"(val));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Call this function to disable the specified interrupts.
|
||||
*
|
||||
* mask - Bit mask of interrupts to be disabled.
|
||||
*/
|
||||
static inline void z_xt_ints_off(unsigned int mask)
|
||||
{
|
||||
int val;
|
||||
|
||||
__asm__ volatile("rsr.intenable %0" : "=r"(val));
|
||||
val &= ~mask;
|
||||
__asm__ volatile("wsr.intenable %0; rsync" : : "r"(val));
|
||||
}
|
||||
|
||||
/*
|
||||
* Call this function to set the specified (s/w) interrupt.
|
||||
*/
|
||||
static inline void z_xt_set_intset(unsigned int arg)
|
||||
{
|
||||
xthal_set_intset(arg);
|
||||
}
|
||||
|
||||
|
||||
/* Call this function to clear the specified (s/w or edge-triggered)
|
||||
* interrupt.
|
||||
*/
|
||||
static inline void _xt_set_intclear(unsigned int arg)
|
||||
{
|
||||
xthal_set_intclear(arg);
|
||||
}
|
||||
|
||||
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_API_H_ */
|
||||
|
132
include/arch/xtensa/xtensa_config.h
Normal file
132
include/arch/xtensa/xtensa_config.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_CONFIG_H_
|
||||
#define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_CONFIG_H_
|
||||
|
||||
#include <xtensa/hal.h>
|
||||
#include <xtensa/config/core.h>
|
||||
#include <xtensa/config/system.h> /* required for XSHAL_CLIB */
|
||||
|
||||
#include "xtensa_context.h"
|
||||
|
||||
/*
|
||||
* STACK REQUIREMENTS
|
||||
*
|
||||
* This section defines the minimum stack size, and the extra space required to
|
||||
* be allocated for saving coprocessor state and/or C library state information
|
||||
* (if thread safety is enabled for the C library). The sizes are in bytes.
|
||||
*
|
||||
* Stack sizes for individual threads should be derived from these minima based
|
||||
* on the maximum call depth of the task and the maximum level of interrupt
|
||||
* nesting. A minimum stack size is defined by XT_STACK_MIN_SIZE. This minimum
|
||||
* is based on the requirement for a task that calls nothing else but can be
|
||||
* interrupted. This assumes that interrupt handlers do not call more than a
|
||||
* few levels deep. If this is not true, i.e. one or more interrupt handlers
|
||||
* make deep calls then the minimum must be increased.
|
||||
*
|
||||
* If the Xtensa processor configuration includes coprocessors, then space is
|
||||
* allocated to save the coprocessor state on the stack.
|
||||
*
|
||||
* If thread safety is enabled for the C runtime library,
|
||||
* (XT_USE_THREAD_SAFE_CLIB is defined) then space is allocated to save the C
|
||||
* library context in the TCB.
|
||||
*
|
||||
* Allocating insufficient stack space is a common source of hard-to-find
|
||||
* errors. During development, it is best to enable the FreeRTOS stack
|
||||
* checking features.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* XT_USE_THREAD_SAFE_CLIB -- Define this to a nonzero value to enable
|
||||
* thread-safe use of the C library. This will require extra stack space to be
|
||||
* allocated for threads that use the C library reentrant functions. See below
|
||||
* for more information.
|
||||
*
|
||||
* NOTE: The Xtensa toolchain supports multiple C libraries and not all of them
|
||||
* support thread safety. Check your core configuration to see which C library
|
||||
* was chosen for your system.
|
||||
*
|
||||
* XT_STACK_MIN_SIZE -- The minimum stack size for any task. It is
|
||||
* recommended that you do not use a stack smaller than this for any task. In
|
||||
* case you want to use stacks smaller than this size, you must verify that the
|
||||
* smaller size(s) will work under all operating conditions.
|
||||
*
|
||||
* XT_STACK_EXTRA -- The amount of extra stack space to allocate for a
|
||||
* task that does not make C library reentrant calls. Add this to the amount of
|
||||
* stack space required by the task itself.
|
||||
*
|
||||
* XT_STACK_EXTRA_CLIB -- The amount of space to allocate for C library
|
||||
* state.
|
||||
*/
|
||||
|
||||
/* Extra space required for interrupt/exception hooks. */
|
||||
#ifdef XT_INTEXC_HOOKS
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
#define STK_INTEXC_EXTRA 0x200
|
||||
#else
|
||||
#define STK_INTEXC_EXTRA 0x180
|
||||
#endif
|
||||
#else
|
||||
#define STK_INTEXC_EXTRA 0
|
||||
#endif
|
||||
|
||||
/* Check C library thread safety support and compute size of C library save
|
||||
* area.
|
||||
*/
|
||||
#if XT_USE_THREAD_SAFE_CLIB > 0u
|
||||
#if XSHAL_CLIB == XTHAL_CLIB_XCLIB
|
||||
#define XT_HAVE_THREAD_SAFE_CLIB 0
|
||||
#error "Thread-safe operation is not yet supported for the XCLIB C library."
|
||||
#elif XSHAL_CLIB == XTHAL_CLIB_NEWLIB
|
||||
#define XT_HAVE_THREAD_SAFE_CLIB 1
|
||||
#if !defined __ASSEMBLER__
|
||||
#include <sys/reent.h>
|
||||
#define XT_CLIB_CONTEXT_AREA_SIZE ((sizeof(struct _reent) + 15) + (-16))
|
||||
#define XT_CLIB_GLOBAL_PTR _impure_ptr
|
||||
#endif
|
||||
#else
|
||||
#define XT_HAVE_THREAD_SAFE_CLIB 0
|
||||
#error "The selected C runtime library is not thread safe."
|
||||
#endif
|
||||
#else
|
||||
#define XT_CLIB_CONTEXT_AREA_SIZE 0
|
||||
#endif
|
||||
|
||||
/* Extra size -- interrupt frame plus coprocessor save area plus hook space.
|
||||
*
|
||||
* NOTE: Make sure XT_INTEXC_HOOKS is undefined unless you really need the
|
||||
* hooks.
|
||||
*/
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
#define XT_XTRA_SIZE (XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x10 + XT_CP_SIZE)
|
||||
#else
|
||||
#define XT_XTRA_SIZE (XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x20 + XT_CP_SIZE)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Space allocated for user code -- function calls and local variables.
|
||||
*
|
||||
* NOTE: This number can be adjusted to suit your needs. You must verify that
|
||||
* the amount of space you reserve is adequate for the worst-case conditions in
|
||||
* your application. NOTE: The windowed ABI requires more stack, since space
|
||||
* has to be reserved for spilling register windows.
|
||||
*/
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
#define XT_USER_SIZE 0x200
|
||||
#else
|
||||
#define XT_USER_SIZE 0x400
|
||||
#endif
|
||||
|
||||
/* Minimum recommended stack size. */
|
||||
#define XT_STACK_MIN_SIZE \
|
||||
((XT_XTRA_SIZE + XT_USER_SIZE) / sizeof(unsigned char))
|
||||
|
||||
/* OS overhead with and without C library thread context. */
|
||||
#define XT_STACK_EXTRA (XT_XTRA_SIZE)
|
||||
#define XT_STACK_EXTRA_CLIB (XT_XTRA_SIZE + XT_CLIB_CONTEXT_AREA_SIZE)
|
||||
|
||||
|
||||
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_CONFIG_H_ */
|
323
include/arch/xtensa/xtensa_context.h
Normal file
323
include/arch/xtensa/xtensa_context.h
Normal file
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES
|
||||
*
|
||||
* This header contains definitions and macros for use primarily by Xtensa RTOS
|
||||
* assembly coded source files. It includes and uses the Xtensa hardware
|
||||
* abstraction layer (HAL) to deal with config specifics. It may also be
|
||||
* included in C source files.
|
||||
*
|
||||
* Supports only Xtensa Exception Architecture 2 (XEA2). XEA1 not supported.
|
||||
*
|
||||
* NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_CONTEXT_H_
|
||||
#define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_CONTEXT_H_
|
||||
|
||||
#include <xtensa/config/tie.h>
|
||||
#include <xtensa/corebits.h>
|
||||
#include <xtensa/config/system.h>
|
||||
#include <xtensa/xtruntime-frames.h>
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
#include <xtensa/coreasm.h>
|
||||
#else /* __ASSEMBLER__ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
/* Align a value up to nearest n-byte boundary, where n is a power of 2. */
|
||||
#define ALIGNUP(n, val) (((val) + (n)-1) & -(n))
|
||||
|
||||
/*
|
||||
* INTERRUPT/EXCEPTION STACK FRAME FOR A THREAD OR NESTED INTERRUPT
|
||||
*
|
||||
* A stack frame of this structure is allocated for any interrupt or exception.
|
||||
* It goes on the current stack. If the RTOS has a system stack for handling
|
||||
* interrupts, every thread stack must allow space for just one interrupt stack
|
||||
* frame, then nested interrupt stack frames go on the system stack.
|
||||
*
|
||||
* The frame includes basic registers (explicit) and "extra" registers
|
||||
* introduced by user TIE or the use of the MAC16 option in the user's Xtensa
|
||||
* config. The frame size is minimized by omitting regs not applicable to
|
||||
* user's config.
|
||||
*
|
||||
* For Windowed ABI, this stack frame includes the interruptee's base save
|
||||
* area, another base save area to manage gcc nested functions, and a little
|
||||
* temporary space to help manage the spilling of the register windows.
|
||||
*/
|
||||
|
||||
STRUCT_BEGIN
|
||||
STRUCT_FIELD(long, 4, XT_STK_, exit) /* exit point for dispatch */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, pc) /* return PC */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, ps) /* return PS */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a0)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a1) /* stack pointer before irq */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a2)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a3)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a4)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a5)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a6)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a7)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a8)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a9)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a10)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a11)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a12)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a13)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a14)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, a15)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, sar)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, exccause)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, excvaddr)
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
STRUCT_FIELD(long, 4, XT_STK_, lbeg)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, lend)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, lcount)
|
||||
#endif
|
||||
#ifndef __XTENSA_CALL0_ABI__
|
||||
/* Temporary space for saving stuff during window spill */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, tmp0)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, tmp1)
|
||||
STRUCT_FIELD(long, 4, XT_STK_, tmp2)
|
||||
#endif
|
||||
#ifdef XT_USE_SWPRI
|
||||
/* Storage for virtual priority mask */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, vpri)
|
||||
#endif
|
||||
#ifdef XT_USE_OVLY
|
||||
/* Storage for overlay state */
|
||||
STRUCT_FIELD(long, 4, XT_STK_, ovly)
|
||||
#endif
|
||||
STRUCT_END(XtExcFrame)
|
||||
|
||||
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
|
||||
#define XT_STK_NEXT1 XtExcFrameSize
|
||||
#else
|
||||
#define XT_STK_NEXT1 sizeof(XtExcFrame)
|
||||
#endif
|
||||
|
||||
/* Allocate extra storage if needed */
|
||||
#if XCHAL_EXTRA_SA_SIZE != 0
|
||||
|
||||
#if XCHAL_EXTRA_SA_ALIGN <= 16
|
||||
#define XT_STK_EXTRA ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1)
|
||||
#else
|
||||
/* If need more alignment than stack, add space for dynamic alignment */
|
||||
#define XT_STK_EXTRA (ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) \
|
||||
+ XCHAL_EXTRA_SA_ALIGN)
|
||||
#endif
|
||||
#define XT_STK_NEXT2 (XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE)
|
||||
|
||||
#else
|
||||
|
||||
#define XT_STK_NEXT2 XT_STK_NEXT1
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is the frame size. Add space for 4 registers (interruptee's base save
|
||||
* area) and some space for gcc nested functions if any.
|
||||
*/
|
||||
#define XT_STK_FRMSZ (ALIGNUP(0x10, XT_STK_NEXT2) + 0x20)
|
||||
|
||||
|
||||
/*
|
||||
* SOLICITED STACK FRAME FOR A THREAD
|
||||
*
|
||||
* A stack frame of this structure is allocated whenever a thread enters the
|
||||
* RTOS kernel intentionally (and synchronously) to submit to thread
|
||||
* scheduling. It goes on the current thread's stack.
|
||||
*
|
||||
* The solicited frame only includes registers that are required to be
|
||||
* preserved by the callee according to the compiler's ABI conventions, some
|
||||
* space to save the return address for returning to the caller, and the
|
||||
* caller's PS register. For Windowed ABI, this stack frame includes the
|
||||
* caller's base save area.
|
||||
*
|
||||
* Note on XT_SOL_EXIT field:
|
||||
*
|
||||
* It is necessary to distinguish a solicited from an interrupt stack frame.
|
||||
* This field corresponds to XT_STK_EXIT in the interrupt stack frame and is
|
||||
* always at the same offset (0). It can be written with a code (usually 0) to
|
||||
* distinguish a solicted frame from an interrupt frame. An RTOS port may opt
|
||||
* to ignore this field if it has another way of distinguishing frames.
|
||||
*/
|
||||
|
||||
STRUCT_BEGIN
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, exit)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, pc)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, ps)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, next)
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a12) /* should be on 16-byte alignment */
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a13)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a14)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a15)
|
||||
#else
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a0) /* should be on 16-byte alignment */
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a1)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a2)
|
||||
STRUCT_FIELD(long, 4, XT_SOL_, a3)
|
||||
#endif
|
||||
STRUCT_END(XtSolFrame)
|
||||
|
||||
/* Size of solicited stack frame */
|
||||
#define XT_SOL_FRMSZ ALIGNUP(0x10, XtSolFrameSize)
|
||||
|
||||
|
||||
/*
|
||||
* CO-PROCESSOR STATE SAVE AREA FOR A THREAD
|
||||
*
|
||||
* The RTOS must provide an area per thread to save the state of co-processors
|
||||
* when that thread does not have control. Co-processors are context-switched
|
||||
* lazily (on demand) only when a new thread uses a co-processor instruction,
|
||||
* otherwise a thread retains ownership of the co-processor even when it loses
|
||||
* control of the processor. An Xtensa co-processor exception is triggered when
|
||||
* any co-processor instruction is executed by a thread that is not the owner,
|
||||
* and the context switch of that co-processor is then performed by the handler.
|
||||
* Ownership represents which thread's state is currently in the co-processor.
|
||||
*
|
||||
* Co-processors may not be used by interrupt or exception handlers. If a
|
||||
* co-processor instruction is executed by an interrupt or exception handler,
|
||||
* the co-processor exception handler will trigger a kernel panic and freeze.
|
||||
* This restriction is introduced to reduce the overhead of saving and
|
||||
* restoring co-processor state (which can be quite large) and in particular
|
||||
* remove that overhead from interrupt handlers.
|
||||
*
|
||||
* The co-processor state save area may be in any convenient per-thread
|
||||
* location such as in the thread control block or above the thread stack area.
|
||||
* It need not be in the interrupt stack frame since interrupts don't use
|
||||
* co-processors.
|
||||
*
|
||||
* Along with the save area for each co-processor, two bitmasks with flags per
|
||||
* co-processor (laid out as in the CPENABLE reg) help manage context-switching
|
||||
* co-processors as efficiently as possible:
|
||||
*
|
||||
* XT_CPENABLE
|
||||
*
|
||||
* The contents of a non-running thread's CPENABLE register. It represents the
|
||||
* co-processors owned (and whose state is still needed) by the thread. When a
|
||||
* thread is preempted, its CPENABLE is saved here. When a thread solicits a
|
||||
* context-swtich, its CPENABLE is cleared - the compiler has saved the
|
||||
* (caller-saved) co-proc state if it needs to. When a non-running thread
|
||||
* loses ownership of a CP, its bit is cleared. When a thread runs, it's
|
||||
* XT_CPENABLE is loaded into the CPENABLE reg. Avoids co-processor exceptions
|
||||
* when no change of ownership is needed.
|
||||
*
|
||||
* XT_CPSTORED
|
||||
*
|
||||
* A bitmask with the same layout as CPENABLE, a bit per co-processor.
|
||||
* Indicates whether the state of each co-processor is saved in the state save
|
||||
* area. When a thread enters the kernel, only the state of co-procs still
|
||||
* enabled in CPENABLE is saved. When the co-processor exception handler
|
||||
* assigns ownership of a co-processor to a thread, it restores the saved state
|
||||
* only if this bit is set, and clears this bit.
|
||||
*
|
||||
* XT_CP_CS_ST
|
||||
*
|
||||
* A bitmask with the same layout as CPENABLE, a bit per co-processor.
|
||||
* Indicates whether callee-saved state is saved in the state save area.
|
||||
* Callee-saved state is saved by itself on a solicited context switch, and
|
||||
* restored when needed by the coprocessor exception handler. Unsolicited
|
||||
* switches will cause the entire coprocessor to be saved when necessary.
|
||||
*
|
||||
* XT_CP_ASA
|
||||
*
|
||||
* Pointer to the aligned save area. Allows it to be aligned more than the
|
||||
* overall save area (which might only be stack-aligned or TCB-aligned).
|
||||
* Especially relevant for Xtensa cores configured with a very large data path
|
||||
* that requires alignment greater than 16 bytes (ABI stack alignment).
|
||||
*/
|
||||
|
||||
#define XT_CP_DESCR_SIZE 12
|
||||
|
||||
#if XCHAL_CP_NUM > 0
|
||||
|
||||
/* Offsets of each coprocessor save area within the 'aligned save area': */
|
||||
#define XT_CP0_SA 0
|
||||
#define XT_CP1_SA ALIGNUP(XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE)
|
||||
#define XT_CP2_SA ALIGNUP(XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE)
|
||||
#define XT_CP3_SA ALIGNUP(XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE)
|
||||
#define XT_CP4_SA ALIGNUP(XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE)
|
||||
#define XT_CP5_SA ALIGNUP(XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE)
|
||||
#define XT_CP6_SA ALIGNUP(XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE)
|
||||
#define XT_CP7_SA ALIGNUP(XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE)
|
||||
#define XT_CP_SA_SIZE ALIGNUP(16, XT_CP7_SA + XCHAL_CP7_SA_SIZE)
|
||||
|
||||
/* Offsets within the overall save area: */
|
||||
|
||||
/* (2 bytes) coprocessors active for this thread */
|
||||
#define XT_CPENABLE 0
|
||||
|
||||
/* (2 bytes) coprocessors saved for this thread */
|
||||
#define XT_CPSTORED 2
|
||||
|
||||
/* (2 bytes) coprocessor callee-saved regs stored for this thread */
|
||||
#define XT_CP_CS_ST 4
|
||||
|
||||
/* (4 bytes) ptr to aligned save area */
|
||||
#define XT_CP_ASA 8
|
||||
|
||||
/* Overall size allows for dynamic alignment: */
|
||||
#define XT_CP_SIZE ALIGNUP(XCHAL_TOTAL_SA_ALIGN, \
|
||||
XT_CP_DESCR_SIZE + XT_CP_SA_SIZE)
|
||||
#else
|
||||
#define XT_CP_SIZE 0
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN
|
||||
*
|
||||
* Convenient where the frame size requirements are the same for both ABIs.
|
||||
* ENTRY(sz), RET(sz) are for framed functions (have locals or make calls).
|
||||
* ENTRY0, RET0 are for frameless functions (no locals, no calls).
|
||||
*
|
||||
* where size = size of stack frame in bytes (must be >0 and aligned to 16).
|
||||
* For framed functions the frame is created and the return address saved at
|
||||
* base of frame (Call0 ABI) or as determined by hardware (Windowed ABI). For
|
||||
* frameless functions, there is no frame and return address remains in
|
||||
* a0.
|
||||
*
|
||||
* Note: Because CPP macros expand to a single line, macros requiring
|
||||
* multi-line expansions are implemented as assembler macros.
|
||||
*/
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
/* Call0 */
|
||||
#define ENTRY(sz) entry1 sz
|
||||
.macro entry1 size=0x10
|
||||
addi sp, sp, -\size
|
||||
s32i a0, sp, 0
|
||||
.endm
|
||||
#define ENTRY0
|
||||
#define RET(sz) ret1 sz
|
||||
.macro ret1 size=0x10
|
||||
l32i a0, sp, 0
|
||||
addi sp, sp, \size
|
||||
ret
|
||||
.endm
|
||||
#define RET0 ret
|
||||
#else
|
||||
/* Windowed */
|
||||
#define ENTRY(sz) entry sp, sz
|
||||
#define ENTRY0 entry sp, 0x10
|
||||
#define RET(sz) retw
|
||||
#define RET0 retw
|
||||
#endif /* __XTENSA_CALL0_ABI__ */
|
||||
#else /* __ASSEMBLER__ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
|
||||
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_CONTEXT_H_ */
|
204
include/arch/xtensa/xtensa_rtos.h
Normal file
204
include/arch/xtensa/xtensa_rtos.h
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* RTOS-SPECIFIC INFORMATION FOR XTENSA RTOS ASSEMBLER SOURCES
|
||||
* (FreeRTOS Port)
|
||||
*
|
||||
* This header is the primary glue between generic Xtensa RTOS support
|
||||
* sources and a specific RTOS port for Xtensa. It contains definitions
|
||||
* and macros for use primarily by Xtensa assembly coded source files.
|
||||
*
|
||||
* Macros in this header map callouts from generic Xtensa files to specific
|
||||
* RTOS functions. It may also be included in C source files.
|
||||
*
|
||||
* Xtensa RTOS ports support all RTOS-compatible configurations of the Xtensa
|
||||
* architecture, using the Xtensa hardware abstraction layer (HAL) to deal
|
||||
* with configuration specifics.
|
||||
*
|
||||
* Should be included by all Xtensa generic and RTOS port-specific sources.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_RTOS_H_
|
||||
#define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_RTOS_H_
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
#include <xtensa/coreasm.h>
|
||||
#else
|
||||
#include <xtensa/config/core.h>
|
||||
#endif
|
||||
|
||||
#include <xtensa/corebits.h>
|
||||
#include <xtensa/config/system.h>
|
||||
|
||||
|
||||
/*
|
||||
* Convert Zephyr definitions to XTENSA definitions.
|
||||
*/
|
||||
|
||||
#undef XT_SIMULATOR
|
||||
#undef XT_BOARD
|
||||
#ifdef CONFIG_SIMULATOR_XTENSA
|
||||
#define XT_SIMULATOR 1
|
||||
#else
|
||||
#define XT_BOARD 1
|
||||
#endif
|
||||
|
||||
#undef XT_CLOCK_FREQ
|
||||
#define XT_CLOCK_FREQ DT_CPU_CLOCK_FREQUENCY
|
||||
|
||||
#ifndef XT_TIMER_INDEX
|
||||
#if defined configXT_TIMER_INDEX
|
||||
/* Index of hardware timer to be used */
|
||||
#define XT_TIMER_INDEX configXT_TIMER_INDEX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef XT_INTEXC_HOOKS
|
||||
#if configXT_INTEXC_HOOKS
|
||||
#define XT_INTEXC_HOOKS 1 /* Enables exception hooks */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (!XT_SIMULATOR) && (!XT_BOARD)
|
||||
#error Either XT_SIMULATOR or XT_BOARD must be defined.
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Name of RTOS (for messages).
|
||||
*/
|
||||
#define XT_RTOS_NAME Zephyr
|
||||
|
||||
/*
|
||||
* Define for enabling RTOS specific code. Enable only one of below lines.
|
||||
*/
|
||||
#define XT_RTOS_IS_ZEPHYR_OS 1
|
||||
#undef XT_RTOS_IS_FREE_RTOS
|
||||
|
||||
/*
|
||||
* Check some Xtensa configuration requirements and report error if not met.
|
||||
* Error messages can be customize to the RTOS port.
|
||||
*/
|
||||
|
||||
#if !XCHAL_HAVE_XEA2
|
||||
#error "Zephyr/Xtensa requires XEA2 (exception architecture 2)."
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RTOS CALLOUT MACROS MAPPED TO RTOS PORT-SPECIFIC FUNCTIONS.
|
||||
*
|
||||
* Define callout macros used in generic Xtensa code to interact with the RTOS.
|
||||
* The macros are simply the function names for use in calls from assembler
|
||||
* code.
|
||||
* Some of these functions may call back to generic functions in
|
||||
* xtensa_context.h .
|
||||
*/
|
||||
|
||||
/*
|
||||
* Inform RTOS of entry into an interrupt handler that will affect it.
|
||||
* Allows RTOS to manage switch to any system stack and count nesting level.
|
||||
* Called after minimal context has been saved, with interrupts disabled.
|
||||
* RTOS port can call0 _xt_context_save to save the rest of the context.
|
||||
* May only be called from assembly code by the 'call0' instruction.
|
||||
*/
|
||||
#define XT_RTOS_INT_ENTER _zxt_int_enter
|
||||
|
||||
/*
|
||||
* Inform RTOS of completion of an interrupt handler, and give control to
|
||||
* RTOS to perform thread/task scheduling, switch back from any system stack
|
||||
* and restore the context, and return to the exit dispatcher saved in the
|
||||
* stack frame at XT_STK_EXIT. RTOS port can call0 _xt_context_restore
|
||||
* to save the context saved in XT_RTOS_INT_ENTER via _xt_context_save,
|
||||
* leaving only a minimal part of the context to be restored by the exit
|
||||
* dispatcher. This function does not return to the place it was called from.
|
||||
* May only be called from assembly code by the 'call0' instruction.
|
||||
*/
|
||||
#define XT_RTOS_INT_EXIT _zxt_int_exit
|
||||
|
||||
/*
|
||||
* Inform RTOS of the occurrence of a tick timer interrupt.
|
||||
* If RTOS has no tick timer, leave XT_RTOS_TIMER_INT undefined.
|
||||
* May be coded in or called from C or assembly, per ABI conventions.
|
||||
* RTOS may optionally define XT_TICK_PER_SEC in its own way (eg. macro).
|
||||
*/
|
||||
#define XT_RTOS_TIMER_INT _zxt_timer_int
|
||||
|
||||
#if CONFIG_TICKLESS_KERNEL
|
||||
#define XT_TICK_PER_SEC 1000
|
||||
#else
|
||||
#define XT_TICK_PER_SEC CONFIG_SYS_CLOCK_TICKS_PER_SEC
|
||||
#endif /* CONFIG_TICKLESS_KERNEL */
|
||||
|
||||
/*
|
||||
* Return in a15 the base address of the co-processor state save area for the
|
||||
* thread that triggered a co-processor exception, or 0 if no thread was
|
||||
* running. The state save area is structured as defined in xtensa_context.h
|
||||
* and has size XT_CP_SIZE. Co-processor instructions should only be used in
|
||||
* thread code, never in interrupt handlers or the RTOS kernel. May only be
|
||||
* called from assembly code and by the 'call0' instruction. A result of 0
|
||||
* indicates an unrecoverable error.
|
||||
*
|
||||
* The implementation may use only a2-4, a15 (all other regs must be
|
||||
* preserved).
|
||||
*/
|
||||
#define XT_RTOS_CP_STATE _zxt_task_coproc_state
|
||||
|
||||
|
||||
/*
|
||||
* HOOKS TO DYNAMICALLY INSTALL INTERRUPT AND EXCEPTION HANDLERS PER LEVEL.
|
||||
*
|
||||
* This Xtensa RTOS port provides hooks for dynamically installing exception
|
||||
* and interrupt handlers to facilitate automated testing where each test case
|
||||
* can install its own handler for user exceptions and each interrupt priority
|
||||
* (level). This consists of an array of function pointers indexed by interrupt
|
||||
* priority, with index 0 being the user exception handler hook. Each entry in
|
||||
* the array is initially 0, and may be replaced by a function pointer of type
|
||||
* XT_INTEXC_HOOK. A handler may be uninstalled by installing 0.
|
||||
*
|
||||
* The handler for low and medium priority obeys ABI conventions so may be
|
||||
* coded in C. For the exception handler, the cause is the contents of the
|
||||
* EXCCAUSE reg, and the result is -1 if handled, else the cause (still needs
|
||||
* handling). For interrupt handlers, the cause is a mask of pending enabled
|
||||
* interrupts at that level, and the result is the same mask with the bits for
|
||||
* the handled interrupts cleared (those not cleared still need handling). This
|
||||
* allows a test case to either pre-handle or override the default handling for
|
||||
* the exception or interrupt level (see xtensa_vectors.S).
|
||||
*
|
||||
* High priority handlers (including NMI) must be coded in assembly, are always
|
||||
* called by 'call0' regardless of ABI, must preserve all registers except a0,
|
||||
* and must not use or modify the interrupted stack. The hook argument 'cause'
|
||||
* is not passed and the result is ignored, so as not to burden the caller
|
||||
* with saving and restoring a2 (it assumes only one interrupt per level - see
|
||||
* the discussion in high priority interrupts in xtensa_vectors.S). The handler
|
||||
* therefore should be coded to prototype 'void h(void)' even though it plugs
|
||||
* into an array of handlers of prototype 'unsigned h(unsigned)'.
|
||||
*
|
||||
* To enable interrupt/exception hooks, compile the RTOS with
|
||||
* '-DXT_INTEXC_HOOKS'.
|
||||
*/
|
||||
#define XT_INTEXC_HOOK_NUM (1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
typedef unsigned int (*XT_INTEXC_HOOK)(unsigned int cause);
|
||||
extern volatile XT_INTEXC_HOOK _xt_intexc_hooks[XT_INTEXC_HOOK_NUM];
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* CONVENIENCE INCLUSIONS.
|
||||
*
|
||||
* Ensures RTOS specific files need only include this one Xtensa-generic
|
||||
* header. These headers are included last so they can use the RTOS
|
||||
* definitions above.
|
||||
*/
|
||||
|
||||
#include "xtensa_context.h"
|
||||
|
||||
#ifdef XT_RTOS_TIMER_INT
|
||||
#include "xtensa_timer.h"
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_RTOS_H_ */
|
156
include/arch/xtensa/xtensa_timer.h
Normal file
156
include/arch/xtensa/xtensa_timer.h
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Cadence Design Systems, Inc.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* XTENSA INFORMATION FOR RTOS TICK TIMER AND CLOCK FREQUENCY
|
||||
*
|
||||
* This header contains definitions and macros for use primarily by Xtensa
|
||||
* RTOS assembly coded source files. It includes and uses the Xtensa hardware
|
||||
* abstraction layer (HAL) to deal with config specifics. It may also be
|
||||
* included in C source files.
|
||||
*
|
||||
* User may edit to modify timer selection and to specify clock frequency and
|
||||
* tick duration to match timer interrupt to the real-time tick duration.
|
||||
*
|
||||
* If the RTOS has no timer interrupt, then there is no tick timer and the
|
||||
* clock frequency is irrelevant, so all of these macros are left undefined
|
||||
* and the Xtensa core configuration need not have a timer.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_TIMER_H_
|
||||
#define ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_TIMER_H_
|
||||
|
||||
#ifdef __ASSEMBLER__
|
||||
#include <xtensa/coreasm.h>
|
||||
#endif
|
||||
|
||||
#include <xtensa/corebits.h>
|
||||
#include <xtensa/config/system.h>
|
||||
|
||||
#include "xtensa_rtos.h" /* in case this wasn't included directly */
|
||||
|
||||
#define USE_INTERNAL_TIMER 1
|
||||
#define EXTERNAL_TIMER_IRQ -1
|
||||
|
||||
#if USE_INTERNAL_TIMER || (EXTERNAL_TIMER_IRQ < 0)
|
||||
/*
|
||||
* Select timer to use for periodic tick, and determine its interrupt number
|
||||
* and priority. User may specify a timer by defining XT_TIMER_INDEX with -D,
|
||||
* in which case its validity is checked (it must exist in this core and must
|
||||
* not be on a high priority interrupt - an error will be reported in invalid).
|
||||
* Otherwise select the first low or medium priority interrupt timer available.
|
||||
*/
|
||||
#if XCHAL_NUM_TIMERS == 0
|
||||
#error "This Xtensa configuration is unsupported, it has no timers."
|
||||
#endif /* XCHAL_NUM_TIMERS */
|
||||
|
||||
#ifndef XT_TIMER_INDEX
|
||||
#if XCHAL_TIMER3_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
|
||||
#if XCHAL_INT_LEVEL(XCHAL_TIMER3_INTERRUPT) <= XCHAL_EXCM_LEVEL
|
||||
#undef XT_TIMER_INDEX
|
||||
#define XT_TIMER_INDEX 3
|
||||
#endif
|
||||
#endif
|
||||
#if XCHAL_TIMER2_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
|
||||
#if XCHAL_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL
|
||||
#undef XT_TIMER_INDEX
|
||||
#define XT_TIMER_INDEX 2
|
||||
#endif
|
||||
#endif
|
||||
#if XCHAL_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
|
||||
#if XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL
|
||||
#undef XT_TIMER_INDEX
|
||||
#define XT_TIMER_INDEX 1
|
||||
#endif
|
||||
#endif
|
||||
#if XCHAL_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
|
||||
#if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL
|
||||
#undef XT_TIMER_INDEX
|
||||
#define XT_TIMER_INDEX 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifndef XT_TIMER_INDEX
|
||||
#error "There is no suitable timer in this Xtensa configuration."
|
||||
#endif
|
||||
|
||||
#define XT_CCOMPARE ((CCOMPARE) + (XT_TIMER_INDEX))
|
||||
#define XT_TIMER_INTNUM XCHAL_TIMER_INTERRUPT(XT_TIMER_INDEX)
|
||||
#if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED
|
||||
#error "The timer selected by XT_TIMER_INDEX does not exist in this core."
|
||||
#endif
|
||||
#else /* Case of an external timer which is not emulated by internal timer */
|
||||
#define XT_TIMER_INTNUM EXTERNAL_TIMER_IRQ
|
||||
#endif /* USE_INTERNAL_TIMER || (EXTERNAL_TIMER_IRQ < 0) */
|
||||
|
||||
#if USE_INTERNAL_TIMER
|
||||
#define XT_TIMER_INTPRI XCHAL_INT_LEVEL(XT_TIMER_INTNUM)
|
||||
#else
|
||||
#define XT_TIMER_INTPRI EXTERNAL_TIMER_IRQ_PRIORITY
|
||||
#endif /* USE_INTERNAL_TIMER */
|
||||
|
||||
#if XT_TIMER_INTPRI > XCHAL_EXCM_LEVEL
|
||||
#error "The timer interrupt cannot be high priority (use medium or low)."
|
||||
#endif
|
||||
|
||||
#define XT_TIMER_INTEN (1 << (XT_TIMER_INTNUM))
|
||||
|
||||
/*
|
||||
* Set processor clock frequency, used to determine clock divisor for timer
|
||||
* tick. User should BE SURE TO ADJUST THIS for the Xtensa platform being
|
||||
* used. If using a supported board via the board-independent API defined in
|
||||
* xtbsp.h, this may be left undefined and frequency and tick divisor will be
|
||||
* computed and cached during run-time initialization.
|
||||
*
|
||||
* NOTE ON SIMULATOR: Under the Xtensa instruction set simulator, the frequency
|
||||
* can only be estimated because it depends on the speed of the host and the
|
||||
* version of the simulator. Also because it runs much slower than hardware,
|
||||
* it is not possible to achieve real-time performance for most applications
|
||||
* under the simulator. A frequency too low does not allow enough time between
|
||||
* timer interrupts, starving threads. To obtain a more convenient but
|
||||
* non-real-time tick duration on the simulator, compile with xt-xcc option
|
||||
* "-DXT_SIMULATOR". Adjust this frequency to taste (it's not real-time
|
||||
* anyway!).
|
||||
*/
|
||||
#if defined(XT_SIMULATOR) && !defined(XT_CLOCK_FREQ)
|
||||
#define XT_CLOCK_FREQ DT_CPU_CLOCK_FREQUENCY
|
||||
#endif
|
||||
|
||||
#if !defined(XT_CLOCK_FREQ) && !defined(XT_BOARD)
|
||||
#error "XT_CLOCK_FREQ must be defined for the target platform."
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default number of timer "ticks" per second (default 100 for 10ms tick).
|
||||
* RTOS may define this in its own way (if applicable) in xtensa_rtos.h.
|
||||
* User may redefine this to an optimal value for the application, either by
|
||||
* editing this here or in xtensa_rtos.h, or compiling with xt-xcc option
|
||||
* "-DXT_TICK_PER_SEC=<value>" where <value> is a suitable number.
|
||||
*/
|
||||
#ifndef XT_TICK_PER_SEC
|
||||
#if CONFIG_TICKLESS_KERNEL
|
||||
#define XT_TICK_PER_SEC 1000 /* In tickless kernel 1TICK = 1msec */
|
||||
#else
|
||||
#define XT_TICK_PER_SEC CONFIG_SYS_CLOCK_TICKS_PER_SEC
|
||||
#endif /* CONFIG_TICKLESS_KERNEL */
|
||||
#endif /* XT_TICK_PER_SEC */
|
||||
|
||||
/*
|
||||
* Derivation of clock divisor for timer tick and interrupt (one per tick).
|
||||
*/
|
||||
#ifdef XT_CLOCK_FREQ
|
||||
#define XT_TICK_DIVISOR (XT_CLOCK_FREQ / XT_TICK_PER_SEC)
|
||||
#endif
|
||||
|
||||
#if USE_INTERNAL_TIMER || (EXTERNAL_TIMER_IRQ < 0)
|
||||
#ifndef __ASSEMBLER__
|
||||
extern unsigned int _xt_tick_divisor;
|
||||
extern void z_xt_tick_divisor_init(void);
|
||||
#endif
|
||||
|
||||
#endif // Internal/External timer
|
||||
|
||||
#endif /* ZEPHYR_ARCH_XTENSA_INCLUDE_XTENSA_TIMER_H_ */
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue